142 |
int SostenutoKeyCount; |
int SostenutoKeyCount; |
143 |
uint32_t RoundRobinIndexes[128]; |
uint32_t RoundRobinIndexes[128]; |
144 |
int8_t KeyDown[128]; ///< True if the respective key is currently pressed down. Currently only used as built-in instrument script array variable %KEY_DOWN. It is currently not used by the sampler for any other purpose. |
int8_t KeyDown[128]; ///< True if the respective key is currently pressed down. Currently only used as built-in instrument script array variable %KEY_DOWN. It is currently not used by the sampler for any other purpose. |
145 |
|
|
146 |
|
virtual void ProcessReleaseTrigger(RTList<Event>::Iterator& itEvent) = 0; |
147 |
}; |
}; |
148 |
|
|
149 |
template <class V> |
template <class V> |
684 |
if (itNewEvent) { |
if (itNewEvent) { |
685 |
*itNewEvent = *itEvent; // copy event to the key's own event list |
*itNewEvent = *itEvent; // copy event to the key's own event list |
686 |
itNewEvent->Type = Event::type_release; // transform event type |
itNewEvent->Type = Event::type_release; // transform event type |
687 |
|
itNewEvent->Param.Note.Key = *iuiKey; |
688 |
|
itNewEvent->Param.Note.Velocity = 127; |
689 |
|
if (!SostenutoActiveOnKey(*iuiKey)) { |
690 |
|
//HACK: set sustain CC (64) as "pressed down" for a short moment, so that release trigger voices can distinguish between note off and sustain pedal up cases |
691 |
|
AbstractEngineChannel* pChannel = (AbstractEngineChannel*) itEvent->pEngineChannel; |
692 |
|
const int8_t CC64Value = pChannel->ControllerTable[64]; |
693 |
|
pChannel->ControllerTable[64] = 127; |
694 |
|
|
695 |
|
// now spawn release trigger voices (if required) |
696 |
|
ProcessReleaseTrigger(itNewEvent); |
697 |
|
|
698 |
|
//HACK: reset sustain pedal CC value to old one (see comment above) |
699 |
|
pChannel->ControllerTable[64] = CC64Value; |
700 |
|
} |
701 |
} |
} |
702 |
else dmsg(1,("Event pool emtpy!\n")); |
else dmsg(1,("Event pool emtpy!\n")); |
703 |
} |
} |
705 |
} |
} |
706 |
|
|
707 |
/** |
/** |
708 |
|
* Whether @a key is still kept active due to sostenuto pedal usage. |
709 |
|
* |
710 |
|
* @param key - note number of key |
711 |
|
*/ |
712 |
|
inline bool SostenutoActiveOnKey(int key) const { |
713 |
|
if (SostenutoPedal) { |
714 |
|
for (int i = 0; i < SostenutoKeyCount; i++) |
715 |
|
if (key == SostenutoKeys[i]) return true; |
716 |
|
} |
717 |
|
return false; |
718 |
|
} |
719 |
|
|
720 |
|
/** |
721 |
* Determines whether the specified voice should be released. |
* Determines whether the specified voice should be released. |
722 |
* |
* |
723 |
* @param pEngineChannel - The engine channel on which the voice should be checked |
* @param pEngineChannel - The engine channel on which the voice should be checked |
726 |
*/ |
*/ |
727 |
bool ShouldReleaseVoice(int Key) { |
bool ShouldReleaseVoice(int Key) { |
728 |
if (SustainPedal) return false; |
if (SustainPedal) return false; |
729 |
|
if (SostenutoActiveOnKey(Key)) return false; |
|
if (SostenutoPedal) { |
|
|
for (int i = 0; i < SostenutoKeyCount; i++) |
|
|
if (Key == SostenutoKeys[i]) return false; |
|
|
} |
|
|
|
|
730 |
return true; |
return true; |
731 |
} |
} |
732 |
|
|