/[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 554 - (show annotations) (download)
Thu May 19 19:25:14 2005 UTC (18 years, 10 months ago) by schoenebeck
File size: 51798 byte(s)
* All compile time options are now centrally alterable as arguments to the
  ./configure script. All options are C Macros beginning with CONFIG_
  prefix and will be placed into auto generated config.h file.

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

  ViewVC Help
Powered by ViewVC