/[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 3246 - (hide annotations) (download)
Sun May 28 22:22:56 2017 UTC (6 years, 11 months ago) by schoenebeck
File size: 45313 byte(s)
* NKSP: Implemented built-in script function "change_vol_curve()".
* NKSP: Implemented built-in script function "change_tune_curve()".
* NKSP: Added built-in script constant "$NKSP_LINEAR".
* NKSP: Added built-in script constant "$NKSP_EASE_IN_EASE_OUT".
* Bumped version (2.0.0.svn54).

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     finalSynthesisParameters.dPos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
352     Pos = RgnInfo.SampleStartOffset;
353     }
354 iliev 2015
355     /**
356     * Synthesizes the current audio fragment for this voice.
357     *
358     * @param Samples - number of sample points to be rendered in this audio
359     * fragment cycle
360     * @param pSrc - pointer to input sample data
361     * @param Skip - number of sample points to skip in output buffer
362     */
363     void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
364 iliev 2297 bool delay = false; // Whether the voice playback should be delayed for this call
365    
366     if (pSignalUnitRack != NULL) {
367     uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
368     if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
369     if (delaySteps >= Samples) {
370     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
371     delay = true;
372     } else {
373     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
374     Samples -= delaySteps;
375     Skip += delaySteps;
376     }
377     }
378     }
379    
380 iliev 2015 AbstractEngineChannel* pChannel = pEngineChannel;
381 schoenebeck 2879 MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey());
382 iliev 2015
383 schoenebeck 2121 const bool bVoiceRequiresDedicatedRouting =
384     pEngineChannel->GetFxSendCount() > 0 &&
385     (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
386 iliev 2296
387     const bool bEq =
388 iliev 2298 pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
389 schoenebeck 2121
390 iliev 2296 if (bEq) {
391 iliev 2298 pEq->GetInChannelLeft()->Clear();
392     pEq->GetInChannelRight()->Clear();
393     finalSynthesisParameters.pOutLeft = &pEq->GetInChannelLeft()->Buffer()[Skip];
394     finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
395     pSignalUnitRack->UpdateEqSettings(pEq);
396 iliev 2296 } else if (bVoiceRequiresDedicatedRouting) {
397 schoenebeck 2121 finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
398     finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
399     } else {
400     finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
401     finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
402     }
403     finalSynthesisParameters.pSrc = pSrc;
404    
405 iliev 2015 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
406     RTList<Event>::Iterator itNoteEvent;
407 schoenebeck 2879 GetFirstEventOnKey(HostKey(), itNoteEvent);
408 iliev 2015
409 persson 2114 RTList<Event>::Iterator itGroupEvent;
410 persson 2352 if (pGroupEvents && !Orphan) itGroupEvent = pGroupEvents->first();
411 persson 2114
412 iliev 2015 if (itTriggerEvent) { // skip events that happened before this voice was triggered
413     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
414 persson 2114 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
415    
416 iliev 2015 // we can't simply compare the timestamp here, because note events
417     // might happen on the same time stamp, so we have to deal on the
418     // actual sequence the note events arrived instead (see bug #112)
419     for (; itNoteEvent; ++itNoteEvent) {
420     if (itTriggerEvent == itNoteEvent) {
421     ++itNoteEvent;
422     break;
423     }
424     }
425     }
426    
427 schoenebeck 3054 uint killPos = 0;
428 iliev 2015 if (itKillEvent) {
429     int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
430     if (maxFadeOutPos < 0) {
431     // There's not enough space in buffer to do a fade out
432     // from max volume (this can only happen for audio
433     // drivers that use Samples < MaxSamplesPerCycle).
434     // End the EG1 here, at pos 0, with a shorter max fade
435     // out time.
436 iliev 2217 if (pSignalUnitRack == NULL) {
437 iliev 2205 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
438     } else {
439 persson 2327 pSignalUnitRack->EnterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
440 iliev 2205 }
441 iliev 2015 itKillEvent = Pool<Event>::Iterator();
442     } else {
443     killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
444     }
445     }
446    
447     uint i = Skip;
448     while (i < Samples) {
449     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
450    
451     // initialize all final synthesis parameters
452     fFinalCutoff = VCFCutoffCtrl.fvalue;
453     fFinalResonance = VCFResonanceCtrl.fvalue;
454    
455 schoenebeck 2559 // process MIDI control change, aftertouch and pitchbend events for this subfragment
456 iliev 2015 processCCEvents(itCCEvent, iSubFragmentEnd);
457 iliev 2219 uint8_t pan = MIDIPan;
458 persson 2382 if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
459 iliev 2015
460 schoenebeck 2931 PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan] * NotePanLeft);
461     PanRightSmoother.update(AbstractEngine::PanCurve[pan] * NotePanRight);
462    
463 schoenebeck 3188 finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend * NotePitch.render();
464 schoenebeck 2931
465 schoenebeck 3188 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render() * NoteVolume.render();
466 iliev 2015 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
467     if (pChannel->GetMute()) fFinalVolume = 0;
468     #endif
469    
470     // process transition events (note on, note off & sustain pedal)
471     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
472 persson 2114 processGroupEvents(itGroupEvent, iSubFragmentEnd);
473 iliev 2297
474 iliev 2217 if (pSignalUnitRack == NULL) {
475 iliev 2205 // if the voice was killed in this subfragment, or if the
476     // filter EG is finished, switch EG1 to fade out stage
477     if ((itKillEvent && killPos <= iSubFragmentEnd) ||
478     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
479     pEG2->getSegmentType() == EG::segment_end)) {
480     pEG1->enterFadeOutStage();
481     itKillEvent = Pool<Event>::Iterator();
482     }
483 iliev 2015
484 iliev 2205 // process envelope generators
485     switch (pEG1->getSegmentType()) {
486     case EG::segment_lin:
487     fFinalVolume *= pEG1->processLin();
488     break;
489     case EG::segment_exp:
490     fFinalVolume *= pEG1->processExp();
491     break;
492     case EG::segment_end:
493     fFinalVolume *= pEG1->getLevel();
494     break; // noop
495     case EG::segment_pow:
496     fFinalVolume *= pEG1->processPow();
497     break;
498     }
499     switch (pEG2->getSegmentType()) {
500     case EG::segment_lin:
501     fFinalCutoff *= pEG2->processLin();
502     break;
503     case EG::segment_exp:
504     fFinalCutoff *= pEG2->processExp();
505     break;
506     case EG::segment_end:
507     fFinalCutoff *= pEG2->getLevel();
508     break; // noop
509     case EG::segment_pow:
510     fFinalCutoff *= pEG2->processPow();
511     break;
512     }
513     if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
514 iliev 2015
515 iliev 2205 // process low frequency oscillators
516     if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
517 persson 2673 if (bLFO2Enabled) fFinalCutoff *= (1.0f - pLFO2->render());
518 iliev 2205 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
519     } else {
520 iliev 2322 // if the voice was killed in this subfragment, enter fade out stage
521     if (itKillEvent && killPos <= iSubFragmentEnd) {
522     pSignalUnitRack->EnterFadeOutStage();
523     itKillEvent = Pool<Event>::Iterator();
524     }
525    
526     // if the filter EG is finished, switch EG1 to fade out stage
527     /*if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
528     pEG2->getSegmentType() == EG::segment_end) {
529 iliev 2205 pEG1->enterFadeOutStage();
530     itKillEvent = Pool<Event>::Iterator();
531     }*/
532     // TODO: ^^^
533 iliev 2015
534 iliev 2217 fFinalVolume *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
535     fFinalCutoff = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
536     fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
537 iliev 2205
538     finalSynthesisParameters.fFinalPitch =
539 iliev 2217 pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
540 iliev 2205
541     }
542 schoenebeck 2935
543     fFinalCutoff *= NoteCutoff;
544     fFinalResonance *= NoteResonance;
545    
546 iliev 2015 // limit the pitch so we don't read outside the buffer
547     finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
548    
549     // if filter enabled then update filter coefficients
550     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
551     finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
552     finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
553     }
554    
555     // do we need resampling?
556     const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
557     const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
558     const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
559     finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
560     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
561    
562     // prepare final synthesis parameters structure
563     finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
564     #ifdef CONFIG_INTERPOLATE_VOLUME
565     finalSynthesisParameters.fFinalVolumeDeltaLeft =
566     (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
567     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
568     finalSynthesisParameters.fFinalVolumeDeltaRight =
569     (fFinalVolume * VolumeRight * PanRightSmoother.render() -
570     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
571     #else
572     finalSynthesisParameters.fFinalVolumeLeft =
573     fFinalVolume * VolumeLeft * PanLeftSmoother.render();
574     finalSynthesisParameters.fFinalVolumeRight =
575     fFinalVolume * VolumeRight * PanRightSmoother.render();
576     #endif
577     // render audio for one subfragment
578 iliev 2297 if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
579 iliev 2015
580 iliev 2217 if (pSignalUnitRack == NULL) {
581 iliev 2205 // stop the rendering if volume EG is finished
582     if (pEG1->getSegmentType() == EG::segment_end) break;
583     } else {
584     // stop the rendering if the endpoint unit is not active
585 iliev 2217 if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
586 iliev 2205 }
587 iliev 2015
588     const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
589    
590 iliev 2217 if (pSignalUnitRack == NULL) {
591 iliev 2205 // increment envelopes' positions
592     if (pEG1->active()) {
593 iliev 2015
594 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
595     if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
596     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
597     }
598    
599     pEG1->increment(1);
600     if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
601 iliev 2015 }
602 iliev 2205 if (pEG2->active()) {
603     pEG2->increment(1);
604     if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
605     }
606     EG3.increment(1);
607     if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
608     } else {
609     // 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
610     /*if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
611     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
612     }*/
613     // TODO: ^^^
614    
615 iliev 2297 if (!delay) pSignalUnitRack->Increment();
616 iliev 2015 }
617    
618     Pos = newPos;
619     i = iSubFragmentEnd;
620     }
621 iliev 2297
622     if (delay) return;
623 schoenebeck 2121
624     if (bVoiceRequiresDedicatedRouting) {
625 iliev 2296 if (bEq) {
626 iliev 2298 pEq->RenderAudio(Samples);
627     pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
628     pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
629 iliev 2296 }
630 schoenebeck 2121 optional<float> effectSendLevels[2] = {
631     pMidiKeyInfo->ReverbSend,
632     pMidiKeyInfo->ChorusSend
633     };
634     GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
635 iliev 2296 } else if (bEq) {
636 iliev 2298 pEq->RenderAudio(Samples);
637     pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
638     pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
639 schoenebeck 2121 }
640 iliev 2015 }
641 persson 2045
642 iliev 2015 /**
643 schoenebeck 2559 * Process given list of MIDI control change, aftertouch and pitch bend
644     * events for the given time.
645 iliev 2015 *
646     * @param itEvent - iterator pointing to the next event to be processed
647     * @param End - youngest time stamp where processing should be stopped
648     */
649     void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
650     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
651 schoenebeck 3016 if ((itEvent->Type == Event::type_control_change || itEvent->Type == Event::type_channel_pressure)
652 schoenebeck 3017 && itEvent->Param.CC.Controller) // if (valid) MIDI control change event
653     {
654 iliev 2015 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
655     ProcessCutoffEvent(itEvent);
656     }
657     if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
658     processResonanceEvent(itEvent);
659     }
660 schoenebeck 3017 if (itEvent->Param.CC.Controller == CTRL_TABLE_IDX_AFTERTOUCH ||
661     itEvent->Type == Event::type_channel_pressure)
662     {
663     ProcessChannelPressureEvent(itEvent);
664     }
665 iliev 2217 if (pSignalUnitRack == NULL) {
666 iliev 2205 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
667 schoenebeck 3118 pLFO1->updateByMIDICtrlValue(itEvent->Param.CC.Value);
668 iliev 2205 }
669     if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
670 schoenebeck 3118 pLFO2->updateByMIDICtrlValue(itEvent->Param.CC.Value);
671 iliev 2205 }
672     if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
673 schoenebeck 3118 pLFO3->updateByMIDICtrlValue(itEvent->Param.CC.Value);
674 iliev 2205 }
675 iliev 2015 }
676     if (itEvent->Param.CC.Controller == 7) { // volume
677     VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
678     } else if (itEvent->Param.CC.Controller == 10) { // panpot
679 persson 2382 MIDIPan = CalculatePan(itEvent->Param.CC.Value);
680 iliev 2015 }
681     } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
682     processPitchEvent(itEvent);
683 schoenebeck 2559 } else if (itEvent->Type == Event::type_note_pressure) {
684     ProcessPolyphonicKeyPressureEvent(itEvent);
685 iliev 2015 }
686    
687     ProcessCCEvent(itEvent);
688 iliev 2217 if (pSignalUnitRack != NULL) {
689     pSignalUnitRack->ProcessCCEvent(itEvent);
690 iliev 2205 }
691 iliev 2015 }
692     }
693    
694     void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
695     Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
696     }
697    
698     void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
699     // convert absolute controller value to differential
700     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
701     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
702     const float resonancedelta = (float) ctrldelta;
703     fFinalResonance += resonancedelta;
704     // needed for initialization of parameter
705     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
706     }
707    
708     /**
709 schoenebeck 2931 * Process given list of MIDI note on, note off, sustain pedal events and
710     * note synthesis parameter events for the given time.
711 iliev 2015 *
712     * @param itEvent - iterator pointing to the next event to be processed
713     * @param End - youngest time stamp where processing should be stopped
714     */
715     void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
716     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
717 persson 2115 // some voice types ignore note off
718     if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
719 schoenebeck 2938 if (itEvent->Type == Event::type_release_key) {
720 persson 2114 EnterReleaseStage();
721 schoenebeck 2938 } else if (itEvent->Type == Event::type_cancel_release_key) {
722 iliev 2217 if (pSignalUnitRack == NULL) {
723 iliev 2205 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
724     pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
725     } else {
726 iliev 2217 pSignalUnitRack->CancelRelease();
727 iliev 2205 }
728 persson 2114 }
729 iliev 2015 }
730 schoenebeck 2938 // process stop-note events (caused by built-in instrument script function note_off())
731     if (itEvent->Type == Event::type_release_note && pNote &&
732     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
733     {
734     EnterReleaseStage();
735     }
736 schoenebeck 3188 // process kill-note events (caused by built-in instrument script function fade_out())
737     if (itEvent->Type == Event::type_kill_note && pNote &&
738     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
739     {
740     Kill(itEvent);
741     }
742 schoenebeck 2931 // process synthesis parameter events (caused by built-in realt-time instrument script functions)
743     if (itEvent->Type == Event::type_note_synth_param && pNote &&
744     pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
745     {
746     switch (itEvent->Param.NoteSynthParam.Type) {
747     case Event::synth_param_volume:
748 schoenebeck 3188 NoteVolume.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
749 schoenebeck 2931 break;
750 schoenebeck 3188 case Event::synth_param_volume_time:
751     NoteVolume.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
752     break;
753 schoenebeck 3246 case Event::synth_param_volume_curve:
754     NoteVolume.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
755     break;
756 schoenebeck 2931 case Event::synth_param_pitch:
757 schoenebeck 3188 NotePitch.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
758 schoenebeck 2931 break;
759 schoenebeck 3188 case Event::synth_param_pitch_time:
760     NotePitch.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
761     break;
762 schoenebeck 3246 case Event::synth_param_pitch_curve:
763     NotePitch.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
764     break;
765 schoenebeck 2931 case Event::synth_param_pan:
766     NotePanLeft = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);
767     NotePanRight = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 1 /*right*/);
768     break;
769 schoenebeck 2935 case Event::synth_param_cutoff:
770     NoteCutoff = itEvent->Param.NoteSynthParam.AbsValue;
771     break;
772     case Event::synth_param_resonance:
773     NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;
774     break;
775 schoenebeck 3118 case Event::synth_param_amp_lfo_depth:
776     pLFO1->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
777     break;
778     case Event::synth_param_amp_lfo_freq:
779     pLFO1->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
780     break;
781     case Event::synth_param_pitch_lfo_depth:
782     pLFO3->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
783     break;
784     case Event::synth_param_pitch_lfo_freq:
785     pLFO3->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
786     break;
787 schoenebeck 3034
788     case Event::synth_param_attack:
789     case Event::synth_param_decay:
790     case Event::synth_param_release:
791     break; // noop
792 schoenebeck 2931 }
793     }
794 iliev 2015 }
795     }
796    
797 persson 2114 /**
798     * Process given list of events aimed at all voices in a key group.
799     *
800     * @param itEvent - iterator pointing to the next event to be processed
801     * @param End - youngest time stamp where processing should be stopped
802     */
803     void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
804     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
805     ProcessGroupEvent(itEvent);
806     }
807     }
808    
809 iliev 2015 /** @brief Update current portamento position.
810     *
811     * Will be called when portamento mode is enabled to get the final
812     * portamento position of this active voice from where the next voice(s)
813     * might continue to slide on.
814     *
815     * @param itNoteOffEvent - event which causes this voice to die soon
816     */
817     void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
818 iliev 2217 if (pSignalUnitRack == NULL) {
819 iliev 2205 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
820 schoenebeck 2879 pEngineChannel->PortamentoPos = (float) MIDIKey() + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
821 iliev 2205 } else {
822     // TODO:
823     }
824 iliev 2015 }
825    
826     /**
827     * Kill the voice in regular sense. Let the voice render audio until
828     * the kill event actually occured and then fade down the volume level
829     * very quickly and let the voice die finally. Unlike a normal release
830     * of a voice, a kill process cannot be cancalled and is therefore
831     * usually used for voice stealing and key group conflicts.
832     *
833     * @param itKillEvent - event which caused the voice to be killed
834     */
835     void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
836     #if CONFIG_DEVMODE
837     if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
838     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
839     #endif // CONFIG_DEVMODE
840    
841     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
842     this->itKillEvent = itKillEvent;
843     }
844    
845     Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
846     PitchInfo pitch;
847 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
848 iliev 2015
849     // GSt behaviour: maximum transpose up is 40 semitones. If
850     // MIDI key is more than 40 semitones above unity note,
851     // the transpose is not done.
852 schoenebeck 2879 if (!SmplInfo.Unpitched && (MIDIKey() - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
853 iliev 2015
854     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
855     pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
856     pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
857    
858     return pitch;
859     }
860 schoenebeck 2448
861     void AbstractVoice::onScaleTuningChanged() {
862     PitchInfo pitch = this->Pitch;
863 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
864 schoenebeck 2448
865     // GSt behaviour: maximum transpose up is 40 semitones. If
866     // MIDI key is more than 40 semitones above unity note,
867     // the transpose is not done.
868 schoenebeck 2879 if (!SmplInfo.Unpitched && (MIDIKey() - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
869 schoenebeck 2448
870     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
871     this->Pitch = pitch;
872     }
873 iliev 2015
874     double AbstractVoice::CalculateVolume(double velocityAttenuation) {
875     // For 16 bit samples, we downscale by 32768 to convert from
876     // int16 value range to DSP value range (which is
877     // -1.0..1.0). For 24 bit, we downscale from int32.
878     float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
879    
880     volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
881    
882     // the volume of release triggered samples depends on note length
883 persson 2115 if (Type & Voice::type_release_trigger) {
884 iliev 2015 float noteLength = float(GetEngine()->FrameTime + Delay -
885 schoenebeck 2879 GetNoteOnTime(MIDIKey()) ) / GetEngine()->SampleRate;
886 iliev 2015
887 persson 2061 volume *= GetReleaseTriggerAttenuation(noteLength);
888 iliev 2015 }
889    
890     return volume;
891     }
892 persson 2061
893     float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
894     return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
895     }
896 persson 2114
897     void AbstractVoice::EnterReleaseStage() {
898 iliev 2217 if (pSignalUnitRack == NULL) {
899 iliev 2205 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
900     pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
901     } else {
902 iliev 2217 pSignalUnitRack->EnterReleaseStage();
903 iliev 2205 }
904 persson 2114 }
905    
906 iliev 2205 bool AbstractVoice::EG1Finished() {
907 iliev 2217 if (pSignalUnitRack == NULL) {
908 iliev 2205 return pEG1->getSegmentType() == EG::segment_end;
909     } else {
910 iliev 2217 return !pSignalUnitRack->GetEndpointUnit()->Active();
911 iliev 2205 }
912     }
913    
914 iliev 2015 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC