/[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 840 by persson, Sun Feb 26 13:00:08 2006 UTC revision 922 by persson, Mon Oct 2 18:40:10 2006 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 Christian Schoenebeck                              *   *   Copyright (C) 2005, 2006 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 51  namespace LinuxSampler { Line 51  namespace LinuxSampler {
51          return std::vector<String>();          return std::vector<String>();
52      }      }
53    
54      void MidiInputPort::ParameterName::OnSetValue(String s) throw (LinuxSamplerException) {      void MidiInputPort::ParameterName::OnSetValue(String s) throw (Exception) {
55          return; /* FIXME: Nothing to do here */          return; /* FIXME: Nothing to do here */
56      }      }
57    
# Line 69  namespace LinuxSampler { Line 69  namespace LinuxSampler {
69          Parameters.clear();          Parameters.clear();
70      }      }
71    
72      MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber) {      MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber)
73            : MidiChannelMapReader(MidiChannelMap),
74              SysexListenersReader(SysexListeners) {
75          this->pDevice = pDevice;          this->pDevice = pDevice;
76          this->portNumber = portNumber;          this->portNumber = portNumber;
77          Parameters["NAME"] = new ParameterName(this);          Parameters["NAME"] = new ParameterName(this);
# Line 89  namespace LinuxSampler { Line 91  namespace LinuxSampler {
91      }      }
92    
93      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) {      void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) {
94          const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();          if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
95            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
96          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
97          {          {
98              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
# Line 102  namespace LinuxSampler { Line 105  namespace LinuxSampler {
105              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
106              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity);
107          }          }
108          MidiChannelMap.Unlock();          MidiChannelMapReader.Unlock();
109        }
110    
111        void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos) {
112            if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
113            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
114            // dispatch event for engines listening to the same MIDI channel
115            {
116                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
117                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
118                for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, FragmentPos);
119            }
120            // dispatch event for engines listening to ALL MIDI channels
121            {
122                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
123                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
124                for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity, FragmentPos);
125            }
126            MidiChannelMapReader.Unlock();
127      }      }
128    
129      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) {      void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) {
130          const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();          if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
131            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
132          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
133          {          {
134              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
# Line 119  namespace LinuxSampler { Line 141  namespace LinuxSampler {
141              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
142              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);              for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity);
143          }          }
144          MidiChannelMap.Unlock();          MidiChannelMapReader.Unlock();
145        }
146    
147        void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos) {
148            if (Key > 127 || Velocity > 127 || MidiChannel > 16) return;
149            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
150            // dispatch event for engines listening to the same MIDI channel
151            {
152                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
153                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
154                for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, FragmentPos);
155            }
156            // dispatch event for engines listening to ALL MIDI channels
157            {
158                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
159                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
160                for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity, FragmentPos);
161            }
162            MidiChannelMapReader.Unlock();
163      }      }
164    
165      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) {      void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) {
166          const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();          if (Pitch < -8192 || Pitch > 8191 || MidiChannel > 16) return;
167            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
168          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
169          {          {
170              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
# Line 136  namespace LinuxSampler { Line 177  namespace LinuxSampler {
177              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
178              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);              for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch);
179          }          }
180          MidiChannelMap.Unlock();          MidiChannelMapReader.Unlock();
181        }
182    
183        void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel, int32_t FragmentPos) {
184            if (Pitch < -8192 || Pitch > 8191 || MidiChannel > 16) return;
185            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
186            // dispatch event for engines listening to the same MIDI channel
187            {
188                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
189                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
190                for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, FragmentPos);
191            }
192            // dispatch event for engines listening to ALL MIDI channels
193            {
194                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
195                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
196                for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch, FragmentPos);
197            }
198            MidiChannelMapReader.Unlock();
199      }      }
200    
201      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) {      void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) {
202          const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock();          if (Controller > 128 || Value > 127 || MidiChannel > 16) return;
203            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
204          // dispatch event for engines listening to the same MIDI channel          // dispatch event for engines listening to the same MIDI channel
205          {          {
206              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();              std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
# Line 153  namespace LinuxSampler { Line 213  namespace LinuxSampler {
213              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();              std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
214              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);              for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value);
215          }          }
216          MidiChannelMap.Unlock();          MidiChannelMapReader.Unlock();
217        }
218    
219        void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel, int32_t FragmentPos) {
220            if (Controller > 128 || Value > 127 || MidiChannel > 16) return;
221            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
222            // dispatch event for engines listening to the same MIDI channel
223            {
224                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
225                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
226                for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, FragmentPos);
227            }
228            // dispatch event for engines listening to ALL MIDI channels
229            {
230                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
231                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
232                for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value, FragmentPos);
233            }
234            MidiChannelMapReader.Unlock();
235      }      }
236    
237      void MidiInputPort::DispatchSysex(void* pData, uint Size) {      void MidiInputPort::DispatchSysex(void* pData, uint Size) {
238            const std::set<Engine*> allEngines = SysexListenersReader.Lock();
239          // dispatch event to all engine instances          // dispatch event to all engine instances
240          std::set<Engine*>::iterator engineiter = EngineFactory::EngineInstances().begin();          std::set<Engine*>::iterator engineiter = allEngines.begin();
241          std::set<Engine*>::iterator end        = EngineFactory::EngineInstances().end();          std::set<Engine*>::iterator end        = allEngines.end();
242          for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size);          for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size);
243            SysexListenersReader.Unlock();
244      }      }
245    
246      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {
247            if (Program > 127 || MidiChannel > 16) return;
248          if (!pDevice || !pDevice->pSampler) {          if (!pDevice || !pDevice->pSampler) {
249              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."
250                        << "This is a bug, please report it!\n" << std::flush;                        << "This is a bug, please report it!\n" << std::flush;
# Line 250  namespace LinuxSampler { Line 331  namespace LinuxSampler {
331          pEngineChannel->StatusChanged(true);          pEngineChannel->StatusChanged(true);
332      }      }
333    
334        SynchronizedConfig<std::set<LinuxSampler::Engine*> > MidiInputPort::SysexListeners;
335    
336        void MidiInputPort::AddSysexListener(Engine* engine) {
337            std::pair<std::set<Engine*>::iterator, bool> p = SysexListeners.GetConfigForUpdate().insert(engine);
338            if (p.second) SysexListeners.SwitchConfig().insert(engine);
339        }
340    
341        bool MidiInputPort::RemoveSysexListener(Engine* engine) {
342            int count = SysexListeners.GetConfigForUpdate().erase(engine);
343            if (count) SysexListeners.SwitchConfig().erase(engine);
344            return count;
345        }
346    
347  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC