/[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 2935 - (hide annotations) (download)
Sun Jul 10 14:24:13 2016 UTC (7 years, 9 months ago) by schoenebeck
File size: 41339 byte(s)
* NKSP: Added & implemented built-in script function "change_cutoff()".
* NKSP: Added & implemented built-in script function "change_reso()".
* NKSP: Added & implemented built-in script function "event_status()".
* NKSP: Added built-in script constants "$EVENT_STATUS_INACTIVE" and
  "$EVENT_STATUS_NOTE_QUEUE" both for being used as flags for
  built-in "event_status()" script function.
* NKSP language: Added support for bitwise operators ".or.", ".and."
  and ".not.".
* NKSP language scanner: Fixed IDs matching to require at least one
  character (i.e. when matching function names or variable names).
* NKSP language scanner: disabled unusued rules.
* Bumped version (2.0.0.svn12).

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

  ViewVC Help
Powered by ViewVC