/[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 438 - (show annotations) (download)
Wed Mar 9 22:12:15 2005 UTC (14 years, 7 months ago) by persson
File size: 51825 byte(s)
* 24-bit decompression now supports the 20 and 18 bit formats
* support for "random" and "round robin" dimensions
* removed a warning printout for empty samples during instrument
  loading

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

  ViewVC Help
Powered by ViewVC