/[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 3638 - (hide annotations) (download)
Fri Oct 25 17:08:46 2019 UTC (4 years, 5 months ago) by schoenebeck
File size: 50253 byte(s)
Use #if instead of #ifdef for boolean preprocessor configs.

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 schoenebeck 3625 pLFO1 = new LFOClusterUnsigned(1.0f); // amplitude LFO (0..1 range)
33     pLFO2 = new LFOClusterUnsigned(1.0f); // filter LFO (0..1 range)
34     pLFO3 = new LFOClusterSigned(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 3561 NoteVolume.setCurrentValue(pNote ? pNote->Override.Volume.Value : 1.f);
156 schoenebeck 3188 NoteVolume.setDefaultDuration(pNote ? pNote->Override.VolumeTime : DEFAULT_NOTE_VOLUME_TIME_S);
157 schoenebeck 3561 NoteVolume.setFinal(pNote ? pNote->Override.Volume.Final : false);
158 iliev 2015
159     // Check if the sample needs disk streaming or is too short for that
160     long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
161     DiskVoice = cachedsamples < SmplInfo.TotalFrameCount;
162    
163 iliev 2216 SetSampleStartOffset();
164    
165 iliev 2015 if (DiskVoice) { // voice to be streamed from disk
166     if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
167     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)
168     } else {
169     // The cache is too small to fit a max sample buffer.
170     // Setting MaxRAMPos to 0 will probably cause a click
171     // in the audio, but it's better than not handling
172     // this case at all, which would have caused the
173     // unsigned MaxRAMPos to be set to a negative number.
174     MaxRAMPos = 0;
175     }
176    
177     // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
178     RAMLoop = (SmplInfo.HasLoops && (SmplInfo.LoopStart + SmplInfo.LoopLength) <= MaxRAMPos);
179    
180     if (OrderNewStream()) return -1;
181 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"));
182 iliev 2015 }
183     else { // RAM only voice
184     MaxRAMPos = cachedsamples;
185     RAMLoop = (SmplInfo.HasLoops);
186     dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
187     }
188     if (RAMLoop) {
189     loop.uiTotalCycles = SmplInfo.LoopPlayCount;
190     loop.uiCyclesLeft = SmplInfo.LoopPlayCount;
191     loop.uiStart = SmplInfo.LoopStart;
192     loop.uiEnd = SmplInfo.LoopStart + SmplInfo.LoopLength;
193     loop.uiSize = SmplInfo.LoopLength;
194     }
195    
196     Pitch = CalculatePitchInfo(PitchBend);
197 schoenebeck 3246 NotePitch.setCurveOnly(pNote ? pNote->Override.PitchCurve : DEFAULT_FADE_CURVE);
198 schoenebeck 3561 NotePitch.setCurrentValue(pNote ? pNote->Override.Pitch.Value : 1.0f);
199     NotePitch.setFinal(pNote ? pNote->Override.Pitch.Final : false);
200 schoenebeck 3188 NotePitch.setDefaultDuration(pNote ? pNote->Override.PitchTime : DEFAULT_NOTE_PITCH_TIME_S);
201 schoenebeck 3561 NoteCutoff.Value = (pNote) ? pNote->Override.Cutoff.Value : 1.0f;
202     NoteCutoff.Final = (pNote) ? pNote->Override.Cutoff.isFinal() : false;
203     NoteResonance.Value = (pNote) ? pNote->Override.Resonance.Value : 1.0f;
204     NoteResonance.Final = (pNote) ? pNote->Override.Resonance.Final : false;
205 iliev 2015
206     // the length of the decay and release curves are dependent on the velocity
207 schoenebeck 3214 const double velrelease = 1 / GetVelocityRelease(MIDIVelocity());
208 iliev 2015
209 iliev 2217 if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
210 iliev 2015 // get current value of EG1 controller
211 schoenebeck 3214 double eg1controllervalue = GetEG1ControllerValue(MIDIVelocity());
212 iliev 2015
213     // calculate influence of EG1 controller on EG1's parameters
214     EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);
215    
216 schoenebeck 2953 if (pNote) {
217 schoenebeck 3561 pNote->Override.Attack.applyTo(egInfo.Attack);
218     pNote->Override.Decay.applyTo(egInfo.Decay);
219     pNote->Override.Release.applyTo(egInfo.Release);
220 schoenebeck 2953 }
221    
222 schoenebeck 3214 TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, MIDIVelocity());
223 iliev 2205 } else {
224 iliev 2217 pSignalUnitRack->Trigger();
225 iliev 2015 }
226    
227 schoenebeck 2931 const uint8_t pan = (pSignalUnitRack) ? pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan) : MIDIPan;
228 schoenebeck 3335 for (int c = 0; c < 2; ++c) {
229 schoenebeck 3561 float value = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan.Value, c) : 1.f;
230 schoenebeck 3335 NotePan[c].setCurveOnly(pNote ? pNote->Override.PanCurve : DEFAULT_FADE_CURVE);
231     NotePan[c].setCurrentValue(value);
232 schoenebeck 3561 NotePan[c].setFinal(pNote ? pNote->Override.Pan.Final : false);
233 schoenebeck 3335 NotePan[c].setDefaultDuration(pNote ? pNote->Override.PanTime : DEFAULT_NOTE_PAN_TIME_S);
234     }
235    
236 schoenebeck 2931 PanLeftSmoother.trigger(
237 schoenebeck 3335 AbstractEngine::PanCurve[128 - pan],
238 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)
239 schoenebeck 2931 );
240     PanRightSmoother.trigger(
241 schoenebeck 3335 AbstractEngine::PanCurve[pan],
242 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)
243 schoenebeck 2931 );
244 persson 2382
245 schoenebeck 3638 #if CONFIG_INTERPOLATE_VOLUME
246 iliev 2015 // setup initial volume in synthesis parameters
247 schoenebeck 3638 #if CONFIG_PROCESS_MUTED_CHANNELS
248 iliev 2015 if (pEngineChannel->GetMute()) {
249     finalSynthesisParameters.fFinalVolumeLeft = 0;
250     finalSynthesisParameters.fFinalVolumeRight = 0;
251     }
252     else
253     #else
254     {
255 schoenebeck 3561 float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume;
256     float fModVolume;
257 iliev 2217 if (pSignalUnitRack == NULL) {
258 schoenebeck 3561 fModVolume = pEG1->getLevel();
259 iliev 2205 } else {
260 schoenebeck 3561 fModVolume = pSignalUnitRack->GetEndpointUnit()->GetVolume();
261 iliev 2205 }
262 schoenebeck 3564 NoteVolume.applyCurrentValueTo(fModVolume);
263 schoenebeck 3561 finalVolume *= fModVolume;
264 iliev 2015
265 schoenebeck 3561 float panL = PanLeftSmoother.render();
266     float panR = PanRightSmoother.render();
267 schoenebeck 3564 NotePan[0].applyCurrentValueTo(panL);
268     NotePan[1].applyCurrentValueTo(panR);
269 schoenebeck 3561
270     finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * panL;
271     finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * panR;
272 iliev 2015 }
273     #endif
274     #endif
275    
276 iliev 2217 if (pSignalUnitRack == NULL) {
277 iliev 2205 // setup EG 2 (VCF Cutoff EG)
278     {
279     // get current value of EG2 controller
280 schoenebeck 3214 double eg2controllervalue = GetEG2ControllerValue(MIDIVelocity());
281 iliev 2015
282 iliev 2205 // calculate influence of EG2 controller on EG2's parameters
283     EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);
284 iliev 2015
285 schoenebeck 3360 if (pNote) {
286 schoenebeck 3561 pNote->Override.CutoffAttack.applyTo(egInfo.Attack);
287     pNote->Override.CutoffDecay.applyTo(egInfo.Decay);
288     pNote->Override.CutoffRelease.applyTo(egInfo.Release);
289 schoenebeck 3360 }
290    
291 schoenebeck 3214 TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, MIDIVelocity());
292 iliev 2205 }
293 iliev 2015
294    
295 iliev 2205 // setup EG 3 (VCO EG)
296     {
297     // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
298     bool bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
299     float eg3depth = (bPortamento)
300 schoenebeck 2879 ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey()) * 100)
301 iliev 2205 : RTMath::CentsToFreqRatio(RgnInfo.EG3Depth);
302     float eg3time = (bPortamento)
303     ? pEngineChannel->PortamentoTime
304     : RgnInfo.EG3Attack;
305     EG3.trigger(eg3depth, eg3time, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
306     dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
307     }
308 iliev 2015
309    
310 iliev 2205 // setup LFO 1 (VCA LFO)
311     InitLFO1();
312     // setup LFO 2 (VCF Cutoff LFO)
313     InitLFO2();
314     // setup LFO 3 (VCO LFO)
315     InitLFO3();
316     }
317 iliev 2015
318    
319     #if CONFIG_FORCE_FILTER
320     const bool bUseFilter = true;
321     #else // use filter only if instrument file told so
322     const bool bUseFilter = RgnInfo.VCFEnabled;
323     #endif // CONFIG_FORCE_FILTER
324     SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
325     if (bUseFilter) {
326     #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
327     VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
328     #else // use the one defined in the instrument file
329     VCFCutoffCtrl.controller = GetVCFCutoffCtrl();
330     #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
331    
332     #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
333     VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
334     #else // use the one defined in the instrument file
335     VCFResonanceCtrl.controller = GetVCFResonanceCtrl();
336     #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
337    
338     #ifndef CONFIG_OVERRIDE_FILTER_TYPE
339     finalSynthesisParameters.filterLeft.SetType(RgnInfo.VCFType);
340     finalSynthesisParameters.filterRight.SetType(RgnInfo.VCFType);
341     #else // override filter type
342     finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
343     finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
344     #endif // CONFIG_OVERRIDE_FILTER_TYPE
345    
346     VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
347     VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
348    
349     // calculate cutoff frequency
350 schoenebeck 3214 CutoffBase = CalculateCutoffBase(MIDIVelocity());
351 iliev 2015
352     VCFCutoffCtrl.fvalue = CalculateFinalCutoff(CutoffBase);
353    
354     // calculate resonance
355     float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : RgnInfo.VCFResonance);
356     VCFResonanceCtrl.fvalue = resonance;
357     } else {
358     VCFCutoffCtrl.controller = 0;
359     VCFResonanceCtrl.controller = 0;
360     }
361 iliev 2299
362     const bool bEq =
363     pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
364 iliev 2015
365 iliev 2299 if (bEq) {
366     pEq->GetInChannelLeft()->Clear();
367     pEq->GetInChannelRight()->Clear();
368     pEq->RenderAudio(GetEngine()->pAudioOutputDevice->MaxSamplesPerCycle());
369     }
370    
371 iliev 2015 return 0; // success
372     }
373 iliev 2216
374     void AbstractVoice::SetSampleStartOffset() {
375 schoenebeck 3251 double pos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample
376    
377     // if another sample playback start position was requested by instrument
378     // script (built-in script function play_note())
379     if (pNote && pNote->Override.SampleOffset >= 0) {
380     double overridePos =
381     double(SmplInfo.SampleRate) * double(pNote->Override.SampleOffset) / 1000000.0;
382     if (overridePos < SmplInfo.TotalFrameCount)
383     pos = overridePos;
384     }
385    
386     finalSynthesisParameters.dPos = pos;
387     Pos = pos;
388 iliev 2216 }
389 iliev 2015
390     /**
391     * Synthesizes the current audio fragment for this voice.
392     *
393     * @param Samples - number of sample points to be rendered in this audio
394     * fragment cycle
395     * @param pSrc - pointer to input sample data
396     * @param Skip - number of sample points to skip in output buffer
397     */
398     void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
399 iliev 2297 bool delay = false; // Whether the voice playback should be delayed for this call
400    
401     if (pSignalUnitRack != NULL) {
402     uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
403     if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
404     if (delaySteps >= Samples) {
405     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
406     delay = true;
407     } else {
408     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
409     Samples -= delaySteps;
410     Skip += delaySteps;
411     }
412     }
413     }
414    
415 iliev 2015 AbstractEngineChannel* pChannel = pEngineChannel;
416 schoenebeck 2879 MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey());
417 iliev 2015
418 schoenebeck 2121 const bool bVoiceRequiresDedicatedRouting =
419     pEngineChannel->GetFxSendCount() > 0 &&
420     (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
421 iliev 2296
422     const bool bEq =
423 iliev 2298 pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
424 schoenebeck 2121
425 iliev 2296 if (bEq) {
426 iliev 2298 pEq->GetInChannelLeft()->Clear();
427     pEq->GetInChannelRight()->Clear();
428     finalSynthesisParameters.pOutLeft = &pEq->GetInChannelLeft()->Buffer()[Skip];
429     finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
430     pSignalUnitRack->UpdateEqSettings(pEq);
431 iliev 2296 } else if (bVoiceRequiresDedicatedRouting) {
432 schoenebeck 2121 finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
433     finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
434     } else {
435     finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
436     finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
437     }
438     finalSynthesisParameters.pSrc = pSrc;
439    
440 iliev 2015 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
441     RTList<Event>::Iterator itNoteEvent;
442 schoenebeck 2879 GetFirstEventOnKey(HostKey(), itNoteEvent);
443 iliev 2015
444 persson 2114 RTList<Event>::Iterator itGroupEvent;
445 persson 2352 if (pGroupEvents && !Orphan) itGroupEvent = pGroupEvents->first();
446 persson 2114
447 iliev 2015 if (itTriggerEvent) { // skip events that happened before this voice was triggered
448     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
449 persson 2114 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
450    
451 iliev 2015 // we can't simply compare the timestamp here, because note events
452     // might happen on the same time stamp, so we have to deal on the
453     // actual sequence the note events arrived instead (see bug #112)
454     for (; itNoteEvent; ++itNoteEvent) {
455     if (itTriggerEvent == itNoteEvent) {
456     ++itNoteEvent;
457     break;
458     }
459     }
460     }
461    
462 schoenebeck 3054 uint killPos = 0;
463 iliev 2015 if (itKillEvent) {
464     int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
465     if (maxFadeOutPos < 0) {
466     // There's not enough space in buffer to do a fade out
467     // from max volume (this can only happen for audio
468     // drivers that use Samples < MaxSamplesPerCycle).
469     // End the EG1 here, at pos 0, with a shorter max fade
470     // out time.
471 iliev 2217 if (pSignalUnitRack == NULL) {
472 iliev 2205 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
473     } else {
474 persson 2327 pSignalUnitRack->EnterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
475 iliev 2205 }
476 iliev 2015 itKillEvent = Pool<Event>::Iterator();
477     } else {
478     killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
479     }
480     }
481    
482     uint i = Skip;
483     while (i < Samples) {
484     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
485    
486     // initialize all final synthesis parameters
487     fFinalCutoff = VCFCutoffCtrl.fvalue;
488     fFinalResonance = VCFResonanceCtrl.fvalue;
489    
490 schoenebeck 2559 // process MIDI control change, aftertouch and pitchbend events for this subfragment
491 iliev 2015 processCCEvents(itCCEvent, iSubFragmentEnd);
492 iliev 2219 uint8_t pan = MIDIPan;
493 persson 2382 if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
494 iliev 2015
495 schoenebeck 3335 PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]);
496     PanRightSmoother.update(AbstractEngine::PanCurve[pan]);
497 schoenebeck 2931
498 schoenebeck 3561 finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;
499 schoenebeck 2931
500 schoenebeck 3561 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
501 schoenebeck 3638 #if CONFIG_PROCESS_MUTED_CHANNELS
502 iliev 2015 if (pChannel->GetMute()) fFinalVolume = 0;
503     #endif
504    
505     // process transition events (note on, note off & sustain pedal)
506     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
507 persson 2114 processGroupEvents(itGroupEvent, iSubFragmentEnd);
508 schoenebeck 3561
509     float fModVolume = 1;
510     float fModPitch = 1;
511    
512 iliev 2217 if (pSignalUnitRack == NULL) {
513 iliev 2205 // if the voice was killed in this subfragment, or if the
514     // filter EG is finished, switch EG1 to fade out stage
515     if ((itKillEvent && killPos <= iSubFragmentEnd) ||
516     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
517     pEG2->getSegmentType() == EG::segment_end)) {
518     pEG1->enterFadeOutStage();
519     itKillEvent = Pool<Event>::Iterator();
520     }
521 iliev 2015
522 iliev 2205 // process envelope generators
523     switch (pEG1->getSegmentType()) {
524     case EG::segment_lin:
525 schoenebeck 3561 fModVolume *= pEG1->processLin();
526 iliev 2205 break;
527     case EG::segment_exp:
528 schoenebeck 3561 fModVolume *= pEG1->processExp();
529 iliev 2205 break;
530     case EG::segment_end:
531 schoenebeck 3561 fModVolume *= pEG1->getLevel();
532 iliev 2205 break; // noop
533     case EG::segment_pow:
534 schoenebeck 3561 fModVolume *= pEG1->processPow();
535 iliev 2205 break;
536     }
537     switch (pEG2->getSegmentType()) {
538     case EG::segment_lin:
539     fFinalCutoff *= pEG2->processLin();
540     break;
541     case EG::segment_exp:
542     fFinalCutoff *= pEG2->processExp();
543     break;
544     case EG::segment_end:
545     fFinalCutoff *= pEG2->getLevel();
546     break; // noop
547     case EG::segment_pow:
548     fFinalCutoff *= pEG2->processPow();
549     break;
550     }
551 schoenebeck 3561 if (EG3.active()) fModPitch *= EG3.render();
552 iliev 2015
553 iliev 2205 // process low frequency oscillators
554 schoenebeck 3561 if (bLFO1Enabled) fModVolume *= (1.0f - pLFO1->render());
555 persson 2673 if (bLFO2Enabled) fFinalCutoff *= (1.0f - pLFO2->render());
556 schoenebeck 3561 if (bLFO3Enabled) fModPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
557 iliev 2205 } else {
558 iliev 2322 // if the voice was killed in this subfragment, enter fade out stage
559     if (itKillEvent && killPos <= iSubFragmentEnd) {
560     pSignalUnitRack->EnterFadeOutStage();
561     itKillEvent = Pool<Event>::Iterator();
562     }
563    
564     // if the filter EG is finished, switch EG1 to fade out stage
565     /*if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
566     pEG2->getSegmentType() == EG::segment_end) {
567 iliev 2205 pEG1->enterFadeOutStage();
568     itKillEvent = Pool<Event>::Iterator();
569     }*/
570     // TODO: ^^^
571 iliev 2015
572 iliev 2217 fFinalVolume *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
573     fFinalCutoff = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
574     fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
575 iliev 2205
576 schoenebeck 3561 fModPitch = pSignalUnitRack->GetEndpointUnit()->CalculatePitch(fModPitch);
577 iliev 2205 }
578 schoenebeck 2935
579 schoenebeck 3564 NoteVolume.renderApplyTo(fModVolume);
580     NotePitch.renderApplyTo(fModPitch);
581 schoenebeck 3561 NoteCutoff.applyTo(fFinalCutoff);
582     NoteResonance.applyTo(fFinalResonance);
583 schoenebeck 2935
584 schoenebeck 3561 fFinalVolume *= fModVolume;
585    
586     finalSynthesisParameters.fFinalPitch *= fModPitch;
587    
588 iliev 2015 // limit the pitch so we don't read outside the buffer
589     finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
590    
591     // if filter enabled then update filter coefficients
592     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
593     finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
594     finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
595     }
596    
597     // do we need resampling?
598     const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
599     const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
600     const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
601     finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
602     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
603    
604     // prepare final synthesis parameters structure
605     finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
606 schoenebeck 3561
607     float panL = PanLeftSmoother.render();
608     float panR = PanRightSmoother.render();
609 schoenebeck 3564 NotePan[0].renderApplyTo(panL);
610     NotePan[1].renderApplyTo(panR);
611 schoenebeck 3561
612 schoenebeck 3638 #if CONFIG_INTERPOLATE_VOLUME
613 iliev 2015 finalSynthesisParameters.fFinalVolumeDeltaLeft =
614 schoenebeck 3561 (fFinalVolume * VolumeLeft * panL -
615 iliev 2015 finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
616     finalSynthesisParameters.fFinalVolumeDeltaRight =
617 schoenebeck 3561 (fFinalVolume * VolumeRight * panR -
618 iliev 2015 finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
619     #else
620     finalSynthesisParameters.fFinalVolumeLeft =
621 schoenebeck 3561 fFinalVolume * VolumeLeft * panL;
622 iliev 2015 finalSynthesisParameters.fFinalVolumeRight =
623 schoenebeck 3561 fFinalVolume * VolumeRight * panR;
624 iliev 2015 #endif
625     // render audio for one subfragment
626 iliev 2297 if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
627 iliev 2015
628 iliev 2217 if (pSignalUnitRack == NULL) {
629 iliev 2205 // stop the rendering if volume EG is finished
630     if (pEG1->getSegmentType() == EG::segment_end) break;
631     } else {
632     // stop the rendering if the endpoint unit is not active
633 iliev 2217 if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
634 iliev 2205 }
635 iliev 2015
636     const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
637    
638 iliev 2217 if (pSignalUnitRack == NULL) {
639 iliev 2205 // increment envelopes' positions
640     if (pEG1->active()) {
641 iliev 2015
642 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
643     if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
644     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
645     }
646    
647     pEG1->increment(1);
648     if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
649 iliev 2015 }
650 iliev 2205 if (pEG2->active()) {
651     pEG2->increment(1);
652     if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
653     }
654     EG3.increment(1);
655     if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
656     } else {
657     // 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
658     /*if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
659     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
660     }*/
661     // TODO: ^^^
662    
663 iliev 2297 if (!delay) pSignalUnitRack->Increment();
664 iliev 2015 }
665    
666     Pos = newPos;
667     i = iSubFragmentEnd;
668     }
669 iliev 2297
670     if (delay) return;
671 schoenebeck 2121
672     if (bVoiceRequiresDedicatedRouting) {
673 iliev 2296 if (bEq) {
674 iliev 2298 pEq->RenderAudio(Samples);
675     pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
676     pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
677 iliev 2296 }
678 schoenebeck 2121 optional<float> effectSendLevels[2] = {
679     pMidiKeyInfo->ReverbSend,
680     pMidiKeyInfo->ChorusSend
681     };
682     GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
683 iliev 2296 } else if (bEq) {
684 iliev 2298 pEq->RenderAudio(Samples);
685     pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
686     pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
687 schoenebeck 2121 }
688 iliev 2015 }
689 persson 2045
690 iliev 2015 /**
691 schoenebeck 2559 * Process given list of MIDI control change, aftertouch and pitch bend
692     * events for the given time.
693 iliev 2015 *
694     * @param itEvent - iterator pointing to the next event to be processed
695     * @param End - youngest time stamp where processing should be stopped
696     */
697     void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
698     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
699 schoenebeck 3016 if ((itEvent->Type == Event::type_control_change || itEvent->Type == Event::type_channel_pressure)
700 schoenebeck 3017 && itEvent->Param.CC.Controller) // if (valid) MIDI control change event
701     {
702 iliev 2015 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
703     ProcessCutoffEvent(itEvent);
704     }
705     if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
706     processResonanceEvent(itEvent);
707     }
708 schoenebeck 3017 if (itEvent->Param.CC.Controller == CTRL_TABLE_IDX_AFTERTOUCH ||
709     itEvent->Type == Event::type_channel_pressure)
710     {
711     ProcessChannelPressureEvent(itEvent);
712     }
713 iliev 2217 if (pSignalUnitRack == NULL) {
714 iliev 2205 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
715 schoenebeck 3118 pLFO1->updateByMIDICtrlValue(itEvent->Param.CC.Value);
716 iliev 2205 }
717     if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
718 schoenebeck 3118 pLFO2->updateByMIDICtrlValue(itEvent->Param.CC.Value);
719 iliev 2205 }
720     if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
721 schoenebeck 3118 pLFO3->updateByMIDICtrlValue(itEvent->Param.CC.Value);
722 iliev 2205 }
723 iliev 2015 }
724     if (itEvent->Param.CC.Controller == 7) { // volume
725     VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
726     } else if (itEvent->Param.CC.Controller == 10) { // panpot
727 persson 2382 MIDIPan = CalculatePan(itEvent->Param.CC.Value);
728 iliev 2015 }
729     } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
730     processPitchEvent(itEvent);
731 schoenebeck 2559 } else if (itEvent->Type == Event::type_note_pressure) {
732     ProcessPolyphonicKeyPressureEvent(itEvent);
733 iliev 2015 }
734    
735     ProcessCCEvent(itEvent);
736 iliev 2217 if (pSignalUnitRack != NULL) {
737     pSignalUnitRack->ProcessCCEvent(itEvent);
738 iliev 2205 }
739 iliev 2015 }
740     }
741    
742     void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
743     Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
744     }
745    
746     void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
747     // convert absolute controller value to differential
748     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
749     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
750     const float resonancedelta = (float) ctrldelta;
751     fFinalResonance += resonancedelta;
752     // needed for initialization of parameter
753     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
754     }
755    
756     /**
757 schoenebeck 2931 * Process given list of MIDI note on, note off, sustain pedal events and
758     * note synthesis parameter events for the given time.
759 iliev 2015 *
760     * @param itEvent - iterator pointing to the next event to be processed
761     * @param End - youngest time stamp where processing should be stopped
762     */
763     void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
764     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
765 persson 2115 // some voice types ignore note off
766     if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
767 schoenebeck 2938 if (itEvent->Type == Event::type_release_key) {
768 persson 2114 EnterReleaseStage();
769 schoenebeck 2938 } else if (itEvent->Type == Event::type_cancel_release_key) {
770 iliev 2217 if (pSignalUnitRack == NULL) {
771 iliev 2205 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
772     pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
773     } else {
774 iliev 2217 pSignalUnitRack->CancelRelease();
775 iliev 2205 }
776 persson 2114 }
777 iliev 2015 }
778 schoenebeck 2938 // process stop-note events (caused by built-in instrument script function note_off())
779     if (itEvent->Type == Event::type_release_note && pNote &&
780     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
781     {
782     EnterReleaseStage();
783     }
784 schoenebeck 3188 // process kill-note events (caused by built-in instrument script function fade_out())
785     if (itEvent->Type == Event::type_kill_note && pNote &&
786     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
787     {
788     Kill(itEvent);
789     }
790 schoenebeck 2931 // process synthesis parameter events (caused by built-in realt-time instrument script functions)
791     if (itEvent->Type == Event::type_note_synth_param && pNote &&
792     pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
793     {
794     switch (itEvent->Param.NoteSynthParam.Type) {
795     case Event::synth_param_volume:
796 schoenebeck 3188 NoteVolume.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
797 schoenebeck 3561 NoteVolume.setFinal(itEvent->Param.NoteSynthParam.isFinal());
798 schoenebeck 2931 break;
799 schoenebeck 3188 case Event::synth_param_volume_time:
800     NoteVolume.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
801     break;
802 schoenebeck 3246 case Event::synth_param_volume_curve:
803     NoteVolume.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
804     break;
805 schoenebeck 2931 case Event::synth_param_pitch:
806 schoenebeck 3188 NotePitch.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
807 schoenebeck 3561 NotePitch.setFinal(itEvent->Param.NoteSynthParam.isFinal());
808 schoenebeck 2931 break;
809 schoenebeck 3188 case Event::synth_param_pitch_time:
810     NotePitch.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
811     break;
812 schoenebeck 3246 case Event::synth_param_pitch_curve:
813     NotePitch.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
814     break;
815 schoenebeck 2931 case Event::synth_param_pan:
816 schoenebeck 3335 NotePan[0].fadeTo(
817     AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/),
818     GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE
819     );
820     NotePan[1].fadeTo(
821     AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 1 /*right*/),
822     GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE
823     );
824 schoenebeck 3561 NotePan[0].setFinal(itEvent->Param.NoteSynthParam.isFinal());
825     NotePan[1].setFinal(itEvent->Param.NoteSynthParam.isFinal());
826 schoenebeck 2931 break;
827 schoenebeck 3335 case Event::synth_param_pan_time:
828     NotePan[0].setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
829     NotePan[1].setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
830     break;
831     case Event::synth_param_pan_curve:
832     NotePan[0].setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
833     NotePan[1].setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
834     break;
835 schoenebeck 2935 case Event::synth_param_cutoff:
836 schoenebeck 3561 NoteCutoff.Value = itEvent->Param.NoteSynthParam.AbsValue;
837     NoteCutoff.Final = itEvent->Param.NoteSynthParam.isFinal();
838 schoenebeck 2935 break;
839     case Event::synth_param_resonance:
840 schoenebeck 3561 NoteResonance.Value = itEvent->Param.NoteSynthParam.AbsValue;
841     NoteResonance.Final = itEvent->Param.NoteSynthParam.isFinal();
842 schoenebeck 2935 break;
843 schoenebeck 3118 case Event::synth_param_amp_lfo_depth:
844 schoenebeck 3561 pLFO1->setScriptDepthFactor(
845     itEvent->Param.NoteSynthParam.AbsValue,
846     itEvent->Param.NoteSynthParam.isFinal()
847     );
848 schoenebeck 3118 break;
849     case Event::synth_param_amp_lfo_freq:
850 schoenebeck 3561 if (itEvent->Param.NoteSynthParam.isFinal())
851     pLFO1->setScriptFrequencyFinal(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
852     else
853     pLFO1->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
854 schoenebeck 3118 break;
855 schoenebeck 3360 case Event::synth_param_cutoff_lfo_depth:
856 schoenebeck 3561 pLFO2->setScriptDepthFactor(
857     itEvent->Param.NoteSynthParam.AbsValue,
858     itEvent->Param.NoteSynthParam.isFinal()
859     );
860 schoenebeck 3360 break;
861     case Event::synth_param_cutoff_lfo_freq:
862 schoenebeck 3561 if (itEvent->Param.NoteSynthParam.isFinal())
863     pLFO2->setScriptFrequencyFinal(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
864     else
865     pLFO2->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
866 schoenebeck 3360 break;
867 schoenebeck 3118 case Event::synth_param_pitch_lfo_depth:
868 schoenebeck 3561 pLFO3->setScriptDepthFactor(
869     itEvent->Param.NoteSynthParam.AbsValue,
870     itEvent->Param.NoteSynthParam.isFinal()
871     );
872 schoenebeck 3118 break;
873     case Event::synth_param_pitch_lfo_freq:
874     pLFO3->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
875     break;
876 schoenebeck 3034
877     case Event::synth_param_attack:
878     case Event::synth_param_decay:
879 schoenebeck 3316 case Event::synth_param_sustain:
880 schoenebeck 3034 case Event::synth_param_release:
881     break; // noop
882 schoenebeck 2931 }
883     }
884 iliev 2015 }
885     }
886    
887 persson 2114 /**
888     * Process given list of events aimed at all voices in a key group.
889     *
890     * @param itEvent - iterator pointing to the next event to be processed
891     * @param End - youngest time stamp where processing should be stopped
892     */
893     void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
894     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
895     ProcessGroupEvent(itEvent);
896     }
897     }
898    
899 iliev 2015 /** @brief Update current portamento position.
900     *
901     * Will be called when portamento mode is enabled to get the final
902     * portamento position of this active voice from where the next voice(s)
903     * might continue to slide on.
904     *
905     * @param itNoteOffEvent - event which causes this voice to die soon
906     */
907     void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
908 iliev 2217 if (pSignalUnitRack == NULL) {
909 iliev 2205 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
910 schoenebeck 2879 pEngineChannel->PortamentoPos = (float) MIDIKey() + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
911 iliev 2205 } else {
912     // TODO:
913     }
914 iliev 2015 }
915    
916     /**
917     * Kill the voice in regular sense. Let the voice render audio until
918     * the kill event actually occured and then fade down the volume level
919     * very quickly and let the voice die finally. Unlike a normal release
920     * of a voice, a kill process cannot be cancalled and is therefore
921     * usually used for voice stealing and key group conflicts.
922     *
923     * @param itKillEvent - event which caused the voice to be killed
924     */
925     void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
926     #if CONFIG_DEVMODE
927     if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
928     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
929     #endif // CONFIG_DEVMODE
930    
931     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
932     this->itKillEvent = itKillEvent;
933     }
934    
935     Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
936     PitchInfo pitch;
937 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
938 iliev 2015
939     // GSt behaviour: maximum transpose up is 40 semitones. If
940     // MIDI key is more than 40 semitones above unity note,
941     // the transpose is not done.
942 schoenebeck 3302 //
943     // Update: Removed this GSt misbehavior. I don't think that any stock
944     // gig sound requires it to resemble its original sound.
945     // -- Christian, 2017-07-09
946     if (!SmplInfo.Unpitched /* && (MIDIKey() - (int) RgnInfo.UnityNote) < 40*/)
947     pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
948 iliev 2015
949     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
950     pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
951     pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
952    
953     return pitch;
954     }
955 schoenebeck 2448
956     void AbstractVoice::onScaleTuningChanged() {
957     PitchInfo pitch = this->Pitch;
958 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
959 schoenebeck 2448
960     // GSt behaviour: maximum transpose up is 40 semitones. If
961     // MIDI key is more than 40 semitones above unity note,
962     // the transpose is not done.
963 schoenebeck 3302 //
964     // Update: Removed this GSt misbehavior. I don't think that any stock
965     // gig sound requires it to resemble its original sound.
966     // -- Christian, 2017-07-09
967     if (!SmplInfo.Unpitched /* && (MIDIKey() - (int) RgnInfo.UnityNote) < 40*/)
968     pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
969 schoenebeck 2448
970     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
971     this->Pitch = pitch;
972     }
973 iliev 2015
974     double AbstractVoice::CalculateVolume(double velocityAttenuation) {
975     // For 16 bit samples, we downscale by 32768 to convert from
976     // int16 value range to DSP value range (which is
977     // -1.0..1.0). For 24 bit, we downscale from int32.
978     float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
979    
980     volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
981    
982     // the volume of release triggered samples depends on note length
983 persson 2115 if (Type & Voice::type_release_trigger) {
984 iliev 2015 float noteLength = float(GetEngine()->FrameTime + Delay -
985 schoenebeck 2879 GetNoteOnTime(MIDIKey()) ) / GetEngine()->SampleRate;
986 iliev 2015
987 persson 2061 volume *= GetReleaseTriggerAttenuation(noteLength);
988 iliev 2015 }
989    
990     return volume;
991     }
992 persson 2061
993     float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
994     return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
995     }
996 persson 2114
997     void AbstractVoice::EnterReleaseStage() {
998 iliev 2217 if (pSignalUnitRack == NULL) {
999 iliev 2205 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
1000     pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
1001     } else {
1002 iliev 2217 pSignalUnitRack->EnterReleaseStage();
1003 iliev 2205 }
1004 persson 2114 }
1005    
1006 iliev 2205 bool AbstractVoice::EG1Finished() {
1007 iliev 2217 if (pSignalUnitRack == NULL) {
1008 iliev 2205 return pEG1->getSegmentType() == EG::segment_end;
1009     } else {
1010 iliev 2217 return !pSignalUnitRack->GetEndpointUnit()->Active();
1011 iliev 2205 }
1012     }
1013    
1014 iliev 2015 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC