/[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 2218 - (hide annotations) (download)
Thu Jul 28 08:05:57 2011 UTC (12 years, 9 months ago) by iliev
File size: 35264 byte(s)
* sfz engine: use the newly introduced signal units model

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

  ViewVC Help
Powered by ViewVC