/[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 3335 - (hide annotations) (download)
Sun Jul 30 14:33:15 2017 UTC (6 years, 8 months ago) by schoenebeck
File size: 47466 byte(s)
* NKSP: Added built-in script function "change_pan_time()".
* NKSP: Added built-in script function "change_pan_curve()".
* Bumped version (2.0.0.svn75).

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

  ViewVC Help
Powered by ViewVC