/[svn]/linuxsampler/trunk/src/engines/EngineChannel.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/EngineChannel.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 947 by schoenebeck, Mon Nov 27 21:34:55 2006 UTC revision 973 by schoenebeck, Fri Dec 15 21:40:27 2006 UTC
# Line 23  Line 23 
23    
24  #include "EngineChannel.h"  #include "EngineChannel.h"
25    
26    #include <algorithm>
27    
28    #include "../drivers/midi/MidiInstrumentMapper.h"
29    
30    #define NO_MIDI_INSTRUMENT_MAP          -1
31    #define DEFAULT_MIDI_INSTRUMENT_MAP     -2
32    
33  namespace LinuxSampler {  namespace LinuxSampler {
34    
35      EngineChannel::EngineChannel() {      EngineChannel::EngineChannel() {
# Line 31  namespace LinuxSampler { Line 38  namespace LinuxSampler {
38          uiMidiBankMsb = 0;          uiMidiBankMsb = 0;
39          uiMidiBankLsb = 0;          uiMidiBankLsb = 0;
40          uiMidiProgram = 0;          uiMidiProgram = 0;
41            bProgramChangeReceived = bMidiBankMsbReceived = bMidiBankLsbReceived = false;
42            iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
43      }      }
44    
45      void EngineChannel::SetMute(int state) throw (Exception) {      void EngineChannel::SetMute(int state) throw (Exception) {
# Line 57  namespace LinuxSampler { Line 66  namespace LinuxSampler {
66          return bSolo;          return bSolo;
67      }      }
68    
69        /*
70           We use a workaround for MIDI devices (i.e. old keyboards) which either
71           only send bank select MSB or only bank select LSB messages. Bank
72           selects will be modified according to the following table:
73    
74           MIDI Sequence received:            -> GetMidiBankMsb()= | GetMidiBankLsb()=
75           ---------------------------------------------------------------------------
76           program change                     ->        0          |        0
77           bank LSB, program change           ->        0          |     LSB value
78           bank MSB, program change           ->        0          |     MSB value
79           bank LSB, bank MSB, program change ->     MSB value     |     LSB value
80           bank MSB, bank LSB, program change ->     MSB value     |     LSB value
81           ---------------------------------------------------------------------------
82    
83           That way we ensure those limited devices always to switch between the
84           following set of MIDI instrument banks:  { 0, 1, 2, ..., 127 }
85        */
86    
87      uint8_t EngineChannel::GetMidiProgram() {      uint8_t EngineChannel::GetMidiProgram() {
88          return uiMidiProgram; // AFAIK atomic on all systems          return uiMidiProgram; // AFAIK atomic on all systems
89      }      }
90    
91      void EngineChannel::SetMidiProgram(uint8_t Program) {      void EngineChannel::SetMidiProgram(uint8_t Program) {
92            bProgramChangeReceived = true;
93          uiMidiProgram = Program; // AFAIK atomic on all systems          uiMidiProgram = Program; // AFAIK atomic on all systems
94      }      }
95    
96      uint8_t EngineChannel::GetMidiBankMsb() {      uint8_t EngineChannel::GetMidiBankMsb() {
97          return uiMidiBankMsb; // AFAIK atomic on all systems          return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;
98      }      }
99    
100      void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {      void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
101            if (bProgramChangeReceived)
102                bProgramChangeReceived = bMidiBankLsbReceived = false;
103            bMidiBankMsbReceived = true;
104          uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems          uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
105      }      }
106    
107      uint8_t EngineChannel::GetMidiBankLsb() {      uint8_t EngineChannel::GetMidiBankLsb() {
108          return uiMidiBankLsb; // AFAIK atomic on all systems          return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)
109                       ? 0
110                       : (bMidiBankMsbReceived && !bMidiBankLsbReceived)
111                             ? uiMidiBankMsb
112                             : uiMidiBankLsb;
113      }      }
114    
115      void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {      void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
116            if (bProgramChangeReceived)
117                bProgramChangeReceived = bMidiBankMsbReceived = false;
118            bMidiBankLsbReceived = true;
119          uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems          uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
120      }      }
121    
122        bool EngineChannel::UsesNoMidiInstrumentMap() {
123            return (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);
124        }
125    
126        bool EngineChannel::UsesDefaultMidiInstrumentMap() {
127            return (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);
128        }
129    
130        int EngineChannel::GetMidiInstrumentMap() throw (Exception) {
131            if (UsesNoMidiInstrumentMap())
132                throw Exception("EngineChannel is using no MIDI instrument map");
133            if (UsesDefaultMidiInstrumentMap())
134                throw Exception("EngineChannel is using default MIDI instrument map");
135            // check if the stored map still exists in the MIDI instrument mapper
136            std::vector<int> maps = MidiInstrumentMapper::Maps();
137            if (find(maps.begin(), maps.end(), iMidiInstrumentMap) == maps.end()) {
138                // it doesn't exist anymore, so fall back to NONE and throw an exception
139                iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
140                throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE");
141            }
142            return iMidiInstrumentMap;
143        }
144    
145        void EngineChannel::SetMidiInstrumentMapToNone() {
146            iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
147        }
148    
149        void EngineChannel::SetMidiInstrumentMapToDefault() {
150            iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
151        }
152    
153        void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
154            // check if given map actually exists in the MIDI instrument mapper
155            std::vector<int> maps = MidiInstrumentMapper::Maps();
156            if (find(maps.begin(), maps.end(), MidiMap) == maps.end())
157                throw Exception("MIDI instrument map doesn't exist");
158            iMidiInstrumentMap = MidiMap; // assign the new map ID
159        }
160    
161  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.947  
changed lines
  Added in v.973

  ViewVC Help
Powered by ViewVC