/[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 411 by schoenebeck, Sat Feb 26 02:01:14 2005 UTC revision 775 by schoenebeck, Wed Sep 21 14:30:43 2005 UTC
# Line 23  Line 23 
23    
24  #include "MidiInputPort.h"  #include "MidiInputPort.h"
25    
26    #include "../../Sampler.h"
27    #include "../../engines/EngineFactory.h"
28    
29  namespace LinuxSampler {  namespace LinuxSampler {
30    
31  // *************** ParameterName ***************  // *************** ParameterName ***************
# Line 70  namespace LinuxSampler { Line 73  namespace LinuxSampler {
73          this->pDevice = pDevice;          this->pDevice = pDevice;
74          this->portNumber = portNumber;          this->portNumber = portNumber;
75          Parameters["NAME"] = new ParameterName(this);          Parameters["NAME"] = new ParameterName(this);
76            pPreviousProgramChangeEngineChannel = NULL;
77      }      }
78    
79      MidiInputDevice* MidiInputPort::GetDevice() {      MidiInputDevice* MidiInputPort::GetDevice() {
# Line 145  namespace LinuxSampler { Line 149  namespace LinuxSampler {
149      }      }
150    
151      void MidiInputPort::DispatchSysex(void* pData, uint Size) {      void MidiInputPort::DispatchSysex(void* pData, uint Size) {
152          // dispatch event for engines listening to the same MIDI channel          // dispatch event to all engine instances
153          {          std::set<Engine*>::iterator engineiter = EngineFactory::EngineInstances().begin();
154              for (uint MidiChannel = 0; MidiChannel <= 16; MidiChannel++) {          std::set<Engine*>::iterator end        = EngineFactory::EngineInstances().end();
155                  std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin();          for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size);
156                  std::set<EngineChannel*>::iterator end        = MidiChannelMap[MidiChannel].end();      }
157                  for (; engineiter != end; engineiter++) {  
158                      Engine* pEngine = (*engineiter)->GetEngine();      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {
159                      if (pEngine) pEngine->SendSysex(pData, Size);          if (!pDevice || !pDevice->pSampler) {
160                  }              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."
161              }                        << "This is a bug, please report it!\n" << std::flush;
162                return;
163          }          }
164          // dispatch event for engines listening to ALL MIDI channels  
165          {          Sampler*        pSampler        = (Sampler*) pDevice->pSampler;
166              for (uint MidiChannel = 0; MidiChannel <= 16; MidiChannel++) {          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(Program);
167                  std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin();          if (!pSamplerChannel) return;
168                  std::set<EngineChannel*>::iterator end        = MidiChannelMap[midi_chan_all].end();  
169                  for (; engineiter != end; engineiter++) {          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
170                      Engine* pEngine = (*engineiter)->GetEngine();          if (!pEngineChannel) return;
171                      if (pEngine) pEngine->SendSysex(pData, Size);  
172                  }          // disconnect from the engine channel which was connected by the last PC event
173              }          if (pPreviousProgramChangeEngineChannel)
174                Disconnect(pPreviousProgramChangeEngineChannel);
175    
176            // now connect to the new engine channel and remember it
177            try {
178                Connect(pEngineChannel, (midi_chan_t) MidiChannel);
179                pPreviousProgramChangeEngineChannel = pEngineChannel;
180          }          }
181            catch (...) { /* NOOP */ }
182      }      }
183    
184      void MidiInputPort::Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel) {      void MidiInputPort::Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel) {
185          if (MidiChannel < 0 || MidiChannel > 16)          if (MidiChannel < 0 || MidiChannel > 16)
186              throw MidiInputException("MIDI channel index out of bounds");              throw MidiInputException("MIDI channel index out of bounds");
187    
188            // firt check if desired connection is already established
189            MidiChannelMapMutex.Lock();
190            bool bAlreadyDone = MidiChannelMap[MidiChannel].count(pEngineChannel);
191            MidiChannelMapMutex.Unlock();
192            if (bAlreadyDone) return;
193    
194            // remove all other connections of that engine channel (if any)
195          Disconnect(pEngineChannel);          Disconnect(pEngineChannel);
196    
197            // register engine channel on the desired MIDI channel
198            MidiChannelMapMutex.Lock();
199          MidiChannelMap[MidiChannel].insert(pEngineChannel);          MidiChannelMap[MidiChannel].insert(pEngineChannel);
200            MidiChannelMapMutex.Unlock();
201    
202            // inform engine channel about this connection
203            pEngineChannel->Connect(this, MidiChannel);
204    
205            // mark engine channel as changed
206            pEngineChannel->StatusChanged(true);
207      }      }
208    
209      void MidiInputPort::Disconnect(EngineChannel* pEngineChannel) {      void MidiInputPort::Disconnect(EngineChannel* pEngineChannel) {
210          try { for (int i = 0; i <= 16; i++) MidiChannelMap[i].erase(pEngineChannel); }          if (!pEngineChannel) return;
211    
212            bool bChannelFound = false;
213    
214            // unregister engine channel from all MIDI channels
215            MidiChannelMapMutex.Lock();
216            try {
217                for (int i = 0; i <= 16; i++) {
218                    bChannelFound |= MidiChannelMap[i].count(pEngineChannel);
219                    MidiChannelMap[i].erase(pEngineChannel);
220                }
221            }
222          catch(...) { /* NOOP */ }          catch(...) { /* NOOP */ }
223            MidiChannelMapMutex.Unlock();
224    
225            // inform engine channel about the disconnection (if there is one)
226            if (bChannelFound) pEngineChannel->DisconnectMidiInputPort();
227    
228            // mark engine channel as changed
229            pEngineChannel->StatusChanged(true);
230      }      }
231    
232  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.411  
changed lines
  Added in v.775

  ViewVC Help
Powered by ViewVC