347 |
} |
} |
348 |
|
|
349 |
virtual void ProcessKeySwitchChange(int key) = 0; |
virtual void ProcessKeySwitchChange(int key) = 0; |
350 |
|
|
351 |
|
/** |
352 |
|
* Handle key group (a.k.a. exclusive group) conflicts |
353 |
|
*/ |
354 |
|
void HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent, bool UseRelease = false) { |
355 |
|
if (KeyGroup) { // if this voice / key belongs to a key group |
356 |
|
uint* pKeyGroup = MidiKeyboardManager<V>::ActiveKeyGroups[KeyGroup]; |
357 |
|
if (pKeyGroup) { // if there's already an active key in that key group |
358 |
|
MidiKey* pOtherKey = &MidiKeyboardManager<V>::pMIDIKeyInfo[*pKeyGroup]; |
359 |
|
|
360 |
|
if (UseRelease) { |
361 |
|
// send a note off to the other key |
362 |
|
if (pOtherKey->KeyPressed && itNoteOnEvent->Param.Note.Key != *pKeyGroup) { |
363 |
|
RTList<Event>::Iterator itNewEvent = pEngine->pGlobalEvents->allocAppend(); |
364 |
|
if (itNewEvent) { |
365 |
|
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 |