/[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 1857 - (show annotations) (download)
Sat Mar 7 19:23:10 2009 UTC (9 years, 9 months ago) by schoenebeck
File size: 50485 byte(s)
* fixed hanging notes which occured when note-off event had the exact
  same time stamp as the voice's note-on event and occured both in the
  same audio fragment cycle (fixes bug #112)
* bumped version to 0.5.1.11cvs

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2009 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 "../../common/Features.h"
25 #include "Synthesizer.h"
26 #include "Profiler.h"
27
28 #include "Voice.h"
29
30 namespace LinuxSampler { namespace gig {
31
32 Voice::Voice() {
33 pEngine = NULL;
34 pDiskThread = NULL;
35 PlaybackState = playback_state_end;
36 pLFO1 = new LFOUnsigned(1.0f); // amplitude EG (0..1 range)
37 pLFO2 = new LFOUnsigned(1.0f); // filter EG (0..1 range)
38 pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)
39 KeyGroup = 0;
40 SynthesisMode = 0; // set all mode bits to 0 first
41 // select synthesis implementation (asm core is not supported ATM)
42 #if 0 // CONFIG_ASM && ARCH_X86
43 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
44 #else
45 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
46 #endif
47 SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, Profiler::isEnabled());
48
49 finalSynthesisParameters.filterLeft.Reset();
50 finalSynthesisParameters.filterRight.Reset();
51 }
52
53 Voice::~Voice() {
54 if (pLFO1) delete pLFO1;
55 if (pLFO2) delete pLFO2;
56 if (pLFO3) delete pLFO3;
57 }
58
59 void Voice::SetEngine(Engine* pEngine) {
60 this->pEngine = pEngine;
61 this->pDiskThread = pEngine->pDiskThread;
62 dmsg(6,("Voice::SetEngine()\n"));
63 }
64
65 /**
66 * Initializes and triggers the voice, a disk stream will be launched if
67 * needed.
68 *
69 * @param pEngineChannel - engine channel on which this voice was ordered
70 * @param itNoteOnEvent - event that caused triggering of this voice
71 * @param PitchBend - MIDI detune factor (-8192 ... +8191)
72 * @param pDimRgn - points to the dimension region which provides sample wave(s) and articulation data
73 * @param VoiceType - type of this voice
74 * @param iKeyGroup - a value > 0 defines a key group in which this voice is member of
75 * @returns 0 on success, a value < 0 if the voice wasn't triggered
76 * (either due to an error or e.g. because no region is
77 * defined for the given key)
78 */
79 int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
80 this->pEngineChannel = pEngineChannel;
81 this->pDimRgn = pDimRgn;
82 Orphan = false;
83
84 #if CONFIG_DEVMODE
85 if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
86 dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
87 }
88 #endif // CONFIG_DEVMODE
89
90 Type = VoiceType;
91 MIDIKey = itNoteOnEvent->Param.Note.Key;
92 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
93 Delay = itNoteOnEvent->FragmentPos();
94 itTriggerEvent = itNoteOnEvent;
95 itKillEvent = Pool<Event>::Iterator();
96 KeyGroup = iKeyGroup;
97 pSample = pDimRgn->pSample; // sample won't change until the voice is finished
98
99 // calculate volume
100 const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
101
102 // For 16 bit samples, we downscale by 32768 to convert from
103 // int16 value range to DSP value range (which is
104 // -1.0..1.0). For 24 bit, we downscale from int32.
105 float volume = velocityAttenuation / (pSample->BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
106
107 volume *= pDimRgn->SampleAttenuation * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
108
109 // the volume of release triggered samples depends on note length
110 if (Type == type_release_trigger) {
111 float noteLength = float(pEngine->FrameTime + Delay -
112 pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
113 float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
114 if (attenuation <= 0) return -1;
115 volume *= attenuation;
116 }
117
118 // select channel mode (mono or stereo)
119 SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
120 // select bit depth (16 or 24)
121 SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, pSample->BitDepth == 24);
122
123 // get starting crossfade volume level
124 float crossfadeVolume;
125 switch (pDimRgn->AttenuationController.type) {
126 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
127 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[128])];
128 break;
129 case ::gig::attenuation_ctrl_t::type_velocity:
130 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
131 break;
132 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
133 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number])];
134 break;
135 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
136 default:
137 crossfadeVolume = 1.0f;
138 }
139
140 VolumeLeft = volume * Engine::PanCurve[64 - pDimRgn->Pan];
141 VolumeRight = volume * Engine::PanCurve[64 + pDimRgn->Pan];
142
143 float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
144 CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
145 VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
146 PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
147 PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
148
149 finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
150 Pos = pDimRgn->SampleStartOffset;
151
152 // Check if the sample needs disk streaming or is too short for that
153 long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
154 DiskVoice = cachedsamples < pSample->SamplesTotal;
155
156 const DLS::sample_loop_t& loopinfo = pDimRgn->pSampleLoops[0];
157
158 if (DiskVoice) { // voice to be streamed from disk
159 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)
160
161 // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
162 RAMLoop = (pDimRgn->SampleLoops && (loopinfo.LoopStart + loopinfo.LoopLength) <= MaxRAMPos);
163
164 if (pDiskThread->OrderNewStream(&DiskStreamRef, pDimRgn, MaxRAMPos, !RAMLoop) < 0) {
165 dmsg(1,("Disk stream order failed!\n"));
166 KillImmediately();
167 return -1;
168 }
169 dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
170 }
171 else { // RAM only voice
172 MaxRAMPos = cachedsamples;
173 RAMLoop = (pDimRgn->SampleLoops != 0);
174 dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
175 }
176 if (RAMLoop) {
177 loop.uiTotalCycles = pSample->LoopPlayCount;
178 loop.uiCyclesLeft = pSample->LoopPlayCount;
179 loop.uiStart = loopinfo.LoopStart;
180 loop.uiEnd = loopinfo.LoopStart + loopinfo.LoopLength;
181 loop.uiSize = loopinfo.LoopLength;
182 }
183
184 // calculate initial pitch value
185 {
186 double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
187
188 // GSt behaviour: maximum transpose up is 40 semitones. If
189 // MIDI key is more than 40 semitones above unity note,
190 // the transpose is not done.
191 if (pDimRgn->PitchTrack && (MIDIKey - (int) pDimRgn->UnityNote) < 40) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
192
193 this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));
194 this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
195 }
196
197 // the length of the decay and release curves are dependent on the velocity
198 const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
199
200 // setup EG 1 (VCA EG)
201 {
202 // get current value of EG1 controller
203 double eg1controllervalue;
204 switch (pDimRgn->EG1Controller.type) {
205 case ::gig::eg1_ctrl_t::type_none: // no controller defined
206 eg1controllervalue = 0;
207 break;
208 case ::gig::eg1_ctrl_t::type_channelaftertouch:
209 eg1controllervalue = pEngineChannel->ControllerTable[128];
210 break;
211 case ::gig::eg1_ctrl_t::type_velocity:
212 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
213 break;
214 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
215 eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
216 break;
217 }
218 if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
219
220 // calculate influence of EG1 controller on EG1's parameters
221 // (eg1attack is different from the others)
222 double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ?
223 1 + 0.031 * (double) (pDimRgn->EG1ControllerAttackInfluence == 1 ?
224 1 : 1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 1.0;
225 double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 1.0;
226 double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 1.0;
227
228 EG1.trigger(pDimRgn->EG1PreAttack,
229 pDimRgn->EG1Attack * eg1attack,
230 pDimRgn->EG1Hold,
231 pDimRgn->EG1Decay1 * eg1decay * velrelease,
232 pDimRgn->EG1Decay2 * eg1decay * velrelease,
233 pDimRgn->EG1InfiniteSustain,
234 pDimRgn->EG1Sustain,
235 pDimRgn->EG1Release * eg1release * velrelease,
236 velocityAttenuation,
237 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
238 }
239
240 #ifdef CONFIG_INTERPOLATE_VOLUME
241 // setup initial volume in synthesis parameters
242 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
243 if (pEngineChannel->GetMute()) {
244 finalSynthesisParameters.fFinalVolumeLeft = 0;
245 finalSynthesisParameters.fFinalVolumeRight = 0;
246 }
247 else
248 #else
249 {
250 float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel();
251
252 finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * pEngineChannel->GlobalPanLeft;
253 finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
254 }
255 #endif
256 #endif
257
258 // setup EG 2 (VCF Cutoff EG)
259 {
260 // get current value of EG2 controller
261 double eg2controllervalue;
262 switch (pDimRgn->EG2Controller.type) {
263 case ::gig::eg2_ctrl_t::type_none: // no controller defined
264 eg2controllervalue = 0;
265 break;
266 case ::gig::eg2_ctrl_t::type_channelaftertouch:
267 eg2controllervalue = pEngineChannel->ControllerTable[128];
268 break;
269 case ::gig::eg2_ctrl_t::type_velocity:
270 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
271 break;
272 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
273 eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
274 break;
275 }
276 if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
277
278 // calculate influence of EG2 controller on EG2's parameters
279 double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 1.0;
280 double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 1.0;
281 double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 1.0;
282
283 EG2.trigger(pDimRgn->EG2PreAttack,
284 pDimRgn->EG2Attack * eg2attack,
285 false,
286 pDimRgn->EG2Decay1 * eg2decay * velrelease,
287 pDimRgn->EG2Decay2 * eg2decay * velrelease,
288 pDimRgn->EG2InfiniteSustain,
289 pDimRgn->EG2Sustain,
290 pDimRgn->EG2Release * eg2release * velrelease,
291 velocityAttenuation,
292 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
293 }
294
295
296 // setup EG 3 (VCO EG)
297 {
298 // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
299 bool bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
300 float eg3depth = (bPortamento)
301 ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
302 : RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
303 float eg3time = (bPortamento)
304 ? pEngineChannel->PortamentoTime
305 : pDimRgn->EG3Attack;
306 EG3.trigger(eg3depth, eg3time, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
307 dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
308 }
309
310
311 // setup LFO 1 (VCA LFO)
312 {
313 uint16_t lfo1_internal_depth;
314 switch (pDimRgn->LFO1Controller) {
315 case ::gig::lfo1_ctrl_internal:
316 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
317 pLFO1->ExtController = 0; // no external controller
318 bLFO1Enabled = (lfo1_internal_depth > 0);
319 break;
320 case ::gig::lfo1_ctrl_modwheel:
321 lfo1_internal_depth = 0;
322 pLFO1->ExtController = 1; // MIDI controller 1
323 bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0);
324 break;
325 case ::gig::lfo1_ctrl_breath:
326 lfo1_internal_depth = 0;
327 pLFO1->ExtController = 2; // MIDI controller 2
328 bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0);
329 break;
330 case ::gig::lfo1_ctrl_internal_modwheel:
331 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
332 pLFO1->ExtController = 1; // MIDI controller 1
333 bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
334 break;
335 case ::gig::lfo1_ctrl_internal_breath:
336 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
337 pLFO1->ExtController = 2; // MIDI controller 2
338 bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
339 break;
340 default:
341 lfo1_internal_depth = 0;
342 pLFO1->ExtController = 0; // no external controller
343 bLFO1Enabled = false;
344 }
345 if (bLFO1Enabled) {
346 pLFO1->trigger(pDimRgn->LFO1Frequency,
347 start_level_min,
348 lfo1_internal_depth,
349 pDimRgn->LFO1ControlDepth,
350 pDimRgn->LFO1FlipPhase,
351 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
352 pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
353 }
354 }
355
356
357 // setup LFO 2 (VCF Cutoff LFO)
358 {
359 uint16_t lfo2_internal_depth;
360 switch (pDimRgn->LFO2Controller) {
361 case ::gig::lfo2_ctrl_internal:
362 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
363 pLFO2->ExtController = 0; // no external controller
364 bLFO2Enabled = (lfo2_internal_depth > 0);
365 break;
366 case ::gig::lfo2_ctrl_modwheel:
367 lfo2_internal_depth = 0;
368 pLFO2->ExtController = 1; // MIDI controller 1
369 bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0);
370 break;
371 case ::gig::lfo2_ctrl_foot:
372 lfo2_internal_depth = 0;
373 pLFO2->ExtController = 4; // MIDI controller 4
374 bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0);
375 break;
376 case ::gig::lfo2_ctrl_internal_modwheel:
377 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
378 pLFO2->ExtController = 1; // MIDI controller 1
379 bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
380 break;
381 case ::gig::lfo2_ctrl_internal_foot:
382 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
383 pLFO2->ExtController = 4; // MIDI controller 4
384 bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
385 break;
386 default:
387 lfo2_internal_depth = 0;
388 pLFO2->ExtController = 0; // no external controller
389 bLFO2Enabled = false;
390 }
391 if (bLFO2Enabled) {
392 pLFO2->trigger(pDimRgn->LFO2Frequency,
393 start_level_max,
394 lfo2_internal_depth,
395 pDimRgn->LFO2ControlDepth,
396 pDimRgn->LFO2FlipPhase,
397 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
398 pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
399 }
400 }
401
402
403 // setup LFO 3 (VCO LFO)
404 {
405 uint16_t lfo3_internal_depth;
406 switch (pDimRgn->LFO3Controller) {
407 case ::gig::lfo3_ctrl_internal:
408 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
409 pLFO3->ExtController = 0; // no external controller
410 bLFO3Enabled = (lfo3_internal_depth > 0);
411 break;
412 case ::gig::lfo3_ctrl_modwheel:
413 lfo3_internal_depth = 0;
414 pLFO3->ExtController = 1; // MIDI controller 1
415 bLFO3Enabled = (pDimRgn->LFO3ControlDepth > 0);
416 break;
417 case ::gig::lfo3_ctrl_aftertouch:
418 lfo3_internal_depth = 0;
419 pLFO3->ExtController = 128;
420 bLFO3Enabled = true;
421 break;
422 case ::gig::lfo3_ctrl_internal_modwheel:
423 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
424 pLFO3->ExtController = 1; // MIDI controller 1
425 bLFO3Enabled = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
426 break;
427 case ::gig::lfo3_ctrl_internal_aftertouch:
428 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
429 pLFO1->ExtController = 128;
430 bLFO3Enabled = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
431 break;
432 default:
433 lfo3_internal_depth = 0;
434 pLFO3->ExtController = 0; // no external controller
435 bLFO3Enabled = false;
436 }
437 if (bLFO3Enabled) {
438 pLFO3->trigger(pDimRgn->LFO3Frequency,
439 start_level_mid,
440 lfo3_internal_depth,
441 pDimRgn->LFO3ControlDepth,
442 false,
443 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
444 pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
445 }
446 }
447
448
449 #if CONFIG_FORCE_FILTER
450 const bool bUseFilter = true;
451 #else // use filter only if instrument file told so
452 const bool bUseFilter = pDimRgn->VCFEnabled;
453 #endif // CONFIG_FORCE_FILTER
454 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
455 if (bUseFilter) {
456 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
457 VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
458 #else // use the one defined in the instrument file
459 switch (pDimRgn->VCFCutoffController) {
460 case ::gig::vcf_cutoff_ctrl_modwheel:
461 VCFCutoffCtrl.controller = 1;
462 break;
463 case ::gig::vcf_cutoff_ctrl_effect1:
464 VCFCutoffCtrl.controller = 12;
465 break;
466 case ::gig::vcf_cutoff_ctrl_effect2:
467 VCFCutoffCtrl.controller = 13;
468 break;
469 case ::gig::vcf_cutoff_ctrl_breath:
470 VCFCutoffCtrl.controller = 2;
471 break;
472 case ::gig::vcf_cutoff_ctrl_foot:
473 VCFCutoffCtrl.controller = 4;
474 break;
475 case ::gig::vcf_cutoff_ctrl_sustainpedal:
476 VCFCutoffCtrl.controller = 64;
477 break;
478 case ::gig::vcf_cutoff_ctrl_softpedal:
479 VCFCutoffCtrl.controller = 67;
480 break;
481 case ::gig::vcf_cutoff_ctrl_genpurpose7:
482 VCFCutoffCtrl.controller = 82;
483 break;
484 case ::gig::vcf_cutoff_ctrl_genpurpose8:
485 VCFCutoffCtrl.controller = 83;
486 break;
487 case ::gig::vcf_cutoff_ctrl_aftertouch:
488 VCFCutoffCtrl.controller = 128;
489 break;
490 case ::gig::vcf_cutoff_ctrl_none:
491 default:
492 VCFCutoffCtrl.controller = 0;
493 break;
494 }
495 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
496
497 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
498 VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
499 #else // use the one defined in the instrument file
500 switch (pDimRgn->VCFResonanceController) {
501 case ::gig::vcf_res_ctrl_genpurpose3:
502 VCFResonanceCtrl.controller = 18;
503 break;
504 case ::gig::vcf_res_ctrl_genpurpose4:
505 VCFResonanceCtrl.controller = 19;
506 break;
507 case ::gig::vcf_res_ctrl_genpurpose5:
508 VCFResonanceCtrl.controller = 80;
509 break;
510 case ::gig::vcf_res_ctrl_genpurpose6:
511 VCFResonanceCtrl.controller = 81;
512 break;
513 case ::gig::vcf_res_ctrl_none:
514 default:
515 VCFResonanceCtrl.controller = 0;
516 }
517 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
518
519 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
520 finalSynthesisParameters.filterLeft.SetType(pDimRgn->VCFType);
521 finalSynthesisParameters.filterRight.SetType(pDimRgn->VCFType);
522 #else // override filter type
523 finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
524 finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
525 #endif // CONFIG_OVERRIDE_FILTER_TYPE
526
527 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
528 VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
529
530 // calculate cutoff frequency
531 float cutoff = pDimRgn->GetVelocityCutoff(itNoteOnEvent->Param.Note.Velocity);
532 if (pDimRgn->VCFKeyboardTracking) {
533 cutoff *= exp((itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.057762265f); // (ln(2) / 12)
534 }
535 CutoffBase = cutoff;
536
537 int cvalue;
538 if (VCFCutoffCtrl.controller) {
539 cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
540 if (pDimRgn->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
541 // VCFVelocityScale in this case means Minimum cutoff
542 if (cvalue < pDimRgn->VCFVelocityScale) cvalue = pDimRgn->VCFVelocityScale;
543 }
544 else {
545 cvalue = pDimRgn->VCFCutoff;
546 }
547 cutoff *= float(cvalue);
548 if (cutoff > 127.0f) cutoff = 127.0f;
549
550 // calculate resonance
551 float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance);
552
553 VCFCutoffCtrl.fvalue = cutoff;
554 VCFResonanceCtrl.fvalue = resonance;
555 }
556 else {
557 VCFCutoffCtrl.controller = 0;
558 VCFResonanceCtrl.controller = 0;
559 }
560
561 return 0; // success
562 }
563
564 /**
565 * Renders the audio data for this voice for the current audio fragment.
566 * The sample input data can either come from RAM (cached sample or sample
567 * part) or directly from disk. The output signal will be rendered by
568 * resampling / interpolation. If this voice is a disk streaming voice and
569 * the voice completely played back the cached RAM part of the sample, it
570 * will automatically switch to disk playback for the next RenderAudio()
571 * call.
572 *
573 * @param Samples - number of samples to be rendered in this audio fragment cycle
574 */
575 void Voice::Render(uint Samples) {
576
577 // select default values for synthesis mode bits
578 SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
579
580 switch (this->PlaybackState) {
581
582 case playback_state_init:
583 this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
584 // no break - continue with playback_state_ram
585
586 case playback_state_ram: {
587 if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
588
589 // render current fragment
590 Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
591
592 if (DiskVoice) {
593 // check if we reached the allowed limit of the sample RAM cache
594 if (finalSynthesisParameters.dPos > MaxRAMPos) {
595 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", finalSynthesisParameters.dPos));
596 this->PlaybackState = playback_state_disk;
597 }
598 } else if (finalSynthesisParameters.dPos >= pSample->GetCache().Size / pSample->FrameSize) {
599 this->PlaybackState = playback_state_end;
600 }
601 }
602 break;
603
604 case playback_state_disk: {
605 if (!DiskStreamRef.pStream) {
606 // check if the disk thread created our ordered disk stream in the meantime
607 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
608 if (!DiskStreamRef.pStream) {
609 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
610 KillImmediately();
611 return;
612 }
613 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(finalSynthesisParameters.dPos) - MaxRAMPos));
614 finalSynthesisParameters.dPos -= int(finalSynthesisParameters.dPos);
615 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
616 }
617
618 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
619
620 // add silence sample at the end if we reached the end of the stream (for the interpolator)
621 if (DiskStreamRef.State == Stream::state_end) {
622 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
623 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
624 // remember how many sample words there are before any silence has been added
625 if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
626 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
627 }
628 }
629
630 sample_t* ptr = (sample_t*)DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
631
632 // render current audio fragment
633 Synthesize(Samples, ptr, Delay);
634
635 const int iPos = (int) finalSynthesisParameters.dPos;
636 const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
637 DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
638 finalSynthesisParameters.dPos -= iPos; // just keep fractional part of playback position
639
640 // change state of voice to 'end' if we really reached the end of the sample data
641 if (RealSampleWordsLeftToRead >= 0) {
642 RealSampleWordsLeftToRead -= readSampleWords;
643 if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
644 }
645 }
646 break;
647
648 case playback_state_end:
649 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
650 break;
651 }
652
653 // Reset delay
654 Delay = 0;
655
656 itTriggerEvent = Pool<Event>::Iterator();
657
658 // If sample stream or release stage finished, kill the voice
659 if (PlaybackState == playback_state_end || EG1.getSegmentType() == EGADSR::segment_end) KillImmediately();
660 }
661
662 /**
663 * Resets voice variables. Should only be called if rendering process is
664 * suspended / not running.
665 */
666 void Voice::Reset() {
667 finalSynthesisParameters.filterLeft.Reset();
668 finalSynthesisParameters.filterRight.Reset();
669 DiskStreamRef.pStream = NULL;
670 DiskStreamRef.hStream = 0;
671 DiskStreamRef.State = Stream::state_unused;
672 DiskStreamRef.OrderID = 0;
673 PlaybackState = playback_state_end;
674 itTriggerEvent = Pool<Event>::Iterator();
675 itKillEvent = Pool<Event>::Iterator();
676 }
677
678 /**
679 * Process given list of MIDI note on, note off and sustain pedal events
680 * for the given time.
681 *
682 * @param itEvent - iterator pointing to the next event to be processed
683 * @param End - youngest time stamp where processing should be stopped
684 */
685 void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
686 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
687 if (itEvent->Type == Event::type_release) {
688 EG1.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
689 EG2.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
690 } else if (itEvent->Type == Event::type_cancel_release) {
691 EG1.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
692 EG2.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
693 }
694 }
695 }
696
697 /**
698 * Process given list of MIDI control change and pitch bend events for
699 * the given time.
700 *
701 * @param itEvent - iterator pointing to the next event to be processed
702 * @param End - youngest time stamp where processing should be stopped
703 */
704 void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
705 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
706 if (itEvent->Type == Event::type_control_change &&
707 itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
708 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
709 processCutoffEvent(itEvent);
710 }
711 if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
712 processResonanceEvent(itEvent);
713 }
714 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
715 pLFO1->update(itEvent->Param.CC.Value);
716 }
717 if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
718 pLFO2->update(itEvent->Param.CC.Value);
719 }
720 if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
721 pLFO3->update(itEvent->Param.CC.Value);
722 }
723 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
724 itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
725 CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
726 }
727 if (itEvent->Param.CC.Controller == 7) { // volume
728 VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]);
729 } else if (itEvent->Param.CC.Controller == 10) { // panpot
730 PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
731 PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
732 }
733 } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
734 processPitchEvent(itEvent);
735 }
736 }
737 }
738
739 void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
740 const float pitch = RTMath::CentsToFreqRatio(((double) itEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
741 finalSynthesisParameters.fFinalPitch *= pitch;
742 PitchBend = pitch;
743 }
744
745 void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
746 int ccvalue = itEvent->Param.CC.Value;
747 if (VCFCutoffCtrl.value == ccvalue) return;
748 VCFCutoffCtrl.value == ccvalue;
749 if (pDimRgn->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
750 if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
751 float cutoff = CutoffBase * float(ccvalue);
752 if (cutoff > 127.0f) cutoff = 127.0f;
753
754 VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
755 fFinalCutoff = cutoff;
756 }
757
758 void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
759 // convert absolute controller value to differential
760 const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
761 VCFResonanceCtrl.value = itEvent->Param.CC.Value;
762 const float resonancedelta = (float) ctrldelta;
763 fFinalResonance += resonancedelta;
764 // needed for initialization of parameter
765 VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
766 }
767
768 /**
769 * Synthesizes the current audio fragment for this voice.
770 *
771 * @param Samples - number of sample points to be rendered in this audio
772 * fragment cycle
773 * @param pSrc - pointer to input sample data
774 * @param Skip - number of sample points to skip in output buffer
775 */
776 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
777 finalSynthesisParameters.pOutLeft = &pEngineChannel->pChannelLeft->Buffer()[Skip];
778 finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip];
779 finalSynthesisParameters.pSrc = pSrc;
780
781 RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
782 RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
783
784 if (itTriggerEvent) { // skip events that happened before this voice was triggered
785 while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
786 // we can't simply compare the timestamp here, because note events
787 // might happen on the same time stamp, so we have to deal on the
788 // actual sequence the note events arrived instead (see bug #112)
789 for (; itNoteEvent; ++itNoteEvent) {
790 if (itTriggerEvent == itNoteEvent) {
791 ++itNoteEvent;
792 break;
793 }
794 }
795 }
796
797 uint killPos;
798 if (itKillEvent) {
799 int maxFadeOutPos = Samples - pEngine->MinFadeOutSamples;
800 if (maxFadeOutPos < 0) {
801 // There's not enough space in buffer to do a fade out
802 // from max volume (this can only happen for audio
803 // drivers that use Samples < MaxSamplesPerCycle).
804 // End the EG1 here, at pos 0, with a shorter max fade
805 // out time.
806 EG1.enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
807 itKillEvent = Pool<Event>::Iterator();
808 } else {
809 killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
810 }
811 }
812
813 uint i = Skip;
814 while (i < Samples) {
815 int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
816
817 // initialize all final synthesis parameters
818 finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
819 fFinalCutoff = VCFCutoffCtrl.fvalue;
820 fFinalResonance = VCFResonanceCtrl.fvalue;
821
822 // process MIDI control change and pitchbend events for this subfragment
823 processCCEvents(itCCEvent, iSubFragmentEnd);
824
825 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
826 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
827 if (pEngineChannel->GetMute()) fFinalVolume = 0;
828 #endif
829
830 // process transition events (note on, note off & sustain pedal)
831 processTransitionEvents(itNoteEvent, iSubFragmentEnd);
832
833 // if the voice was killed in this subfragment, or if the
834 // filter EG is finished, switch EG1 to fade out stage
835 if ((itKillEvent && killPos <= iSubFragmentEnd) ||
836 (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
837 EG2.getSegmentType() == EGADSR::segment_end)) {
838 EG1.enterFadeOutStage();
839 itKillEvent = Pool<Event>::Iterator();
840 }
841
842 // process envelope generators
843 switch (EG1.getSegmentType()) {
844 case EGADSR::segment_lin:
845 fFinalVolume *= EG1.processLin();
846 break;
847 case EGADSR::segment_exp:
848 fFinalVolume *= EG1.processExp();
849 break;
850 case EGADSR::segment_end:
851 fFinalVolume *= EG1.getLevel();
852 break; // noop
853 }
854 switch (EG2.getSegmentType()) {
855 case EGADSR::segment_lin:
856 fFinalCutoff *= EG2.processLin();
857 break;
858 case EGADSR::segment_exp:
859 fFinalCutoff *= EG2.processExp();
860 break;
861 case EGADSR::segment_end:
862 fFinalCutoff *= EG2.getLevel();
863 break; // noop
864 }
865 if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
866
867 // process low frequency oscillators
868 if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
869 if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
870 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
871
872 // if filter enabled then update filter coefficients
873 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
874 finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
875 finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
876 }
877
878 // do we need resampling?
879 const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
880 const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
881 const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
882 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
883 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
884
885 // prepare final synthesis parameters structure
886 finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
887 #ifdef CONFIG_INTERPOLATE_VOLUME
888 finalSynthesisParameters.fFinalVolumeDeltaLeft =
889 (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
890 finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
891 finalSynthesisParameters.fFinalVolumeDeltaRight =
892 (fFinalVolume * VolumeRight * PanRightSmoother.render() -
893 finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
894 #else
895 finalSynthesisParameters.fFinalVolumeLeft =
896 fFinalVolume * VolumeLeft * PanLeftSmoother.render();
897 finalSynthesisParameters.fFinalVolumeRight =
898 fFinalVolume * VolumeRight * PanRightSmoother.render();
899 #endif
900 // render audio for one subfragment
901 RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
902
903 // stop the rendering if volume EG is finished
904 if (EG1.getSegmentType() == EGADSR::segment_end) break;
905
906 const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
907
908 // increment envelopes' positions
909 if (EG1.active()) {
910
911 // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage
912 if (pDimRgn->SampleLoops && Pos <= pDimRgn->pSampleLoops[0].LoopStart && pDimRgn->pSampleLoops[0].LoopStart < newPos) {
913 EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
914 }
915
916 EG1.increment(1);
917 if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
918 }
919 if (EG2.active()) {
920 EG2.increment(1);
921 if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
922 }
923 EG3.increment(1);
924 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
925
926 Pos = newPos;
927 i = iSubFragmentEnd;
928 }
929 }
930
931 /** @brief Update current portamento position.
932 *
933 * Will be called when portamento mode is enabled to get the final
934 * portamento position of this active voice from where the next voice(s)
935 * might continue to slide on.
936 *
937 * @param itNoteOffEvent - event which causes this voice to die soon
938 */
939 void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
940 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
941 pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
942 }
943
944 /**
945 * Immediately kill the voice. This method should not be used to kill
946 * a normal, active voice, because it doesn't take care of things like
947 * fading down the volume level to avoid clicks and regular processing
948 * until the kill event actually occured!
949 *
950 * If it's necessary to know when the voice's disk stream was actually
951 * deleted, then one can set the optional @a bRequestNotification
952 * parameter and this method will then return the handle of the disk
953 * stream (unique identifier) and one can use this handle to poll the
954 * disk thread if this stream has been deleted. In any case this method
955 * will return immediately and will not block until the stream actually
956 * was deleted.
957 *
958 * @param bRequestNotification - (optional) whether the disk thread shall
959 * provide a notification once it deleted
960 * the respective disk stream
961 * (default=false)
962 * @returns handle to the voice's disk stream or @c Stream::INVALID_HANDLE
963 * if the voice did not use a disk stream at all
964 * @see Kill()
965 */
966 Stream::Handle Voice::KillImmediately(bool bRequestNotification) {
967 Stream::Handle hStream = Stream::INVALID_HANDLE;
968 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
969 pDiskThread->OrderDeletionOfStream(&DiskStreamRef, bRequestNotification);
970 hStream = DiskStreamRef.hStream;
971 }
972 Reset();
973 return hStream;
974 }
975
976 /**
977 * Kill the voice in regular sense. Let the voice render audio until
978 * the kill event actually occured and then fade down the volume level
979 * very quickly and let the voice die finally. Unlike a normal release
980 * of a voice, a kill process cannot be cancalled and is therefore
981 * usually used for voice stealing and key group conflicts.
982 *
983 * @param itKillEvent - event which caused the voice to be killed
984 */
985 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
986 #if CONFIG_DEVMODE
987 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
988 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
989 #endif // CONFIG_DEVMODE
990
991 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
992 this->itKillEvent = itKillEvent;
993 }
994
995 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC