/[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 239 - (show annotations) (download)
Sun Sep 12 14:48:19 2004 UTC (19 years, 6 months ago) by schoenebeck
File size: 51972 byte(s)
* implemented key groups (a.k.a exclusive groups) which is important for
  drum patches and monphonic instruments
* src/engines/gig/Engine.cpp: bugfix in ProcessNoteOn() - did not always
  stick the note on event to the respective key's own event list although
  e.g. the EGADRS expects it to find there

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

  ViewVC Help
Powered by ViewVC