/[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 1862 - (show annotations) (download)
Wed Mar 11 19:03:37 2009 UTC (15 years ago) by persson
File size: 50630 byte(s)
* allow gig files to use unlimited downward pitch shifting
* added a limit check for upward pitch shifting

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 = pEngineChannel->pInstrument->FineTune + pDimRgn->FineTune + 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::CentsToFreqRatioUnlimited(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));
194 this->PitchBend = RTMath::CentsToFreqRatio(PitchBend / 8192.0 * 100.0 * pEngineChannel->pInstrument->PitchbendRange);
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 PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch / 8192.0 * 100.0 * pEngineChannel->pInstrument->PitchbendRange);
741 }
742
743 void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
744 int ccvalue = itEvent->Param.CC.Value;
745 if (VCFCutoffCtrl.value == ccvalue) return;
746 VCFCutoffCtrl.value == ccvalue;
747 if (pDimRgn->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
748 if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
749 float cutoff = CutoffBase * float(ccvalue);
750 if (cutoff > 127.0f) cutoff = 127.0f;
751
752 VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
753 fFinalCutoff = cutoff;
754 }
755
756 void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
757 // convert absolute controller value to differential
758 const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
759 VCFResonanceCtrl.value = itEvent->Param.CC.Value;
760 const float resonancedelta = (float) ctrldelta;
761 fFinalResonance += resonancedelta;
762 // needed for initialization of parameter
763 VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
764 }
765
766 /**
767 * Synthesizes the current audio fragment for this voice.
768 *
769 * @param Samples - number of sample points to be rendered in this audio
770 * fragment cycle
771 * @param pSrc - pointer to input sample data
772 * @param Skip - number of sample points to skip in output buffer
773 */
774 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
775 finalSynthesisParameters.pOutLeft = &pEngineChannel->pChannelLeft->Buffer()[Skip];
776 finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip];
777 finalSynthesisParameters.pSrc = pSrc;
778
779 RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
780 RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
781
782 if (itTriggerEvent) { // skip events that happened before this voice was triggered
783 while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
784 // we can't simply compare the timestamp here, because note events
785 // might happen on the same time stamp, so we have to deal on the
786 // actual sequence the note events arrived instead (see bug #112)
787 for (; itNoteEvent; ++itNoteEvent) {
788 if (itTriggerEvent == itNoteEvent) {
789 ++itNoteEvent;
790 break;
791 }
792 }
793 }
794
795 uint killPos;
796 if (itKillEvent) {
797 int maxFadeOutPos = Samples - pEngine->MinFadeOutSamples;
798 if (maxFadeOutPos < 0) {
799 // There's not enough space in buffer to do a fade out
800 // from max volume (this can only happen for audio
801 // drivers that use Samples < MaxSamplesPerCycle).
802 // End the EG1 here, at pos 0, with a shorter max fade
803 // out time.
804 EG1.enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
805 itKillEvent = Pool<Event>::Iterator();
806 } else {
807 killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
808 }
809 }
810
811 uint i = Skip;
812 while (i < Samples) {
813 int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
814
815 // initialize all final synthesis parameters
816 fFinalCutoff = VCFCutoffCtrl.fvalue;
817 fFinalResonance = VCFResonanceCtrl.fvalue;
818
819 // process MIDI control change and pitchbend events for this subfragment
820 processCCEvents(itCCEvent, iSubFragmentEnd);
821
822 finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
823 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
824 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
825 if (pEngineChannel->GetMute()) fFinalVolume = 0;
826 #endif
827
828 // process transition events (note on, note off & sustain pedal)
829 processTransitionEvents(itNoteEvent, iSubFragmentEnd);
830
831 // if the voice was killed in this subfragment, or if the
832 // filter EG is finished, switch EG1 to fade out stage
833 if ((itKillEvent && killPos <= iSubFragmentEnd) ||
834 (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
835 EG2.getSegmentType() == EGADSR::segment_end)) {
836 EG1.enterFadeOutStage();
837 itKillEvent = Pool<Event>::Iterator();
838 }
839
840 // process envelope generators
841 switch (EG1.getSegmentType()) {
842 case EGADSR::segment_lin:
843 fFinalVolume *= EG1.processLin();
844 break;
845 case EGADSR::segment_exp:
846 fFinalVolume *= EG1.processExp();
847 break;
848 case EGADSR::segment_end:
849 fFinalVolume *= EG1.getLevel();
850 break; // noop
851 }
852 switch (EG2.getSegmentType()) {
853 case EGADSR::segment_lin:
854 fFinalCutoff *= EG2.processLin();
855 break;
856 case EGADSR::segment_exp:
857 fFinalCutoff *= EG2.processExp();
858 break;
859 case EGADSR::segment_end:
860 fFinalCutoff *= EG2.getLevel();
861 break; // noop
862 }
863 if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
864
865 // process low frequency oscillators
866 if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
867 if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
868 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
869
870 // limit the pitch so we don't read outside the buffer
871 finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
872
873 // if filter enabled then update filter coefficients
874 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
875 finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
876 finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
877 }
878
879 // do we need resampling?
880 const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
881 const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
882 const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
883 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
884 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
885
886 // prepare final synthesis parameters structure
887 finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
888 #ifdef CONFIG_INTERPOLATE_VOLUME
889 finalSynthesisParameters.fFinalVolumeDeltaLeft =
890 (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
891 finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
892 finalSynthesisParameters.fFinalVolumeDeltaRight =
893 (fFinalVolume * VolumeRight * PanRightSmoother.render() -
894 finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
895 #else
896 finalSynthesisParameters.fFinalVolumeLeft =
897 fFinalVolume * VolumeLeft * PanLeftSmoother.render();
898 finalSynthesisParameters.fFinalVolumeRight =
899 fFinalVolume * VolumeRight * PanRightSmoother.render();
900 #endif
901 // render audio for one subfragment
902 RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
903
904 // stop the rendering if volume EG is finished
905 if (EG1.getSegmentType() == EGADSR::segment_end) break;
906
907 const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
908
909 // increment envelopes' positions
910 if (EG1.active()) {
911
912 // 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
913 if (pDimRgn->SampleLoops && Pos <= pDimRgn->pSampleLoops[0].LoopStart && pDimRgn->pSampleLoops[0].LoopStart < newPos) {
914 EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
915 }
916
917 EG1.increment(1);
918 if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
919 }
920 if (EG2.active()) {
921 EG2.increment(1);
922 if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
923 }
924 EG3.increment(1);
925 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
926
927 Pos = newPos;
928 i = iSubFragmentEnd;
929 }
930 }
931
932 /** @brief Update current portamento position.
933 *
934 * Will be called when portamento mode is enabled to get the final
935 * portamento position of this active voice from where the next voice(s)
936 * might continue to slide on.
937 *
938 * @param itNoteOffEvent - event which causes this voice to die soon
939 */
940 void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
941 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
942 pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
943 }
944
945 /**
946 * Immediately kill the voice. This method should not be used to kill
947 * a normal, active voice, because it doesn't take care of things like
948 * fading down the volume level to avoid clicks and regular processing
949 * until the kill event actually occured!
950 *
951 * If it's necessary to know when the voice's disk stream was actually
952 * deleted, then one can set the optional @a bRequestNotification
953 * parameter and this method will then return the handle of the disk
954 * stream (unique identifier) and one can use this handle to poll the
955 * disk thread if this stream has been deleted. In any case this method
956 * will return immediately and will not block until the stream actually
957 * was deleted.
958 *
959 * @param bRequestNotification - (optional) whether the disk thread shall
960 * provide a notification once it deleted
961 * the respective disk stream
962 * (default=false)
963 * @returns handle to the voice's disk stream or @c Stream::INVALID_HANDLE
964 * if the voice did not use a disk stream at all
965 * @see Kill()
966 */
967 Stream::Handle Voice::KillImmediately(bool bRequestNotification) {
968 Stream::Handle hStream = Stream::INVALID_HANDLE;
969 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
970 pDiskThread->OrderDeletionOfStream(&DiskStreamRef, bRequestNotification);
971 hStream = DiskStreamRef.hStream;
972 }
973 Reset();
974 return hStream;
975 }
976
977 /**
978 * Kill the voice in regular sense. Let the voice render audio until
979 * the kill event actually occured and then fade down the volume level
980 * very quickly and let the voice die finally. Unlike a normal release
981 * of a voice, a kill process cannot be cancalled and is therefore
982 * usually used for voice stealing and key group conflicts.
983 *
984 * @param itKillEvent - event which caused the voice to be killed
985 */
986 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
987 #if CONFIG_DEVMODE
988 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
989 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
990 #endif // CONFIG_DEVMODE
991
992 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
993 this->itKillEvent = itKillEvent;
994 }
995
996 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC