/[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 425 - (show annotations) (download)
Sat Mar 5 07:27:48 2005 UTC (19 years, 1 month ago) by persson
File size: 51276 byte(s)
* fixed a bug that sometimes caused clicks at the beginning of samples
* added denormal number elimination for CPUs with SSE2 support

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

  ViewVC Help
Powered by ViewVC