/[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 335 - (show annotations) (download)
Mon Jan 3 02:48:25 2005 UTC (14 years, 8 months ago) by senkov
File size: 50100 byte(s)
* Fixed pitch calculation. FineTune needs to be taken as is
 without multiplying it by 10.

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

  ViewVC Help
Powered by ViewVC