/[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 411 - (show annotations) (download)
Sat Feb 26 02:01:14 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 51039 byte(s)
* design change: using now one sampler engine instance and one disk thread
  instance for all sampler channels that are connected to the same audio
  output device (and are using the same engine type of course)
* added EngineFactory / EngineChannelFactory to remove the annoying build
  dependencies e.g. of the lscpserver to the actual sampler engine
  implementations
* bumped version to 0.3.0 (current CVS state is still quite broken,
  previous, stable CVS version was tagged as "v0_2_0" and is also available
  as source tarball)

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

  ViewVC Help
Powered by ViewVC