/[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 729 - (show annotations) (download)
Tue Jul 26 11:18:46 2005 UTC (18 years, 8 months ago) by persson
File size: 49925 byte(s)
* improved filter cutoff calculation by adding support for the
  following gig parameters: Cutoff freq (used when no cutoff
  controller is defined), Control invert, Minimum cutoff, Velocity
  curve and Velocity range. The keyboard tracking now also scales
  cutoff frequency, not just resonance.

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

  ViewVC Help
Powered by ViewVC