/[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 287 - (show annotations) (download)
Sat Oct 16 17:38:03 2004 UTC (15 years ago) by schoenebeck
File size: 50637 byte(s)
* fixed segfault which occured whenever a voice stole a voice and was in
  turn killed in the same audio fragment, to fix that the MIDI key
  informations are now updated only after all voices were processed

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

  ViewVC Help
Powered by ViewVC