/[svn]/linuxsampler/trunk/src/engines/gig/Voice.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/gig/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 630 - (show annotations) (download)
Sat Jun 11 14:51:49 2005 UTC (18 years, 10 months ago) by persson
File size: 52965 byte(s)
* volume of release triggered samples now depends on note-on velocity,
  note length and gig parameter "release trigger decay" instead of
  note-off velocity.

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 Christian Schoenebeck *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "EGADSR.h"
25 #include "Manipulator.h"
26 #include "../../common/Features.h"
27 #include "Synthesizer.h"
28
29 #include "Voice.h"
30
31 namespace LinuxSampler { namespace gig {
32
33 const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
34
35 const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
36
37 float Voice::CalculateFilterCutoffCoeff() {
38 return log(CONFIG_FILTER_CUTOFF_MIN / CONFIG_FILTER_CUTOFF_MAX);
39 }
40
41 int Voice::CalculateFilterUpdateMask() {
42 if (CONFIG_FILTER_UPDATE_STEPS <= 0) return 0;
43 int power_of_two;
44 for (power_of_two = 0; 1<<power_of_two < CONFIG_FILTER_UPDATE_STEPS; power_of_two++);
45 return (1 << power_of_two) - 1;
46 }
47
48 Voice::Voice() {
49 pEngine = NULL;
50 pDiskThread = NULL;
51 PlaybackState = playback_state_end;
52 pEG1 = NULL;
53 pEG2 = NULL;
54 pEG3 = NULL;
55 pVCAManipulator = NULL;
56 pVCFCManipulator = NULL;
57 pVCOManipulator = NULL;
58 pLFO1 = NULL;
59 pLFO2 = NULL;
60 pLFO3 = NULL;
61 KeyGroup = 0;
62 SynthesisMode = 0; // set all mode bits to 0 first
63 // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
64 #if CONFIG_ASM && ARCH_X86
65 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
66 #else
67 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
68 #endif
69 SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
70
71 FilterLeft.Reset();
72 FilterRight.Reset();
73 }
74
75 Voice::~Voice() {
76 if (pEG1) delete pEG1;
77 if (pEG2) delete pEG2;
78 if (pEG3) delete pEG3;
79 if (pLFO1) delete pLFO1;
80 if (pLFO2) delete pLFO2;
81 if (pLFO3) delete pLFO3;
82 if (pVCAManipulator) delete pVCAManipulator;
83 if (pVCFCManipulator) delete pVCFCManipulator;
84 if (pVCOManipulator) delete pVCOManipulator;
85 }
86
87 void Voice::SetEngine(Engine* pEngine) {
88 this->pEngine = pEngine;
89
90 // delete old objects
91 if (pEG1) delete pEG1;
92 if (pEG2) delete pEG2;
93 if (pEG3) delete pEG3;
94 if (pVCAManipulator) delete pVCAManipulator;
95 if (pVCFCManipulator) delete pVCFCManipulator;
96 if (pVCOManipulator) delete pVCOManipulator;
97 if (pLFO1) delete pLFO1;
98 if (pLFO2) delete pLFO2;
99 if (pLFO3) delete pLFO3;
100
101 // create new ones
102 pEG1 = new EGADSR(pEngine, Event::destination_vca);
103 pEG2 = new EGADSR(pEngine, Event::destination_vcfc);
104 pEG3 = new EGDecay(pEngine, Event::destination_vco);
105 pVCAManipulator = new VCAManipulator(pEngine);
106 pVCFCManipulator = new VCFCManipulator(pEngine);
107 pVCOManipulator = new VCOManipulator(pEngine);
108 pLFO1 = new LFO<gig::VCAManipulator>(0.0f, 1.0f, LFO<VCAManipulator>::propagation_top_down, pVCAManipulator, pEngine->pEventPool);
109 pLFO2 = new LFO<gig::VCFCManipulator>(0.0f, 1.0f, LFO<VCFCManipulator>::propagation_top_down, pVCFCManipulator, pEngine->pEventPool);
110 pLFO3 = new LFO<gig::VCOManipulator>(-1200.0f, 1200.0f, LFO<VCOManipulator>::propagation_middle_balanced, pVCOManipulator, pEngine->pEventPool); // +-1 octave (+-1200 cents) max.
111
112 this->pDiskThread = pEngine->pDiskThread;
113 dmsg(6,("Voice::SetEngine()\n"));
114 }
115
116 /**
117 * Initializes and triggers the voice, a disk stream will be launched if
118 * needed.
119 *
120 * @param pEngineChannel - engine channel on which this voice was ordered
121 * @param itNoteOnEvent - event that caused triggering of this voice
122 * @param PitchBend - MIDI detune factor (-8192 ... +8191)
123 * @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)
125 * @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)
126 * @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
128 * (either due to an error or e.g. because no region is
129 * 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 VoiceStealingAllowed) {
132 this->pEngineChannel = pEngineChannel;
133 if (!pInstrument) {
134 dmsg(1,("voice::trigger: !pInstrument\n"));
135 exit(EXIT_FAILURE);
136 }
137 #if CONFIG_DEVMODE
138 if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
139 dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
140 }
141 #endif // CONFIG_DEVMODE
142
143 Type = type_normal;
144 MIDIKey = itNoteOnEvent->Param.Note.Key;
145 pRegion = pInstrument->GetRegion(MIDIKey);
146 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
147 Delay = itNoteOnEvent->FragmentPos();
148 itTriggerEvent = itNoteOnEvent;
149 itKillEvent = Pool<Event>::Iterator();
150
151 if (!pRegion) {
152 dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));
153 return -1;
154 }
155
156 // only mark the first voice of a layered voice (group) to be in a
157 // key group, so the layered voices won't kill each other
158 KeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
159
160 // get current dimension values to select the right dimension region
161 //FIXME: controller values for selecting the dimension region here are currently not sample accurate
162 uint DimValues[8] = { 0 };
163 for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
164 switch (pRegion->pDimensionDefinitions[i].dimension) {
165 case ::gig::dimension_samplechannel:
166 DimValues[i] = 0; //TODO: we currently ignore this dimension
167 break;
168 case ::gig::dimension_layer:
169 DimValues[i] = iLayer;
170 break;
171 case ::gig::dimension_velocity:
172 DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
173 break;
174 case ::gig::dimension_channelaftertouch:
175 DimValues[i] = 0; //TODO: we currently ignore this dimension
176 break;
177 case ::gig::dimension_releasetrigger:
178 Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal;
179 DimValues[i] = (uint) ReleaseTriggerVoice;
180 break;
181 case ::gig::dimension_keyboard:
182 DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;
183 break;
184 case ::gig::dimension_roundrobin:
185 DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
186 break;
187 case ::gig::dimension_random:
188 pEngine->RandomSeed = pEngine->RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
189 DimValues[i] = (uint) pEngine->RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
190 break;
191 case ::gig::dimension_modwheel:
192 DimValues[i] = pEngineChannel->ControllerTable[1];
193 break;
194 case ::gig::dimension_breath:
195 DimValues[i] = pEngineChannel->ControllerTable[2];
196 break;
197 case ::gig::dimension_foot:
198 DimValues[i] = pEngineChannel->ControllerTable[4];
199 break;
200 case ::gig::dimension_portamentotime:
201 DimValues[i] = pEngineChannel->ControllerTable[5];
202 break;
203 case ::gig::dimension_effect1:
204 DimValues[i] = pEngineChannel->ControllerTable[12];
205 break;
206 case ::gig::dimension_effect2:
207 DimValues[i] = pEngineChannel->ControllerTable[13];
208 break;
209 case ::gig::dimension_genpurpose1:
210 DimValues[i] = pEngineChannel->ControllerTable[16];
211 break;
212 case ::gig::dimension_genpurpose2:
213 DimValues[i] = pEngineChannel->ControllerTable[17];
214 break;
215 case ::gig::dimension_genpurpose3:
216 DimValues[i] = pEngineChannel->ControllerTable[18];
217 break;
218 case ::gig::dimension_genpurpose4:
219 DimValues[i] = pEngineChannel->ControllerTable[19];
220 break;
221 case ::gig::dimension_sustainpedal:
222 DimValues[i] = pEngineChannel->ControllerTable[64];
223 break;
224 case ::gig::dimension_portamento:
225 DimValues[i] = pEngineChannel->ControllerTable[65];
226 break;
227 case ::gig::dimension_sostenutopedal:
228 DimValues[i] = pEngineChannel->ControllerTable[66];
229 break;
230 case ::gig::dimension_softpedal:
231 DimValues[i] = pEngineChannel->ControllerTable[67];
232 break;
233 case ::gig::dimension_genpurpose5:
234 DimValues[i] = pEngineChannel->ControllerTable[80];
235 break;
236 case ::gig::dimension_genpurpose6:
237 DimValues[i] = pEngineChannel->ControllerTable[81];
238 break;
239 case ::gig::dimension_genpurpose7:
240 DimValues[i] = pEngineChannel->ControllerTable[82];
241 break;
242 case ::gig::dimension_genpurpose8:
243 DimValues[i] = pEngineChannel->ControllerTable[83];
244 break;
245 case ::gig::dimension_effect1depth:
246 DimValues[i] = pEngineChannel->ControllerTable[91];
247 break;
248 case ::gig::dimension_effect2depth:
249 DimValues[i] = pEngineChannel->ControllerTable[92];
250 break;
251 case ::gig::dimension_effect3depth:
252 DimValues[i] = pEngineChannel->ControllerTable[93];
253 break;
254 case ::gig::dimension_effect4depth:
255 DimValues[i] = pEngineChannel->ControllerTable[94];
256 break;
257 case ::gig::dimension_effect5depth:
258 DimValues[i] = pEngineChannel->ControllerTable[95];
259 break;
260 case ::gig::dimension_none:
261 std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;
262 break;
263 default:
264 std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;
265 }
266 }
267 pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
268
269 pSample = pDimRgn->pSample; // sample won't change until the voice is finished
270 if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
271
272 // calculate volume
273 const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
274
275 Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
276
277 Volume *= pDimRgn->SampleAttenuation;
278
279 // the volume of release triggered samples depends on note length
280 if (ReleaseTriggerVoice) {
281 float noteLength = float(pEngine->FrameTime + Delay -
282 pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
283 float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
284 if (attenuation <= 0) return -1;
285 Volume *= attenuation;
286 }
287
288 // select channel mode (mono or stereo)
289 SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
290
291 // get starting crossfade volume level
292 switch (pDimRgn->AttenuationController.type) {
293 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
294 CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
295 break;
296 case ::gig::attenuation_ctrl_t::type_velocity:
297 CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
298 break;
299 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
300 CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
301 break;
302 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
303 default:
304 CrossfadeVolume = 1.0f;
305 }
306
307 PanLeft = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) / 63.0f;
308 PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
309
310 Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
311
312 // Check if the sample needs disk streaming or is too short for that
313 long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
314 DiskVoice = cachedsamples < pSample->SamplesTotal;
315
316 if (DiskVoice) { // voice to be streamed from disk
317 MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
318
319 // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
320 if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
321 RAMLoop = true;
322 LoopCyclesLeft = pSample->LoopPlayCount;
323 }
324 else RAMLoop = false;
325
326 if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
327 dmsg(1,("Disk stream order failed!\n"));
328 KillImmediately();
329 return -1;
330 }
331 dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
332 }
333 else { // RAM only voice
334 MaxRAMPos = cachedsamples;
335 if (pSample->Loops) {
336 RAMLoop = true;
337 LoopCyclesLeft = pSample->LoopPlayCount;
338 }
339 else RAMLoop = false;
340 dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
341 }
342
343
344 // calculate initial pitch value
345 {
346 double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
347 if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
348 this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
349 this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
350 }
351
352 // the length of the decay and release curves are dependent on the velocity
353 const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
354
355 // setup EG 1 (VCA EG)
356 {
357 // get current value of EG1 controller
358 double eg1controllervalue;
359 switch (pDimRgn->EG1Controller.type) {
360 case ::gig::eg1_ctrl_t::type_none: // no controller defined
361 eg1controllervalue = 0;
362 break;
363 case ::gig::eg1_ctrl_t::type_channelaftertouch:
364 eg1controllervalue = 0; // TODO: aftertouch not yet supported
365 break;
366 case ::gig::eg1_ctrl_t::type_velocity:
367 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
368 break;
369 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
370 eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
371 break;
372 }
373 if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
374
375 // calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned)
376 double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0;
377 double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0;
378 double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0;
379
380 pEG1->Trigger(pDimRgn->EG1PreAttack,
381 pDimRgn->EG1Attack + eg1attack,
382 pDimRgn->EG1Hold,
383 pSample->LoopStart,
384 (pDimRgn->EG1Decay1 + eg1decay) * velrelease,
385 (pDimRgn->EG1Decay2 + eg1decay) * velrelease,
386 pDimRgn->EG1InfiniteSustain,
387 pDimRgn->EG1Sustain,
388 (pDimRgn->EG1Release + eg1release) * velrelease,
389 // the SSE synthesis implementation requires
390 // the vca start to be 16 byte aligned
391 SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
392 Delay & 0xfffffffc : Delay,
393 velocityAttenuation);
394 }
395
396
397 // setup EG 2 (VCF Cutoff EG)
398 {
399 // get current value of EG2 controller
400 double eg2controllervalue;
401 switch (pDimRgn->EG2Controller.type) {
402 case ::gig::eg2_ctrl_t::type_none: // no controller defined
403 eg2controllervalue = 0;
404 break;
405 case ::gig::eg2_ctrl_t::type_channelaftertouch:
406 eg2controllervalue = 0; // TODO: aftertouch not yet supported
407 break;
408 case ::gig::eg2_ctrl_t::type_velocity:
409 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
410 break;
411 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
412 eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
413 break;
414 }
415 if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
416
417 // calculate influence of EG2 controller on EG2's parameters (TODO: needs to be fine tuned)
418 double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 0.0;
419 double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 0.0;
420 double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 0.0;
421
422 pEG2->Trigger(pDimRgn->EG2PreAttack,
423 pDimRgn->EG2Attack + eg2attack,
424 false,
425 pSample->LoopStart,
426 (pDimRgn->EG2Decay1 + eg2decay) * velrelease,
427 (pDimRgn->EG2Decay2 + eg2decay) * velrelease,
428 pDimRgn->EG2InfiniteSustain,
429 pDimRgn->EG2Sustain,
430 (pDimRgn->EG2Release + eg2release) * velrelease,
431 Delay,
432 velocityAttenuation);
433 }
434
435
436 // setup EG 3 (VCO EG)
437 {
438 double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
439 pEG3->Trigger(eg3depth, pDimRgn->EG3Attack, Delay);
440 }
441
442
443 // setup LFO 1 (VCA LFO)
444 {
445 uint16_t lfo1_internal_depth;
446 switch (pDimRgn->LFO1Controller) {
447 case ::gig::lfo1_ctrl_internal:
448 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
449 pLFO1->ExtController = 0; // no external controller
450 break;
451 case ::gig::lfo1_ctrl_modwheel:
452 lfo1_internal_depth = 0;
453 pLFO1->ExtController = 1; // MIDI controller 1
454 break;
455 case ::gig::lfo1_ctrl_breath:
456 lfo1_internal_depth = 0;
457 pLFO1->ExtController = 2; // MIDI controller 2
458 break;
459 case ::gig::lfo1_ctrl_internal_modwheel:
460 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
461 pLFO1->ExtController = 1; // MIDI controller 1
462 break;
463 case ::gig::lfo1_ctrl_internal_breath:
464 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
465 pLFO1->ExtController = 2; // MIDI controller 2
466 break;
467 default:
468 lfo1_internal_depth = 0;
469 pLFO1->ExtController = 0; // no external controller
470 }
471 pLFO1->Trigger(pDimRgn->LFO1Frequency,
472 lfo1_internal_depth,
473 pDimRgn->LFO1ControlDepth,
474 pEngineChannel->ControllerTable[pLFO1->ExtController],
475 pDimRgn->LFO1FlipPhase,
476 pEngine->SampleRate,
477 Delay);
478 }
479
480
481 // setup LFO 2 (VCF Cutoff LFO)
482 {
483 uint16_t lfo2_internal_depth;
484 switch (pDimRgn->LFO2Controller) {
485 case ::gig::lfo2_ctrl_internal:
486 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
487 pLFO2->ExtController = 0; // no external controller
488 break;
489 case ::gig::lfo2_ctrl_modwheel:
490 lfo2_internal_depth = 0;
491 pLFO2->ExtController = 1; // MIDI controller 1
492 break;
493 case ::gig::lfo2_ctrl_foot:
494 lfo2_internal_depth = 0;
495 pLFO2->ExtController = 4; // MIDI controller 4
496 break;
497 case ::gig::lfo2_ctrl_internal_modwheel:
498 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
499 pLFO2->ExtController = 1; // MIDI controller 1
500 break;
501 case ::gig::lfo2_ctrl_internal_foot:
502 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
503 pLFO2->ExtController = 4; // MIDI controller 4
504 break;
505 default:
506 lfo2_internal_depth = 0;
507 pLFO2->ExtController = 0; // no external controller
508 }
509 pLFO2->Trigger(pDimRgn->LFO2Frequency,
510 lfo2_internal_depth,
511 pDimRgn->LFO2ControlDepth,
512 pEngineChannel->ControllerTable[pLFO2->ExtController],
513 pDimRgn->LFO2FlipPhase,
514 pEngine->SampleRate,
515 Delay);
516 }
517
518
519 // setup LFO 3 (VCO LFO)
520 {
521 uint16_t lfo3_internal_depth;
522 switch (pDimRgn->LFO3Controller) {
523 case ::gig::lfo3_ctrl_internal:
524 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
525 pLFO3->ExtController = 0; // no external controller
526 break;
527 case ::gig::lfo3_ctrl_modwheel:
528 lfo3_internal_depth = 0;
529 pLFO3->ExtController = 1; // MIDI controller 1
530 break;
531 case ::gig::lfo3_ctrl_aftertouch:
532 lfo3_internal_depth = 0;
533 pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
534 break;
535 case ::gig::lfo3_ctrl_internal_modwheel:
536 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
537 pLFO3->ExtController = 1; // MIDI controller 1
538 break;
539 case ::gig::lfo3_ctrl_internal_aftertouch:
540 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
541 pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
542 break;
543 default:
544 lfo3_internal_depth = 0;
545 pLFO3->ExtController = 0; // no external controller
546 }
547 pLFO3->Trigger(pDimRgn->LFO3Frequency,
548 lfo3_internal_depth,
549 pDimRgn->LFO3ControlDepth,
550 pEngineChannel->ControllerTable[pLFO3->ExtController],
551 false,
552 pEngine->SampleRate,
553 Delay);
554 }
555
556
557 #if CONFIG_FORCE_FILTER
558 const bool bUseFilter = true;
559 #else // use filter only if instrument file told so
560 const bool bUseFilter = pDimRgn->VCFEnabled;
561 #endif // CONFIG_FORCE_FILTER
562 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
563 if (bUseFilter) {
564 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
565 VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
566 #else // use the one defined in the instrument file
567 switch (pDimRgn->VCFCutoffController) {
568 case ::gig::vcf_cutoff_ctrl_modwheel:
569 VCFCutoffCtrl.controller = 1;
570 break;
571 case ::gig::vcf_cutoff_ctrl_effect1:
572 VCFCutoffCtrl.controller = 12;
573 break;
574 case ::gig::vcf_cutoff_ctrl_effect2:
575 VCFCutoffCtrl.controller = 13;
576 break;
577 case ::gig::vcf_cutoff_ctrl_breath:
578 VCFCutoffCtrl.controller = 2;
579 break;
580 case ::gig::vcf_cutoff_ctrl_foot:
581 VCFCutoffCtrl.controller = 4;
582 break;
583 case ::gig::vcf_cutoff_ctrl_sustainpedal:
584 VCFCutoffCtrl.controller = 64;
585 break;
586 case ::gig::vcf_cutoff_ctrl_softpedal:
587 VCFCutoffCtrl.controller = 67;
588 break;
589 case ::gig::vcf_cutoff_ctrl_genpurpose7:
590 VCFCutoffCtrl.controller = 82;
591 break;
592 case ::gig::vcf_cutoff_ctrl_genpurpose8:
593 VCFCutoffCtrl.controller = 83;
594 break;
595 case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet
596 case ::gig::vcf_cutoff_ctrl_none:
597 default:
598 VCFCutoffCtrl.controller = 0;
599 break;
600 }
601 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
602
603 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
604 VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
605 #else // use the one defined in the instrument file
606 switch (pDimRgn->VCFResonanceController) {
607 case ::gig::vcf_res_ctrl_genpurpose3:
608 VCFResonanceCtrl.controller = 18;
609 break;
610 case ::gig::vcf_res_ctrl_genpurpose4:
611 VCFResonanceCtrl.controller = 19;
612 break;
613 case ::gig::vcf_res_ctrl_genpurpose5:
614 VCFResonanceCtrl.controller = 80;
615 break;
616 case ::gig::vcf_res_ctrl_genpurpose6:
617 VCFResonanceCtrl.controller = 81;
618 break;
619 case ::gig::vcf_res_ctrl_none:
620 default:
621 VCFResonanceCtrl.controller = 0;
622 }
623 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
624
625 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
626 FilterLeft.SetType(pDimRgn->VCFType);
627 FilterRight.SetType(pDimRgn->VCFType);
628 #else // override filter type
629 FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
630 FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
631 #endif // CONFIG_OVERRIDE_FILTER_TYPE
632
633 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
634 VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
635
636 // calculate cutoff frequency
637 float cutoff = (!VCFCutoffCtrl.controller)
638 ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX
639 : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX;
640
641 // calculate resonance
642 float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0
643 if (pDimRgn->VCFKeyboardTracking) {
644 resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
645 }
646 Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
647
648 VCFCutoffCtrl.fvalue = cutoff - CONFIG_FILTER_CUTOFF_MIN;
649 VCFResonanceCtrl.fvalue = resonance;
650
651 FilterUpdateCounter = -1;
652 }
653 else {
654 VCFCutoffCtrl.controller = 0;
655 VCFResonanceCtrl.controller = 0;
656 }
657
658 return 0; // success
659 }
660
661 /**
662 * Renders the audio data for this voice for the current audio fragment.
663 * The sample input data can either come from RAM (cached sample or sample
664 * part) or directly from disk. The output signal will be rendered by
665 * resampling / interpolation. If this voice is a disk streaming voice and
666 * the voice completely played back the cached RAM part of the sample, it
667 * will automatically switch to disk playback for the next RenderAudio()
668 * call.
669 *
670 * @param Samples - number of samples to be rendered in this audio fragment cycle
671 */
672 void Voice::Render(uint Samples) {
673
674 // select default values for synthesis mode bits
675 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
676 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
677 SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
678
679 // Reset the synthesis parameter matrix
680
681 pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
682 pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
683 pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
684 pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
685
686 // Apply events to the synthesis parameter matrix
687 ProcessEvents(Samples);
688
689 // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
690 pEG1->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
691 pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
692 if (pEG3->Process(Samples)) { // if pitch EG is active
693 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
694 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
695 }
696 pLFO1->Process(Samples);
697 pLFO2->Process(Samples);
698 if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
699 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
700 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
701 }
702
703 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
704 CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
705
706 switch (this->PlaybackState) {
707
708 case playback_state_init:
709 this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
710 // no break - continue with playback_state_ram
711
712 case playback_state_ram: {
713 if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
714
715 // render current fragment
716 Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
717
718 if (DiskVoice) {
719 // check if we reached the allowed limit of the sample RAM cache
720 if (Pos > MaxRAMPos) {
721 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", Pos));
722 this->PlaybackState = playback_state_disk;
723 }
724 }
725 else if (Pos >= pSample->GetCache().Size / pSample->FrameSize) {
726 this->PlaybackState = playback_state_end;
727 }
728 }
729 break;
730
731 case playback_state_disk: {
732 if (!DiskStreamRef.pStream) {
733 // check if the disk thread created our ordered disk stream in the meantime
734 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
735 if (!DiskStreamRef.pStream) {
736 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
737 KillImmediately();
738 return;
739 }
740 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
741 Pos -= int(Pos);
742 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
743 }
744
745 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
746
747 // add silence sample at the end if we reached the end of the stream (for the interpolator)
748 if (DiskStreamRef.State == Stream::state_end) {
749 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
750 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
751 // remember how many sample words there are before any silence has been added
752 if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
753 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
754 }
755 }
756
757 sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
758
759 // render current audio fragment
760 Synthesize(Samples, ptr, Delay);
761
762 const int iPos = (int) Pos;
763 const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
764 DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
765 Pos -= iPos; // just keep fractional part of Pos
766
767 // change state of voice to 'end' if we really reached the end of the sample data
768 if (RealSampleWordsLeftToRead >= 0) {
769 RealSampleWordsLeftToRead -= readSampleWords;
770 if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
771 }
772 }
773 break;
774
775 case playback_state_end:
776 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
777 break;
778 }
779
780 // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
781 pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear();
782 pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear();
783 pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear();
784
785 // Reset delay
786 Delay = 0;
787
788 itTriggerEvent = Pool<Event>::Iterator();
789
790 // If sample stream or release stage finished, kill the voice
791 if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
792 }
793
794 /**
795 * Resets voice variables. Should only be called if rendering process is
796 * suspended / not running.
797 */
798 void Voice::Reset() {
799 pLFO1->Reset();
800 pLFO2->Reset();
801 pLFO3->Reset();
802 FilterLeft.Reset();
803 FilterRight.Reset();
804 DiskStreamRef.pStream = NULL;
805 DiskStreamRef.hStream = 0;
806 DiskStreamRef.State = Stream::state_unused;
807 DiskStreamRef.OrderID = 0;
808 PlaybackState = playback_state_end;
809 itTriggerEvent = Pool<Event>::Iterator();
810 itKillEvent = Pool<Event>::Iterator();
811 }
812
813 /**
814 * Process the control change event lists of the engine for the current
815 * audio fragment. Event values will be applied to the synthesis parameter
816 * matrix.
817 *
818 * @param Samples - number of samples to be rendered in this audio fragment cycle
819 */
820 void Voice::ProcessEvents(uint Samples) {
821
822 // dispatch control change events
823 RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first();
824 if (Delay) { // skip events that happened before this voice was triggered
825 while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
826 }
827 while (itCCEvent) {
828 if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
829 if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
830 *pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
831 }
832 if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
833 *pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
834 }
835 if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
836 pLFO1->SendEvent(itCCEvent);
837 }
838 if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
839 pLFO2->SendEvent(itCCEvent);
840 }
841 if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
842 pLFO3->SendEvent(itCCEvent);
843 }
844 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
845 itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
846 *pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
847 }
848 }
849
850 ++itCCEvent;
851 }
852
853
854 // process pitch events
855 {
856 RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco];
857 RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
858 if (Delay) { // skip events that happened before this voice was triggered
859 while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
860 }
861 // apply old pitchbend value until first pitch event occurs
862 if (this->PitchBend != 1.0) {
863 uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
864 for (uint i = Delay; i < end; i++) {
865 pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
866 }
867 }
868 float pitch;
869 while (itVCOEvent) {
870 RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
871 ++itNextVCOEvent;
872
873 // calculate the influence length of this event (in sample points)
874 uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
875
876 pitch = RTMath::CentsToFreqRatio(((double) itVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
877
878 // apply pitch value to the pitch parameter sequence
879 for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
880 pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
881 }
882
883 itVCOEvent = itNextVCOEvent;
884 }
885 if (!pVCOEventList->isEmpty()) {
886 this->PitchBend = pitch;
887 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
888 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
889 }
890 }
891
892 // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
893 {
894 RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca];
895 RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
896 if (Delay) { // skip events that happened before this voice was triggered
897 while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
898 }
899 float crossfadevolume;
900 while (itVCAEvent) {
901 RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
902 ++itNextVCAEvent;
903
904 // calculate the influence length of this event (in sample points)
905 uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
906
907 crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
908
909 float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
910
911 // apply volume value to the volume parameter sequence
912 for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
913 pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
914 }
915
916 itVCAEvent = itNextVCAEvent;
917 }
918 if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
919 }
920
921 // process filter cutoff events
922 {
923 RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc];
924 RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
925 if (Delay) { // skip events that happened before this voice was triggered
926 while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
927 }
928 float cutoff;
929 while (itCutoffEvent) {
930 RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
931 ++itNextCutoffEvent;
932
933 // calculate the influence length of this event (in sample points)
934 uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
935
936 cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX - CONFIG_FILTER_CUTOFF_MIN;
937
938 // apply cutoff frequency to the cutoff parameter sequence
939 for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
940 pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
941 }
942
943 itCutoffEvent = itNextCutoffEvent;
944 }
945 if (!pCutoffEventList->isEmpty()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
946 }
947
948 // process filter resonance events
949 {
950 RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr];
951 RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
952 if (Delay) { // skip events that happened before this voice was triggered
953 while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
954 }
955 while (itResonanceEvent) {
956 RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
957 ++itNextResonanceEvent;
958
959 // calculate the influence length of this event (in sample points)
960 uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
961
962 // convert absolute controller value to differential
963 int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
964 VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
965
966 float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
967
968 // apply cutoff frequency to the cutoff parameter sequence
969 for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
970 pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
971 }
972
973 itResonanceEvent = itNextResonanceEvent;
974 }
975 if (!pResonanceEventList->isEmpty()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
976 }
977 }
978
979 /**
980 * Calculate all necessary, final biquad filter parameters.
981 *
982 * @param Samples - number of samples to be rendered in this audio fragment cycle
983 */
984 void Voice::CalculateBiquadParameters(uint Samples) {
985 biquad_param_t bqbase;
986 biquad_param_t bqmain;
987 float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
988 float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
989 FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
990 FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
991 pEngine->pBasicFilterParameters[0] = bqbase;
992 pEngine->pMainFilterParameters[0] = bqmain;
993
994 float* bq;
995 for (int i = 1; i < Samples; i++) {
996 // recalculate biquad parameters if cutoff or resonance differ from previous sample point
997 if (!(i & FILTER_UPDATE_MASK)) {
998 if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
999 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
1000 {
1001 prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
1002 prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
1003 FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
1004 FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
1005 }
1006 }
1007
1008 //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
1009 bq = (float*) &pEngine->pBasicFilterParameters[i];
1010 bq[0] = bqbase.b0;
1011 bq[1] = bqbase.b1;
1012 bq[2] = bqbase.b2;
1013 bq[3] = bqbase.a1;
1014 bq[4] = bqbase.a2;
1015
1016 // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
1017 bq = (float*) &pEngine->pMainFilterParameters[i];
1018 bq[0] = bqmain.b0;
1019 bq[1] = bqmain.b1;
1020 bq[2] = bqmain.b2;
1021 bq[3] = bqmain.a1;
1022 bq[4] = bqmain.a2;
1023 }
1024 }
1025
1026 /**
1027 * Synthesizes the current audio fragment for this voice.
1028 *
1029 * @param Samples - number of sample points to be rendered in this audio
1030 * fragment cycle
1031 * @param pSrc - pointer to input sample data
1032 * @param Skip - number of sample points to skip in output buffer
1033 */
1034 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
1035 RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
1036 }
1037
1038 /**
1039 * Immediately kill the voice. This method should not be used to kill
1040 * a normal, active voice, because it doesn't take care of things like
1041 * fading down the volume level to avoid clicks and regular processing
1042 * until the kill event actually occured!
1043 *
1044 * @see Kill()
1045 */
1046 void Voice::KillImmediately() {
1047 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1048 pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
1049 }
1050 Reset();
1051 }
1052
1053 /**
1054 * Kill the voice in regular sense. Let the voice render audio until
1055 * the kill event actually occured and then fade down the volume level
1056 * very quickly and let the voice die finally. Unlike a normal release
1057 * of a voice, a kill process cannot be cancalled and is therefore
1058 * usually used for voice stealing and key group conflicts.
1059 *
1060 * @param itKillEvent - event which caused the voice to be killed
1061 */
1062 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1063 #if CONFIG_DEVMODE
1064 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1065 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1066 #endif // CONFIG_DEVMODE
1067
1068 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1069 this->itKillEvent = itKillEvent;
1070 }
1071
1072 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC