/[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 2216 - (hide annotations) (download)
Mon Jul 25 17:21:16 2011 UTC (12 years, 8 months ago) by iliev
File size: 35257 byte(s)
* sfz: added support for sample offset (offset)

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

  ViewVC Help
Powered by ViewVC