61 |
KeyGroup = 0; |
KeyGroup = 0; |
62 |
SynthesisMode = 0; // set all mode bits to 0 first |
SynthesisMode = 0; // set all mode bits to 0 first |
63 |
// select synthesis implementation (currently either pure C++ or MMX+SSE(1)) |
// select synthesis implementation (currently either pure C++ or MMX+SSE(1)) |
64 |
#if ARCH_X86 |
#if CONFIG_ASM && ARCH_X86 |
65 |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); |
66 |
#else |
#else |
67 |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false); |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false); |
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 pDimRgn - points to the dimension region 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 VoiceType - type of this voice |
125 |
* @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false) |
* @param iKeyGroup - a value > 0 defines a key group in which this voice is member of |
|
* @param VoiceStealingAllowed - wether the voice is allowed to steal voices for further subvoices |
|
126 |
* @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 |
127 |
* (either due to an error or e.g. because no region is |
* (either due to an error or e.g. because no region is |
128 |
* defined for the given key) |
* defined for the given key) |
129 |
*/ |
*/ |
130 |
int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealingAllowed) { |
int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) { |
131 |
this->pEngineChannel = pEngineChannel; |
this->pEngineChannel = pEngineChannel; |
132 |
if (!pInstrument) { |
this->pDimRgn = pDimRgn; |
133 |
dmsg(1,("voice::trigger: !pInstrument\n")); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
134 |
#if CONFIG_DEVMODE |
#if CONFIG_DEVMODE |
135 |
if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging |
if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging |
136 |
dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n")); |
dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n")); |
137 |
} |
} |
138 |
#endif // CONFIG_DEVMODE |
#endif // CONFIG_DEVMODE |
139 |
|
|
140 |
Type = type_normal; |
Type = VoiceType; |
141 |
MIDIKey = itNoteOnEvent->Param.Note.Key; |
MIDIKey = itNoteOnEvent->Param.Note.Key; |
|
pRegion = pInstrument->GetRegion(MIDIKey); |
|
142 |
PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet |
PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet |
143 |
Delay = itNoteOnEvent->FragmentPos(); |
Delay = itNoteOnEvent->FragmentPos(); |
144 |
itTriggerEvent = itNoteOnEvent; |
itTriggerEvent = itNoteOnEvent; |
145 |
itKillEvent = Pool<Event>::Iterator(); |
itKillEvent = Pool<Event>::Iterator(); |
146 |
|
KeyGroup = iKeyGroup; |
147 |
|
pSample = pDimRgn->pSample; // sample won't change until the voice is finished |
148 |
|
|
149 |
if (!pRegion) { |
// calculate volume |
150 |
dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey)); |
const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity); |
|
return -1; |
|
|
} |
|
151 |
|
|
152 |
// only mark the first voice of a layered voice (group) to be in a |
Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0) |
|
// key group, so the layered voices won't kill each other |
|
|
KeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0; |
|
153 |
|
|
154 |
// get current dimension values to select the right dimension region |
Volume *= pDimRgn->SampleAttenuation; |
|
//FIXME: controller values for selecting the dimension region here are currently not sample accurate |
|
|
uint DimValues[8] = { 0 }; |
|
|
for (int i = pRegion->Dimensions - 1; i >= 0; i--) { |
|
|
switch (pRegion->pDimensionDefinitions[i].dimension) { |
|
|
case ::gig::dimension_samplechannel: |
|
|
DimValues[i] = 0; //TODO: we currently ignore this dimension |
|
|
break; |
|
|
case ::gig::dimension_layer: |
|
|
DimValues[i] = iLayer; |
|
|
break; |
|
|
case ::gig::dimension_velocity: |
|
|
DimValues[i] = itNoteOnEvent->Param.Note.Velocity; |
|
|
break; |
|
|
case ::gig::dimension_channelaftertouch: |
|
|
DimValues[i] = 0; //TODO: we currently ignore this dimension |
|
|
break; |
|
|
case ::gig::dimension_releasetrigger: |
|
|
Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal; |
|
|
DimValues[i] = (uint) ReleaseTriggerVoice; |
|
|
break; |
|
|
case ::gig::dimension_keyboard: |
|
|
DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension; |
|
|
break; |
|
|
case ::gig::dimension_roundrobin: |
|
|
DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on |
|
|
break; |
|
|
case ::gig::dimension_random: |
|
|
pEngine->RandomSeed = pEngine->RandomSeed * 1103515245 + 12345; // classic pseudo random number generator |
|
|
DimValues[i] = (uint) pEngine->RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random |
|
|
break; |
|
|
case ::gig::dimension_modwheel: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[1]; |
|
|
break; |
|
|
case ::gig::dimension_breath: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[2]; |
|
|
break; |
|
|
case ::gig::dimension_foot: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[4]; |
|
|
break; |
|
|
case ::gig::dimension_portamentotime: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[5]; |
|
|
break; |
|
|
case ::gig::dimension_effect1: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[12]; |
|
|
break; |
|
|
case ::gig::dimension_effect2: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[13]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose1: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[16]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose2: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[17]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose3: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[18]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose4: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[19]; |
|
|
break; |
|
|
case ::gig::dimension_sustainpedal: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[64]; |
|
|
break; |
|
|
case ::gig::dimension_portamento: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[65]; |
|
|
break; |
|
|
case ::gig::dimension_sostenutopedal: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[66]; |
|
|
break; |
|
|
case ::gig::dimension_softpedal: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[67]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose5: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[80]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose6: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[81]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose7: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[82]; |
|
|
break; |
|
|
case ::gig::dimension_genpurpose8: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[83]; |
|
|
break; |
|
|
case ::gig::dimension_effect1depth: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[91]; |
|
|
break; |
|
|
case ::gig::dimension_effect2depth: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[92]; |
|
|
break; |
|
|
case ::gig::dimension_effect3depth: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[93]; |
|
|
break; |
|
|
case ::gig::dimension_effect4depth: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[94]; |
|
|
break; |
|
|
case ::gig::dimension_effect5depth: |
|
|
DimValues[i] = pEngineChannel->ControllerTable[95]; |
|
|
break; |
|
|
case ::gig::dimension_none: |
|
|
std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush; |
|
|
break; |
|
|
default: |
|
|
std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush; |
|
|
} |
|
|
} |
|
|
pDimRgn = pRegion->GetDimensionRegionByValue(DimValues); |
|
155 |
|
|
156 |
pSample = pDimRgn->pSample; // sample won't change until the voice is finished |
// the volume of release triggered samples depends on note length |
157 |
if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent |
if (Type == type_release_trigger) { |
158 |
|
float noteLength = float(pEngine->FrameTime + Delay - |
159 |
|
pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate; |
160 |
|
float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength; |
161 |
|
if (attenuation <= 0) return -1; |
162 |
|
Volume *= attenuation; |
163 |
|
} |
164 |
|
|
165 |
// select channel mode (mono or stereo) |
// select channel mode (mono or stereo) |
166 |
SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2); |
SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2); |
226 |
this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents |
this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents |
227 |
} |
} |
228 |
|
|
|
const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity); |
|
|
|
|
|
Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0) |
|
|
|
|
|
Volume *= pDimRgn->SampleAttenuation; |
|
|
|
|
229 |
// the length of the decay and release curves are dependent on the velocity |
// the length of the decay and release curves are dependent on the velocity |
230 |
const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity); |
const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity); |
231 |
|
|
249 |
} |
} |
250 |
if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue; |
if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue; |
251 |
|
|
252 |
// calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned) |
// calculate influence of EG1 controller on EG1's parameters |
253 |
double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0; |
// (eg1attack is different from the others) |
254 |
double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0; |
double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? |
255 |
double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0; |
1 + 0.031 * (double) (pDimRgn->EG1ControllerAttackInfluence == 1 ? |
256 |
|
1 : 1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 1.0; |
257 |
|
double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 1.0; |
258 |
|
double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 1.0; |
259 |
|
|
260 |
pEG1->Trigger(pDimRgn->EG1PreAttack, |
pEG1->Trigger(pDimRgn->EG1PreAttack, |
261 |
pDimRgn->EG1Attack + eg1attack, |
pDimRgn->EG1Attack * eg1attack, |
262 |
pDimRgn->EG1Hold, |
pDimRgn->EG1Hold, |
263 |
pSample->LoopStart, |
pSample->LoopStart, |
264 |
(pDimRgn->EG1Decay1 + eg1decay) * velrelease, |
pDimRgn->EG1Decay1 * eg1decay * velrelease, |
265 |
(pDimRgn->EG1Decay2 + eg1decay) * velrelease, |
pDimRgn->EG1Decay2 * eg1decay * velrelease, |
266 |
pDimRgn->EG1InfiniteSustain, |
pDimRgn->EG1InfiniteSustain, |
267 |
pDimRgn->EG1Sustain, |
pDimRgn->EG1Sustain, |
268 |
(pDimRgn->EG1Release + eg1release) * velrelease, |
pDimRgn->EG1Release * eg1release * velrelease, |
269 |
// the SSE synthesis implementation requires |
// the SSE synthesis implementation requires |
270 |
// the vca start to be 16 byte aligned |
// the vca start to be 16 byte aligned |
271 |
SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ? |
SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ? |
294 |
} |
} |
295 |
if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue; |
if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue; |
296 |
|
|
297 |
// calculate influence of EG2 controller on EG2's parameters (TODO: needs to be fine tuned) |
// calculate influence of EG2 controller on EG2's parameters |
298 |
double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 0.0; |
double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 1.0; |
299 |
double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 0.0; |
double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 1.0; |
300 |
double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 0.0; |
double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 1.0; |
301 |
|
|
302 |
pEG2->Trigger(pDimRgn->EG2PreAttack, |
pEG2->Trigger(pDimRgn->EG2PreAttack, |
303 |
pDimRgn->EG2Attack + eg2attack, |
pDimRgn->EG2Attack * eg2attack, |
304 |
false, |
false, |
305 |
pSample->LoopStart, |
pSample->LoopStart, |
306 |
(pDimRgn->EG2Decay1 + eg2decay) * velrelease, |
pDimRgn->EG2Decay1 * eg2decay * velrelease, |
307 |
(pDimRgn->EG2Decay2 + eg2decay) * velrelease, |
pDimRgn->EG2Decay2 * eg2decay * velrelease, |
308 |
pDimRgn->EG2InfiniteSustain, |
pDimRgn->EG2InfiniteSustain, |
309 |
pDimRgn->EG2Sustain, |
pDimRgn->EG2Sustain, |
310 |
(pDimRgn->EG2Release + eg2release) * velrelease, |
pDimRgn->EG2Release * eg2release * velrelease, |
311 |
Delay, |
Delay, |
312 |
velocityAttenuation); |
velocityAttenuation); |
313 |
} |
} |
327 |
case ::gig::lfo1_ctrl_internal: |
case ::gig::lfo1_ctrl_internal: |
328 |
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
329 |
pLFO1->ExtController = 0; // no external controller |
pLFO1->ExtController = 0; // no external controller |
330 |
|
bLFO1Enabled = (lfo1_internal_depth > 0); |
331 |
break; |
break; |
332 |
case ::gig::lfo1_ctrl_modwheel: |
case ::gig::lfo1_ctrl_modwheel: |
333 |
lfo1_internal_depth = 0; |
lfo1_internal_depth = 0; |
334 |
pLFO1->ExtController = 1; // MIDI controller 1 |
pLFO1->ExtController = 1; // MIDI controller 1 |
335 |
|
bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0); |
336 |
break; |
break; |
337 |
case ::gig::lfo1_ctrl_breath: |
case ::gig::lfo1_ctrl_breath: |
338 |
lfo1_internal_depth = 0; |
lfo1_internal_depth = 0; |
339 |
pLFO1->ExtController = 2; // MIDI controller 2 |
pLFO1->ExtController = 2; // MIDI controller 2 |
340 |
|
bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0); |
341 |
break; |
break; |
342 |
case ::gig::lfo1_ctrl_internal_modwheel: |
case ::gig::lfo1_ctrl_internal_modwheel: |
343 |
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
344 |
pLFO1->ExtController = 1; // MIDI controller 1 |
pLFO1->ExtController = 1; // MIDI controller 1 |
345 |
|
bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0); |
346 |
break; |
break; |
347 |
case ::gig::lfo1_ctrl_internal_breath: |
case ::gig::lfo1_ctrl_internal_breath: |
348 |
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
349 |
pLFO1->ExtController = 2; // MIDI controller 2 |
pLFO1->ExtController = 2; // MIDI controller 2 |
350 |
|
bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0); |
351 |
break; |
break; |
352 |
default: |
default: |
353 |
lfo1_internal_depth = 0; |
lfo1_internal_depth = 0; |
354 |
pLFO1->ExtController = 0; // no external controller |
pLFO1->ExtController = 0; // no external controller |
355 |
|
bLFO1Enabled = false; |
356 |
} |
} |
357 |
pLFO1->Trigger(pDimRgn->LFO1Frequency, |
if (bLFO1Enabled) pLFO1->Trigger(pDimRgn->LFO1Frequency, |
358 |
lfo1_internal_depth, |
lfo1_internal_depth, |
359 |
pDimRgn->LFO1ControlDepth, |
pDimRgn->LFO1ControlDepth, |
360 |
pEngineChannel->ControllerTable[pLFO1->ExtController], |
pEngineChannel->ControllerTable[pLFO1->ExtController], |
361 |
pDimRgn->LFO1FlipPhase, |
pDimRgn->LFO1FlipPhase, |
362 |
pEngine->SampleRate, |
pEngine->SampleRate, |
363 |
Delay); |
Delay); |
364 |
} |
} |
365 |
|
|
366 |
|
|
371 |
case ::gig::lfo2_ctrl_internal: |
case ::gig::lfo2_ctrl_internal: |
372 |
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
373 |
pLFO2->ExtController = 0; // no external controller |
pLFO2->ExtController = 0; // no external controller |
374 |
|
bLFO2Enabled = (lfo2_internal_depth > 0); |
375 |
break; |
break; |
376 |
case ::gig::lfo2_ctrl_modwheel: |
case ::gig::lfo2_ctrl_modwheel: |
377 |
lfo2_internal_depth = 0; |
lfo2_internal_depth = 0; |
378 |
pLFO2->ExtController = 1; // MIDI controller 1 |
pLFO2->ExtController = 1; // MIDI controller 1 |
379 |
|
bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0); |
380 |
break; |
break; |
381 |
case ::gig::lfo2_ctrl_foot: |
case ::gig::lfo2_ctrl_foot: |
382 |
lfo2_internal_depth = 0; |
lfo2_internal_depth = 0; |
383 |
pLFO2->ExtController = 4; // MIDI controller 4 |
pLFO2->ExtController = 4; // MIDI controller 4 |
384 |
|
bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0); |
385 |
break; |
break; |
386 |
case ::gig::lfo2_ctrl_internal_modwheel: |
case ::gig::lfo2_ctrl_internal_modwheel: |
387 |
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
388 |
pLFO2->ExtController = 1; // MIDI controller 1 |
pLFO2->ExtController = 1; // MIDI controller 1 |
389 |
|
bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0); |
390 |
break; |
break; |
391 |
case ::gig::lfo2_ctrl_internal_foot: |
case ::gig::lfo2_ctrl_internal_foot: |
392 |
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
393 |
pLFO2->ExtController = 4; // MIDI controller 4 |
pLFO2->ExtController = 4; // MIDI controller 4 |
394 |
|
bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0); |
395 |
break; |
break; |
396 |
default: |
default: |
397 |
lfo2_internal_depth = 0; |
lfo2_internal_depth = 0; |
398 |
pLFO2->ExtController = 0; // no external controller |
pLFO2->ExtController = 0; // no external controller |
399 |
|
bLFO2Enabled = false; |
400 |
} |
} |
401 |
pLFO2->Trigger(pDimRgn->LFO2Frequency, |
if (bLFO2Enabled) pLFO2->Trigger(pDimRgn->LFO2Frequency, |
402 |
lfo2_internal_depth, |
lfo2_internal_depth, |
403 |
pDimRgn->LFO2ControlDepth, |
pDimRgn->LFO2ControlDepth, |
404 |
pEngineChannel->ControllerTable[pLFO2->ExtController], |
pEngineChannel->ControllerTable[pLFO2->ExtController], |
405 |
pDimRgn->LFO2FlipPhase, |
pDimRgn->LFO2FlipPhase, |
406 |
pEngine->SampleRate, |
pEngine->SampleRate, |
407 |
Delay); |
Delay); |
408 |
} |
} |
409 |
|
|
410 |
|
|
415 |
case ::gig::lfo3_ctrl_internal: |
case ::gig::lfo3_ctrl_internal: |
416 |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
417 |
pLFO3->ExtController = 0; // no external controller |
pLFO3->ExtController = 0; // no external controller |
418 |
|
bLFO3Enabled = (lfo3_internal_depth > 0); |
419 |
break; |
break; |
420 |
case ::gig::lfo3_ctrl_modwheel: |
case ::gig::lfo3_ctrl_modwheel: |
421 |
lfo3_internal_depth = 0; |
lfo3_internal_depth = 0; |
422 |
pLFO3->ExtController = 1; // MIDI controller 1 |
pLFO3->ExtController = 1; // MIDI controller 1 |
423 |
|
bLFO3Enabled = (pDimRgn->LFO3ControlDepth > 0); |
424 |
break; |
break; |
425 |
case ::gig::lfo3_ctrl_aftertouch: |
case ::gig::lfo3_ctrl_aftertouch: |
426 |
lfo3_internal_depth = 0; |
lfo3_internal_depth = 0; |
427 |
pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet |
pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet |
428 |
|
bLFO3Enabled = false; // see TODO comment in line above |
429 |
break; |
break; |
430 |
case ::gig::lfo3_ctrl_internal_modwheel: |
case ::gig::lfo3_ctrl_internal_modwheel: |
431 |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
432 |
pLFO3->ExtController = 1; // MIDI controller 1 |
pLFO3->ExtController = 1; // MIDI controller 1 |
433 |
|
bLFO3Enabled = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0); |
434 |
break; |
break; |
435 |
case ::gig::lfo3_ctrl_internal_aftertouch: |
case ::gig::lfo3_ctrl_internal_aftertouch: |
436 |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
437 |
pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet |
pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet |
438 |
|
bLFO3Enabled = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above |
439 |
break; |
break; |
440 |
default: |
default: |
441 |
lfo3_internal_depth = 0; |
lfo3_internal_depth = 0; |
442 |
pLFO3->ExtController = 0; // no external controller |
pLFO3->ExtController = 0; // no external controller |
443 |
|
bLFO3Enabled = false; |
444 |
} |
} |
445 |
pLFO3->Trigger(pDimRgn->LFO3Frequency, |
if (bLFO3Enabled) pLFO3->Trigger(pDimRgn->LFO3Frequency, |
446 |
lfo3_internal_depth, |
lfo3_internal_depth, |
447 |
pDimRgn->LFO3ControlDepth, |
pDimRgn->LFO3ControlDepth, |
448 |
pEngineChannel->ControllerTable[pLFO3->ExtController], |
pEngineChannel->ControllerTable[pLFO3->ExtController], |
449 |
false, |
false, |
450 |
pEngine->SampleRate, |
pEngine->SampleRate, |
451 |
Delay); |
Delay); |
452 |
} |
} |
453 |
|
|
454 |
|
|
591 |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true); |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true); |
592 |
SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false); |
SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false); |
593 |
} |
} |
594 |
pLFO1->Process(Samples); |
if (bLFO1Enabled) pLFO1->Process(Samples); |
595 |
pLFO2->Process(Samples); |
if (bLFO2Enabled) pLFO2->Process(Samples); |
596 |
if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active |
if (bLFO3Enabled) { |
597 |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true); |
if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active |
598 |
SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false); |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true); |
599 |
|
SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false); |
600 |
|
} |
601 |
} |
} |
602 |
|
|
603 |
if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) |
if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) |