/[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 906 by schoenebeck, Sun Jul 23 16:44:08 2006 UTC revision 2317 by persson, Sun Feb 19 12:13:19 2012 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005, 2006 Christian Schoenebeck                        *   *   Copyright (C) 2005 - 2012 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  Line 23 
23    
24  #include "MidiInputPort.h"  #include "MidiInputPort.h"
25    
26    #include "../../common/global_private.h"
27    #include "MidiInstrumentMapper.h"
28  #include "../../Sampler.h"  #include "../../Sampler.h"
29  #include "../../engines/EngineFactory.h"  #include "../../engines/EngineFactory.h"
30    #include "VirtualMidiDevice.h"
31    
32    #include <algorithm>
33    
34  namespace LinuxSampler {  namespace LinuxSampler {
35    
# Line 71  namespace LinuxSampler { Line 76  namespace LinuxSampler {
76    
77      MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber)      MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber)
78          : MidiChannelMapReader(MidiChannelMap),          : MidiChannelMapReader(MidiChannelMap),
79            SysexListenersReader(SysexListeners) {            SysexListenersReader(SysexListeners),
80              virtualMidiDevicesReader(virtualMidiDevices) {
81          this->pDevice = pDevice;          this->pDevice = pDevice;
82          this->portNumber = portNumber;          this->portNumber = portNumber;
83          Parameters["NAME"] = new ParameterName(this);          Parameters["NAME"] = new ParameterName(this);
         pPreviousProgramChangeEngineChannel = NULL;  
84      }      }
85    
86      MidiInputDevice* MidiInputPort::GetDevice() {      MidiInputDevice* MidiInputPort::GetDevice() {
# Line 91  namespace LinuxSampler { Line 96  namespace LinuxSampler {
96      }      }
97    
98      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) {      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) {
99            if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
100          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
101          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
102          {          {
103              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
104              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
105              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, MidiChannel);
106          }          }
107          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
108          {          {
109              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
110              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
111              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, MidiChannel);
112          }          }
113          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
114    
115            // dispatch event to all low priority MIDI listeners
116            const std::vector<VirtualMidiDevice*>& listeners =
117                virtualMidiDevicesReader.Lock();
118            for (int i = 0; i < listeners.size(); ++i)
119                listeners[i]->SendNoteOnToDevice(Key, Velocity);
120            virtualMidiDevicesReader.Unlock();
121      }      }
122    
123      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos) {      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos) {
124            if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
125          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
126          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
127          {          {
128              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
129              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
130              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, MidiChannel, FragmentPos);
131          }          }
132          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
133          {          {
134              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
135              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
136              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, MidiChannel, FragmentPos);
137          }          }
138          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
139    
140            // dispatch event to all low priority MIDI listeners
141            const std::vector<VirtualMidiDevice*>& listeners =
142                virtualMidiDevicesReader.Lock();
143            for (int i = 0; i < listeners.size(); ++i)
144                listeners[i]->SendNoteOnToDevice(Key, Velocity);
145            virtualMidiDevicesReader.Unlock();
146      }      }
147    
148      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) {      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) {
149            if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
150          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
151          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
152          {          {
153              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
154              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
155              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, MidiChannel);
156          }          }
157          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
158          {          {
159              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
160              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
161              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, MidiChannel);
162          }          }
163          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
164    
165            // dispatch event to all low priority MIDI listeners
166            const std::vector<VirtualMidiDevice*>& listeners =
167                virtualMidiDevicesReader.Lock();
168            for (int i = 0; i < listeners.size(); ++i)
169                listeners[i]->SendNoteOffToDevice(Key, Velocity);
170            virtualMidiDevicesReader.Unlock();
171      }      }
172    
173      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos) {      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos) {
174            if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
175          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
176          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
177          {          {
178              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
179              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
180              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, MidiChannel, FragmentPos);
181          }          }
182          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
183          {          {
184              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
185              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
186              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, MidiChannel, FragmentPos);
187          }          }
188          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
189    
190            // dispatch event to all low priority MIDI listeners
191            const std::vector<VirtualMidiDevice*>& listeners =
192                virtualMidiDevicesReader.Lock();
193            for (int i = 0; i < listeners.size(); ++i)
194                listeners[i]->SendNoteOffToDevice(Key, Velocity);
195            virtualMidiDevicesReader.Unlock();
196      }      }
197    
198      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) {      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) {
199            if (Pitch < -8192 || Pitch > 8191 || MidiChannel > 16) return;
200          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
201          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
202          {          {
203              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
204              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
205              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, MidiChannel);
206          }          }
207          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
208          {          {
209              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
210              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
211              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, MidiChannel);
212          }          }
213          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
214      }      }
215    
216      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel, int32_t FragmentPos) {      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel, int32_t FragmentPos) {
217            if (Pitch < -8192 || Pitch > 8191 || MidiChannel > 16) return;
218          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
219          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
220          {          {
221              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
222              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
223              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, MidiChannel, FragmentPos);
224          }          }
225          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
226          {          {
227              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
228              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
229              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, MidiChannel, FragmentPos);
230          }          }
231          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
232      }      }
233    
234      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) {      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) {
235            if (Controller > 128 || Value > 127 || MidiChannel > 16) return;
236          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
237          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
238          {          {
239              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
240              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
241              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, MidiChannel);
242          }          }
243          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
244          {          {
245              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
246              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
247              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, MidiChannel);
248          }          }
249          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
250            
251            // dispatch event to all low priority MIDI listeners
252            const std::vector<VirtualMidiDevice*>& listeners =
253                virtualMidiDevicesReader.Lock();
254            for (int i = 0; i < listeners.size(); ++i)
255                listeners[i]->SendCCToDevice(Controller, Value);
256            virtualMidiDevicesReader.Unlock();
257      }      }
258    
259      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel, int32_t FragmentPos) {      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel, int32_t FragmentPos) {
260            if (Controller > 128 || Value > 127 || MidiChannel > 16) return;
261          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
262          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
263          {          {
264              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
265              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
266              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, MidiChannel, FragmentPos);
267          }          }
268          // dispatch event for engines listening to ALL MIDI channels          // dispatch event for engines listening to ALL MIDI channels
269          {          {
270              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
271              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
272              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, FragmentPos);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, MidiChannel, FragmentPos);
273          }          }
274          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
275            
276            // dispatch event to all low priority MIDI listeners
277            const std::vector<VirtualMidiDevice*>& listeners =
278                virtualMidiDevicesReader.Lock();
279            for (int i = 0; i < listeners.size(); ++i)
280                listeners[i]->SendCCToDevice(Controller, Value);
281            virtualMidiDevicesReader.Unlock();
282      }      }
283    
284      void MidiInputPort::DispatchSysex(void* pData, uint Size) {      void MidiInputPort::DispatchSysex(void* pData, uint Size) {
# Line 231  namespace LinuxSampler { Line 286  namespace LinuxSampler {
286          // dispatch event to all engine instances          // dispatch event to all engine instances
287          std::set<Engine*>::iterator engineiter = allEngines.begin();          std::set<Engine*>::iterator engineiter = allEngines.begin();
288          std::set<Engine*>::iterator end        = allEngines.end();          std::set<Engine*>::iterator end        = allEngines.end();
289          for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size);          for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size, this);
290          SysexListenersReader.Unlock();          SysexListenersReader.Unlock();
291      }      }
292    
293      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {
294            if (Program > 127 || MidiChannel > 16) return;
295          if (!pDevice || !pDevice->pSampler) {          if (!pDevice || !pDevice->pSampler) {
296              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."
297                        << "This is a bug, please report it!\n" << std::flush;                        << "This is a bug, please report it!\n" << std::flush;
298              return;              return;
299          }          }
300    
301          Sampler*        pSampler        = (Sampler*) pDevice->pSampler;          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
302          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(Program);          // dispatch event for engines listening to the same MIDI channel
303          if (!pSamplerChannel) return;          {
304                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
305                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
306                for (; engineiter != end; engineiter++) (*engineiter)->SendProgramChange(Program);
307            }
308            // dispatch event for engines listening to ALL MIDI channels
309            {
310                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
311                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
312                for (; engineiter != end; engineiter++) (*engineiter)->SendProgramChange(Program);
313            }
314            MidiChannelMapReader.Unlock();
315        }
316    
317          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();      void MidiInputPort::DispatchBankSelectMsb(uint8_t BankMSB, uint MidiChannel) {
318          if (!pEngineChannel) return;          if (BankMSB > 127 || MidiChannel > 16) return;
319            if (!pDevice || !pDevice->pSampler) {
320                std::cerr << "MidiInputPort: ERROR, no sampler instance to handle bank select MSB."
321                          << "This is a bug, please report it!\n" << std::flush;
322                return;
323            }
324            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
325            // dispatch event for engines listening to the same MIDI channel
326            {
327                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
328                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
329                // according to the MIDI specs, a bank select should not alter the patch
330                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankMsb(BankMSB);
331            }
332            // dispatch event for engines listening to ALL MIDI channels
333            {
334                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
335                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
336                // according to the MIDI specs, a bank select should not alter the patch
337                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankMsb(BankMSB);
338            }
339            MidiChannelMapReader.Unlock();
340        }
341    
342          // disconnect from the engine channel which was connected by the last PC event      void MidiInputPort::DispatchBankSelectLsb(uint8_t BankLSB, uint MidiChannel) {
343          if (pPreviousProgramChangeEngineChannel)          if (BankLSB > 127 || MidiChannel > 16) return;
344              Disconnect(pPreviousProgramChangeEngineChannel);          if (!pDevice || !pDevice->pSampler) {
345                std::cerr << "MidiInputPort: ERROR, no sampler instance to handle bank select LSB."
346                          << "This is a bug, please report it!\n" << std::flush;
347                return;
348            }
349            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
350            // dispatch event for engines listening to the same MIDI channel
351            {
352                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
353                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
354                // according to the MIDI specs, a bank select should not alter the patch
355                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankLsb(BankLSB);
356            }
357            // dispatch event for engines listening to ALL MIDI channels
358            {
359                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
360                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
361                // according to the MIDI specs, a bank select should not alter the patch
362                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankLsb(BankLSB);
363            }
364            MidiChannelMapReader.Unlock();
365        }
366    
367          // now connect to the new engine channel and remember it      void MidiInputPort::DispatchRaw(uint8_t* pData) {
368          try {          uint8_t channel = pData[0] & 0x0f;
369              Connect(pEngineChannel, (midi_chan_t) MidiChannel);          switch (pData[0] & 0xf0) {
370              pPreviousProgramChangeEngineChannel = pEngineChannel;          case 0x80:
371                DispatchNoteOff(pData[1], pData[2], channel);
372                break;
373            case 0x90:
374                if (pData[2]) {
375                    DispatchNoteOn(pData[1], pData[2], channel);
376                } else {
377                    DispatchNoteOff(pData[1], pData[2], channel);
378                }
379                break;
380            case 0xb0:
381                if (pData[1] == 0) {
382                    DispatchBankSelectMsb(pData[2], channel);
383                } else if (pData[1] == 32) {
384                    DispatchBankSelectLsb(pData[2], channel);
385                }
386                DispatchControlChange(pData[1], pData[2], channel);
387                break;
388            case 0xc0:
389                DispatchProgramChange(pData[1], channel);
390                break;
391            case 0xd0:
392                DispatchControlChange(128, pData[1], channel);
393                break;
394            case 0xe0:
395                DispatchPitchbend((pData[1] | pData[2] << 7) - 8192, channel);
396                break;
397            }
398        }
399    
400        void MidiInputPort::DispatchRaw(uint8_t* pData, int32_t FragmentPos) {
401            uint8_t channel = pData[0] & 0x0f;
402            switch (pData[0] & 0xf0) {
403            case 0x80:
404                DispatchNoteOff(pData[1], pData[2], channel, FragmentPos);
405                break;
406            case 0x90:
407                if (pData[2]) {
408                    DispatchNoteOn(pData[1], pData[2], channel, FragmentPos);
409                } else {
410                    DispatchNoteOff(pData[1], pData[2], channel, FragmentPos);
411                }
412                break;
413            case 0xb0:
414                if (pData[1] == 0) {
415                    DispatchBankSelectMsb(pData[2], channel);
416                } else if (pData[1] == 32) {
417                    DispatchBankSelectLsb(pData[2], channel);
418                }
419                DispatchControlChange(pData[1], pData[2], channel, FragmentPos);
420                break;
421            case 0xc0:
422                DispatchProgramChange(pData[1], channel);
423                break;
424            case 0xd0:
425                DispatchControlChange(128, pData[1], channel, FragmentPos);
426                break;
427            case 0xe0:
428                DispatchPitchbend((pData[1] | pData[2] << 7) - 8192, channel, FragmentPos);
429                break;
430          }          }
         catch (...) { /* NOOP */ }  
