/[svn]/linuxsampler/trunk/src/engines/sfz/Voice.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/sfz/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2012 - (show annotations) (download)
Fri Oct 23 17:53:17 2009 UTC (14 years, 6 months ago) by iliev
File size: 52947 byte(s)
* Refactoring: moved the independent code from
  the Gigasampler format engine to base classes
* SFZ format engine: experimental code (not usable yet)
* SoundFont format engine: experimental code (not usable yet)
* Fixed crash which may occur when MIDI key + transpose is out of range

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

  ViewVC Help
Powered by ViewVC