117 |
* Initializes and triggers the voice, a disk stream will be launched if |
* Initializes and triggers the voice, a disk stream will be launched if |
118 |
* needed. |
* needed. |
119 |
* |
* |
120 |
* @param pEngineChannel - engine channel on which this voice was ordered |
* @param pEngineChannel - engine channel on which this voice was ordered |
121 |
* @param itNoteOnEvent - event that caused triggering of this voice |
* @param itNoteOnEvent - event that caused triggering of this voice |
122 |
* @param PitchBend - MIDI detune factor (-8192 ... +8191) |
* @param PitchBend - MIDI detune factor (-8192 ... +8191) |
123 |
* @param pInstrument - points to the loaded instrument which provides sample wave(s) and articulation data |
* @param pInstrument - points to the loaded instrument which provides sample wave(s) and articulation data |
124 |
* @param iLayer - layer number this voice refers to (only if this is a layered sound of course) |
* @param iLayer - layer number this voice refers to (only if this is a layered sound of course) |
125 |
* @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false) |
* @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false) |
126 |
* @param VoiceStealing - wether the voice is allowed to steal voices for further subvoices |
* @param VoiceStealingAllowed - wether the voice is allowed to steal voices for further subvoices |
127 |
* @returns 0 on success, a value < 0 if the voice wasn't triggered |
* @returns 0 on success, a value < 0 if the voice wasn't triggered |
128 |
* (either due to an error or e.g. because no region is |
* (either due to an error or e.g. because no region is |
129 |
* defined for the given key) |
* defined for the given key) |
130 |
*/ |
*/ |
131 |
int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) { |
int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealingAllowed) { |
132 |
this->pEngineChannel = pEngineChannel; |
this->pEngineChannel = pEngineChannel; |
133 |
if (!pInstrument) { |
if (!pInstrument) { |
134 |
dmsg(1,("voice::trigger: !pInstrument\n")); |
dmsg(1,("voice::trigger: !pInstrument\n")); |
145 |
Delay = itNoteOnEvent->FragmentPos(); |
Delay = itNoteOnEvent->FragmentPos(); |
146 |
itTriggerEvent = itNoteOnEvent; |
itTriggerEvent = itNoteOnEvent; |
147 |
itKillEvent = Pool<Event>::Iterator(); |
itKillEvent = Pool<Event>::Iterator(); |
|
itChildVoice = Pool<Voice>::Iterator(); |
|
148 |
|
|
149 |
if (!pRegion) { |
if (!pRegion) { |
150 |
dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey)); |
dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey)); |
151 |
return -1; |
return -1; |
152 |
} |
} |
153 |
|
|
154 |
KeyGroup = pRegion->KeyGroup; |
// only mark the first voice of a layered voice (group) to be in a |
155 |
|
// key group, so the layered voices won't kill each other |
156 |
|
KeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0; |
157 |
|
|
158 |
// get current dimension values to select the right dimension region |
// get current dimension values to select the right dimension region |
159 |
//FIXME: controller values for selecting the dimension region here are currently not sample accurate |
//FIXME: controller values for selecting the dimension region here are currently not sample accurate |
165 |
break; |
break; |
166 |
case ::gig::dimension_layer: |
case ::gig::dimension_layer: |
167 |
DimValues[i] = iLayer; |
DimValues[i] = iLayer; |
|
// if this is the 1st layer then spawn further voices for all the other layers |
|
|
if (iLayer == 0) |
|
|
for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++) |
|
|
itChildVoice = pEngine->LaunchVoice(pEngineChannel, itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing); |
|
168 |
break; |
break; |
169 |
case ::gig::dimension_velocity: |
case ::gig::dimension_velocity: |
170 |
DimValues[i] = itNoteOnEvent->Param.Note.Velocity; |
DimValues[i] = itNoteOnEvent->Param.Note.Velocity; |
755 |
} |
} |
756 |
|
|
757 |
// Reset synthesis event lists (except VCO, as VCO events apply channel wide currently) |
// Reset synthesis event lists (except VCO, as VCO events apply channel wide currently) |
758 |
pEngine->pSynthesisEvents[Event::destination_vca]->clear(); |
pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear(); |
759 |
pEngine->pSynthesisEvents[Event::destination_vcfc]->clear(); |
pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear(); |
760 |
pEngine->pSynthesisEvents[Event::destination_vcfr]->clear(); |
pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear(); |
761 |
|
|
762 |
// Reset delay |
// Reset delay |
763 |
Delay = 0; |
Delay = 0; |
797 |
void Voice::ProcessEvents(uint Samples) { |
void Voice::ProcessEvents(uint Samples) { |
798 |
|
|
799 |
// dispatch control change events |
// dispatch control change events |
800 |
RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first(); |
RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first(); |
801 |
if (Delay) { // skip events that happened before this voice was triggered |
if (Delay) { // skip events that happened before this voice was triggered |
802 |
while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent; |
while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent; |
803 |
} |
} |
804 |
while (itCCEvent) { |
while (itCCEvent) { |
805 |
if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller |
if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller |
806 |
if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) { |
if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) { |
807 |
*pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent; |
*pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent; |
808 |
} |
} |
809 |
if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) { |
if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) { |
810 |
*pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent; |
*pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent; |
811 |
} |
} |
812 |
if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) { |
if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) { |
813 |
pLFO1->SendEvent(itCCEvent); |
pLFO1->SendEvent(itCCEvent); |
820 |
} |
} |
821 |
if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange && |
if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange && |
822 |
itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event |
itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event |
823 |
*pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent; |
*pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent; |
824 |
} |
} |
825 |
} |
} |
826 |
|
|
830 |
|
|
831 |
// process pitch events |
// process pitch events |
832 |
{ |
{ |
833 |
RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco]; |
RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco]; |
834 |
RTList<Event>::Iterator itVCOEvent = pVCOEventList->first(); |
RTList<Event>::Iterator itVCOEvent = pVCOEventList->first(); |
835 |
if (Delay) { // skip events that happened before this voice was triggered |
if (Delay) { // skip events that happened before this voice was triggered |
836 |
while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent; |
while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent; |
868 |
|
|
869 |
// process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !) |
// process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !) |
870 |
{ |
{ |
871 |
RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca]; |
RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca]; |
872 |
RTList<Event>::Iterator itVCAEvent = pVCAEventList->first(); |
RTList<Event>::Iterator itVCAEvent = pVCAEventList->first(); |
873 |
if (Delay) { // skip events that happened before this voice was triggered |
if (Delay) { // skip events that happened before this voice was triggered |
874 |
while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent; |
while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent; |
897 |
|
|
898 |
// process filter cutoff events |
// process filter cutoff events |
899 |
{ |
{ |
900 |
RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc]; |
RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc]; |
901 |
RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first(); |
RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first(); |
902 |
if (Delay) { // skip events that happened before this voice was triggered |
if (Delay) { // skip events that happened before this voice was triggered |
903 |
while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent; |
while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent; |
924 |
|
|
925 |
// process filter resonance events |
// process filter resonance events |
926 |
{ |
{ |
927 |
RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr]; |
RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr]; |
928 |
RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first(); |
RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first(); |
929 |
if (Delay) { // skip events that happened before this voice was triggered |
if (Delay) { // skip events that happened before this voice was triggered |
930 |
while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent; |
while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent; |