29 |
|
|
30 |
Voice::Voice() { |
Voice::Voice() { |
31 |
Active = false; |
Active = false; |
32 |
|
pLFO1 = new LFO(ModulationSystem::destination_vca, LFO::manipulation_type_multiply, 0.0f, 1.0f, LFO::propagation_top_down, pEngine->pEventPool); |
33 |
|
pLFO2 = new LFO(ModulationSystem::destination_vcfc, LFO::manipulation_type_multiply, 0.0f, 1.0f, LFO::propagation_top_down, pEngine->pEventPool); |
34 |
|
pLFO3 = new LFO(ModulationSystem::destination_vco, LFO::manipulation_type_add, -1.0f, 1.0f, LFO::propagation_middle_balanced, pEngine->pEventPool); |
35 |
} |
} |
36 |
|
|
37 |
Voice::~Voice() { |
Voice::~Voice() { |
38 |
|
if (pLFO1) delete pLFO1; |
39 |
|
if (pLFO2) delete pLFO2; |
40 |
|
if (pLFO3) delete pLFO3; |
41 |
} |
} |
42 |
|
|
43 |
/** |
/** |
118 |
: pow(2, ((double) pDimRgn->FineTune / 100.0) / 12.0)); |
: pow(2, ((double) pDimRgn->FineTune / 100.0) / 12.0)); |
119 |
|
|
120 |
Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->Velocity); |
Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->Velocity); |
121 |
|
|
122 |
// get current value of EG1 controller |
// get current value of EG1 controller |
123 |
double eg1controllervalue; |
double eg1controllervalue; |
124 |
switch (pDimRgn->EG1Controller.type) { |
switch (pDimRgn->EG1Controller.type) { |
136 |
break; |
break; |
137 |
} |
} |
138 |
if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue; |
if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue; |
139 |
|
|
140 |
// calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned) |
// calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned) |
141 |
double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0; |
double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0; |
142 |
double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0; |
double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0; |
143 |
double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0; |
double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0; |
144 |
|
|
145 |
EG1.Trigger(pDimRgn->EG1PreAttack, |
EG1.Trigger(pDimRgn->EG1PreAttack, |
146 |
pDimRgn->EG1Attack + eg1attack, |
pDimRgn->EG1Attack + eg1attack, |
147 |
pDimRgn->EG1Hold, |
pDimRgn->EG1Hold, |
153 |
pDimRgn->EG1Release + eg1release, |
pDimRgn->EG1Release + eg1release, |
154 |
Delay); |
Delay); |
155 |
|
|
156 |
|
// setup LFO 1 (VCA LFO) |
157 |
|
{ |
158 |
|
uint16_t lfo1_internal_depth; |
159 |
|
switch (pDimRgn->LFO1Controller) { |
160 |
|
case gig::lfo1_ctrl_internal: |
161 |
|
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
162 |
|
pLFO1->ExtController = 0; // no external controller |
163 |
|
break; |
164 |
|
case gig::lfo1_ctrl_modwheel: |
165 |
|
lfo1_internal_depth = 0; |
166 |
|
pLFO1->ExtController = 1; // MIDI controller 1 |
167 |
|
break; |
168 |
|
case gig::lfo1_ctrl_breath: |
169 |
|
lfo1_internal_depth = 0; |
170 |
|
pLFO1->ExtController = 2; // MIDI controller 2 |
171 |
|
break; |
172 |
|
case gig::lfo1_ctrl_internal_modwheel: |
173 |
|
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
174 |
|
pLFO1->ExtController = 1; // MIDI controller 1 |
175 |
|
break; |
176 |
|
case gig::lfo1_ctrl_internal_breath: |
177 |
|
lfo1_internal_depth = pDimRgn->LFO1InternalDepth; |
178 |
|
pLFO1->ExtController = 2; // MIDI controller 2 |
179 |
|
break; |
180 |
|
default: |
181 |
|
lfo1_internal_depth = 0; |
182 |
|
pLFO1->ExtController = 0; // no external controller |
183 |
|
} |
184 |
|
pLFO1->Trigger(pDimRgn->LFO1Frequency, |
185 |
|
lfo1_internal_depth, |
186 |
|
pDimRgn->LFO1ControlDepth, |
187 |
|
pEngine->ControllerTable[pLFO1->ExtController], |
188 |
|
pDimRgn->LFO1FlipPhase, |
189 |
|
Delay); |
190 |
|
} |
191 |
|
|
192 |
|
#if ENABLE_FILTER |
193 |
|
// setup LFO 2 (VCF Cutoff LFO) |
194 |
|
{ |
195 |
|
uint16_t lfo2_internal_depth; |
196 |
|
switch (pDimRgn->LFO2Controller) { |
197 |
|
case gig::lfo2_ctrl_internal: |
198 |
|
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
199 |
|
pLFO2->ExtController = 0; // no external controller |
200 |
|
break; |
201 |
|
case gig::lfo2_ctrl_modwheel: |
202 |
|
lfo2_internal_depth = 0; |
203 |
|
pLFO2->ExtController = 1; // MIDI controller 1 |
204 |
|
break; |
205 |
|
case gig::lfo2_ctrl_foot: |
206 |
|
lfo2_internal_depth = 0; |
207 |
|
pLFO2->ExtController = 4; // MIDI controller 4 |
208 |
|
break; |
209 |
|
case gig::lfo2_ctrl_internal_modwheel: |
210 |
|
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
211 |
|
pLFO2->ExtController = 1; // MIDI controller 1 |
212 |
|
break; |
213 |
|
case gig::lfo2_ctrl_internal_foot: |
214 |
|
lfo2_internal_depth = pDimRgn->LFO2InternalDepth; |
215 |
|
pLFO2->ExtController = 4; // MIDI controller 4 |
216 |
|
break; |
217 |
|
default: |
218 |
|
lfo2_internal_depth = 0; |
219 |
|
pLFO2->ExtController = 0; // no external controller |
220 |
|
} |
221 |
|
pLFO2->Trigger(pDimRgn->LFO2Frequency, |
222 |
|
lfo2_internal_depth, |
223 |
|
pDimRgn->LFO2ControlDepth, |
224 |
|
pEngine->ControllerTable[pLFO2->ExtController], |
225 |
|
pDimRgn->LFO2FlipPhase, |
226 |
|
Delay); |
227 |
|
} |
228 |
|
#endif // ENABLE_FILTER |
229 |
|
|
230 |
|
// setup LFO 3 (VCO LFO) |
231 |
|
{ |
232 |
|
uint16_t lfo3_internal_depth; |
233 |
|
switch (pDimRgn->LFO3Controller) { |
234 |
|
case gig::lfo3_ctrl_internal: |
235 |
|
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
236 |
|
pLFO3->ExtController = 0; // no external controller |
237 |
|
break; |
238 |
|
case gig::lfo3_ctrl_modwheel: |
239 |
|
lfo3_internal_depth = 0; |
240 |
|
pLFO3->ExtController = 1; // MIDI controller 1 |
241 |
|
break; |
242 |
|
case gig::lfo3_ctrl_aftertouch: |
243 |
|
lfo3_internal_depth = 0; |
244 |
|
pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet |
245 |
|
break; |
246 |
|
case gig::lfo3_ctrl_internal_modwheel: |
247 |
|
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
248 |
|
pLFO3->ExtController = 1; // MIDI controller 1 |
249 |
|
break; |
250 |
|
case gig::lfo3_ctrl_internal_aftertouch: |
251 |
|
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
252 |
|
pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet |
253 |
|
break; |
254 |
|
default: |
255 |
|
lfo3_internal_depth = 0; |
256 |
|
pLFO3->ExtController = 0; // no external controller |
257 |
|
} |
258 |
|
pLFO3->Trigger(pDimRgn->LFO3Frequency, |
259 |
|
lfo3_internal_depth, |
260 |
|
pDimRgn->LFO3ControlDepth, |
261 |
|
pEngine->ControllerTable[pLFO3->ExtController], |
262 |
|
false, |
263 |
|
Delay); |
264 |
|
} |
265 |
|
|
266 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
267 |
#if FORCE_FILTER_USAGE |
#if FORCE_FILTER_USAGE |
268 |
FilterLeft.Enabled = FilterRight.Enabled = true; |
FilterLeft.Enabled = FilterRight.Enabled = true; |
273 |
#ifdef OVERRIDE_FILTER_CUTOFF_CTRL |
#ifdef OVERRIDE_FILTER_CUTOFF_CTRL |
274 |
VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL; |
VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL; |
275 |
#else // use the one defined in the instrument file |
#else // use the one defined in the instrument file |
276 |
switch (pDimRgn->VCFCutoffController) { |
switch (pDimRgn->VCFCutoffController) { |
277 |
case gig::vcf_cutoff_ctrl_modwheel: |
case gig::vcf_cutoff_ctrl_modwheel: |
278 |
VCFCutoffCtrl.controller = 1; |
VCFCutoffCtrl.controller = 1; |
279 |
break; |
break; |
308 |
break; |
break; |
309 |
} |
} |
310 |
#endif // OVERRIDE_FILTER_CUTOFF_CTRL |
#endif // OVERRIDE_FILTER_CUTOFF_CTRL |
311 |
|
|
312 |
#ifdef OVERRIDE_FILTER_RES_CTRL |
#ifdef OVERRIDE_FILTER_RES_CTRL |
313 |
VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL; |
VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL; |
314 |
#else // use the one defined in the instrument file |
#else // use the one defined in the instrument file |
330 |
VCFResonanceCtrl.controller = 0; |
VCFResonanceCtrl.controller = 0; |
331 |
} |
} |
332 |
#endif // OVERRIDE_FILTER_RES_CTRL |
#endif // OVERRIDE_FILTER_RES_CTRL |
333 |
|
|
334 |
#ifndef OVERRIDE_FILTER_TYPE |
#ifndef OVERRIDE_FILTER_TYPE |
335 |
FilterLeft.SetType(pDimRgn->VCFType); |
FilterLeft.SetType(pDimRgn->VCFType); |
336 |
FilterRight.SetType(pDimRgn->VCFType); |
FilterRight.SetType(pDimRgn->VCFType); |
338 |
FilterLeft.SetType(OVERRIDE_FILTER_TYPE); |
FilterLeft.SetType(OVERRIDE_FILTER_TYPE); |
339 |
FilterRight.SetType(OVERRIDE_FILTER_TYPE); |
FilterRight.SetType(OVERRIDE_FILTER_TYPE); |
340 |
#endif // OVERRIDE_FILTER_TYPE |
#endif // OVERRIDE_FILTER_TYPE |
341 |
|
|
342 |
VCFCutoffCtrl.value = pEngine->ControllerTable[VCFCutoffCtrl.controller]; |
VCFCutoffCtrl.value = pEngine->ControllerTable[VCFCutoffCtrl.controller]; |
343 |
VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller]; |
VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller]; |
344 |
|
|
345 |
// calculate cutoff frequency |
// calculate cutoff frequency |
346 |
float cutoff = (!VCFCutoffCtrl.controller && pDimRgn->VCFVelocityScale) |
float cutoff = (!VCFCutoffCtrl.controller && pDimRgn->VCFVelocityScale) |
347 |
? (float) pNoteOnEvent->Velocity * pDimRgn->VCFVelocityScale * 0.31f + 20.0f // 20Hz..5kHz |
? (float) pNoteOnEvent->Velocity * pDimRgn->VCFVelocityScale * 0.31f // up to 5kHz |
348 |
: (float) (127 - VCFCutoffCtrl.value) * 39.4f + 20.0f; // 20Hz..5kHz (inverted) |
: (float) (127 - VCFCutoffCtrl.value) * 39.4f; // up to 5kHz (inverted) |
349 |
|
|
350 |
// calculate resonance |
// calculate resonance |
351 |
float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0 |
float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0 |
352 |
if (pDimRgn->VCFKeyboardTracking) { |
if (pDimRgn->VCFKeyboardTracking) { |
353 |
resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f; |
resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f; |
354 |
} |
} |
355 |
Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0) |
Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0) |
356 |
|
|
357 |
FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate()); |
VCFCutoffCtrl.fvalue = cutoff; |
358 |
FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate()); |
VCFResonanceCtrl.fvalue = resonance; |
359 |
|
|
360 |
|
FilterLeft.SetParameters(cutoff + 20.0f, resonance, ModulationSystem::SampleRate()); // 20Hz min. |
361 |
|
FilterRight.SetParameters(cutoff + 20.0f, resonance, ModulationSystem::SampleRate()); // 20Hz min. |
362 |
} |
} |
363 |
else { |
else { |
364 |
VCFCutoffCtrl.controller = 0; |
VCFCutoffCtrl.controller = 0; |
389 |
// Reset the synthesis parameter matrix |
// Reset the synthesis parameter matrix |
390 |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vca, this->Volume); |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vca, this->Volume); |
391 |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vco, this->Pitch); |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vco, this->Pitch); |
392 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
393 |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vcfc, FilterLeft.Cutoff()); // intialize with last cutoff value from previous render cycle |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vcfc, VCFCutoffCtrl.fvalue); |
394 |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vcfr, FilterLeft.Resonance()); // intialize with last resonance value from previous render cycle |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vcfr, VCFResonanceCtrl.fvalue); |
395 |
|
#endif // ENABLE_FILTER |
|
|
|
|
// Reset synthesis event lists (except VCO, as VCO events apply channel wide currently) |
|
|
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfc]->clear(); |
|
|
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfr]->clear(); |
|
|
#endif // ENABLE_FILTER |
|
396 |
|
|
397 |
|
|
398 |
// Apply events to the synthesis parameter matrix |
// Apply events to the synthesis parameter matrix |
400 |
|
|
401 |
|
|
402 |
// Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment |
// Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment |
403 |
EG1.Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->Pitch); |
EG1.Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->Pitch); |
404 |
|
pLFO1->Process(Samples); |
405 |
|
#if ENABLE_FILTER |
406 |
|
pLFO2->Process(Samples); |
407 |
|
#endif // ENABLE_FILTER |
408 |
|
pLFO3->Process(Samples); |
409 |
|
|
410 |
|
|
411 |
switch (this->PlaybackState) { |
switch (this->PlaybackState) { |
458 |
} |
} |
459 |
|
|
460 |
|
|
461 |
|
#if ENABLE_FILTER |
462 |
|
// Reset synthesis event lists (except VCO, as VCO events apply channel wide currently) |
463 |
|
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfc]->clear(); |
464 |
|
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfr]->clear(); |
465 |
|
#endif // ENABLE_FILTER |
466 |
|
|
467 |
// Reset delay |
// Reset delay |
468 |
Delay = 0; |
Delay = 0; |
469 |
|
|
478 |
* suspended / not running. |
* suspended / not running. |
479 |
*/ |
*/ |
480 |
void Voice::Reset() { |
void Voice::Reset() { |
481 |
|
pLFO1->Reset(); |
482 |
|
pLFO2->Reset(); |
483 |
|
pLFO3->Reset(); |
484 |
DiskStreamRef.pStream = NULL; |
DiskStreamRef.pStream = NULL; |
485 |
DiskStreamRef.hStream = 0; |
DiskStreamRef.hStream = 0; |
486 |
DiskStreamRef.State = Stream::state_unused; |
DiskStreamRef.State = Stream::state_unused; |
496 |
* @param Samples - number of samples to be rendered in this audio fragment cycle |
* @param Samples - number of samples to be rendered in this audio fragment cycle |
497 |
*/ |
*/ |
498 |
void Voice::ProcessEvents(uint Samples) { |
void Voice::ProcessEvents(uint Samples) { |
499 |
#if ENABLE_FILTER |
|
500 |
// dispatch control change events |
// dispatch control change events |
501 |
ModulationSystem::Event* pCCEvent = pEngine->pCCEvents->first(); |
ModulationSystem::Event* pCCEvent = pEngine->pCCEvents->first(); |
502 |
while (pCCEvent) { |
while (pCCEvent) { |
503 |
if (pCCEvent->Controller == VCFCutoffCtrl.controller) { |
if (pCCEvent->Controller) { // if valid MIDI controller |
504 |
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfc]->alloc_assign(*pCCEvent); |
#if ENABLE_FILTER |
505 |
} |
if (pCCEvent->Controller == VCFCutoffCtrl.controller) { |
506 |
if (pCCEvent->Controller == VCFResonanceCtrl.controller) { |
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfc]->alloc_assign(*pCCEvent); |
507 |
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfr]->alloc_assign(*pCCEvent); |
} |
508 |
|
if (pCCEvent->Controller == VCFResonanceCtrl.controller) { |
509 |
|
pEngine->pSynthesisEvents[ModulationSystem::destination_vcfr]->alloc_assign(*pCCEvent); |
510 |
|
} |
511 |
|
#endif // ENABLE_FILTER |
512 |
|
if (pCCEvent->Controller == pLFO1->ExtController) { |
513 |
|
pLFO1->SendEvent(pCCEvent); |
514 |
|
} |
515 |
|
#if ENABLE_FILTER |
516 |
|
if (pCCEvent->Controller == pLFO2->ExtController) { |
517 |
|
pLFO2->SendEvent(pCCEvent); |
518 |
|
} |
519 |
|
#endif // ENABLE_FILTER |
520 |
|
if (pCCEvent->Controller == pLFO3->ExtController) { |
521 |
|
pLFO3->SendEvent(pCCEvent); |
522 |
|
} |
523 |
} |
} |
524 |
|
|
525 |
pCCEvent = pEngine->pCCEvents->next(); |
pCCEvent = pEngine->pCCEvents->next(); |
526 |
} |
} |
|
#endif // ENABLE_FILTER |
|
527 |
|
|
528 |
// process pitch events |
// process pitch events |
529 |
RTEList<ModulationSystem::Event>* pVCOEventList = pEngine->pSynthesisEvents[ModulationSystem::destination_vco]; |
RTEList<ModulationSystem::Event>* pVCOEventList = pEngine->pSynthesisEvents[ModulationSystem::destination_vco]; |
533 |
|
|
534 |
// calculate the influence length of this event (in sample points) |
// calculate the influence length of this event (in sample points) |
535 |
uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples; |
uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples; |
536 |
|
|
537 |
this->Pitch += ((double) pVCOEvent->Pitch / 8192.0) / 12.0; // +- one semitone |
this->Pitch += ((double) pVCOEvent->Pitch / 8192.0) / 12.0; // +- one semitone |
538 |
|
|
539 |
// apply pitch value to the pitch parameter sequence |
// apply pitch value to the pitch parameter sequence |
557 |
// convert absolute controller value to differential |
// convert absolute controller value to differential |
558 |
int ctrldelta = pCutoffEvent->Value - VCFCutoffCtrl.value; |
int ctrldelta = pCutoffEvent->Value - VCFCutoffCtrl.value; |
559 |
VCFCutoffCtrl.value = pCutoffEvent->Value; |
VCFCutoffCtrl.value = pCutoffEvent->Value; |
560 |
|
|
561 |
float cutoffdelta = (float) ctrldelta * -39.4f; // (20Hz)..5kHz (inverted) |
float cutoffdelta = (float) ctrldelta * -39.4f; // (20Hz)..5kHz (inverted) |
562 |
|
|
563 |
// apply cutoff frequency to the cutoff parameter sequence |
// apply cutoff frequency to the cutoff parameter sequence |
564 |
for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) { |
for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) { |
565 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][i] += cutoffdelta; |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][i] += cutoffdelta; |
567 |
|
|
568 |
pCutoffEvent = pNextCutoffEvent; |
pCutoffEvent = pNextCutoffEvent; |
569 |
} |
} |
570 |
|
if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = (float) (127 - pCutoffEventList->last()->Value) * 39.4f; // needed for initialization of parameter matrix next time |
571 |
|
|
572 |
// process filter resonance events |
// process filter resonance events |
573 |
RTEList<ModulationSystem::Event>* pResonanceEventList = pEngine->pSynthesisEvents[ModulationSystem::destination_vcfr]; |
RTEList<ModulationSystem::Event>* pResonanceEventList = pEngine->pSynthesisEvents[ModulationSystem::destination_vcfr]; |
574 |
ModulationSystem::Event* pResonanceEvent = pResonanceEventList->first(); |
ModulationSystem::Event* pResonanceEvent = pResonanceEventList->first(); |
577 |
|
|
578 |
// calculate the influence length of this event (in sample points) |
// calculate the influence length of this event (in sample points) |
579 |
uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples; |
uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples; |
580 |
|
|
581 |
// convert absolute controller value to differential |
// convert absolute controller value to differential |
582 |
int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value; |
int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value; |
583 |
VCFResonanceCtrl.value = pResonanceEvent->Value; |
VCFResonanceCtrl.value = pResonanceEvent->Value; |
584 |
|
|
585 |
float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0 |
float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0 |
586 |
|
|
587 |
// apply cutoff frequency to the cutoff parameter sequence |
// apply cutoff frequency to the cutoff parameter sequence |
588 |
for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) { |
for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) { |
589 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][i] += resonancedelta; |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][i] += resonancedelta; |
591 |
|
|
592 |
pResonanceEvent = pNextResonanceEvent; |
pResonanceEvent = pNextResonanceEvent; |
593 |
} |
} |
594 |
|
if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Value * 0.00787f; // needed for initialization of parameter matrix next time |
595 |
#endif // ENABLE_FILTER |
#endif // ENABLE_FILTER |
596 |
} |
} |
597 |
|
|
615 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][i], |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][i], |
616 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][i]); |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][i]); |
617 |
} |
} |
618 |
|
|
619 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
620 |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
621 |
ForceUpdateFilter_Stereo(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
ForceUpdateFilter_Stereo(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
622 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
630 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][i], |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][i], |
631 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][i]); |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][i]); |
632 |
} |
} |
633 |
|
|
634 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
635 |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
636 |
ForceUpdateFilter_Mono(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
ForceUpdateFilter_Mono(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
637 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
638 |
#endif // ENABLE_FILTER |
#endif // ENABLE_FILTER |
639 |
} |
} |
640 |
} |
} |
641 |
|
|
642 |
/** |
/** |
686 |
} |
} |
687 |
} |
} |
688 |
} |
} |
689 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
690 |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
691 |
ForceUpdateFilter_Stereo(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
ForceUpdateFilter_Stereo(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
692 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
693 |
#endif // ENABLE_FILTER |
#endif // ENABLE_FILTER |
694 |
} |
} |
695 |
else { // Mono Sample |
else { // Mono Sample |
696 |
if (pSample->LoopPlayCount) { |
if (pSample->LoopPlayCount) { |
727 |
} |
} |
728 |
} |
} |
729 |
} |
} |
730 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
731 |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
// to save the last filter setting for the next render cycle (only needed when we update the filter not-sample-accurate) |
732 |
ForceUpdateFilter_Mono(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
ForceUpdateFilter_Mono(ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfc][Samples - 1], |
733 |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
ModulationSystem::pDestinationParameter[ModulationSystem::destination_vcfr][Samples - 1]); |
734 |
#endif // ENABLE_FILTER |
#endif // ENABLE_FILTER |
735 |
} |
} |
736 |
} |
} |
737 |
|
|
738 |
/** |
/** |