431      }      }
432    
433      void MidiInputPort::Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel) {      void MidiInputPort::Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel) {
# Line 335  namespace LinuxSampler { Line 504  namespace LinuxSampler {
504          return count;          return count;
505      }      }
506    
507        void MidiInputPort::Connect(VirtualMidiDevice* pDevice) {
508            virtualMidiDevicesMutex.Lock();
509            // double buffer ... double work ...
510            {
511                std::vector<VirtualMidiDevice*>& devices =
512                    virtualMidiDevices.GetConfigForUpdate();
513                devices.push_back(pDevice);
514            }
515            {
516                std::vector<VirtualMidiDevice*>& devices =
517                    virtualMidiDevices.SwitchConfig();
518                devices.push_back(pDevice);
519            }
520            virtualMidiDevicesMutex.Unlock();
521        }
522    
523        void MidiInputPort::Disconnect(VirtualMidiDevice* pDevice) {
524            virtualMidiDevicesMutex.Lock();
525            // double buffer ... double work ...
526            {
527                std::vector<VirtualMidiDevice*>& devices =
528                    virtualMidiDevices.GetConfigForUpdate();
529                devices.erase(std::find(devices.begin(), devices.end(), pDevice));
530            }
531            {
532                std::vector<VirtualMidiDevice*>& devices =
533                    virtualMidiDevices.SwitchConfig();
534                devices.erase(std::find(devices.begin(), devices.end(), pDevice));
535            }
536            virtualMidiDevicesMutex.Unlock();
537        }
538    
539  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.906  
changed lines
  Added in v.2317

  ViewVC Help
Powered by ViewVC