/[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 2114 - (hide annotations) (download)
Tue Aug 10 12:05:19 2010 UTC (13 years, 7 months ago) by persson
File size: 30742 byte(s)
* sfz engine: improved support for exclusive groups (group, off_by and
  off_mode)
* minor valgrind fixes

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

  ViewVC Help
Powered by ViewVC