/[svn]/linuxsampler/trunk/src/drivers/midi/MidiInputPort.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/drivers/midi/MidiInputPort.cpp

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

revision 675 by schoenebeck, Wed Jun 22 22:09:28 2005 UTC revision 840 by persson, Sun Feb 26 13:00:08 2006 UTC
# Line 24  Line 24 
24  #include "MidiInputPort.h"  #include "MidiInputPort.h"
25    
26  #include "../../Sampler.h"  #include "../../Sampler.h"
27    #include "../../engines/EngineFactory.h"
28    
29  namespace LinuxSampler {  namespace LinuxSampler {
30    
# Line 62  namespace LinuxSampler { Line 63  namespace LinuxSampler {
63      MidiInputPort::~MidiInputPort() {      MidiInputPort::~MidiInputPort() {
64          std::map<String,DeviceRuntimeParameter*>::iterator iter = Parameters.begin();          std::map<String,DeviceRuntimeParameter*>::iterator iter = Parameters.begin();
65          while (iter != Parameters.end()) {          while (iter != Parameters.end()) {
             Parameters.erase(iter);  
66              delete iter->second;              delete iter->second;
67              iter++;              iter++;
68          }          }
69            Parameters.clear();
70      }      }
71    
72      MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber) {      MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber) {
# Line 88  namespace LinuxSampler { Line 89  namespace LinuxSampler {
89      }      }
90    
91      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) {      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) {
92            const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();
93          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
94          {          {
95              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
96              std::set<EngineChannel*>::iterator end        = MidiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
97              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);
98          }          }
99          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
100          {          {
101              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
102              std::set<EngineChannel*>::iterator end        = MidiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
103              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);
104          }          }
105            MidiChannelMap.Unlock();
106      }      }
107    
108      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) {      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) {
109            const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();
110          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
111          {          {
112              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
113              std::set<EngineChannel*>::iterator end        = MidiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
114              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);
115          }          }
116          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
117          {          {
118              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
119              std::set<EngineChannel*>::iterator end        = MidiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
120              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);
121          }          }
122            MidiChannelMap.Unlock();
123      }      }
124    
125      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) {      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) {
126            const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();
127          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
128          {          {
129              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
130              std::set<EngineChannel*>::iterator end        = MidiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
131              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);
132          }          }
133          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
134          {          {
135              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
136              std::set<EngineChannel*>::iterator end        = MidiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
137              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);
138          }          }
139            MidiChannelMap.Unlock();
140      }      }
141    
142      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) {      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) {
143            const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();
144          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
145          {          {
146              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
147              std::set<EngineChannel*>::iterator end        = MidiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
148              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);
149          }          }
150          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
151          {          {
152              std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
153              std::set<EngineChannel*>::iterator end        = MidiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
154              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);
155          }          }
156            MidiChannelMap.Unlock();
157      }      }
158    
159      void MidiInputPort::DispatchSysex(void* pData, uint Size) {      void MidiInputPort::DispatchSysex(void* pData, uint Size) {
160          // dispatch event for engines listening to the same MIDI channel          // dispatch event to all engine instances
161          {          std::set<Engine*>::iterator engineiter = EngineFactory::EngineInstances().begin();
162              for (uint MidiChannel = 0; MidiChannel <= 16; MidiChannel++) {          std::set<Engine*>::iterator end        = EngineFactory::EngineInstances().end();
163                  std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin();          for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size);
                 std::set<EngineChannel*>::iterator end        = MidiChannelMap[MidiChannel].end();  
                 for (; engineiter != end; engineiter++) {  
                     Engine* pEngine = (*engineiter)->GetEngine();  
                     if (pEngine) pEngine->SendSysex(pData, Size);  
                 }  
             }  
         }  
         // dispatch event for engines listening to ALL MIDI channels  
         {  
             for (uint MidiChannel = 0; MidiChannel <= 16; MidiChannel++) {  
                 std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin();  
                 std::set<EngineChannel*>::iterator end        = MidiChannelMap[midi_chan_all].end();  
                 for (; engineiter != end; engineiter++) {  
                     Engine* pEngine = (*engineiter)->GetEngine();  
                     if (pEngine) pEngine->SendSysex(pData, Size);  
                 }  
             }  
         }  
164      }      }
165    
166      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {
# Line 202  namespace LinuxSampler { Line 193  namespace LinuxSampler {
193          if (MidiChannel < 0 || MidiChannel > 16)          if (MidiChannel < 0 || MidiChannel > 16)
194              throw MidiInputException("MIDI channel index out of bounds");              throw MidiInputException("MIDI channel index out of bounds");
195    
196          // firt check if desired connection is already established          // first check if desired connection is already established
197          MidiChannelMapMutex.Lock();          MidiChannelMapMutex.Lock();
198          bool bAlreadyDone = MidiChannelMap[MidiChannel].count(pEngineChannel);          MidiChannelMap_t& midiChannelMap = MidiChannelMap.GetConfigForUpdate();
199            bool bAlreadyDone = midiChannelMap[MidiChannel].count(pEngineChannel);
200          MidiChannelMapMutex.Unlock();          MidiChannelMapMutex.Unlock();
201          if (bAlreadyDone) return;          if (bAlreadyDone) return;
202    
# Line 213  namespace LinuxSampler { Line 205  namespace LinuxSampler {
205    
206          // register engine channel on the desired MIDI channel          // register engine channel on the desired MIDI channel
207          MidiChannelMapMutex.Lock();          MidiChannelMapMutex.Lock();
208          MidiChannelMap[MidiChannel].insert(pEngineChannel);          MidiChannelMap.GetConfigForUpdate()[MidiChannel].insert(pEngineChannel);
209            MidiChannelMap.SwitchConfig()[MidiChannel].insert(pEngineChannel);
210          MidiChannelMapMutex.Unlock();          MidiChannelMapMutex.Unlock();
211    
212          // inform engine channel about this connection          // inform engine channel about this connection
# Line 231  namespace LinuxSampler { Line 224  namespace LinuxSampler {
224          // unregister engine channel from all MIDI channels          // unregister engine channel from all MIDI channels
225          MidiChannelMapMutex.Lock();          MidiChannelMapMutex.Lock();
226          try {          try {
227              for (int i = 0; i <= 16; i++) {              {
228                  bChannelFound |= MidiChannelMap[i].count(pEngineChannel);                  MidiChannelMap_t& midiChannelMap = MidiChannelMap.GetConfigForUpdate();
229                  MidiChannelMap[i].erase(pEngineChannel);                  for (int i = 0; i <= 16; i++) {
230                        bChannelFound |= midiChannelMap[i].count(pEngineChannel);
231                        midiChannelMap[i].erase(pEngineChannel);
232                    }
233                }
234                // do the same update again, after switching to the other config
235                {
236                    MidiChannelMap_t& midiChannelMap = MidiChannelMap.SwitchConfig();
237                    for (int i = 0; i <= 16; i++) {
238                        bChannelFound |= midiChannelMap[i].count(pEngineChannel);
239                        midiChannelMap[i].erase(pEngineChannel);
240                    }
241              }              }
242          }          }
243          catch(...) { /* NOOP */ }          catch(...) { /* NOOP */ }

Legend:
Removed from v.675  
changed lines
  Added in v.840

  ViewVC Help
Powered by ViewVC