/[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 2953 - (hide annotations) (download)
Sat Jul 16 11:24:39 2016 UTC (7 years, 9 months ago) by schoenebeck
File size: 41881 byte(s)
* NKSP: Implemented built-in script function "change_attack()".
* NKSP: Implemented built-in script function "change_decay()".
* NKSP: Implemented built-in script function "change_release()".
* Bumped version (2.0.0.svn19).

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

  ViewVC Help
Powered by ViewVC