/[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 361 - (show annotations) (download)
Wed Feb 9 01:22:18 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 50328 byte(s)
* bunch of fixes for OSX (patch by Stephane Letz)

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

  ViewVC Help
Powered by ViewVC