/[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 368 - (show annotations) (download)
Fri Feb 11 13:13:54 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 50485 byte(s)
* some fixes regarding the filter (fixes the "silence" bug which occured
  occasionally, caused by random biquad parameters which lead to unstable
  filter equation and thus to infinit filter output results)

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 // setup EG 1 (VCA EG)
330 {
331 // get current value of EG1 controller
332 double eg1controllervalue;
333 switch (pDimRgn->EG1Controller.type) {
334 case ::gig::eg1_ctrl_t::type_none: // no controller defined
335 eg1controllervalue = 0;
336 break;
337 case ::gig::eg1_ctrl_t::type_channelaftertouch:
338 eg1controllervalue = 0; // TODO: aftertouch not yet supported
339 break;
340 case ::gig::eg1_ctrl_t::type_velocity:
341 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
342 break;
343 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
344 eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];
345 break;
346 }
347 if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
348
349 // calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned)
350 double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0;
351 double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0;
352 double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0;
353
354 pEG1->Trigger(pDimRgn->EG1PreAttack,
355 pDimRgn->EG1Attack + eg1attack,
356 pDimRgn->EG1Hold,
357 pSample->LoopStart,
358 pDimRgn->EG1Decay1 + eg1decay,
359 pDimRgn->EG1Decay2 + eg1decay,
360 pDimRgn->EG1InfiniteSustain,
361 pDimRgn->EG1Sustain,
362 pDimRgn->EG1Release + eg1release,
363 Delay);
364 }
365
366
367 // setup EG 2 (VCF Cutoff EG)
368 {
369 // get current value of EG2 controller
370 double eg2controllervalue;
371 switch (pDimRgn->EG2Controller.type) {
372 case ::gig::eg2_ctrl_t::type_none: // no controller defined
373 eg2controllervalue = 0;
374 break;
375 case ::gig::eg2_ctrl_t::type_channelaftertouch:
376 eg2controllervalue = 0; // TODO: aftertouch not yet supported
377 break;
378 case ::gig::eg2_ctrl_t::type_velocity:
379 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
380 break;
381 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
382 eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];
383 break;
384 }
385 if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
386
387 // calculate influence of EG2 controller on EG2's parameters (TODO: needs to be fine tuned)
388 double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 0.0;
389 double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 0.0;
390 double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 0.0;
391
392 pEG2->Trigger(pDimRgn->EG2PreAttack,
393 pDimRgn->EG2Attack + eg2attack,
394 false,
395 pSample->LoopStart,
396 pDimRgn->EG2Decay1 + eg2decay,
397 pDimRgn->EG2Decay2 + eg2decay,
398 pDimRgn->EG2InfiniteSustain,
399 pDimRgn->EG2Sustain,
400 pDimRgn->EG2Release + eg2release,
401 Delay);
402 }
403
404
405 // setup EG 3 (VCO EG)
406 {
407 double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
408 pEG3->Trigger(eg3depth, pDimRgn->EG3Attack, Delay);
409 }
410
411
412 // setup LFO 1 (VCA LFO)
413 {
414 uint16_t lfo1_internal_depth;
415 switch (pDimRgn->LFO1Controller) {
416 case ::gig::lfo1_ctrl_internal:
417 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
418 pLFO1->ExtController = 0; // no external controller
419 break;
420 case ::gig::lfo1_ctrl_modwheel:
421 lfo1_internal_depth = 0;
422 pLFO1->ExtController = 1; // MIDI controller 1
423 break;
424 case ::gig::lfo1_ctrl_breath:
425 lfo1_internal_depth = 0;
426 pLFO1->ExtController = 2; // MIDI controller 2
427 break;
428 case ::gig::lfo1_ctrl_internal_modwheel:
429 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
430 pLFO1->ExtController = 1; // MIDI controller 1
431 break;
432 case ::gig::lfo1_ctrl_internal_breath:
433 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
434 pLFO1->ExtController = 2; // MIDI controller 2
435 break;
436 default:
437 lfo1_internal_depth = 0;
438 pLFO1->ExtController = 0; // no external controller
439 }
440 pLFO1->Trigger(pDimRgn->LFO1Frequency,
441 lfo1_internal_depth,
442 pDimRgn->LFO1ControlDepth,
443 pEngine->ControllerTable[pLFO1->ExtController],
444 pDimRgn->LFO1FlipPhase,
445 pEngine->SampleRate,
446 Delay);
447 }
448
449
450 // setup LFO 2 (VCF Cutoff LFO)
451 {
452 uint16_t lfo2_internal_depth;
453 switch (pDimRgn->LFO2Controller) {
454 case ::gig::lfo2_ctrl_internal:
455 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
456 pLFO2->ExtController = 0; // no external controller
457 break;
458 case ::gig::lfo2_ctrl_modwheel:
459 lfo2_internal_depth = 0;
460 pLFO2->ExtController = 1; // MIDI controller 1
461 break;
462 case ::gig::lfo2_ctrl_foot:
463 lfo2_internal_depth = 0;
464 pLFO2->ExtController = 4; // MIDI controller 4
465 break;
466 case ::gig::lfo2_ctrl_internal_modwheel:
467 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
468 pLFO2->ExtController = 1; // MIDI controller 1
469 break;
470 case ::gig::lfo2_ctrl_internal_foot:
471 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
472 pLFO2->ExtController = 4; // MIDI controller 4
473 break;
474 default:
475 lfo2_internal_depth = 0;
476 pLFO2->ExtController = 0; // no external controller
477 }
478 pLFO2->Trigger(pDimRgn->LFO2Frequency,
479 lfo2_internal_depth,
480 pDimRgn->LFO2ControlDepth,
481 pEngine->ControllerTable[pLFO2->ExtController],
482 pDimRgn->LFO2FlipPhase,
483 pEngine->SampleRate,
484 Delay);
485 }
486
487
488 // setup LFO 3 (VCO LFO)
489 {
490 uint16_t lfo3_internal_depth;
491 switch (pDimRgn->LFO3Controller) {
492 case ::gig::lfo3_ctrl_internal:
493 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
494 pLFO3->ExtController = 0; // no external controller
495 break;
496 case ::gig::lfo3_ctrl_modwheel:
497 lfo3_internal_depth = 0;
498 pLFO3->ExtController = 1; // MIDI controller 1
499 break;
500 case ::gig::lfo3_ctrl_aftertouch:
501 lfo3_internal_depth = 0;
502 pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
503 break;
504 case ::gig::lfo3_ctrl_internal_modwheel:
505 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
506 pLFO3->ExtController = 1; // MIDI controller 1
507 break;
508 case ::gig::lfo3_ctrl_internal_aftertouch:
509 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
510 pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
511 break;
512 default:
513 lfo3_internal_depth = 0;
514 pLFO3->ExtController = 0; // no external controller
515 }
516 pLFO3->Trigger(pDimRgn->LFO3Frequency,
517 lfo3_internal_depth,
518 pDimRgn->LFO3ControlDepth,
519 pEngine->ControllerTable[pLFO3->ExtController],
520 false,
521 pEngine->SampleRate,
522 Delay);
523 }
524
525
526 #if FORCE_FILTER_USAGE
527 const bool bUseFilter = true;
528 #else // use filter only if instrument file told so
529 const bool bUseFilter = pDimRgn->VCFEnabled;
530 #endif // FORCE_FILTER_USAGE
531 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
532 if (bUseFilter) {
533 #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
534 VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;
535 #else // use the one defined in the instrument file
536 switch (pDimRgn->VCFCutoffController) {
537 case ::gig::vcf_cutoff_ctrl_modwheel:
538 VCFCutoffCtrl.controller = 1;
539 break;
540 case ::gig::vcf_cutoff_ctrl_effect1:
541 VCFCutoffCtrl.controller = 12;
542 break;
543 case ::gig::vcf_cutoff_ctrl_effect2:
544 VCFCutoffCtrl.controller = 13;
545 break;
546 case ::gig::vcf_cutoff_ctrl_breath:
547 VCFCutoffCtrl.controller = 2;
548 break;
549 case ::gig::vcf_cutoff_ctrl_foot:
550 VCFCutoffCtrl.controller = 4;
551 break;
552 case ::gig::vcf_cutoff_ctrl_sustainpedal:
553 VCFCutoffCtrl.controller = 64;
554 break;
555 case ::gig::vcf_cutoff_ctrl_softpedal:
556 VCFCutoffCtrl.controller = 67;
557 break;
558 case ::gig::vcf_cutoff_ctrl_genpurpose7:
559 VCFCutoffCtrl.controller = 82;
560 break;
561 case ::gig::vcf_cutoff_ctrl_genpurpose8:
562 VCFCutoffCtrl.controller = 83;
563 break;
564 case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet
565 case ::gig::vcf_cutoff_ctrl_none:
566 default:
567 VCFCutoffCtrl.controller = 0;
568 break;
569 }
570 #endif // OVERRIDE_FILTER_CUTOFF_CTRL
571
572 #ifdef OVERRIDE_FILTER_RES_CTRL
573 VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;
574 #else // use the one defined in the instrument file
575 switch (pDimRgn->VCFResonanceController) {
576 case ::gig::vcf_res_ctrl_genpurpose3:
577 VCFResonanceCtrl.controller = 18;
578 break;
579 case ::gig::vcf_res_ctrl_genpurpose4:
580 VCFResonanceCtrl.controller = 19;
581 break;
582 case ::gig::vcf_res_ctrl_genpurpose5:
583 VCFResonanceCtrl.controller = 80;
584 break;
585 case ::gig::vcf_res_ctrl_genpurpose6:
586 VCFResonanceCtrl.controller = 81;
587 break;
588 case ::gig::vcf_res_ctrl_none:
589 default:
590 VCFResonanceCtrl.controller = 0;
591 }
592 #endif // OVERRIDE_FILTER_RES_CTRL
593
594 #ifndef OVERRIDE_FILTER_TYPE
595 FilterLeft.SetType(pDimRgn->VCFType);
596 FilterRight.SetType(pDimRgn->VCFType);
597 #else // override filter type
598 FilterLeft.SetType(OVERRIDE_FILTER_TYPE);
599 FilterRight.SetType(OVERRIDE_FILTER_TYPE);
600 #endif // OVERRIDE_FILTER_TYPE
601
602 VCFCutoffCtrl.value = pEngine->ControllerTable[VCFCutoffCtrl.controller];
603 VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];
604
605 // calculate cutoff frequency
606 float cutoff = (!VCFCutoffCtrl.controller)
607 ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX
608 : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
609
610 // calculate resonance
611 float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0
612 if (pDimRgn->VCFKeyboardTracking) {
613 resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
614 }
615 Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
616
617 VCFCutoffCtrl.fvalue = cutoff - FILTER_CUTOFF_MIN;
618 VCFResonanceCtrl.fvalue = resonance;
619
620 FilterUpdateCounter = -1;
621 }
622 else {
623 VCFCutoffCtrl.controller = 0;
624 VCFResonanceCtrl.controller = 0;
625 }
626
627 return 0; // success
628 }
629
630 /**
631 * Renders the audio data for this voice for the current audio fragment.
632 * The sample input data can either come from RAM (cached sample or sample
633 * part) or directly from disk. The output signal will be rendered by
634 * resampling / interpolation. If this voice is a disk streaming voice and
635 * the voice completely played back the cached RAM part of the sample, it
636 * will automatically switch to disk playback for the next RenderAudio()
637 * call.
638 *
639 * @param Samples - number of samples to be rendered in this audio fragment cycle
640 */
641 void Voice::Render(uint Samples) {
642
643 // select default values for synthesis mode bits
644 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
645 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
646 SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
647
648 // Reset the synthesis parameter matrix
649
650 pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);
651 pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
652 pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
653 pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
654
655 // Apply events to the synthesis parameter matrix
656 ProcessEvents(Samples);
657
658 // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
659 pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
660 pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
661 if (pEG3->Process(Samples)) { // if pitch EG is active
662 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
663 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
664 }
665 pLFO1->Process(Samples);
666 pLFO2->Process(Samples);
667 if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
668 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
669 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
670 }
671
672 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
673 CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
674
675 switch (this->PlaybackState) {
676
677 case playback_state_ram: {
678 if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
679
680 // render current fragment
681 Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
682
683 if (DiskVoice) {
684 // check if we reached the allowed limit of the sample RAM cache
685 if (Pos > MaxRAMPos) {
686 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", Pos));
687 this->PlaybackState = playback_state_disk;
688 }
689 }
690 else if (Pos >= pSample->GetCache().Size / pSample->FrameSize) {
691 this->PlaybackState = playback_state_end;
692 }
693 }
694 break;
695
696 case playback_state_disk: {
697 if (!DiskStreamRef.pStream) {
698 // check if the disk thread created our ordered disk stream in the meantime
699 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
700 if (!DiskStreamRef.pStream) {
701 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
702 KillImmediately();
703 return;
704 }
705 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
706 Pos -= int(Pos);
707 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
708 }
709
710 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
711
712 // add silence sample at the end if we reached the end of the stream (for the interpolator)
713 if (DiskStreamRef.State == Stream::state_end) {
714 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
715 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
716 // remember how many sample words there are before any silence has been added
717 if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
718 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
719 }
720 }
721
722 sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
723
724 // render current audio fragment
725 Synthesize(Samples, ptr, Delay);
726
727 const int iPos = (int) Pos;
728 const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
729 DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
730 Pos -= iPos; // just keep fractional part of Pos
731
732 // change state of voice to 'end' if we really reached the end of the sample data
733 if (RealSampleWordsLeftToRead >= 0) {
734 RealSampleWordsLeftToRead -= readSampleWords;
735 if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
736 }
737 }
738 break;
739
740 case playback_state_end:
741 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
742 break;
743 }
744
745 // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
746 pEngine->pSynthesisEvents[Event::destination_vca]->clear();
747 pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();
748 pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();
749
750 // Reset delay
751 Delay = 0;
752
753 itTriggerEvent = Pool<Event>::Iterator();
754
755 // If sample stream or release stage finished, kill the voice
756 if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
757 }
758
759 /**
760 * Resets voice variables. Should only be called if rendering process is
761 * suspended / not running.
762 */
763 void Voice::Reset() {
764 pLFO1->Reset();
765 pLFO2->Reset();
766 pLFO3->Reset();
767 FilterLeft.Reset();
768 FilterRight.Reset();
769 DiskStreamRef.pStream = NULL;
770 DiskStreamRef.hStream = 0;
771 DiskStreamRef.State = Stream::state_unused;
772 DiskStreamRef.OrderID = 0;
773 PlaybackState = playback_state_end;
774 itTriggerEvent = Pool<Event>::Iterator();
775 itKillEvent = Pool<Event>::Iterator();
776 }
777
778 /**
779 * Process the control change event lists of the engine for the current
780 * audio fragment. Event values will be applied to the synthesis parameter
781 * matrix.
782 *
783 * @param Samples - number of samples to be rendered in this audio fragment cycle
784 */
785 void Voice::ProcessEvents(uint Samples) {
786
787 // dispatch control change events
788 RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();
789 if (Delay) { // skip events that happened before this voice was triggered
790 while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
791 }
792 while (itCCEvent) {
793 if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
794 if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
795 *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
796 }
797 if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
798 *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
799 }
800 if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
801 pLFO1->SendEvent(itCCEvent);
802 }
803 if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
804 pLFO2->SendEvent(itCCEvent);
805 }
806 if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
807 pLFO3->SendEvent(itCCEvent);
808 }
809 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
810 itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
811 *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
812 }
813 }
814
815 ++itCCEvent;
816 }
817
818
819 // process pitch events
820 {
821 RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
822 RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
823 if (Delay) { // skip events that happened before this voice was triggered
824 while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
825 }
826 // apply old pitchbend value until first pitch event occurs
827 if (this->PitchBend != 1.0) {
828 uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
829 for (uint i = Delay; i < end; i++) {
830 pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
831 }
832 }
833 float pitch;
834 while (itVCOEvent) {
835 RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
836 ++itNextVCOEvent;
837
838 // calculate the influence length of this event (in sample points)
839 uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
840
841 pitch = RTMath::CentsToFreqRatio(((double) itVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
842
843 // apply pitch value to the pitch parameter sequence
844 for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
845 pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
846 }
847
848 itVCOEvent = itNextVCOEvent;
849 }
850 if (!pVCOEventList->isEmpty()) {
851 this->PitchBend = pitch;
852 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
853 SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
854 }
855 }
856
857 // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
858 {
859 RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
860 RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
861 if (Delay) { // skip events that happened before this voice was triggered
862 while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
863 }
864 float crossfadevolume;
865 while (itVCAEvent) {
866 RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
867 ++itNextVCAEvent;
868
869 // calculate the influence length of this event (in sample points)
870 uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
871
872 crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
873
874 float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;
875
876 // apply volume value to the volume parameter sequence
877 for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
878 pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
879 }
880
881 itVCAEvent = itNextVCAEvent;
882 }
883 if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
884 }
885
886 // process filter cutoff events
887 {
888 RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
889 RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
890 if (Delay) { // skip events that happened before this voice was triggered
891 while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
892 }
893 float cutoff;
894 while (itCutoffEvent) {
895 RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
896 ++itNextCutoffEvent;
897
898 // calculate the influence length of this event (in sample points)
899 uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
900
901 cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
902
903 // apply cutoff frequency to the cutoff parameter sequence
904 for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
905 pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
906 }
907
908 itCutoffEvent = itNextCutoffEvent;
909 }
910 if (!pCutoffEventList->isEmpty()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
911 }
912
913 // process filter resonance events
914 {
915 RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
916 RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
917 if (Delay) { // skip events that happened before this voice was triggered
918 while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
919 }
920 while (itResonanceEvent) {
921 RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
922 ++itNextResonanceEvent;
923
924 // calculate the influence length of this event (in sample points)
925 uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
926
927 // convert absolute controller value to differential
928 int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
929 VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
930
931 float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
932
933 // apply cutoff frequency to the cutoff parameter sequence
934 for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
935 pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
936 }
937
938 itResonanceEvent = itNextResonanceEvent;
939 }
940 if (!pResonanceEventList->isEmpty()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
941 }
942 }
943
944 /**
945 * Calculate all necessary, final biquad filter parameters.
946 *
947 * @param Samples - number of samples to be rendered in this audio fragment cycle
948 */
949 void Voice::CalculateBiquadParameters(uint Samples) {
950 biquad_param_t bqbase;
951 biquad_param_t bqmain;
952 float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
953 float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
954 FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
955 FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
956 pEngine->pBasicFilterParameters[0] = bqbase;
957 pEngine->pMainFilterParameters[0] = bqmain;
958
959 float* bq;
960 for (int i = 1; i < Samples; i++) {
961 // recalculate biquad parameters if cutoff or resonance differ from previous sample point
962 if (!(i & FILTER_UPDATE_MASK)) {
963 if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
964 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
965 {
966 prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
967 prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
968 FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
969 FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
970 }
971 }
972
973 //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
974 bq = (float*) &pEngine->pBasicFilterParameters[i];
975 bq[0] = bqbase.b0;
976 bq[1] = bqbase.b1;
977 bq[2] = bqbase.b2;
978 bq[3] = bqbase.a1;
979 bq[4] = bqbase.a2;
980
981 // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
982 bq = (float*) &pEngine->pMainFilterParameters[i];
983 bq[0] = bqmain.b0;
984 bq[1] = bqmain.b1;
985 bq[2] = bqmain.b2;
986 bq[3] = bqmain.a1;
987 bq[4] = bqmain.a2;
988 }
989 }
990
991 /**
992 * Synthesizes the current audio fragment for this voice.
993 *
994 * @param Samples - number of sample points to be rendered in this audio
995 * fragment cycle
996 * @param pSrc - pointer to input sample data
997 * @param Skip - number of sample points to skip in output buffer
998 */
999 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
1000 RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
1001 }
1002
1003 /**
1004 * Immediately kill the voice. This method should not be used to kill
1005 * a normal, active voice, because it doesn't take care of things like
1006 * fading down the volume level to avoid clicks and regular processing
1007 * until the kill event actually occured!
1008 *
1009 * @see Kill()
1010 */
1011 void Voice::KillImmediately() {
1012 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1013 pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
1014 }
1015 Reset();
1016 }
1017
1018 /**
1019 * Kill the voice in regular sense. Let the voice render audio until
1020 * the kill event actually occured and then fade down the volume level
1021 * very quickly and let the voice die finally. Unlike a normal release
1022 * of a voice, a kill process cannot be cancalled and is therefore
1023 * usually used for voice stealing and key group conflicts.
1024 *
1025 * @param itKillEvent - event which caused the voice to be killed
1026 */
1027 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1028 //FIXME: just two sanity checks for debugging, can be removed
1029 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1030 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1031
1032 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1033 this->itKillEvent = itKillEvent;
1034 }
1035
1036 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC