/[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 407 - (show annotations) (download)
Wed Feb 23 19:14:14 2005 UTC (19 years, 1 month ago) by persson
File size: 50532 byte(s)
* added support for sample parameter 'attenuation'

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

  ViewVC Help
Powered by ViewVC