/[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 2121 - (hide annotations) (download)
Tue Sep 14 17:09:08 2010 UTC (13 years, 6 months ago) by schoenebeck
File size: 31799 byte(s)
* implemented Roland GS NRPN 1ArrH which allows to set volume per note
* implemented Roland GS NRPN 1CrrH which allows to set pan per note
* implemented Roland GS NRPN 1DrrH which allows to set reverb send per
  note (in this implementation of the sampler its simply hard routed to
  the 1st effect send of the sampler channel, no matter what the actual
  effect type is)
* implemented Roland GS NRPN 1ErrH which allows to set chorus send per
  note (in this implementation of the sampler its simply hard routed to
  the 2nd effect send of the sampler channel, no matter what the actual
  effect type is)
* bumped version to 1.0.0cvs4

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

  ViewVC Help
Powered by ViewVC