/[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 2296 - (hide annotations) (download)
Thu Dec 8 20:03:47 2011 UTC (12 years, 4 months ago) by iliev
File size: 36762 byte(s)
* fixed crash when trying to create an effect instance with controls
  which min and/or max values depend on the sample rate
* experimental support for per voice equalization (work in progress)
* sfz engine: implemented opcodes eq1_freq, eq2_freq, eq3_freq,
  eq1_freqccN, eq2_freqccN, eq3_freqccN, eq1_bw, eq2_bw, eq3_bw,
  eq1_bwccN, eq2_bwccN, eq3_bwccN, eq1_gain, eq2_gain, eq3_gain,
  eq1_gainccN, eq2_gainccN, eq3_gainccN

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

  ViewVC Help
Powered by ViewVC