/[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 922 by persson, Mon Oct 2 18:40:10 2006 UTC revision 947 by schoenebeck, Mon Nov 27 21:34:55 2006 UTC
# Line 23  Line 23 
23    
24  #include "MidiInputPort.h"  #include "MidiInputPort.h"
25    
26    #include "MidiInstrumentMapper.h"
27  #include "../../Sampler.h"  #include "../../Sampler.h"
28  #include "../../engines/EngineFactory.h"  #include "../../engines/EngineFactory.h"
29    
# Line 75  namespace LinuxSampler { Line 76  namespace LinuxSampler {
76          this->pDevice = pDevice;          this->pDevice = pDevice;
77          this->portNumber = portNumber;          this->portNumber = portNumber;
78          Parameters["NAME"] = new ParameterName(this);          Parameters["NAME"] = new ParameterName(this);
         pPreviousProgramChangeEngineChannel = NULL;  
79      }      }
80    
81      MidiInputDevice* MidiInputPort::GetDevice() {      MidiInputDevice* MidiInputPort::GetDevice() {
# Line 244  namespace LinuxSampler { Line 244  namespace LinuxSampler {
244      }      }
245    
246      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {      void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) {
247            dmsg(1,("Received MIDI program change (prog=%d,ch=%d)\n",Program,MidiChannel));
248          if (Program > 127 || MidiChannel > 16) return;          if (Program > 127 || MidiChannel > 16) return;
249          if (!pDevice || !pDevice->pSampler) {          if (!pDevice || !pDevice->pSampler) {
250              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."              std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change."
251                        << "This is a bug, please report it!\n" << std::flush;                        << "This is a bug, please report it!\n" << std::flush;
252              return;              return;
253          }          }
254            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
255            // dispatch event for engines listening to the same MIDI channel
256            {
257                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
258                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
259                for (; engineiter != end; engineiter++) {
260                    (*engineiter)->SetMidiProgram(Program);
261                    // is there a mapping for this MIDI bank&prog pair?
262                    midi_prog_index_t midiIndex;
263                    midiIndex.midi_bank_msb = (*engineiter)->GetMidiBankMsb();
264                    midiIndex.midi_bank_lsb = (*engineiter)->GetMidiBankLsb();
265                    midiIndex.midi_prog     = (*engineiter)->GetMidiProgram();
266                    optional<MidiInstrumentMapper::entry_t> mapping =
267                        MidiInstrumentMapper::GetEntry(midiIndex);
268                    if (mapping) { // if mapping exists ...
269                        InstrumentManager::instrument_id_t id;
270                        id.FileName = mapping->InstrumentFile;
271                        id.Index    = mapping->InstrumentIndex;
272                        //TODO: we should switch the engine type here
273                        InstrumentManager::LoadInstrumentInBackground(id, *engineiter);
274                        (*engineiter)->Volume(mapping->Volume);
275                    }
276                }
277            }
278            // dispatch event for engines listening to ALL MIDI channels
279            {
280                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
281                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
282                for (; engineiter != end; engineiter++) {
283                    (*engineiter)->SetMidiProgram(Program);
284                    // is there a mapping for this MIDI bank&prog pair?
285                    midi_prog_index_t midiIndex;
286                    midiIndex.midi_bank_msb = (*engineiter)->GetMidiBankMsb();
287                    midiIndex.midi_bank_lsb = (*engineiter)->GetMidiBankLsb();
288                    midiIndex.midi_prog     = (*engineiter)->GetMidiProgram();
289                    optional<MidiInstrumentMapper::entry_t> mapping =
290                        MidiInstrumentMapper::GetEntry(midiIndex);
291                    if (mapping) { // if mapping exists ...
292                        InstrumentManager::instrument_id_t id;
293                        id.FileName = mapping->InstrumentFile;
294                        id.Index    = mapping->InstrumentIndex;
295                        //TODO: we should switch the engine type here
296                        InstrumentManager::LoadInstrumentInBackground(id, *engineiter);
297                        (*engineiter)->Volume(mapping->Volume);
298                    }
299                }
300            }
301            MidiChannelMapReader.Unlock();
302        }
303    
304        void MidiInputPort::DispatchBankSelectMsb(uint8_t BankMSB, uint MidiChannel) {
305            if (BankMSB > 127 || MidiChannel > 16) return;
306            if (!pDevice || !pDevice->pSampler) {
307                std::cerr << "MidiInputPort: ERROR, no sampler instance to handle bank select MSB."
308                          << "This is a bug, please report it!\n" << std::flush;
309                return;
310            }
311            const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
312            // dispatch event for engines listening to the same MIDI channel
313            {
314                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
315                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
316                // according to the MIDI specs, a bank select should not alter the patch
317                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankMsb(BankMSB);
318            }
319            // dispatch event for engines listening to ALL MIDI channels
320            {
321                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
322                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
323                // according to the MIDI specs, a bank select should not alter the patch
324                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankMsb(BankMSB);
325            }
326            MidiChannelMapReader.Unlock();
327        }
328    
329          Sampler*        pSampler        = (Sampler*) pDevice->pSampler;      void MidiInputPort::DispatchBankSelectLsb(uint8_t BankLSB, uint MidiChannel) {
330          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(Program);          if (BankLSB > 127 || MidiChannel > 16) return;
331          if (!pSamplerChannel) return;          if (!pDevice || !pDevice->pSampler) {
332                std::cerr << "MidiInputPort: ERROR, no sampler instance to handle bank select LSB."
333          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();                        << "This is a bug, please report it!\n" << std::flush;
334          if (!pEngineChannel) return;              return;
   
         // disconnect from the engine channel which was connected by the last PC event  
         if (pPreviousProgramChangeEngineChannel)  
             Disconnect(pPreviousProgramChangeEngineChannel);  
   
         // now connect to the new engine channel and remember it  
         try {  
             Connect(pEngineChannel, (midi_chan_t) MidiChannel);  
             pPreviousProgramChangeEngineChannel = pEngineChannel;  
335          }          }
336          catch (...) { /* NOOP */ }          const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock();
337            // dispatch event for engines listening to the same MIDI channel
338            {
339                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin();
340                std::set<EngineChannel*>::iterator end        = midiChannelMap[MidiChannel].end();
341                // according to the MIDI specs, a bank select should not alter the patch
342                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankLsb(BankLSB);
343            }
344            // dispatch event for engines listening to ALL MIDI channels
345            {
346                std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin();
347                std::set<EngineChannel*>::iterator end        = midiChannelMap[midi_chan_all].end();
348                // according to the MIDI specs, a bank select should not alter the patch
349                for (; engineiter != end; engineiter++) (*engineiter)->SetMidiBankLsb(BankLSB);
350            }
351            MidiChannelMapReader.Unlock();
352      }      }
353    
354      void MidiInputPort::Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel) {      void MidiInputPort::Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel) {

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

  ViewVC Help
Powered by ViewVC