/[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 3360 - (hide annotations) (download)
Fri Oct 27 21:19:18 2017 UTC (6 years, 5 months ago) by schoenebeck
File size: 48152 byte(s)
* NKSP: Added built-in script function "change_cutoff_attack()".
* NKSP: Added built-in script function "change_cutoff_decay()".
* NKSP: Added built-in script function "change_cutoff_sustain()".
* NKSP: Added built-in script function "change_cutoff_release()".
* NKSP: Added built-in script function "change_cutoff_lfo_depth()".
* NKSP: Added built-in script function "change_cutoff_lfo_freq()".
* Bumped version (2.0.0.svn77).

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

  ViewVC Help
Powered by ViewVC