351 |
/** |
/** |
352 |
* Handle key group (a.k.a. exclusive group) conflicts |
* Handle key group (a.k.a. exclusive group) conflicts |
353 |
*/ |
*/ |
354 |
void HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent) { |
void HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent, bool UseRelease = false) { |
355 |
if (KeyGroup) { // if this voice / key belongs to a key group |
if (KeyGroup) { // if this voice / key belongs to a key group |
356 |
uint** ppKeyGroup = &MidiKeyboardManager<V>::ActiveKeyGroups[KeyGroup]; |
uint* pKeyGroup = MidiKeyboardManager<V>::ActiveKeyGroups[KeyGroup]; |
357 |
if (*ppKeyGroup) { // if there's already an active key in that key group |
if (pKeyGroup) { // if there's already an active key in that key group |
358 |
MidiKey* pOtherKey = &MidiKeyboardManager<V>::pMIDIKeyInfo[**ppKeyGroup]; |
MidiKey* pOtherKey = &MidiKeyboardManager<V>::pMIDIKeyInfo[*pKeyGroup]; |
359 |
// kill all voices on the (other) key |
|
360 |
typename RTList<V>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first(); |
if (UseRelease) { |
361 |
typename RTList<V>::Iterator end = pOtherKey->pActiveVoices->end(); |
// send a note off to the other key |
362 |
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
if (pOtherKey->KeyPressed && itNoteOnEvent->Param.Note.Key != *pKeyGroup) { |
363 |
if (itVoiceToBeKilled->Type != Voice::type_release_trigger) { |
RTList<Event>::Iterator itNewEvent = pEngine->pGlobalEvents->allocAppend(); |
364 |
itVoiceToBeKilled->Kill(itNoteOnEvent); |
if (itNewEvent) { |
365 |
--pEngine->VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict |
pOtherKey->ReleaseTrigger = false; |
366 |
|
*itNewEvent = *itNoteOnEvent; |
367 |
|
itNewEvent->Type = Event::type_note_off; |
368 |
|
itNewEvent->Param.Note.Key = *pKeyGroup; |
369 |
|
pEngine->ProcessNoteOff(this, itNewEvent); |
370 |
|
} |
371 |
|
} |
372 |
|
} else { |
373 |
|
// kill all voices on the (other) key |
374 |
|
typename RTList<V>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first(); |
375 |
|
typename RTList<V>::Iterator end = pOtherKey->pActiveVoices->end(); |
376 |
|
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
377 |
|
if (itVoiceToBeKilled->Type != Voice::type_release_trigger) { |
378 |
|
itVoiceToBeKilled->Kill(itNoteOnEvent); |
379 |
|
--pEngine->VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict |
380 |
|
} |
381 |
|
} |
382 |
} |
} |
383 |
} |
} |
384 |
} |
} |
385 |
} |
} |
|
} |
|
386 |
}; |
}; |
387 |
|
|
388 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |