277 |
} |
} |
278 |
|
|
279 |
void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) { |
void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) { |
|
dmsg(1,("Received MIDI program change (prog=%d,ch=%d)\n",Program,MidiChannel)); |
|
280 |
if (Program > 127 || MidiChannel > 16) return; |
if (Program > 127 || MidiChannel > 16) return; |
281 |
if (!pDevice || !pDevice->pSampler) { |
if (!pDevice || !pDevice->pSampler) { |
282 |
std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change." |
std::cerr << "MidiInputPort: ERROR, no sampler instance to handle program change." |
283 |
<< "This is a bug, please report it!\n" << std::flush; |
<< "This is a bug, please report it!\n" << std::flush; |
284 |
return; |
return; |
285 |
} |
} |
|
std::vector<int> maps = MidiInstrumentMapper::Maps(); |
|
|
if (maps.empty()) return; |
|
286 |
|
|
287 |
const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock(); |
const MidiChannelMap_t& midiChannelMap = MidiChannelMapReader.Lock(); |
288 |
// dispatch event for engines listening to the same MIDI channel |
// dispatch event for engines listening to the same MIDI channel |
289 |
{ |
{ |
290 |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin(); |
291 |
std::set<EngineChannel*>::iterator end = midiChannelMap[MidiChannel].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[MidiChannel].end(); |
292 |
for (; engineiter != end; engineiter++) { |
for (; engineiter != end; engineiter++) (*engineiter)->SendProgramChange(Program); |
|
(*engineiter)->SetMidiProgram(Program); |
|
|
if ((*engineiter)->UsesNoMidiInstrumentMap()) continue; |
|
|
if (MidiInstrumentMapper::GetMapCount() == 0) continue; |
|
|
// retrieve the MIDI instrument map this engine channel is assigned to |
|
|
int iMapID = ((*engineiter)->UsesDefaultMidiInstrumentMap()) |
|
|
? MidiInstrumentMapper::GetDefaultMap() /*default*/ : (*engineiter)->GetMidiInstrumentMap(); |
|
|
// is there an entry for this MIDI bank&prog pair in that map? |
|
|
midi_prog_index_t midiIndex; |
|
|
midiIndex.midi_bank_msb = (*engineiter)->GetMidiBankMsb(); |
|
|
midiIndex.midi_bank_lsb = (*engineiter)->GetMidiBankLsb(); |
|
|
midiIndex.midi_prog = (*engineiter)->GetMidiProgram(); |
|
|
optional<MidiInstrumentMapper::entry_t> mapping = |
|
|
MidiInstrumentMapper::GetEntry(iMapID, midiIndex); |
|
|
if (mapping) { // if mapping exists ... |
|
|
InstrumentManager::instrument_id_t id; |
|
|
id.FileName = mapping->InstrumentFile; |
|
|
id.Index = mapping->InstrumentIndex; |
|
|
//TODO: we should switch the engine type here |
|
|
InstrumentManager::LoadInstrumentInBackground(id, *engineiter); |
|
|
(*engineiter)->Volume(mapping->Volume); |
|
|
} |
|
|
} |
|
293 |
} |
} |
294 |
// dispatch event for engines listening to ALL MIDI channels |
// dispatch event for engines listening to ALL MIDI channels |
295 |
{ |
{ |
296 |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin(); |
297 |
std::set<EngineChannel*>::iterator end = midiChannelMap[midi_chan_all].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[midi_chan_all].end(); |
298 |
for (; engineiter != end; engineiter++) { |
for (; engineiter != end; engineiter++) (*engineiter)->SendProgramChange(Program); |
|
(*engineiter)->SetMidiProgram(Program); |
|
|
if ((*engineiter)->UsesNoMidiInstrumentMap()) continue; |
|
|
if (MidiInstrumentMapper::GetMapCount() == 0) continue; |
|
|
// retrieve the MIDI instrument map this engine channel is assigned to |
|
|
int iMapID = ((*engineiter)->UsesDefaultMidiInstrumentMap()) |
|
|
? MidiInstrumentMapper::GetDefaultMap() /*default*/ : (*engineiter)->GetMidiInstrumentMap(); |
|
|
// is there an entry for this MIDI bank&prog pair in that map? |
|
|
midi_prog_index_t midiIndex; |
|
|
midiIndex.midi_bank_msb = (*engineiter)->GetMidiBankMsb(); |
|
|
midiIndex.midi_bank_lsb = (*engineiter)->GetMidiBankLsb(); |
|
|
midiIndex.midi_prog = (*engineiter)->GetMidiProgram(); |
|
|
optional<MidiInstrumentMapper::entry_t> mapping = |
|
|
MidiInstrumentMapper::GetEntry(iMapID, midiIndex); |
|
|
if (mapping) { // if mapping exists ... |
|
|
InstrumentManager::instrument_id_t id; |
|
|
id.FileName = mapping->InstrumentFile; |
|
|
id.Index = mapping->InstrumentIndex; |
|
|
//TODO: we should switch the engine type here |
|
|
InstrumentManager::LoadInstrumentInBackground(id, *engineiter); |
|
|
(*engineiter)->Volume(mapping->Volume); |
|
|
} |
|
|
} |
|
299 |
} |
} |
300 |
MidiChannelMapReader.Unlock(); |
MidiChannelMapReader.Unlock(); |
301 |
} |
} |