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

Annotation of /linuxsampler/trunk/src/engines/sf2/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2012 - (hide annotations) (download)
Fri Oct 23 17:53:17 2009 UTC (14 years, 6 months ago) by iliev
File size: 53212 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 iliev 2012 /***************************************************************************
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 sf2 {
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, ::sf2::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->fineTune + 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     /*uint8_t* pBuf = (uint8_t*)pSample->GetCache().pStart;
621     pBuf += pRegion->startAddrsOffset * pSample->GetFrameSize();
622     Synthesize(Samples, (sample_t*) pBuf, Delay);*/ // TODO: implement startAddrsOffset
623    
624     if (DiskVoice) {
625     // check if we reached the allowed limit of the sample RAM cache
626     if (finalSynthesisParameters.dPos > MaxRAMPos) {
627     dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", finalSynthesisParameters.dPos));
628     this->PlaybackState = playback_state_disk;
629     }
630     } else if (finalSynthesisParameters.dPos >= pSample->GetCache().Size / pSample->GetFrameSize()) {
631     this->PlaybackState = playback_state_end;
632     }
633     }
634     break;
635    
636     case playback_state_disk: {
637     if (!DiskStreamRef.pStream) {
638     // check if the disk thread created our ordered disk stream in the meantime
639     DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
640     if (!DiskStreamRef.pStream) {
641     std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
642     KillImmediately();
643     return;
644     }
645     DiskStreamRef.pStream->IncrementReadPos(pSample->GetChannelCount() * (int(finalSynthesisParameters.dPos) - MaxRAMPos));
646     finalSynthesisParameters.dPos -= int(finalSynthesisParameters.dPos);
647     RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
648     }
649    
650     const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
651    
652     // add silence sample at the end if we reached the end of the stream (for the interpolator)
653     if (DiskStreamRef.State == Stream::state_end) {
654     const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->GetChannelCount() + 6; // +6 for the interpolator algorithm
655     if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
656     // remember how many sample words there are before any silence has been added
657     if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
658     DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
659     }
660     }
661    
662     sample_t* ptr = (sample_t*)DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
663    
664     // render current audio fragment
665     Synthesize(Samples, ptr, Delay);
666    
667     const int iPos = (int) finalSynthesisParameters.dPos;
668     const int readSampleWords = iPos * pSample->GetChannelCount(); // amount of sample words actually been read
669     DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
670     finalSynthesisParameters.dPos -= iPos; // just keep fractional part of playback position
671    
672     // change state of voice to 'end' if we really reached the end of the sample data
673     if (RealSampleWordsLeftToRead >= 0) {
674     RealSampleWordsLeftToRead -= readSampleWords;
675     if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
676     }
677     }
678     break;
679    
680     case playback_state_end:
681     std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
682     break;
683     }
684    
685     // Reset delay
686     Delay = 0;
687    
688     itTriggerEvent = Pool<Event>::Iterator();
689    
690     // If sample stream or release stage finished, kill the voice
691     if (PlaybackState == playback_state_end || EG1.getSegmentType() == EGADSR::segment_end) KillImmediately();
692     }
693    
694     /**
695     * Resets voice variables. Should only be called if rendering process is
696     * suspended / not running.
697     */
698     void Voice::Reset() {
699     finalSynthesisParameters.filterLeft.Reset();
700     finalSynthesisParameters.filterRight.Reset();
701     DiskStreamRef.pStream = NULL;
702     DiskStreamRef.hStream = 0;
703     DiskStreamRef.State = Stream::state_unused;
704     DiskStreamRef.OrderID = 0;
705     PlaybackState = playback_state_end;
706     itTriggerEvent = Pool<Event>::Iterator();
707     itKillEvent = Pool<Event>::Iterator();
708     }
709    
710     /**
711     * Process given list of MIDI note on, note off and sustain pedal events
712     * for the given time.
713     *
714     * @param itEvent - iterator pointing to the next event to be processed
715     * @param End - youngest time stamp where processing should be stopped
716     */
717     void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
718     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
719     if (itEvent->Type == Event::type_release) {
720     EG1.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
721     EG2.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
722     } else if (itEvent->Type == Event::type_cancel_release) {
723     EG1.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
724     EG2.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
725     }
726     }
727     }
728    
729     /**
730     * Process given list of MIDI control change and pitch bend events for
731     * the given time.
732     *
733     * @param itEvent - iterator pointing to the next event to be processed
734     * @param End - youngest time stamp where processing should be stopped
735     */
736     void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
737     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
738     if (itEvent->Type == Event::type_control_change &&
739     itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
740     if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
741     processCutoffEvent(itEvent);
742     }
743     if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
744     processResonanceEvent(itEvent);
745     }
746     if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
747     pLFO1->update(itEvent->Param.CC.Value);
748     }
749     if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
750     pLFO2->update(itEvent->Param.CC.Value);
751     }
752     if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
753     pLFO3->update(itEvent->Param.CC.Value);
754     }
755     /*if (pRegion->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
756     itEvent->Param.CC.Controller == pRegion->AttenuationController.controller_number) {
757     CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
758     }*/ // TODO:
759     if (itEvent->Param.CC.Controller == 7) { // volume
760     VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]);
761     } else if (itEvent->Param.CC.Controller == 10) { // panpot
762     PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
763     PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
764     }
765     } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
766     processPitchEvent(itEvent);
767     }
768     }
769     }
770    
771     void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
772     PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * PitchBendRange);
773     }
774    
775     void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
776     /*int ccvalue = itEvent->Param.CC.Value;
777     if (VCFCutoffCtrl.value == ccvalue) return;
778     VCFCutoffCtrl.value == ccvalue;
779     if (pRegion->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
780     if (ccvalue < pRegion->VCFVelocityScale) ccvalue = pRegion->VCFVelocityScale;
781     float cutoff = CutoffBase * float(ccvalue);
782     if (cutoff > 127.0f) cutoff = 127.0f;
783    
784     VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
785     fFinalCutoff = cutoff;*/ // TODO: ^^^
786     }
787    
788     void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
789     // convert absolute controller value to differential
790     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
791     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
792     const float resonancedelta = (float) ctrldelta;
793     fFinalResonance += resonancedelta;
794     // needed for initialization of parameter
795     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
796     }
797    
798     /**
799     * Synthesizes the current audio fragment for this voice.
800     *
801     * @param Samples - number of sample points to be rendered in this audio
802     * fragment cycle
803     * @param pSrc - pointer to input sample data
804     * @param Skip - number of sample points to skip in output buffer
805     */
806     void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
807     finalSynthesisParameters.pOutLeft = &pEngineChannel->pChannelLeft->Buffer()[Skip];
808     finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip];
809     finalSynthesisParameters.pSrc = pSrc;
810    
811     RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
812     RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
813    
814    
815     if (itTriggerEvent) { // skip events that happened before this voice was triggered
816     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
817     // we can't simply compare the timestamp here, because note events
818     // might happen on the same time stamp, so we have to deal on the
819     // actual sequence the note events arrived instead (see bug #112)
820     for (; itNoteEvent; ++itNoteEvent) {
821     if (itTriggerEvent == itNoteEvent) {
822     ++itNoteEvent;
823     break;
824     }
825     }
826     }
827    
828     uint killPos;
829     if (itKillEvent) {
830     int maxFadeOutPos = Samples - pEngine->MinFadeOutSamples;
831     if (maxFadeOutPos < 0) {
832     // There's not enough space in buffer to do a fade out
833     // from max volume (this can only happen for audio
834     // drivers that use Samples < MaxSamplesPerCycle).
835     // End the EG1 here, at pos 0, with a shorter max fade
836     // out time.
837     EG1.enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
838     itKillEvent = Pool<Event>::Iterator();
839     } else {
840     killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
841     }
842     }
843    
844     uint i = Skip;
845     /*while (i < Samples) {
846     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
847    
848     // initialize all final synthesis parameters
849     fFinalCutoff = VCFCutoffCtrl.fvalue;
850     fFinalResonance = VCFResonanceCtrl.fvalue;
851    
852     // process MIDI control change and pitchbend events for this subfragment
853     processCCEvents(itCCEvent, iSubFragmentEnd);
854    
855     finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
856     float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
857     #ifdef CONFIG_PROCESS_MUTED_CHANNELS
858     if (pEngineChannel->GetMute()) fFinalVolume = 0;
859     #endif
860    
861     // process transition events (note on, note off & sustain pedal)
862     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
863    
864     // if the voice was killed in this subfragment, or if the
865     // filter EG is finished, switch EG1 to fade out stage
866     if ((itKillEvent && killPos <= iSubFragmentEnd) ||
867     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
868     EG2.getSegmentType() == EGADSR::segment_end)) {
869     EG1.enterFadeOutStage();
870     itKillEvent = Pool<Event>::Iterator();
871     }
872    
873     // process envelope generators
874     switch (EG1.getSegmentType()) {
875     case EGADSR::segment_lin:
876     fFinalVolume *= EG1.processLin();
877     break;
878     case EGADSR::segment_exp:
879     fFinalVolume *= EG1.processExp();
880     break;
881     case EGADSR::segment_end:
882     fFinalVolume *= EG1.getLevel();
883     break; // noop
884     }
885     switch (EG2.getSegmentType()) {
886     case EGADSR::segment_lin:
887     fFinalCutoff *= EG2.processLin();
888     break;
889     case EGADSR::segment_exp:
890     fFinalCutoff *= EG2.processExp();
891     break;
892     case EGADSR::segment_end:
893     fFinalCutoff *= EG2.getLevel();
894     break; // noop
895     }
896     if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
897    
898     // process low frequency oscillators
899     if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
900     if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
901     if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
902    
903     // limit the pitch so we don't read outside the buffer
904     finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
905    
906     // if filter enabled then update filter coefficients
907     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
908     finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
909     finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
910     }
911    
912     // do we need resampling?
913     const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
914     const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
915     const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
916     finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
917     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
918    
919     fFinalVolume = 1.0;
920     // prepare final synthesis parameters structure
921     finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
922     #ifdef CONFIG_INTERPOLATE_VOLUME
923     finalSynthesisParameters.fFinalVolumeDeltaLeft = 1;
924     finalSynthesisParameters.fFinalVolumeDeltaRight = 1;
925     #else
926     finalSynthesisParameters.fFinalVolumeLeft =1;
927     finalSynthesisParameters.fFinalVolumeRight =1;
928     #endif
929     // render audio for one subfragment
930     //RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
931    
932     // stop the rendering if volume EG is finished
933     if (EG1.getSegmentType() == EGADSR::segment_end) break;
934    
935     const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
936    
937     // increment envelopes' positions
938     if (EG1.active()) {
939    
940     // 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
941     if (pRegion->SampleLoops && Pos <= pRegion->pSampleLoops[0].LoopStart && pRegion->pSampleLoops[0].LoopStart < newPos) {
942     EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
943     } // TODO:
944    
945     EG1.increment(1);
946     if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
947     }
948     if (EG2.active()) {
949     EG2.increment(1);
950     if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
951     }
952     EG3.increment(1);
953     if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
954    
955     Pos = newPos;
956     i = iSubFragmentEnd;
957     }*/
958    
959     int32_t* pSrc2 = NULL;
960     if((pSample->GetFrameSize() / pSample->GetChannelCount()) == 4) pSrc2 = (int32_t*)pSrc;
961     for(int j = 0; j < Samples; j++) {
962     int lp, rp;
963     if(pSample->GetChannelCount() == 1) {
964     lp = (int)(finalSynthesisParameters.dPos + j);
965     rp = (int)(finalSynthesisParameters.dPos + j);
966     } else {
967     lp = (int)(finalSynthesisParameters.dPos + j) * 2;
968     rp = (int)(finalSynthesisParameters.dPos + j) * 2 + 1;
969     }
970     float left, right;
971     if(pSrc2 != NULL) {
972     left = pSrc2[lp]; right = pSrc2[rp];
973     } else {
974     left = pSrc[lp]; right = pSrc[rp];
975     }
976     float f = (pSrc2 == NULL ? 32768.0f : 32768.0f * 65536.0f);
977     left /= f; right /= f;
978     finalSynthesisParameters.pOutLeft[j] += left;
979     finalSynthesisParameters.pOutRight[j] += right;
980     }
981     finalSynthesisParameters.dPos += Samples;
982     }
983    
984     /** @brief Update current portamento position.
985     *
986     * Will be called when portamento mode is enabled to get the final
987     * portamento position of this active voice from where the next voice(s)
988     * might continue to slide on.
989     *
990     * @param itNoteOffEvent - event which causes this voice to die soon
991     */
992     void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
993     const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
994     pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
995     }
996    
997     /**
998     * Immediately kill the voice. This method should not be used to kill
999     * a normal, active voice, because it doesn't take care of things like
1000     * fading down the volume level to avoid clicks and regular processing
1001     * until the kill event actually occured!
1002     *
1003     * If it's necessary to know when the voice's disk stream was actually
1004     * deleted, then one can set the optional @a bRequestNotification
1005     * parameter and this method will then return the handle of the disk
1006     * stream (unique identifier) and one can use this handle to poll the
1007     * disk thread if this stream has been deleted. In any case this method
1008     * will return immediately and will not block until the stream actually
1009     * was deleted.
1010     *
1011     * @param bRequestNotification - (optional) whether the disk thread shall
1012     * provide a notification once it deleted
1013     * the respective disk stream
1014     * (default=false)
1015     * @returns handle to the voice's disk stream or @c Stream::INVALID_HANDLE
1016     * if the voice did not use a disk stream at all
1017     * @see Kill()
1018     */
1019     Stream::Handle Voice::KillImmediately(bool bRequestNotification) {
1020     Stream::Handle hStream = Stream::INVALID_HANDLE;
1021     if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1022     pDiskThread->OrderDeletionOfStream(&DiskStreamRef, bRequestNotification);
1023     hStream = DiskStreamRef.hStream;
1024     }
1025     Reset();
1026     return hStream;
1027     }
1028    
1029     /**
1030     * Kill the voice in regular sense. Let the voice render audio until
1031     * the kill event actually occured and then fade down the volume level
1032     * very quickly and let the voice die finally. Unlike a normal release
1033     * of a voice, a kill process cannot be cancalled and is therefore
1034     * usually used for voice stealing and key group conflicts.
1035     *
1036     * @param itKillEvent - event which caused the voice to be killed
1037     */
1038     void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1039     #if CONFIG_DEVMODE
1040     if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1041     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1042     #endif // CONFIG_DEVMODE
1043    
1044     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1045     this->itKillEvent = itKillEvent;
1046     }
1047    
1048     }} // namespace LinuxSampler::sf2

  ViewVC Help
Powered by ViewVC