/[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 2175 - (hide annotations) (download)
Mon Apr 25 08:12:36 2011 UTC (13 years ago) by persson
File size: 31460 byte(s)
* sfz engine: implemeted filters. Filter types: lowpass, bandpass,
  bandreject and highpass. 1, 2, 4 and 6 pole filters. Opcodes:
  fil_type, cutoff, resonance, fil_veltrack, fil_keytrack,
  fil_keycenter, cutoff_cc, cutoff_chanaft.
* sfz engine: bugfix: zero ampeg_sustain didn't work
* gig engine: bugfix: pitch LFO controller "internal+aftertouch" was broken
* gig engine: bugfix: filter keyboard tracking was broken
* gig engine: filter performance fix (an unnecessary copy was made of
  the filter parameters in each sub fragment)
* ASIO driver: fixes for newer gcc versions (fix from PortAudio)

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

  ViewVC Help
Powered by ViewVC