/[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 2205 - (hide annotations) (download)
Mon Jul 11 17:52:01 2011 UTC (12 years, 8 months ago) by iliev
File size: 35165 byte(s)
* Introduced Signal Units and Signal Unit Racks, which hopefully will meet
  the demands of the new engines for flexible signal processing.
* sf2: Initial implementation of vibrato LFO, fixes in modulation EG and
  and volume EG (work in progress)

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

  ViewVC Help
Powered by ViewVC