/[svn]/linuxsampler/trunk/src/engines/common/AbstractVoice.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/common/AbstractVoice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3251 - (hide annotations) (download)
Mon May 29 22:19:19 2017 UTC (6 years, 10 months ago) by schoenebeck
File size: 45720 byte(s)
* NKSP: built-in "play_note()" function now supports a sample playback
  start offset with argument 3, where special value -1 means to use the
  regular sample offset as defined by the instrument file.
* Bumped version (2.0.0.svn55).

1 iliev 2015 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6 persson 2045 * Copyright (C) 2005-2008 Christian Schoenebeck *
7 schoenebeck 3054 * Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev *
8 schoenebeck 3246 * Copyright (C) 2013-2017 Christian Schoenebeck and Andreas Persson *
9 iliev 2015 * *
10     * This program is free software; you can redistribute it and/or modify *
11     * it under the terms of the GNU General Public License as published by *
12     * the Free Software Foundation; either version 2 of the License, or *
13     * (at your option) any later version. *
14     * *
15     * This program is distributed in the hope that it will be useful, *
16     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18     * GNU General Public License for more details. *
19     * *
20     * You should have received a copy of the GNU General Public License *
21     * along with this program; if not, write to the Free Software *
22     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
23     * MA 02111-1307 USA *
24     ***************************************************************************/
25    
26     #include "AbstractVoice.h"
27    
28     namespace LinuxSampler {
29    
30 iliev 2217 AbstractVoice::AbstractVoice(SignalUnitRack* pRack): pSignalUnitRack(pRack) {
31 iliev 2015 pEngineChannel = NULL;
32 persson 2175 pLFO1 = new LFOUnsigned(1.0f); // amplitude LFO (0..1 range)
33     pLFO2 = new LFOUnsigned(1.0f); // filter LFO (0..1 range)
34     pLFO3 = new LFOSigned(1200.0f); // pitch LFO (-1200..+1200 range)
35 iliev 2015 PlaybackState = playback_state_end;
36     SynthesisMode = 0; // set all mode bits to 0 first
37     // select synthesis implementation (asm core is not supported ATM)
38     #if 0 // CONFIG_ASM && ARCH_X86
39     SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
40     #else
41     SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
42     #endif
43     SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, gig::Profiler::isEnabled());
44    
45     finalSynthesisParameters.filterLeft.Reset();
46     finalSynthesisParameters.filterRight.Reset();
47 iliev 2298
48     pEq = NULL;
49     bEqSupport = false;
50 iliev 2015 }
51    
52     AbstractVoice::~AbstractVoice() {
53     if (pLFO1) delete pLFO1;
54     if (pLFO2) delete pLFO2;
55     if (pLFO3) delete pLFO3;
56 iliev 2298
57     if(pEq != NULL) delete pEq;
58 iliev 2015 }
59 iliev 2298
60     void AbstractVoice::CreateEq() {
61     if(!bEqSupport) return;
62     if(pEq != NULL) delete pEq;
63     pEq = new EqSupport;
64     pEq->InitEffect(GetEngine()->pAudioOutputDevice);
65     }
66 persson 2045
67 iliev 2015 /**
68     * Resets voice variables. Should only be called if rendering process is
69     * suspended / not running.
70     */
71     void AbstractVoice::Reset() {
72     finalSynthesisParameters.filterLeft.Reset();
73     finalSynthesisParameters.filterRight.Reset();
74     DiskStreamRef.pStream = NULL;
75     DiskStreamRef.hStream = 0;
76     DiskStreamRef.State = Stream::state_unused;
77     DiskStreamRef.OrderID = 0;
78     PlaybackState = playback_state_end;
79     itTriggerEvent = Pool<Event>::Iterator();
80     itKillEvent = Pool<Event>::Iterator();
81     }
82    
83     /**
84     * Initializes and triggers the voice, a disk stream will be launched if
85     * needed.
86     *
87     * @param pEngineChannel - engine channel on which this voice was ordered
88     * @param itNoteOnEvent - event that caused triggering of this voice
89     * @param PitchBend - MIDI detune factor (-8192 ... +8191)
90     * @param pRegion- points to the region which provides sample wave(s) and articulation data
91     * @param VoiceType - type of this voice
92     * @param iKeyGroup - a value > 0 defines a key group in which this voice is member of
93     * @returns 0 on success, a value < 0 if the voice wasn't triggered
94     * (either due to an error or e.g. because no region is
95     * defined for the given key)
96     */
97     int AbstractVoice::Trigger (
98     AbstractEngineChannel* pEngineChannel,
99     Pool<Event>::Iterator& itNoteOnEvent,
100     int PitchBend,
101     type_t VoiceType,
102     int iKeyGroup
103     ) {
104     this->pEngineChannel = pEngineChannel;
105     Orphan = false;
106    
107     #if CONFIG_DEVMODE
108     if (itNoteOnEvent->FragmentPos() > GetEngine()->MaxSamplesPerCycle) { // just a sanity check for debugging
109     dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
110     }
111     #endif // CONFIG_DEVMODE
112    
113     Type = VoiceType;
114 schoenebeck 2879 pNote = pEngineChannel->pEngine->NoteByID( itNoteOnEvent->Param.Note.ID );
115 iliev 2015 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
116     Delay = itNoteOnEvent->FragmentPos();
117     itTriggerEvent = itNoteOnEvent;
118     itKillEvent = Pool<Event>::Iterator();
119 schoenebeck 2879 MidiKeyBase* pKeyInfo = GetMidiKeyInfo(MIDIKey());
120 iliev 2015
121 persson 2114 pGroupEvents = iKeyGroup ? pEngineChannel->ActiveKeyGroups[iKeyGroup] : 0;
122    
123 iliev 2015 SmplInfo = GetSampleInfo();
124     RgnInfo = GetRegionInfo();
125     InstrInfo = GetInstrumentInfo();
126 iliev 2205
127 persson 2382 MIDIPan = CalculatePan(pEngineChannel->iLastPanRequest);
128    
129 iliev 2205 AboutToTrigger();
130 iliev 2015
131     // calculate volume
132 schoenebeck 3214 const double velocityAttenuation = GetVelocityAttenuation(MIDIVelocity());
133 schoenebeck 2121 float volume = CalculateVolume(velocityAttenuation) * pKeyInfo->Volume;
134 persson 2032 if (volume <= 0) return -1;
135 iliev 2015
136     // select channel mode (mono or stereo)
137     SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, SmplInfo.ChannelCount == 2);
138     // select bit depth (16 or 24)
139     SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, SmplInfo.BitDepth == 24);
140    
141     // get starting crossfade volume level
142 schoenebeck 3214 float crossfadeVolume = CalculateCrossfadeVolume(MIDIVelocity());
143 iliev 2015
144 persson 2382 VolumeLeft = volume * pKeyInfo->PanLeft;
145     VolumeRight = volume * pKeyInfo->PanRight;
146 iliev 2015
147 schoenebeck 2963 // this rate is used for rather mellow volume fades
148     const float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
149     // this rate is used for very fast volume fades
150 schoenebeck 3188 const float quickRampRate = RTMath::Min(subfragmentRate, GetEngine()->SampleRate * 0.001f /* approx. 13ms */);
151 iliev 2015 CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
152 schoenebeck 2963
153 iliev 2015 VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
154 schoenebeck 3246 NoteVolume.setCurveOnly(pNote ? pNote->Override.VolumeCurve : DEFAULT_FADE_CURVE);
155 schoenebeck 3188 NoteVolume.setCurrentValue(pNote ? pNote->Override.Volume : 1.f);
156     NoteVolume.setDefaultDuration(pNote ? pNote->Override.VolumeTime : DEFAULT_NOTE_VOLUME_TIME_S);
157 iliev 2015
158     // Check if the sample needs disk streaming or is too short for that
159     long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
160     DiskVoice = cachedsamples < SmplInfo.TotalFrameCount;
161    
162 iliev 2216 SetSampleStartOffset();
163    
164 iliev 2015 if (DiskVoice) { // voice to be streamed from disk
165     if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
166     MaxRAMPos = cachedsamples - (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / SmplInfo.ChannelCount; //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)
167     } else {
168     // The cache is too small to fit a max sample buffer.
169     // Setting MaxRAMPos to 0 will probably cause a click
170     // in the audio, but it's better than not handling
171     // this case at all, which would have caused the
172     // unsigned MaxRAMPos to be set to a negative number.
173     MaxRAMPos = 0;
174     }
175    
176     // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
177     RAMLoop = (SmplInfo.HasLoops && (SmplInfo.LoopStart + SmplInfo.LoopLength) <= MaxRAMPos);
178    
179     if (OrderNewStream()) return -1;
180 persson 2837 dmsg(4,("Disk voice launched (cached samples: %ld, total Samples: %d, MaxRAMPos: %lu, RAMLooping: %s)\n", cachedsamples, SmplInfo.TotalFrameCount, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
181 iliev 2015 }
182     else { // RAM only voice
183     MaxRAMPos = cachedsamples;
184     RAMLoop = (SmplInfo.HasLoops);
185     dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
186     }
187     if (RAMLoop) {
188     loop.uiTotalCycles = SmplInfo.LoopPlayCount;
189     loop.uiCyclesLeft = SmplInfo.LoopPlayCount;
190     loop.uiStart = SmplInfo.LoopStart;
191     loop.uiEnd = SmplInfo.LoopStart + SmplInfo.LoopLength;
192     loop.uiSize = SmplInfo.LoopLength;
193     }
194    
195     Pitch = CalculatePitchInfo(PitchBend);
196 schoenebeck 3246 NotePitch.setCurveOnly(pNote ? pNote->Override.PitchCurve : DEFAULT_FADE_CURVE);
197 schoenebeck 3188 NotePitch.setCurrentValue(pNote ? pNote->Override.Pitch : 1.0f);
198     NotePitch.setDefaultDuration(pNote ? pNote->Override.PitchTime : DEFAULT_NOTE_PITCH_TIME_S);
199 schoenebeck 2935 NoteCutoff = (pNote) ? pNote->Override.Cutoff : 1.0f;
200     NoteResonance = (pNote) ? pNote->Override.Resonance : 1.0f;
201 iliev 2015
202     // the length of the decay and release curves are dependent on the velocity
203 schoenebeck 3214 const double velrelease = 1 / GetVelocityRelease(MIDIVelocity());
204 iliev 2015
205 iliev 2217 if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
206 iliev 2015 // get current value of EG1 controller
207 schoenebeck 3214 double eg1controllervalue = GetEG1ControllerValue(MIDIVelocity());
208 iliev 2015
209     // calculate influence of EG1 controller on EG1's parameters
210     EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);
211    
212 schoenebeck 2953 if (pNote) {
213     egInfo.Attack *= pNote->Override.Attack;
214     egInfo.Decay *= pNote->Override.Decay;
215     egInfo.Release *= pNote->Override.Release;
216     }
217    
218 schoenebeck 3214 TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, MIDIVelocity());
219 iliev 2205 } else {
220 iliev 2217 pSignalUnitRack->Trigger();
221 iliev 2015 }
222    
223 schoenebeck 2931 const uint8_t pan = (pSignalUnitRack) ? pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan) : MIDIPan;
224     NotePanLeft = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan, 0 /*left*/ ) : 1.f;
225     NotePanRight = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan, 1 /*right*/) : 1.f;
226     PanLeftSmoother.trigger(
227     AbstractEngine::PanCurve[128 - pan] * NotePanLeft,
228 schoenebeck 2963 quickRampRate //NOTE: maybe we should have 2 separate pan smoothers, one for MIDI CC10 (with slow rate) and one for instrument script change_pan() calls (with fast rate)
229 schoenebeck 2931 );
230     PanRightSmoother.trigger(
231     AbstractEngine::PanCurve[pan] * NotePanRight,
232 schoenebeck 2963 quickRampRate //NOTE: maybe we should have 2 separate pan smoothers, one for MIDI CC10 (with slow rate) and one for instrument script change_pan() calls (with fast rate)
233 schoenebeck 2931 );
234 persson 2382
235 iliev 2015 #ifdef CONFIG_INTERPOLATE_VOLUME
236     // setup initial volume in synthesis parameters
237     #ifdef CONFIG_PROCESS_MUTED_CHANNELS
238     if (pEngineChannel->GetMute()) {
239     finalSynthesisParameters.fFinalVolumeLeft = 0;
240     finalSynthesisParameters.fFinalVolumeRight = 0;
241     }
242     else
243     #else
244     {
245 iliev 2205 float finalVolume;
246 iliev 2217 if (pSignalUnitRack == NULL) {
247 iliev 2205 finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();
248     } else {
249 iliev 2217 finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pSignalUnitRack->GetEndpointUnit()->GetVolume();
250 iliev 2205 }
251 iliev 2015
252 persson 2382 finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * PanLeftSmoother.render();
253     finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * PanRightSmoother.render();
254 iliev 2015 }
255     #endif
256     #endif
257    
258 iliev 2217 if (pSignalUnitRack == NULL) {
259 iliev 2205 // setup EG 2 (VCF Cutoff EG)
260     {
261     // get current value of EG2 controller
262 schoenebeck 3214 double eg2controllervalue = GetEG2ControllerValue(MIDIVelocity());
263 iliev 2015
264 iliev 2205 // calculate influence of EG2 controller on EG2's parameters
265     EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);
266 iliev 2015
267 schoenebeck 3214 TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, MIDIVelocity());
268 iliev 2205 }
269 iliev 2015
270    
271 iliev 2205 // setup EG 3 (VCO EG)
272     {
273     // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
274     bool bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
275     float eg3depth = (bPortamento)
276 schoenebeck 2879 ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey()) * 100)
277 iliev 2205 : RTMath::CentsToFreqRatio(RgnInfo.EG3Depth);
278     float eg3time = (bPortamento)
279     ? pEngineChannel->PortamentoTime
280     : RgnInfo.EG3Attack;
281     EG3.trigger(eg3depth, eg3time, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
282     dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
283     }
284 iliev 2015
285    
286 iliev 2205 // setup LFO 1 (VCA LFO)
287     InitLFO1();
288     // setup LFO 2 (VCF Cutoff LFO)
289     InitLFO2();
290     // setup LFO 3 (VCO LFO)
291     InitLFO3();
292     }
293 iliev 2015
294    
295     #if CONFIG_FORCE_FILTER
296     const bool bUseFilter = true;
297     #else // use filter only if instrument file told so
298     const bool bUseFilter = RgnInfo.VCFEnabled;
299     #endif // CONFIG_FORCE_FILTER
300     SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
301     if (bUseFilter) {
302     #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
303     VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
304     #else // use the one defined in the instrument file
305     VCFCutoffCtrl.controller = GetVCFCutoffCtrl();
306     #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
307    
308     #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
309     VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
310     #else // use the one defined in the instrument file
311     VCFResonanceCtrl.controller = GetVCFResonanceCtrl();
312     #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
313    
314     #ifndef CONFIG_OVERRIDE_FILTER_TYPE
315     finalSynthesisParameters.filterLeft.SetType(RgnInfo.VCFType);
316     finalSynthesisParameters.filterRight.SetType(RgnInfo.VCFType);
317     #else // override filter type
318     finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
319     finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
320     #endif // CONFIG_OVERRIDE_FILTER_TYPE
321    
322     VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
323     VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
324    
325     // calculate cutoff frequency
326 schoenebeck 3214 CutoffBase = CalculateCutoffBase(MIDIVelocity());
327 iliev 2015
328     VCFCutoffCtrl.fvalue = CalculateFinalCutoff(CutoffBase);
329    
330     // calculate resonance
331     float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : RgnInfo.VCFResonance);
332     VCFResonanceCtrl.fvalue = resonance;
333     } else {
334     VCFCutoffCtrl.controller = 0;
335     VCFResonanceCtrl.controller = 0;
336     }
337 iliev 2299
338     const bool bEq =
339     pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
340 iliev 2015
341 iliev 2299 if (bEq) {
342     pEq->GetInChannelLeft()->Clear();
343     pEq->GetInChannelRight()->Clear();
344     pEq->RenderAudio(GetEngine()->pAudioOutputDevice->MaxSamplesPerCycle());
345     }
346    
347 iliev 2015 return 0; // success
348     }
349 iliev 2216
350     void AbstractVoice::SetSampleStartOffset() {
351 schoenebeck 3251 double pos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample
352    
353     // if another sample playback start position was requested by instrument
354     // script (built-in script function play_note())
355     if (pNote && pNote->Override.SampleOffset >= 0) {
356     double overridePos =
357     double(SmplInfo.SampleRate) * double(pNote->Override.SampleOffset) / 1000000.0;
358     if (overridePos < SmplInfo.TotalFrameCount)
359     pos = overridePos;
360     }
361    
362     finalSynthesisParameters.dPos = pos;
363     Pos = pos;
364 iliev 2216 }
365 iliev 2015
366     /**
367     * Synthesizes the current audio fragment for this voice.
368     *
369     * @param Samples - number of sample points to be rendered in this audio
370     * fragment cycle
371     * @param pSrc - pointer to input sample data
372     * @param Skip - number of sample points to skip in output buffer
373     */
374     void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
375 iliev 2297 bool delay = false; // Whether the voice playback should be delayed for this call
376    
377     if (pSignalUnitRack != NULL) {
378     uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
379     if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
380     if (delaySteps >= Samples) {
381     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
382     delay = true;
383     } else {
384     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
385     Samples -= delaySteps;
386     Skip += delaySteps;
387     }
388     }
389     }
390    
391 iliev 2015 AbstractEngineChannel* pChannel = pEngineChannel;
392 schoenebeck 2879 MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey());
393 iliev 2015
394 schoenebeck 2121 const bool bVoiceRequiresDedicatedRouting =
395     pEngineChannel->GetFxSendCount() > 0 &&
396     (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
397 iliev 2296
398     const bool bEq =
399 iliev 2298 pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
400 schoenebeck 2121
401 iliev 2296 if (bEq) {
402 iliev 2298 pEq->GetInChannelLeft()->Clear();
403     pEq->GetInChannelRight()->Clear();
404     finalSynthesisParameters.pOutLeft = &pEq->GetInChannelLeft()->Buffer()[Skip];
405     finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
406     pSignalUnitRack->UpdateEqSettings(pEq);
407 iliev 2296 } else if (bVoiceRequiresDedicatedRouting) {
408 schoenebeck 2121 finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
409     finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
410     } else {
411     finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
412     finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
413     }
414     finalSynthesisParameters.pSrc = pSrc;
415    
416 iliev 2015 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
417     RTList<Event>::Iterator itNoteEvent;
418 schoenebeck 2879 GetFirstEventOnKey(HostKey(), itNoteEvent);
419 iliev 2015
420 persson 2114 RTList<Event>::Iterator itGroupEvent;
421 persson 2352 if (pGroupEvents && !Orphan) itGroupEvent = pGroupEvents->first();
422 persson 2114
423 iliev 2015 if (itTriggerEvent) { // skip events that happened before this voice was triggered
424     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
425 persson 2114 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
426    
427 iliev 2015 // we can't simply compare the timestamp here, because note events
428     // might happen on the same time stamp, so we have to deal on the
429     // actual sequence the note events arrived instead (see bug #112)
430     for (; itNoteEvent; ++itNoteEvent) {
431     if (itTriggerEvent == itNoteEvent) {
432     ++itNoteEvent;
433     break;
434     }
435     }
436     }
437    
438 schoenebeck 3054 uint killPos = 0;
439 iliev 2015 if (itKillEvent) {
440     int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
441     if (maxFadeOutPos < 0) {
442     // There's not enough space in buffer to do a fade out
443     // from max volume (this can only happen for audio
444     // drivers that use Samples < MaxSamplesPerCycle).
445     // End the EG1 here, at pos 0, with a shorter max fade
446     // out time.
447 iliev 2217 if (pSignalUnitRack == NULL) {
448 iliev 2205 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
449     } else {
450 persson 2327 pSignalUnitRack->EnterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
451 iliev 2205 }
452 iliev 2015 itKillEvent = Pool<Event>::Iterator();
453     } else {
454     killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
455     }
456     }
457    
458     uint i = Skip;
459     while (i < Samples) {
460     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
461    
462     // initialize all final synthesis parameters
463     fFinalCutoff = VCFCutoffCtrl.fvalue;
464     fFinalResonance = VCFResonanceCtrl.fvalue;
465    
466 schoenebeck 2559 // process MIDI control change, aftertouch and pitchbend events for this subfragment
467 iliev 2015 processCCEvents(itCCEvent, iSubFragmentEnd);
468 iliev 2219 uint8_t pan = MIDIPan;
469 persson 2382 if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
470 iliev 2015
471 schoenebeck 2931 PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan] * NotePanLeft);
472     PanRightSmoother.update(AbstractEngine::PanCurve[pan] * NotePanRight);
473    
474 schoenebeck 3188 finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend * NotePitch.render();
475 schoenebeck 2931
476 schoenebeck 3188 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render() * NoteVolume.render();
477 iliev 2015 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
478     if (pChannel->GetMute()) fFinalVolume = 0;
479     #endif
480    
481     // process transition events (note on, note off & sustain pedal)
482     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
483 persson 2114 processGroupEvents(itGroupEvent, iSubFragmentEnd);
484 iliev 2297
485 iliev 2217 if (pSignalUnitRack == NULL) {
486 iliev 2205 // if the voice was killed in this subfragment, or if the
487     // filter EG is finished, switch EG1 to fade out stage
488     if ((itKillEvent && killPos <= iSubFragmentEnd) ||
489     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
490     pEG2->getSegmentType() == EG::segment_end)) {
491     pEG1->enterFadeOutStage();
492     itKillEvent = Pool<Event>::Iterator();
493     }
494 iliev 2015
495 iliev 2205 // process envelope generators
496     switch (pEG1->getSegmentType()) {
497     case EG::segment_lin:
498     fFinalVolume *= pEG1->processLin();
499     break;
500     case EG::segment_exp:
501     fFinalVolume *= pEG1->processExp();
502     break;
503     case EG::segment_end:
504     fFinalVolume *= pEG1->getLevel();
505     break; // noop
506     case EG::segment_pow:
507     fFinalVolume *= pEG1->processPow();
508     break;
509     }
510     switch (pEG2->getSegmentType()) {
511     case EG::segment_lin:
512     fFinalCutoff *= pEG2->processLin();
513     break;
514     case EG::segment_exp:
515     fFinalCutoff *= pEG2->processExp();
516     break;
517     case EG::segment_end:
518     fFinalCutoff *= pEG2->getLevel();
519     break; // noop
520     case EG::segment_pow:
521     fFinalCutoff *= pEG2->processPow();
522     break;
523     }
524     if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
525 iliev 2015
526 iliev 2205 // process low frequency oscillators
527     if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
528 persson 2673 if (bLFO2Enabled) fFinalCutoff *= (1.0f - pLFO2->render());
529 iliev 2205 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
530     } else {
531 iliev 2322 // if the voice was killed in this subfragment, enter fade out stage
532     if (itKillEvent && killPos <= iSubFragmentEnd) {
533     pSignalUnitRack->EnterFadeOutStage();
534     itKillEvent = Pool<Event>::Iterator();
535     }
536    
537     // if the filter EG is finished, switch EG1 to fade out stage
538     /*if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
539     pEG2->getSegmentType() == EG::segment_end) {
540 iliev 2205 pEG1->enterFadeOutStage();
541     itKillEvent = Pool<Event>::Iterator();
542     }*/
543     // TODO: ^^^
544 iliev 2015
545 iliev 2217 fFinalVolume *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
546     fFinalCutoff = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
547     fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
548 iliev 2205
549     finalSynthesisParameters.fFinalPitch =
550 iliev 2217 pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
551 iliev 2205
552     }
553 schoenebeck 2935
554     fFinalCutoff *= NoteCutoff;
555     fFinalResonance *= NoteResonance;
556    
557 iliev 2015 // limit the pitch so we don't read outside the buffer
558     finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
559    
560     // if filter enabled then update filter coefficients
561     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
562     finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
563     finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
564     }
565    
566     // do we need resampling?
567     const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
568     const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
569     const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
570     finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
571     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
572    
573     // prepare final synthesis parameters structure
574     finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
575     #ifdef CONFIG_INTERPOLATE_VOLUME
576     finalSynthesisParameters.fFinalVolumeDeltaLeft =
577     (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
578     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
579     finalSynthesisParameters.fFinalVolumeDeltaRight =
580     (fFinalVolume * VolumeRight * PanRightSmoother.render() -
581     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
582     #else
583     finalSynthesisParameters.fFinalVolumeLeft =
584     fFinalVolume * VolumeLeft * PanLeftSmoother.render();
585     finalSynthesisParameters.fFinalVolumeRight =
586     fFinalVolume * VolumeRight * PanRightSmoother.render();
587     #endif
588     // render audio for one subfragment
589 iliev 2297 if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
590 iliev 2015
591 iliev 2217 if (pSignalUnitRack == NULL) {
592 iliev 2205 // stop the rendering if volume EG is finished
593     if (pEG1->getSegmentType() == EG::segment_end) break;
594     } else {
595     // stop the rendering if the endpoint unit is not active
596 iliev 2217 if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
597 iliev 2205 }
598 iliev 2015
599     const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
600    
601 iliev 2217 if (pSignalUnitRack == NULL) {
602 iliev 2205 // increment envelopes' positions
603     if (pEG1->active()) {
604 iliev 2015
605 iliev 2205 // 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
606     if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
607     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
608     }
609    
610     pEG1->increment(1);
611     if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
612 iliev 2015 }
613 iliev 2205 if (pEG2->active()) {
614     pEG2->increment(1);
615     if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
616     }
617     EG3.increment(1);
618     if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
619     } else {
620     // 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
621     /*if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
622     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
623     }*/
624     // TODO: ^^^
625    
626 iliev 2297 if (!delay) pSignalUnitRack->Increment();
627 iliev 2015 }
628    
629     Pos = newPos;
630     i = iSubFragmentEnd;
631     }
632 iliev 2297
633     if (delay) return;
634 schoenebeck 2121
635     if (bVoiceRequiresDedicatedRouting) {
636 iliev 2296 if (bEq) {
637 iliev 2298 pEq->RenderAudio(Samples);
638     pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
639     pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
640 iliev 2296 }
641 schoenebeck 2121 optional<float> effectSendLevels[2] = {
642     pMidiKeyInfo->ReverbSend,
643     pMidiKeyInfo->ChorusSend
644     };
645     GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
646 iliev 2296 } else if (bEq) {
647 iliev 2298 pEq->RenderAudio(Samples);
648     pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
649     pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
650 schoenebeck 2121 }
651 iliev 2015 }
652 persson 2045
653 iliev 2015 /**
654 schoenebeck 2559 * Process given list of MIDI control change, aftertouch and pitch bend
655     * events for the given time.
656 iliev 2015 *
657     * @param itEvent - iterator pointing to the next event to be processed
658     * @param End - youngest time stamp where processing should be stopped
659     */
660     void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
661     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
662 schoenebeck 3016 if ((itEvent->Type == Event::type_control_change || itEvent->Type == Event::type_channel_pressure)
663 schoenebeck 3017 && itEvent->Param.CC.Controller) // if (valid) MIDI control change event
664     {
665 iliev 2015 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
666     ProcessCutoffEvent(itEvent);
667     }
668     if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
669     processResonanceEvent(itEvent);
670     }
671 schoenebeck 3017 if (itEvent->Param.CC.Controller == CTRL_TABLE_IDX_AFTERTOUCH ||
672     itEvent->Type == Event::type_channel_pressure)
673     {
674     ProcessChannelPressureEvent(itEvent);
675     }
676 iliev 2217 if (pSignalUnitRack == NULL) {
677 iliev 2205 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
678 schoenebeck 3118 pLFO1->updateByMIDICtrlValue(itEvent->Param.CC.Value);
679 iliev 2205 }
680     if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
681 schoenebeck 3118 pLFO2->updateByMIDICtrlValue(itEvent->Param.CC.Value);
682 iliev 2205 }
683     if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
684 schoenebeck 3118 pLFO3->updateByMIDICtrlValue(itEvent->Param.CC.Value);
685 iliev 2205 }
686 iliev 2015 }
687     if (itEvent->Param.CC.Controller == 7) { // volume
688     VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
689     } else if (itEvent->Param.CC.Controller == 10) { // panpot
690 persson 2382 MIDIPan = CalculatePan(itEvent->Param.CC.Value);
691 iliev 2015 }
692     } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
693     processPitchEvent(itEvent);
694 schoenebeck 2559 } else if (itEvent->Type == Event::type_note_pressure) {
695     ProcessPolyphonicKeyPressureEvent(itEvent);
696 iliev 2015 }
697    
698     ProcessCCEvent(itEvent);
699 iliev 2217 if (pSignalUnitRack != NULL) {
700     pSignalUnitRack->ProcessCCEvent(itEvent);
701 iliev 2205 }
702 iliev 2015 }
703     }
704    
705     void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
706     Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
707     }
708    
709     void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
710     // convert absolute controller value to differential
711     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
712     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
713     const float resonancedelta = (float) ctrldelta;
714     fFinalResonance += resonancedelta;
715     // needed for initialization of parameter
716     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
717     }
718    
719     /**
720 schoenebeck 2931 * Process given list of MIDI note on, note off, sustain pedal events and
721     * note synthesis parameter events for the given time.
722 iliev 2015 *
723     * @param itEvent - iterator pointing to the next event to be processed
724     * @param End - youngest time stamp where processing should be stopped
725     */
726     void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
727     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
728 persson 2115 // some voice types ignore note off
729     if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
730 schoenebeck 2938 if (itEvent->Type == Event::type_release_key) {
731 persson 2114 EnterReleaseStage();
732 schoenebeck 2938 } else if (itEvent->Type == Event::type_cancel_release_key) {
733 iliev 2217 if (pSignalUnitRack == NULL) {
734 iliev 2205 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
735     pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
736     } else {
737 iliev 2217 pSignalUnitRack->CancelRelease();
738 iliev 2205 }
739 persson 2114 }
740 iliev 2015 }
741 schoenebeck 2938 // process stop-note events (caused by built-in instrument script function note_off())
742     if (itEvent->Type == Event::type_release_note && pNote &&
743     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
744     {
745     EnterReleaseStage();
746     }
747 schoenebeck 3188 // process kill-note events (caused by built-in instrument script function fade_out())
748     if (itEvent->Type == Event::type_kill_note && pNote &&
749     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
750     {
751     Kill(itEvent);
752     }
753 schoenebeck 2931 // process synthesis parameter events (caused by built-in realt-time instrument script functions)
754     if (itEvent->Type == Event::type_note_synth_param && pNote &&
755     pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
756     {
757     switch (itEvent->Param.NoteSynthParam.Type) {
758     case Event::synth_param_volume:
759 schoenebeck 3188 NoteVolume.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
760 schoenebeck 2931 break;
761 schoenebeck 3188 case Event::synth_param_volume_time:
762     NoteVolume.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
763     break;
764 schoenebeck 3246 case Event::synth_param_volume_curve:
765     NoteVolume.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
766     break;
767 schoenebeck 2931 case Event::synth_param_pitch:
768 schoenebeck 3188 NotePitch.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
769 schoenebeck 2931 break;
770 schoenebeck 3188 case Event::synth_param_pitch_time:
771     NotePitch.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
772     break;
773 schoenebeck 3246 case Event::synth_param_pitch_curve:
774     NotePitch.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
775     break;
776 schoenebeck 2931 case Event::synth_param_pan:
777     NotePanLeft = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);
778     NotePanRight = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 1 /*right*/);
779     break;
780 schoenebeck 2935 case Event::synth_param_cutoff:
781     NoteCutoff = itEvent->Param.NoteSynthParam.AbsValue;
782     break;
783     case Event::synth_param_resonance:
784     NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;
785     break;
786 schoenebeck 3118 case Event::synth_param_amp_lfo_depth:
787     pLFO1->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
788     break;
789     case Event::synth_param_amp_lfo_freq:
790     pLFO1->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
791     break;
792     case Event::synth_param_pitch_lfo_depth:
793     pLFO3->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
794     break;
795     case Event::synth_param_pitch_lfo_freq:
796     pLFO3->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
797     break;
798 schoenebeck 3034
799     case Event::synth_param_attack:
800     case Event::synth_param_decay:
801     case Event::synth_param_release:
802     break; // noop
803 schoenebeck 2931 }
804     }
805 iliev 2015 }
806     }
807    
808 persson 2114 /**
809     * Process given list of events aimed at all voices in a key group.
810     *
811     * @param itEvent - iterator pointing to the next event to be processed
812     * @param End - youngest time stamp where processing should be stopped
813     */
814     void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
815     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
816     ProcessGroupEvent(itEvent);
817     }
818     }
819    
820 iliev 2015 /** @brief Update current portamento position.
821     *
822     * Will be called when portamento mode is enabled to get the final
823     * portamento position of this active voice from where the next voice(s)
824     * might continue to slide on.
825     *
826     * @param itNoteOffEvent - event which causes this voice to die soon
827     */
828     void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
829 iliev 2217 if (pSignalUnitRack == NULL) {
830 iliev 2205 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
831 schoenebeck 2879 pEngineChannel->PortamentoPos = (float) MIDIKey() + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
832 iliev 2205 } else {
833     // TODO:
834     }
835 iliev 2015 }
836    
837     /**
838     * Kill the voice in regular sense. Let the voice render audio until
839     * the kill event actually occured and then fade down the volume level
840     * very quickly and let the voice die finally. Unlike a normal release
841     * of a voice, a kill process cannot be cancalled and is therefore
842     * usually used for voice stealing and key group conflicts.
843     *
844     * @param itKillEvent - event which caused the voice to be killed
845     */
846     void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
847     #if CONFIG_DEVMODE
848     if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
849     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
850     #endif // CONFIG_DEVMODE
851    
852     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
853     this->itKillEvent = itKillEvent;
854     }
855    
856     Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
857     PitchInfo pitch;
858 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
859 iliev 2015
860     // GSt behaviour: maximum transpose up is 40 semitones. If
861     // MIDI key is more than 40 semitones above unity note,
862     // the transpose is not done.
863 schoenebeck 2879 if (!SmplInfo.Unpitched && (MIDIKey() - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
864 iliev 2015
865     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
866     pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
867     pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
868    
869     return pitch;
870     }
871 schoenebeck 2448
872     void AbstractVoice::onScaleTuningChanged() {
873     PitchInfo pitch = this->Pitch;
874 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
875 schoenebeck 2448
876     // GSt behaviour: maximum transpose up is 40 semitones. If
877     // MIDI key is more than 40 semitones above unity note,
878     // the transpose is not done.
879 schoenebeck 2879 if (!SmplInfo.Unpitched && (MIDIKey() - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
880 schoenebeck 2448
881     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
882     this->Pitch = pitch;
883     }
884 iliev 2015
885     double AbstractVoice::CalculateVolume(double velocityAttenuation) {
886     // For 16 bit samples, we downscale by 32768 to convert from
887     // int16 value range to DSP value range (which is
888     // -1.0..1.0). For 24 bit, we downscale from int32.
889     float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
890    
891     volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
892    
893     // the volume of release triggered samples depends on note length
894 persson 2115 if (Type & Voice::type_release_trigger) {
895 iliev 2015 float noteLength = float(GetEngine()->FrameTime + Delay -
896 schoenebeck 2879 GetNoteOnTime(MIDIKey()) ) / GetEngine()->SampleRate;
897 iliev 2015
898 persson 2061 volume *= GetReleaseTriggerAttenuation(noteLength);
899 iliev 2015 }
900    
901     return volume;
902     }
903 persson 2061
904     float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
905     return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
906     }
907 persson 2114
908     void AbstractVoice::EnterReleaseStage() {
909 iliev 2217 if (pSignalUnitRack == NULL) {
910 iliev 2205 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
911     pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
912     } else {
913 iliev 2217 pSignalUnitRack->EnterReleaseStage();
914 iliev 2205 }
915 persson 2114 }
916    
917 iliev 2205 bool AbstractVoice::EG1Finished() {
918 iliev 2217 if (pSignalUnitRack == NULL) {
919 iliev 2205 return pEG1->getSegmentType() == EG::segment_end;
920     } else {
921 iliev 2217 return !pSignalUnitRack->GetEndpointUnit()->Active();
922 iliev 2205 }
923     }
924    
925 iliev 2015 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC