183 |
|
|
184 |
MidiKeyboardManager<V>::DeleteActiveVoices(); |
MidiKeyboardManager<V>::DeleteActiveVoices(); |
185 |
MidiKeyboardManager<V>::DeleteEvents(); |
MidiKeyboardManager<V>::DeleteEvents(); |
186 |
|
DeleteGroupEventLists(); |
187 |
|
|
188 |
AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice; |
AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice; |
189 |
pEngine = NULL; |
pEngine = NULL; |
209 |
// empty MIDI key specific event lists |
// empty MIDI key specific event lists |
210 |
ClearEventListsHandler handler; |
ClearEventListsHandler handler; |
211 |
ProcessActiveVoices(&handler); |
ProcessActiveVoices(&handler); |
212 |
|
|
213 |
|
// empty exclusive group specific event lists |
214 |
|
ClearGroupEventLists(); |
215 |
} |
} |
216 |
|
|
217 |
// implementation of abstract methods derived from interface class 'InstrumentConsumer' |
// implementation of abstract methods derived from interface class 'InstrumentConsumer' |
351 |
} |
} |
352 |
|
|
353 |
virtual void ProcessKeySwitchChange(int key) = 0; |
virtual void ProcessKeySwitchChange(int key) = 0; |
|
|
|
|
/** |
|
|
* Handle key group (a.k.a. exclusive group) conflicts |
|
|
*/ |
|
|
void HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent, bool UseRelease = false) { |
|
|
if (KeyGroup) { // if this voice / key belongs to a key group |
|
|
uint* pKeyGroup = MidiKeyboardManager<V>::ActiveKeyGroups[KeyGroup]; |
|
|
if (pKeyGroup) { // if there's already an active key in that key group |
|
|
MidiKey* pOtherKey = &MidiKeyboardManager<V>::pMIDIKeyInfo[*pKeyGroup]; |
|
|
|
|
|
if (UseRelease) { |
|
|
// send a note off to the other key |
|
|
if (pOtherKey->KeyPressed && itNoteOnEvent->Param.Note.Key != *pKeyGroup) { |
|
|
RTList<Event>::Iterator itNewEvent = pEngine->pGlobalEvents->allocAppend(); |
|
|
if (itNewEvent) { |
|
|
pOtherKey->ReleaseTrigger = false; |
|
|
*itNewEvent = *itNoteOnEvent; |
|
|
itNewEvent->Type = Event::type_note_off; |
|
|
itNewEvent->Param.Note.Key = *pKeyGroup; |
|
|
pEngine->ProcessNoteOff(this, itNewEvent); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
// kill all voices on the (other) key |
|
|
typename RTList<V>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first(); |
|
|
typename RTList<V>::Iterator end = pOtherKey->pActiveVoices->end(); |
|
|
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
|
|
if (itVoiceToBeKilled->Type != Voice::type_release_trigger) { |
|
|
itVoiceToBeKilled->Kill(itNoteOnEvent); |
|
|
--pEngine->VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
354 |
}; |
}; |
355 |
|
|
356 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |