/[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 563 - (show annotations) (download)
Sun May 22 20:43:32 2005 UTC (18 years, 11 months ago) by schoenebeck
File size: 52012 byte(s)
* (re)implemented voice stealing algorithm "oldestvoiceonkey" and made it
  the default voice stealing algorithm
* added new LSCP command "GET SERVER INFO" which currently returns
  description and version about this sampler
* added some API documentation comments
* minor cleanup

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 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 // select channel mode (mono or stereo)
273 SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
274
275 // get starting crossfade volume level
276 switch (pDimRgn->AttenuationController.type) {
277 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
278 CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
279 break;
280 case ::gig::attenuation_ctrl_t::type_velocity:
281 CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
282 break;
283 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
284 CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
285 break;
286 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
287 default:
288 CrossfadeVolume = 1.0f;
289 }
290
291 PanLeft = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) / 63.0f;
292 PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
293
294 Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
295
296 // Check if the sample needs disk streaming or is too short for that
297 long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
298 DiskVoice = cachedsamples < pSample->SamplesTotal;
299
300 if (DiskVoice) { // voice to be streamed from disk
301 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)
302
303 // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
304 if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
305 RAMLoop = true;
306 LoopCyclesLeft = pSample->LoopPlayCount;
307 }
308 else RAMLoop = false;
309
310 if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
311 dmsg(1,("Disk stream order failed!\n"));
312 KillImmediately();
313 return -1;
314 }
315 dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
316 }
317 else { // RAM only voice
318 MaxRAMPos = cachedsamples;
319 if (pSample->Loops) {
320 RAMLoop = true;
321 LoopCyclesLeft = pSample->LoopPlayCount;
322 }
323 else RAMLoop = false;
324 dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
325 }
326
327
328 // calculate initial pitch value
329 {
330 double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
331 if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
332 this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
333 this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
334 }
335
336 Volume = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
337
338 Volume *= pDimRgn->SampleAttenuation;
339
340 // setup EG 1 (VCA EG)
341 {
342 // get current value of EG1 controller
343 double eg1controllervalue;
344 switch (pDimRgn->EG1Controller.type) {
345 case ::gig::eg1_ctrl_t::type_none: // no controller defined
346 eg1controllervalue = 0;
347 break;
348 case ::gig::eg1_ctrl_t::type_channelaftertouch:
349 eg1controllervalue = 0; // TODO: aftertouch not yet supported
350 break;
351 case ::gig::eg1_ctrl_t::type_velocity:
352 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
353 break;
354 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
355 eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
356 break;
357 }
358 if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
359
360 // calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned)
361 double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0;
362 double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0;
363 double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0;
364
365 pEG1->Trigger(pDimRgn->EG1PreAttack,
366 pDimRgn->EG1Attack + eg1attack,
367 pDimRgn->EG1Hold,
368 pSample->LoopStart,
369 pDimRgn->EG1Decay1 + eg1decay,
370 pDimRgn->EG1Decay2 + eg1decay,
371 pDimRgn->EG1InfiniteSustain,
372 pDimRgn->EG1Sustain,
373 pDimRgn->EG1Release + eg1release,
374 // the SSE synthesis implementation requires
375 // the vca start to be 16 byte aligned
376 SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
377 Delay & 0xfffffffc : Delay);
378 }
379
380
381 // setup EG 2 (VCF Cutoff EG)
382 {
383 // get current value of EG2 controller
384 double eg2controllervalue;
385 switch (pDimRgn->EG2Controller.type) {
386 case ::gig::eg2_ctrl_t::type_none: // no controller defined
387 eg2controllervalue = 0;
388 break;
389 case ::gig::eg2_ctrl_t::type_channelaftertouch:
390 eg2controllervalue = 0; // TODO: aftertouch not yet supported
391 break;
392 case ::gig::eg2_ctrl_t::type_velocity:
393 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
394 break;
395 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
396 eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
397 break;
398 }
399 if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
400
401 // calculate influence of EG2 controller on EG2's parameters (TODO: needs to be fine tuned)
402 double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 0.0;
403 double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 0.0;
404 double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 0.0;
405
406 pEG2->Trigger(pDimRgn->EG2PreAttack,
407 pDimRgn->EG2Attack + eg2attack,
408 false,
409 pSample->LoopStart,
410 pDimRgn->EG2Decay1 + eg2decay,
411 pDimRgn->EG2Decay2 + eg2decay,
412 pDimRgn->EG2InfiniteSustain,
413 pDimRgn->EG2Sustain,
414 pDimRgn->EG2Release + eg2release,
415 Delay);
416 }
417
418
419 // setup EG 3 (VCO EG)
420 {
421 double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
422 pEG3->Trigger(eg3depth, pDimRgn->EG3Attack, Delay);
423 }
424
425
426 // setup LFO 1 (VCA LFO)
427 {
428 uint16_t lfo1_internal_depth;
429 switch (pDimRgn->LFO1Controller) {
430 case ::gig::lfo1_ctrl_internal:
431 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
432 pLFO1->ExtController = 0; // no external controller
433 break;
434 case ::gig::lfo1_ctrl_modwheel:
435 lfo1_internal_depth = 0;
436 pLFO1->ExtController = 1; // MIDI controller 1
437 break;
438 case ::gig::lfo1_ctrl_breath:
439 lfo1_internal_depth = 0;
440 pLFO1->ExtController = 2; // MIDI controller 2
441 break;
442 case ::gig::lfo1_ctrl_internal_modwheel:
443 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
444 pLFO1->ExtController = 1; // MIDI controller 1
445 break;
446 case ::gig::lfo1_ctrl_internal_breath:
447 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
448 pLFO1->ExtController = 2; // MIDI controller 2
449 break;
450 default:
451 lfo1_internal_depth = 0;
452 pLFO1->ExtController = 0; // no external controller
453 }
454 pLFO1->Trigger(pDimRgn->LFO1Frequency,
455 lfo1_internal_depth,
456 pDimRgn->LFO1ControlDepth,
457 pEngineChannel->ControllerTable[pLFO1->ExtController],
458 pDimRgn->LFO1FlipPhase,
459 pEngine->SampleRate,
460 Delay);
461 }
462
463
464 // setup LFO 2 (VCF Cutoff LFO)
465 {
466 uint16_t lfo2_internal_depth;
467 switch (pDimRgn->LFO2Controller) {
468 case ::gig::lfo2_ctrl_internal:
469 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
470 pLFO2->ExtController = 0; // no external controller
471 break;
472 case ::gig::lfo2_ctrl_modwheel:
473 lfo2_internal_depth = 0;
474 pLFO2->ExtController = 1; // MIDI controller 1
475 break;
476 case ::gig::lfo2_ctrl_foot:
477 lfo2_internal_depth = 0;
478 pLFO2->ExtController = 4; // MIDI controller 4
479 break;
480 case ::gig::lfo2_ctrl_internal_modwheel:
481 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
482 pLFO2->ExtController = 1; // MIDI controller 1
483 break;
484 case ::gig::lfo2_ctrl_internal_foot:
485 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
486 pLFO2->ExtController = 4; // MIDI controller 4
487 break;
488 default:
489 lfo2_internal_depth = 0;
490 pLFO2->ExtController = 0; // no external controller
491 }
492 pLFO2->Trigger(pDimRgn->LFO2Frequency,
493 lfo2_internal_depth,
494 pDimRgn->LFO2ControlDepth,
495 pEngineChannel->ControllerTable[pLFO2->ExtController],
496 pDimRgn->LFO2FlipPhase,
497 pEngine->SampleRate,
498 Delay);
499 }
500
501
502 // setup LFO 3 (VCO LFO)
503 {
504 uint16_t lfo3_internal_depth;
505 switch (pDimRgn->LFO3Controller) {
506 case ::gig::lfo3_ctrl_internal:
507 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
508 pLFO3->ExtController = 0; // no external controller
509 break;
510 case ::gig::lfo3_ctrl_modwheel:
511 lfo3_internal_depth = 0;
512 pLFO3->ExtController = 1; // MIDI controller 1
513 break;
514 case ::gig::lfo3_ctrl_aftertouch:
515 lfo3_internal_depth = 0;
516 pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
517 break;
518 case ::gig::lfo3_ctrl_internal_modwheel:
519 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
520 pLFO3->ExtController = 1; // MIDI controller 1
521 break;
522 case ::gig::lfo3_ctrl_internal_aftertouch:
523 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
524 pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
525 break;
526 default:
527 lfo3_internal_depth = 0;
528 pLFO3->ExtController = 0; // no external controller
529 }
530 pLFO3->Trigger(pDimRgn->LFO3Frequency,
531 lfo3_internal_depth,
532 pDimRgn->LFO3ControlDepth,
533 pEngineChannel->ControllerTable[pLFO3->ExtController],
534 false,
535 pEngine->SampleRate,
536 Delay);
537 }
538
539
540 #if CONFIG_FORCE_FILTER
541 const bool bUseFilter = true;
542 #else // use filter only if instrument file told so
543 const bool bUseFilter = pDimRgn->VCFEnabled;
544 #endif // CONFIG_FORCE_FILTER
545 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
546 if (bUseFilter) {
547 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
548 VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
549 #else // use the one defined in the instrument file
550 switch (pDimRgn->VCFCutoffController) {
551 case ::gig::vcf_cutoff_ctrl_modwheel:
552 VCFCutoffCtrl.controller = 1;
553 break;
554 case ::gig::vcf_cutoff_ctrl_effect1:
555 VCFCutoffCtrl.controller = 12;
556 break;
557 case ::gig::vcf_cutoff_ctrl_effect2:
558 VCFCutoffCtrl.controller = 13;
559 break;
560 case ::gig::vcf_cutoff_ctrl_breath:
561 VCFCutoffCtrl.controller = 2;
562 break;
563 case ::gig::vcf_cutoff_ctrl_foot:
564 VCFCutoffCtrl.controller = 4;
565 break;
566 case ::gig::vcf_cutoff_ctrl_sustainpedal:
567 VCFCutoffCtrl.controller = 64;
568 break;
569 case ::gig::vcf_cutoff_ctrl_softpedal:
570 VCFCutoffCtrl.controller = 67;
571 break;
572 case ::gig::vcf_cutoff_ctrl_genpurpose7:
573 VCFCutoffCtrl.controller = 82;
574 break;
575 case ::gig::vcf_cutoff_ctrl_genpurpose8:
576 VCFCutoffCtrl.controller = 83;
577 break;
578 case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet
579 case ::gig::vcf_cutoff_ctrl_none:
580 default:
581 VCFCutoffCtrl.controller = 0;
582 break;
583 }
584 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
585
586 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
587 VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
588 #else // use the one defined in the instrument file
589 switch (pDimRgn->VCFResonanceController) {
590 case ::gig::vcf_res_ctrl_genpurpose3:
591 VCFResonanceCtrl.controller = 18;
592 break;
593 case ::gig::vcf_res_ctrl_genpurpose4:
594 VCFResonanceCtrl.controller = 19;
595 break;
596 case ::gig::vcf_res_ctrl_genpurpose5:
597 VCFResonanceCtrl.controller = 80;
598 break;
599 case ::gig::vcf_res_ctrl_genpurpose6:
600 VCFResonanceCtrl.controller = 81;
601 break;
602 case ::gig::vcf_res_ctrl_none:
603 default:
604 VCFResonanceCtrl.controller = 0;
605 }
606 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
607
608 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
609 FilterLeft.SetType(pDimRgn->VCFType);
610 FilterRight.SetType(pDimRgn->VCFType);
611 #else // override filter type
612 FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
613 FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
614 #endif // CONFIG_OVERRIDE_FILTER_TYPE
615
616 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
617 VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
618
619 // calculate cutoff frequency
620 float cutoff = (!VCFCutoffCtrl.controller)
621 ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX
622 : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX;
623
624 // calculate resonance
625 float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0
626 if (pDimRgn->VCFKeyboardTracking) {
627 resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
628 }
629 Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
630
631 VCFCutoffCtrl.fvalue = cutoff - CONFIG_FILTER_CUTOFF_MIN;
632 VCFResonanceCtrl.fvalue = resonance;
633
634 FilterUpdateCounter = -1;
635 }
636 else {
637 VCFCutoffCtrl.controller = 0;
638 VCFResonanceCtrl.controller = 0;
639 }
640
641 return 0; // success
642 }
643
644 /**
645 * Renders the audio data for this voice for the current audio fragment.
646 * The sample input data can either come from RAM (cached sample or sample
647 * part) or directly from disk. The output signal will be rendered by
648 * resampling / interpolation. If this voice is a disk streaming voice and
649 * the voice completely played back the cached RAM part of the sample, it
650 * will automatically switch to disk playback for the next RenderAudio()
651 * call.
652 *
653 * @param Samples - number of samples to be rendered in this audio fragment cycle
654 */
655 void Voice::Render(uint Samples) {
656
657 // select default values for synthesis mode bits
658 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
659 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
660 SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
661
662 // Reset the synthesis parameter matrix
663
664 pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
665 pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
666 pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
667 pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
668
669 // Apply events to the synthesis parameter matrix
670 ProcessEvents(Samples);
671
672 // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
673 pEG1->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
674 pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
675 if (pEG3->Process(Samples)) { // if pitch EG is active
676 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
677 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
678 }
679 pLFO1->Process(Samples);
680 pLFO2->Process(Samples);
681 if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
682 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
683 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
684 }
685
686 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
687 CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
688
689 switch (this->PlaybackState) {
690
691 case playback_state_init:
692 this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
693 // no break - continue with playback_state_ram
694
695 case playback_state_ram: {
696 if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
697
698 // render current fragment
699 Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
700
701 if (DiskVoice) {
702 // check if we reached the allowed limit of the sample RAM cache
703 if (Pos > MaxRAMPos) {
704 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", Pos));
705 this->PlaybackState = playback_state_disk;
706 }
707 }
708 else if (Pos >= pSample->GetCache().Size / pSample->FrameSize) {
709 this->PlaybackState = playback_state_end;
710 }
711 }
712 break;
713
714 case playback_state_disk: {
715 if (!DiskStreamRef.pStream) {
716 // check if the disk thread created our ordered disk stream in the meantime
717 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
718 if (!DiskStreamRef.pStream) {
719 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
720 KillImmediately();
721 return;
722 }
723 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
724 Pos -= int(Pos);
725 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
726 }
727
728 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
729
730 // add silence sample at the end if we reached the end of the stream (for the interpolator)
731 if (DiskStreamRef.State == Stream::state_end) {
732 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
733 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
734 // remember how many sample words there are before any silence has been added
735 if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
736 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
737 }
738 }
739
740 sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
741
742 // render current audio fragment
743 Synthesize(Samples, ptr, Delay);
744
745 const int iPos = (int) Pos;
746 const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
747 DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
748 Pos -= iPos; // just keep fractional part of Pos
749
750 // change state of voice to 'end' if we really reached the end of the sample data
751 if (RealSampleWordsLeftToRead >= 0) {
752 RealSampleWordsLeftToRead -= readSampleWords;
753 if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
754 }
755 }
756 break;
757
758 case playback_state_end:
759 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
760 break;
761 }
762
763 // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
764 pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear();
765 pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear();
766 pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear();
767
768 // Reset delay
769 Delay = 0;
770
771 itTriggerEvent = Pool<Event>::Iterator();
772
773 // If sample stream or release stage finished, kill the voice
774 if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
775 }
776
777 /**
778 * Resets voice variables. Should only be called if rendering process is
779 * suspended / not running.
780 */
781 void Voice::Reset() {
782 pLFO1->Reset();
783 pLFO2->Reset();
784 pLFO3->Reset();
785 FilterLeft.Reset();
786 FilterRight.Reset();
787 DiskStreamRef.pStream = NULL;
788 DiskStreamRef.hStream = 0;
789 DiskStreamRef.State = Stream::state_unused;
790 DiskStreamRef.OrderID = 0;
791 PlaybackState = playback_state_end;
792 itTriggerEvent = Pool<Event>::Iterator();
793 itKillEvent = Pool<Event>::Iterator();
794 }
795
796 /**
797 * Process the control change event lists of the engine for the current
798 * audio fragment. Event values will be applied to the synthesis parameter
799 * matrix.
800 *
801 * @param Samples - number of samples to be rendered in this audio fragment cycle
802 */
803 void Voice::ProcessEvents(uint Samples) {
804
805 // dispatch control change events
806 RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first();
807 if (Delay) { // skip events that happened before this voice was triggered
808 while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
809 }
810 while (itCCEvent) {
811 if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
812 if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
813 *pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
814 }
815 if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
816 *pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
817 }
818 if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
819 pLFO1->SendEvent(itCCEvent);
820 }
821 if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
822 pLFO2->SendEvent(itCCEvent);
823 }
824 if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
825 pLFO3->SendEvent(itCCEvent);
826 }
827 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
828 itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
829 *pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
830 }
831 }
832
833 ++itCCEvent;
834 }
835
836
837 // process pitch events
838 {
839 RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco];
840 RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
841 if (Delay) { // skip events that happened before this voice was triggered
842 while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
843 }
844 // apply old pitchbend value until first pitch event occurs
845 if (this->PitchBend != 1.0) {
846 uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
847 for (uint i = Delay; i < end; i++) {
848 pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
849 }
850 }
851 float pitch;
852 while (itVCOEvent) {
853 RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
854 ++itNextVCOEvent;
855
856 // calculate the influence length of this event (in sample points)
857 uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
858
859 pitch = RTMath::CentsToFreqRatio(((double) itVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
860
861 // apply pitch value to the pitch parameter sequence
862 for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
863 pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
864 }
865
866 itVCOEvent = itNextVCOEvent;
867 }
868 if (!pVCOEventList->isEmpty()) {
869 this->PitchBend = pitch;
870 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
871 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
872 }
873 }
874
875 // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
876 {
877 RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca];
878 RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
879 if (Delay) { // skip events that happened before this voice was triggered
880 while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
881 }
882 float crossfadevolume;
883 while (itVCAEvent) {
884 RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
885 ++itNextVCAEvent;
886
887 // calculate the influence length of this event (in sample points)
888 uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
889
890 crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
891
892 float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
893
894 // apply volume value to the volume parameter sequence
895 for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
896 pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
897 }
898
899 itVCAEvent = itNextVCAEvent;
900 }
901 if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
902 }
903
904 // process filter cutoff events
905 {
906 RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc];
907 RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
908 if (Delay) { // skip events that happened before this voice was triggered
909 while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
910 }
911 float cutoff;
912 while (itCutoffEvent) {
913 RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
914 ++itNextCutoffEvent;
915
916 // calculate the influence length of this event (in sample points)
917 uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
918
919 cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX - CONFIG_FILTER_CUTOFF_MIN;
920
921 // apply cutoff frequency to the cutoff parameter sequence
922 for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
923 pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
924 }
925
926 itCutoffEvent = itNextCutoffEvent;
927 }
928 if (!pCutoffEventList->isEmpty()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
929 }
930
931 // process filter resonance events
932 {
933 RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr];
934 RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
935 if (Delay) { // skip events that happened before this voice was triggered
936 while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
937 }
938 while (itResonanceEvent) {
939 RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
940 ++itNextResonanceEvent;
941
942 // calculate the influence length of this event (in sample points)
943 uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
944
945 // convert absolute controller value to differential
946 int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
947 VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
948
949 float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
950
951 // apply cutoff frequency to the cutoff parameter sequence
952 for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
953 pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
954 }
955
956 itResonanceEvent = itNextResonanceEvent;
957 }
958 if (!pResonanceEventList->isEmpty()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
959 }
960 }
961
962 /**
963 * Calculate all necessary, final biquad filter parameters.
964 *
965 * @param Samples - number of samples to be rendered in this audio fragment cycle
966 */
967 void Voice::CalculateBiquadParameters(uint Samples) {
968 biquad_param_t bqbase;
969 biquad_param_t bqmain;
970 float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
971 float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
972 FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
973 FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
974 pEngine->pBasicFilterParameters[0] = bqbase;
975 pEngine->pMainFilterParameters[0] = bqmain;
976
977 float* bq;
978 for (int i = 1; i < Samples; i++) {
979 // recalculate biquad parameters if cutoff or resonance differ from previous sample point
980 if (!(i & FILTER_UPDATE_MASK)) {
981 if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
982 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
983 {
984 prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
985 prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
986 FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
987 FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
988 }
989 }
990
991 //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
992 bq = (float*) &pEngine->pBasicFilterParameters[i];
993 bq[0] = bqbase.b0;
994 bq[1] = bqbase.b1;
995 bq[2] = bqbase.b2;
996 bq[3] = bqbase.a1;
997 bq[4] = bqbase.a2;
998
999 // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
1000 bq = (float*) &pEngine->pMainFilterParameters[i];
1001 bq[0] = bqmain.b0;
1002 bq[1] = bqmain.b1;
1003 bq[2] = bqmain.b2;
1004 bq[3] = bqmain.a1;
1005 bq[4] = bqmain.a2;
1006 }
1007 }
1008
1009 /**
1010 * Synthesizes the current audio fragment for this voice.
1011 *
1012 * @param Samples - number of sample points to be rendered in this audio
1013 * fragment cycle
1014 * @param pSrc - pointer to input sample data
1015 * @param Skip - number of sample points to skip in output buffer
1016 */
1017 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
1018 RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
1019 }
1020
1021 /**
1022 * Immediately kill the voice. This method should not be used to kill
1023 * a normal, active voice, because it doesn't take care of things like
1024 * fading down the volume level to avoid clicks and regular processing
1025 * until the kill event actually occured!
1026 *
1027 * @see Kill()
1028 */
1029 void Voice::KillImmediately() {
1030 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1031 pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
1032 }
1033 Reset();
1034 }
1035
1036 /**
1037 * Kill the voice in regular sense. Let the voice render audio until
1038 * the kill event actually occured and then fade down the volume level
1039 * very quickly and let the voice die finally. Unlike a normal release
1040 * of a voice, a kill process cannot be cancalled and is therefore
1041 * usually used for voice stealing and key group conflicts.
1042 *
1043 * @param itKillEvent - event which caused the voice to be killed
1044 */
1045 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1046 #if CONFIG_DEVMODE
1047 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1048 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1049 #endif // CONFIG_DEVMODE
1050
1051 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1052 this->itKillEvent = itKillEvent;
1053 }
1054
1055 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC