/[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 2938 - (hide annotations) (download)
Mon Jul 11 17:10:40 2016 UTC (7 years, 8 months ago) by schoenebeck
File size: 41667 byte(s)
* Fixed behavior of built-in instrument script functions play_note()
  and note_off(), which must be distinguished engine internally
  from "real" MIDI note on/off events in order to avoid
  misbehaviors like hanging notes.
* Bumped version (2.0.0.svn13).

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 schoenebeck 2938 if (itEvent->Type == Event::type_release_key) {
700 persson 2114 EnterReleaseStage();
701 schoenebeck 2938 } else if (itEvent->Type == Event::type_cancel_release_key) {
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 2938 // process stop-note events (caused by built-in instrument script function note_off())
711     if (itEvent->Type == Event::type_release_note && pNote &&
712     pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
713     {
714     EnterReleaseStage();
715     }
716 schoenebeck 2931 // process synthesis parameter events (caused by built-in realt-time instrument script functions)
717     if (itEvent->Type == Event::type_note_synth_param && pNote &&
718     pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
719     {
720     switch (itEvent->Param.NoteSynthParam.Type) {
721     case Event::synth_param_volume:
722     NoteVolumeSmoother.update(itEvent->Param.NoteSynthParam.AbsValue);
723     break;
724     case Event::synth_param_pitch:
725     NotePitch = itEvent->Param.NoteSynthParam.AbsValue;
726     break;
727     case Event::synth_param_pan:
728     NotePanLeft = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);
729     NotePanRight = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 1 /*right*/);
730     break;
731 schoenebeck 2935 case Event::synth_param_cutoff:
732     NoteCutoff = itEvent->Param.NoteSynthParam.AbsValue;
733     break;
734     case Event::synth_param_resonance:
735     NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;
736     break;
737 schoenebeck 2931 }
738     }
739 iliev 2015 }
740     }
741    
742 persson 2114 /**
743     * Process given list of events aimed at all voices in a key group.
744     *
745     * @param itEvent - iterator pointing to the next event to be processed
746     * @param End - youngest time stamp where processing should be stopped
747     */
748     void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
749     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
750     ProcessGroupEvent(itEvent);
751     }
752     }
753    
754 iliev 2015 /** @brief Update current portamento position.
755     *
756     * Will be called when portamento mode is enabled to get the final
757     * portamento position of this active voice from where the next voice(s)
758     * might continue to slide on.
759     *
760     * @param itNoteOffEvent - event which causes this voice to die soon
761     */
762     void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
763 iliev 2217 if (pSignalUnitRack == NULL) {
764 iliev 2205 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
765 schoenebeck 2879 pEngineChannel->PortamentoPos = (float) MIDIKey() + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
766 iliev 2205 } else {
767     // TODO:
768     }
769 iliev 2015 }
770    
771     /**
772     * Kill the voice in regular sense. Let the voice render audio until
773     * the kill event actually occured and then fade down the volume level
774     * very quickly and let the voice die finally. Unlike a normal release
775     * of a voice, a kill process cannot be cancalled and is therefore
776     * usually used for voice stealing and key group conflicts.
777     *
778     * @param itKillEvent - event which caused the voice to be killed
779     */
780     void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
781     #if CONFIG_DEVMODE
782     if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
783     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
784     #endif // CONFIG_DEVMODE
785    
786     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
787     this->itKillEvent = itKillEvent;
788     }
789    
790     Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
791     PitchInfo pitch;
792 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
793 iliev 2015
794     // GSt behaviour: maximum transpose up is 40 semitones. If
795     // MIDI key is more than 40 semitones above unity note,
796     // the transpose is not done.
797 schoenebeck 2879 if (!SmplInfo.Unpitched && (MIDIKey() - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
798 iliev 2015
799     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
800     pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
801     pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
802    
803     return pitch;
804     }
805 schoenebeck 2448
806     void AbstractVoice::onScaleTuningChanged() {
807     PitchInfo pitch = this->Pitch;
808 schoenebeck 2879 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
809 schoenebeck 2448
810     // GSt behaviour: maximum transpose up is 40 semitones. If
811     // MIDI key is more than 40 semitones above unity note,
812     // the transpose is not done.
813 schoenebeck 2879 if (!SmplInfo.Unpitched && (MIDIKey() - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
814 schoenebeck 2448
815     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
816     this->Pitch = pitch;
817     }
818 iliev 2015
819     double AbstractVoice::CalculateVolume(double velocityAttenuation) {
820     // For 16 bit samples, we downscale by 32768 to convert from
821     // int16 value range to DSP value range (which is
822     // -1.0..1.0). For 24 bit, we downscale from int32.
823     float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
824    
825     volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
826    
827     // the volume of release triggered samples depends on note length
828 persson 2115 if (Type & Voice::type_release_trigger) {
829 iliev 2015 float noteLength = float(GetEngine()->FrameTime + Delay -
830 schoenebeck 2879 GetNoteOnTime(MIDIKey()) ) / GetEngine()->SampleRate;
831 iliev 2015
832 persson 2061 volume *= GetReleaseTriggerAttenuation(noteLength);
833 iliev 2015 }
834    
835     return volume;
836     }
837 persson 2061
838     float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
839     return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
840     }
841 persson 2114
842     void AbstractVoice::EnterReleaseStage() {
843 iliev 2217 if (pSignalUnitRack == NULL) {
844 iliev 2205 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
845     pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
846     } else {
847 iliev 2217 pSignalUnitRack->EnterReleaseStage();
848 iliev 2205 }
849 persson 2114 }
850    
851 iliev 2205 bool AbstractVoice::EG1Finished() {
852 iliev 2217 if (pSignalUnitRack == NULL) {
853 iliev 2205 return pEG1->getSegmentType() == EG::segment_end;
854     } else {
855 iliev 2217 return !pSignalUnitRack->GetEndpointUnit()->Active();
856 iliev 2205 }
857     }
858    
859 iliev 2015 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC