/[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 2219 - (hide annotations) (download)
Thu Jul 28 12:35:49 2011 UTC (12 years, 8 months ago) by iliev
File size: 35625 byte(s)
* sfz engine: implemented opcodes lfoN_delay,
  lfoN_freq, lfoN_pan, lfoN_cutoff, lfoN_resonance

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    
322     if (bVoiceRequiresDedicatedRouting) {
323     finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
324     finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
325     } else {
326     finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
327     finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
328     }
329     finalSynthesisParameters.pSrc = pSrc;
330    
331 iliev 2015 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
332     RTList<Event>::Iterator itNoteEvent;
333     GetFirstEventOnKey(MIDIKey, itNoteEvent);
334    
335 persson 2114 RTList<Event>::Iterator itGroupEvent;
336     if (pGroupEvents) itGroupEvent = pGroupEvents->first();
337    
338 iliev 2015 if (itTriggerEvent) { // skip events that happened before this voice was triggered
339     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
340 persson 2114 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
341    
342 iliev 2015 // we can't simply compare the timestamp here, because note events
343     // might happen on the same time stamp, so we have to deal on the
344     // actual sequence the note events arrived instead (see bug #112)
345     for (; itNoteEvent; ++itNoteEvent) {
346     if (itTriggerEvent == itNoteEvent) {
347     ++itNoteEvent;
348     break;
349     }
350     }
351     }
352    
353     uint killPos;
354     if (itKillEvent) {
355     int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
356     if (maxFadeOutPos < 0) {
357     // There's not enough space in buffer to do a fade out
358     // from max volume (this can only happen for audio
359     // drivers that use Samples < MaxSamplesPerCycle).
360     // End the EG1 here, at pos 0, with a shorter max fade
361     // out time.
362 iliev 2217 if (pSignalUnitRack == NULL) {
363 iliev 2205 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
364     } else {
365     // TODO:
366     }
367 iliev 2015 itKillEvent = Pool<Event>::Iterator();
368     } else {
369     killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
370     }
371     }
372    
373     uint i = Skip;
374     while (i < Samples) {
375     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
376    
377     // initialize all final synthesis parameters
378     fFinalCutoff = VCFCutoffCtrl.fvalue;
379     fFinalResonance = VCFResonanceCtrl.fvalue;
380    
381     // process MIDI control change and pitchbend events for this subfragment
382     processCCEvents(itCCEvent, iSubFragmentEnd);
383 iliev 2219 uint8_t pan = MIDIPan;
384     if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CaluclatePan(pan);
385    
386     PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]);
387     PanRightSmoother.update(AbstractEngine::PanCurve[pan]);
388 iliev 2015
389     finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;
390     float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
391     #ifdef CONFIG_PROCESS_MUTED_CHANNELS
392     if (pChannel->GetMute()) fFinalVolume = 0;
393     #endif
394    
395     // process transition events (note on, note off & sustain pedal)
396     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
397 persson 2114 processGroupEvents(itGroupEvent, iSubFragmentEnd);
398 iliev 2015
399 iliev 2217 if (pSignalUnitRack == NULL) {
400 iliev 2205 // if the voice was killed in this subfragment, or if the
401     // filter EG is finished, switch EG1 to fade out stage
402     if ((itKillEvent && killPos <= iSubFragmentEnd) ||
403     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
404     pEG2->getSegmentType() == EG::segment_end)) {
405     pEG1->enterFadeOutStage();
406     itKillEvent = Pool<Event>::Iterator();
407     }
408 iliev 2015
409 iliev 2205 // process envelope generators
410     switch (pEG1->getSegmentType()) {
411     case EG::segment_lin:
412     fFinalVolume *= pEG1->processLin();
413     break;
414     case EG::segment_exp:
415     fFinalVolume *= pEG1->processExp();
416     break;
417     case EG::segment_end:
418     fFinalVolume *= pEG1->getLevel();
419     break; // noop
420     case EG::segment_pow:
421     fFinalVolume *= pEG1->processPow();
422     break;
423     }
424     switch (pEG2->getSegmentType()) {
425     case EG::segment_lin:
426     fFinalCutoff *= pEG2->processLin();
427     break;
428     case EG::segment_exp:
429     fFinalCutoff *= pEG2->processExp();
430     break;
431     case EG::segment_end:
432     fFinalCutoff *= pEG2->getLevel();
433     break; // noop
434     case EG::segment_pow:
435     fFinalCutoff *= pEG2->processPow();
436     break;
437     }
438     if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
439 iliev 2015
440 iliev 2205 // process low frequency oscillators
441     if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
442     if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
443     if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
444     } else {
445     // if the voice was killed in this subfragment, or if the
446     // filter EG is finished, switch EG1 to fade out stage
447     /*if ((itKillEvent && killPos <= iSubFragmentEnd) ||
448     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
449     pEG2->getSegmentType() == EG::segment_end)) {
450     pEG1->enterFadeOutStage();
451     itKillEvent = Pool<Event>::Iterator();
452     }*/
453     // TODO: ^^^
454 iliev 2015
455 iliev 2217 fFinalVolume *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
456     fFinalCutoff = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
457     fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
458 iliev 2205
459     finalSynthesisParameters.fFinalPitch =
460 iliev 2217 pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
461 iliev 2205
462     }
463    
464 iliev 2015 // limit the pitch so we don't read outside the buffer
465     finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
466    
467     // if filter enabled then update filter coefficients
468     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
469     finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
470     finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
471     }
472    
473     // do we need resampling?
474     const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
475     const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
476     const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
477     finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
478     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
479    
480     // prepare final synthesis parameters structure
481     finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
482     #ifdef CONFIG_INTERPOLATE_VOLUME
483     finalSynthesisParameters.fFinalVolumeDeltaLeft =
484     (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
485     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
486     finalSynthesisParameters.fFinalVolumeDeltaRight =
487     (fFinalVolume * VolumeRight * PanRightSmoother.render() -
488     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
489     #else
490     finalSynthesisParameters.fFinalVolumeLeft =
491     fFinalVolume * VolumeLeft * PanLeftSmoother.render();
492     finalSynthesisParameters.fFinalVolumeRight =
493     fFinalVolume * VolumeRight * PanRightSmoother.render();
494     #endif
495     // render audio for one subfragment
496     RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
497    
498 iliev 2217 if (pSignalUnitRack == NULL) {
499 iliev 2205 // stop the rendering if volume EG is finished
500     if (pEG1->getSegmentType() == EG::segment_end) break;
501     } else {
502     // stop the rendering if the endpoint unit is not active
503 iliev 2217 if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
504 iliev 2205 }
505 iliev 2015
506     const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
507    
508 iliev 2217 if (pSignalUnitRack == NULL) {
509 iliev 2205 // increment envelopes' positions
510     if (pEG1->active()) {
511 iliev 2015
512 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
513     if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
514     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
515     }
516    
517     pEG1->increment(1);
518     if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
519 iliev 2015 }
520 iliev 2205 if (pEG2->active()) {
521     pEG2->increment(1);
522     if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
523     }
524     EG3.increment(1);
525     if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
526     } else {
527     // 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
528     /*if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
529     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
530     }*/
531     // TODO: ^^^
532    
533 iliev 2217 pSignalUnitRack->Increment();
534 iliev 2015 }
535    
536     Pos = newPos;
537     i = iSubFragmentEnd;
538     }
539 schoenebeck 2121
540     if (bVoiceRequiresDedicatedRouting) {
541     optional<float> effectSendLevels[2] = {
542     pMidiKeyInfo->ReverbSend,
543     pMidiKeyInfo->ChorusSend
544     };
545     GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
546     }
547 iliev 2015 }
548 persson 2045
549 iliev 2015 /**
550     * Process given list of MIDI control change and pitch bend events for
551     * the given time.
552     *
553     * @param itEvent - iterator pointing to the next event to be processed
554     * @param End - youngest time stamp where processing should be stopped
555     */
556     void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
557     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
558     if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
559     if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
560     ProcessCutoffEvent(itEvent);
561     }
562     if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
563     processResonanceEvent(itEvent);
564     }
565 iliev 2217 if (pSignalUnitRack == NULL) {
566 iliev 2205 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
567     pLFO1->update(itEvent->Param.CC.Value);
568     }
569     if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
570     pLFO2->update(itEvent->Param.CC.Value);
571     }
572     if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
573     pLFO3->update(itEvent->Param.CC.Value);
574     }
575 iliev 2015 }
576     if (itEvent->Param.CC.Controller == 7) { // volume
577     VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
578     } else if (itEvent->Param.CC.Controller == 10) { // panpot
579 iliev 2219 MIDIPan = itEvent->Param.CC.Value;
580 iliev 2015 }
581     } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
582     processPitchEvent(itEvent);
583     }
584    
585     ProcessCCEvent(itEvent);
586 iliev 2217 if (pSignalUnitRack != NULL) {
587     pSignalUnitRack->ProcessCCEvent(itEvent);
588 iliev 2205 }
589 iliev 2015 }
590     }
591    
592     void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
593     Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
594     }
595    
596     void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
597     // convert absolute controller value to differential
598     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
599     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
600     const float resonancedelta = (float) ctrldelta;
601     fFinalResonance += resonancedelta;
602     // needed for initialization of parameter
603     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
604     }
605    
606     /**
607     * Process given list of MIDI note on, note off and sustain pedal events
608     * for the given time.
609     *
610     * @param itEvent - iterator pointing to the next event to be processed
611     * @param End - youngest time stamp where processing should be stopped
612     */
613     void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
614     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
615 persson 2115 // some voice types ignore note off
616     if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
617 persson 2114 if (itEvent->Type == Event::type_release) {
618     EnterReleaseStage();
619     } else if (itEvent->Type == Event::type_cancel_release) {
620 iliev 2217 if (pSignalUnitRack == NULL) {
621 iliev 2205 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
622     pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
623     } else {
624 iliev 2217 pSignalUnitRack->CancelRelease();
625 iliev 2205 }
626 persson 2114 }
627 iliev 2015 }
628     }
629     }
630    
631 persson 2114 /**
632     * Process given list of events aimed at all voices in a key group.
633     *
634     * @param itEvent - iterator pointing to the next event to be processed
635     * @param End - youngest time stamp where processing should be stopped
636     */
637     void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
638     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
639     ProcessGroupEvent(itEvent);
640     }
641     }
642    
643 iliev 2015 /** @brief Update current portamento position.
644     *
645     * Will be called when portamento mode is enabled to get the final
646     * portamento position of this active voice from where the next voice(s)
647     * might continue to slide on.
648     *
649     * @param itNoteOffEvent - event which causes this voice to die soon
650     */
651     void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
652 iliev 2217 if (pSignalUnitRack == NULL) {
653 iliev 2205 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
654     pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
655     } else {
656     // TODO:
657     }
658 iliev 2015 }
659    
660     /**
661     * Kill the voice in regular sense. Let the voice render audio until
662     * the kill event actually occured and then fade down the volume level
663     * very quickly and let the voice die finally. Unlike a normal release
664     * of a voice, a kill process cannot be cancalled and is therefore
665     * usually used for voice stealing and key group conflicts.
666     *
667     * @param itKillEvent - event which caused the voice to be killed
668     */
669     void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
670     #if CONFIG_DEVMODE
671     if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
672     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
673     #endif // CONFIG_DEVMODE
674    
675     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
676     this->itKillEvent = itKillEvent;
677     }
678    
679     Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
680     PitchInfo pitch;
681     double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey % 12];
682    
683     // GSt behaviour: maximum transpose up is 40 semitones. If
684     // MIDI key is more than 40 semitones above unity note,
685     // the transpose is not done.
686     if (!SmplInfo.Unpitched && (MIDIKey - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey - (int) RgnInfo.UnityNote) * 100;
687    
688     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
689     pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
690     pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
691    
692     return pitch;
693     }
694    
695     double AbstractVoice::CalculateVolume(double velocityAttenuation) {
696     // For 16 bit samples, we downscale by 32768 to convert from
697     // int16 value range to DSP value range (which is
698     // -1.0..1.0). For 24 bit, we downscale from int32.
699     float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
700    
701     volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
702    
703     // the volume of release triggered samples depends on note length
704 persson 2115 if (Type & Voice::type_release_trigger) {
705 iliev 2015 float noteLength = float(GetEngine()->FrameTime + Delay -
706     GetNoteOnTime(MIDIKey) ) / GetEngine()->SampleRate;
707    
708 persson 2061 volume *= GetReleaseTriggerAttenuation(noteLength);
709 iliev 2015 }
710    
711     return volume;
712     }
713 persson 2061
714     float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
715     return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
716     }
717 persson 2114
718     void AbstractVoice::EnterReleaseStage() {
719 iliev 2217 if (pSignalUnitRack == NULL) {
720 iliev 2205 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
721     pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
722     } else {
723 iliev 2217 pSignalUnitRack->EnterReleaseStage();
724 iliev 2205 }
725 persson 2114 }
726    
727 iliev 2205 bool AbstractVoice::EG1Finished() {
728 iliev 2217 if (pSignalUnitRack == NULL) {
729 iliev 2205 return pEG1->getSegmentType() == EG::segment_end;
730     } else {
731 iliev 2217 return !pSignalUnitRack->GetEndpointUnit()->Active();
732 iliev 2205 }
733     }
734    
735 iliev 2015 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC