/[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 2299 - (hide annotations) (download)
Sun Dec 11 20:50:31 2011 UTC (12 years, 4 months ago) by iliev
File size: 38047 byte(s)
* implemented opcodes egN_eq1gain, egN_eq2gain, egN_eq3gain,
  egN_eq1gain_onccX, egN_eq2gain_onccX, egN_eq3gain_onccX, egN_eq1freq,
  egN_eq2freq, egN_eq3freq, egN_eq1freq_onccX, egN_eq2freq_onccX,
  egN_eq3freq_onccX, egN_eq1bw, egN_eq2bw, egN_eq3bw, egN_eq1bw_onccX,
  egN_eq2bw_onccX, egN_eq3bw_onccX, lfoN_eq1gain, lfoN_eq2gain,
  lfoN_eq3gain, lfoN_eq1gain_onccX, lfoN_eq2gain_onccX, lfoN_eq3gain_onccX,
  lfoN_eq1gain_smoothccX, lfoN_eq2gain_smoothccX, lfoN_eq3gain_smoothccX,
  lfoN_eq1gain_stepccX, lfoN_eq2gain_stepccX, lfoN_eq3gain_stepccX,
  lfoN_eq1freq, lfoN_eq2freq, lfoN_eq3freq, lfoN_eq1freq_onccX,
  lfoN_eq2freq_onccX, lfoN_eq3freq_onccX, lfoN_eq1freq_smoothccX,
  lfoN_eq2freq_smoothccX, lfoN_eq3freq_smoothccX, lfoN_eq1freq_stepccX,
  lfoN_eq2freq_stepccX, lfoN_eq3freq_stepccX, lfoN_eq1bw, lfoN_eq2bw,
  lfoN_eq3bw, lfoN_eq1bw_onccX, lfoN_eq2bw_onccX, lfoN_eq3bw_onccX,
  lfoN_eq1bw_smoothccX, lfoN_eq2bw_smoothccX, lfoN_eq3bw_smoothccX,
  lfoN_eq1bw_stepccX, lfoN_eq2bw_stepccX, lfoN_eq3bw_stepccX

1 iliev 2015 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6 persson 2045 * Copyright (C) 2005-2008 Christian Schoenebeck *
7 persson 2175 * Copyright (C) 2009-2011 Christian Schoenebeck and Grigor Iliev *
8 iliev 2015 * *
9     * This program is free software; you can redistribute it and/or modify *
10     * it under the terms of the GNU General Public License as published by *
11     * the Free Software Foundation; either version 2 of the License, or *
12     * (at your option) any later version. *
13     * *
14     * This program is distributed in the hope that it will be useful, *
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17     * GNU General Public License for more details. *
18     * *
19     * You should have received a copy of the GNU General Public License *
20     * along with this program; if not, write to the Free Software *
21     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22     * MA 02111-1307 USA *
23     ***************************************************************************/
24    
25     #include "AbstractVoice.h"
26    
27     namespace LinuxSampler {
28    
29 iliev 2217 AbstractVoice::AbstractVoice(SignalUnitRack* pRack): pSignalUnitRack(pRack) {
30 iliev 2015 pEngineChannel = NULL;
31 persson 2175 pLFO1 = new LFOUnsigned(1.0f); // amplitude LFO (0..1 range)
32     pLFO2 = new LFOUnsigned(1.0f); // filter LFO (0..1 range)
33     pLFO3 = new LFOSigned(1200.0f); // pitch LFO (-1200..+1200 range)
34 iliev 2015 PlaybackState = playback_state_end;
35     SynthesisMode = 0; // set all mode bits to 0 first
36     // select synthesis implementation (asm core is not supported ATM)
37     #if 0 // CONFIG_ASM && ARCH_X86
38     SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
39     #else
40     SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
41     #endif
42     SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, gig::Profiler::isEnabled());
43    
44     finalSynthesisParameters.filterLeft.Reset();
45     finalSynthesisParameters.filterRight.Reset();
46 iliev 2298
47     pEq = NULL;
48     bEqSupport = false;
49 iliev 2015 }
50    
51     AbstractVoice::~AbstractVoice() {
52     if (pLFO1) delete pLFO1;
53     if (pLFO2) delete pLFO2;
54     if (pLFO3) delete pLFO3;
55 iliev 2298
56     if(pEq != NULL) delete pEq;
57 iliev 2015 }
58 iliev 2298
59     void AbstractVoice::CreateEq() {
60     if(!bEqSupport) return;
61     if(pEq != NULL) delete pEq;
62     pEq = new EqSupport;
63     pEq->InitEffect(GetEngine()->pAudioOutputDevice);
64     }
65 persson 2045
66 iliev 2015 /**
67     * Resets voice variables. Should only be called if rendering process is
68     * suspended / not running.
69     */
70     void AbstractVoice::Reset() {
71     finalSynthesisParameters.filterLeft.Reset();
72     finalSynthesisParameters.filterRight.Reset();
73     DiskStreamRef.pStream = NULL;
74     DiskStreamRef.hStream = 0;
75     DiskStreamRef.State = Stream::state_unused;
76     DiskStreamRef.OrderID = 0;
77     PlaybackState = playback_state_end;
78     itTriggerEvent = Pool<Event>::Iterator();
79     itKillEvent = Pool<Event>::Iterator();
80     }
81    
82     /**
83     * Initializes and triggers the voice, a disk stream will be launched if
84     * needed.
85     *
86     * @param pEngineChannel - engine channel on which this voice was ordered
87     * @param itNoteOnEvent - event that caused triggering of this voice
88     * @param PitchBend - MIDI detune factor (-8192 ... +8191)
89     * @param pRegion- points to the region which provides sample wave(s) and articulation data
90     * @param VoiceType - type of this voice
91     * @param iKeyGroup - a value > 0 defines a key group in which this voice is member of
92     * @returns 0 on success, a value < 0 if the voice wasn't triggered
93     * (either due to an error or e.g. because no region is
94     * defined for the given key)
95     */
96     int AbstractVoice::Trigger (
97     AbstractEngineChannel* pEngineChannel,
98     Pool<Event>::Iterator& itNoteOnEvent,
99     int PitchBend,
100     type_t VoiceType,
101     int iKeyGroup
102     ) {
103     this->pEngineChannel = pEngineChannel;
104     Orphan = false;
105    
106     #if CONFIG_DEVMODE
107     if (itNoteOnEvent->FragmentPos() > GetEngine()->MaxSamplesPerCycle) { // just a sanity check for debugging
108     dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
109     }
110     #endif // CONFIG_DEVMODE
111    
112     Type = VoiceType;
113     MIDIKey = itNoteOnEvent->Param.Note.Key;
114 iliev 2218 MIDIVelocity = itNoteOnEvent->Param.Note.Velocity;
115 iliev 2219 MIDIPan = pEngineChannel->ControllerTable[10];
116     if (MIDIPan == 0 && pEngineChannel->GlobalPanRight == 1) MIDIPan = 64; // workaround used to determine whether the MIDI pan has not been set
117 iliev 2015 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
118     Delay = itNoteOnEvent->FragmentPos();
119     itTriggerEvent = itNoteOnEvent;
120     itKillEvent = Pool<Event>::Iterator();
121 schoenebeck 2121 MidiKeyBase* pKeyInfo = GetMidiKeyInfo(MIDIKey);
122 iliev 2015
123 persson 2114 pGroupEvents = iKeyGroup ? pEngineChannel->ActiveKeyGroups[iKeyGroup] : 0;
124    
125 iliev 2015 SmplInfo = GetSampleInfo();
126     RgnInfo = GetRegionInfo();
127     InstrInfo = GetInstrumentInfo();
128 iliev 2205
129     AboutToTrigger();
130 iliev 2015
131     // calculate volume
132     const double velocityAttenuation = GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
133 schoenebeck 2121 float volume = CalculateVolume(velocityAttenuation) * pKeyInfo->Volume;
134 persson 2032 if (volume <= 0) return -1;
135 iliev 2015
136     // select channel mode (mono or stereo)
137     SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, SmplInfo.ChannelCount == 2);
138     // select bit depth (16 or 24)
139     SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, SmplInfo.BitDepth == 24);
140    
141     // get starting crossfade volume level
142     float crossfadeVolume = CalculateCrossfadeVolume(itNoteOnEvent->Param.Note.Velocity);
143    
144 schoenebeck 2121 VolumeLeft = volume * pKeyInfo->PanLeft * AbstractEngine::PanCurve[64 - RgnInfo.Pan];
145     VolumeRight = volume * pKeyInfo->PanRight * AbstractEngine::PanCurve[64 + RgnInfo.Pan];
146 iliev 2015
147     float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
148     CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
149     VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
150     PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
151     PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
152    
153     // Check if the sample needs disk streaming or is too short for that
154     long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
155     DiskVoice = cachedsamples < SmplInfo.TotalFrameCount;
156    
157 iliev 2216 SetSampleStartOffset();
158    
159 iliev 2015 if (DiskVoice) { // voice to be streamed from disk
160     if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
161     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)
162     } else {
163     // The cache is too small to fit a max sample buffer.
164     // Setting MaxRAMPos to 0 will probably cause a click
165     // in the audio, but it's better than not handling
166     // this case at all, which would have caused the
167     // unsigned MaxRAMPos to be set to a negative number.
168     MaxRAMPos = 0;
169     }
170    
171     // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
172     RAMLoop = (SmplInfo.HasLoops && (SmplInfo.LoopStart + SmplInfo.LoopLength) <= MaxRAMPos);
173    
174     if (OrderNewStream()) return -1;
175     dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, SmplInfo.TotalFrameCount, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
176     }
177     else { // RAM only voice
178     MaxRAMPos = cachedsamples;
179     RAMLoop = (SmplInfo.HasLoops);
180     dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
181     }
182     if (RAMLoop) {
183     loop.uiTotalCycles = SmplInfo.LoopPlayCount;
184     loop.uiCyclesLeft = SmplInfo.LoopPlayCount;
185     loop.uiStart = SmplInfo.LoopStart;
186     loop.uiEnd = SmplInfo.LoopStart + SmplInfo.LoopLength;
187     loop.uiSize = SmplInfo.LoopLength;
188     }
189    
190     Pitch = CalculatePitchInfo(PitchBend);
191    
192     // the length of the decay and release curves are dependent on the velocity
193     const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
194    
195 iliev 2217 if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
196 iliev 2015 // get current value of EG1 controller
197     double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);
198    
199     // calculate influence of EG1 controller on EG1's parameters
200     EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);
201    
202 persson 2055 TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
203 iliev 2205 } else {
204 iliev 2217 pSignalUnitRack->Trigger();
205 iliev 2015 }
206    
207     #ifdef CONFIG_INTERPOLATE_VOLUME
208     // setup initial volume in synthesis parameters
209     #ifdef CONFIG_PROCESS_MUTED_CHANNELS
210     if (pEngineChannel->GetMute()) {
211     finalSynthesisParameters.fFinalVolumeLeft = 0;
212     finalSynthesisParameters.fFinalVolumeRight = 0;
213     }
214     else
215     #else
216     {
217 iliev 2205 float finalVolume;
218 iliev 2217 if (pSignalUnitRack == NULL) {
219 iliev 2205 finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();
220     } else {
221 iliev 2217 finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pSignalUnitRack->GetEndpointUnit()->GetVolume();
222 iliev 2205 }
223 iliev 2015
224     finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * pEngineChannel->GlobalPanLeft;
225     finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
226     }
227     #endif
228     #endif
229    
230 iliev 2217 if (pSignalUnitRack == NULL) {
231 iliev 2205 // setup EG 2 (VCF Cutoff EG)
232     {
233     // get current value of EG2 controller
234     double eg2controllervalue = GetEG2ControllerValue(itNoteOnEvent->Param.Note.Velocity);
235 iliev 2015
236 iliev 2205 // calculate influence of EG2 controller on EG2's parameters
237     EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);
238 iliev 2015
239 iliev 2205 TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
240     }
241 iliev 2015
242    
243 iliev 2205 // setup EG 3 (VCO EG)
244     {
245     // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
246     bool bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
247     float eg3depth = (bPortamento)
248     ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
249     : RTMath::CentsToFreqRatio(RgnInfo.EG3Depth);
250     float eg3time = (bPortamento)
251     ? pEngineChannel->PortamentoTime
252     : RgnInfo.EG3Attack;
253     EG3.trigger(eg3depth, eg3time, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
254     dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
255     }
256 iliev 2015
257    
258 iliev 2205 // setup LFO 1 (VCA LFO)
259     InitLFO1();
260     // setup LFO 2 (VCF Cutoff LFO)
261     InitLFO2();
262     // setup LFO 3 (VCO LFO)
263     InitLFO3();
264     }
265 iliev 2015
266    
267     #if CONFIG_FORCE_FILTER
268     const bool bUseFilter = true;
269     #else // use filter only if instrument file told so
270     const bool bUseFilter = RgnInfo.VCFEnabled;
271     #endif // CONFIG_FORCE_FILTER
272     SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
273     if (bUseFilter) {
274     #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
275     VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
276     #else // use the one defined in the instrument file
277     VCFCutoffCtrl.controller = GetVCFCutoffCtrl();
278     #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
279    
280     #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
281     VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
282     #else // use the one defined in the instrument file
283     VCFResonanceCtrl.controller = GetVCFResonanceCtrl();
284     #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
285    
286     #ifndef CONFIG_OVERRIDE_FILTER_TYPE
287     finalSynthesisParameters.filterLeft.SetType(RgnInfo.VCFType);
288     finalSynthesisParameters.filterRight.SetType(RgnInfo.VCFType);
289     #else // override filter type
290     finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
291     finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
292     #endif // CONFIG_OVERRIDE_FILTER_TYPE
293    
294     VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
295     VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
296    
297     // calculate cutoff frequency
298     CutoffBase = CalculateCutoffBase(itNoteOnEvent->Param.Note.Velocity);
299    
300     VCFCutoffCtrl.fvalue = CalculateFinalCutoff(CutoffBase);
301    
302     // calculate resonance
303     float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : RgnInfo.VCFResonance);
304     VCFResonanceCtrl.fvalue = resonance;
305     } else {
306     VCFCutoffCtrl.controller = 0;
307     VCFResonanceCtrl.controller = 0;
308     }
309 iliev 2299
310     const bool bEq =
311     pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
312 iliev 2015
313 iliev 2299 if (bEq) {
314     pEq->GetInChannelLeft()->Clear();
315     pEq->GetInChannelRight()->Clear();
316     pEq->RenderAudio(GetEngine()->pAudioOutputDevice->MaxSamplesPerCycle());
317     }
318    
319 iliev 2015 return 0; // success
320     }
321 iliev 2216
322     void AbstractVoice::SetSampleStartOffset() {
323     finalSynthesisParameters.dPos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
324     Pos = RgnInfo.SampleStartOffset;
325     }
326 iliev 2015
327     /**
328     * Synthesizes the current audio fragment for this voice.
329     *
330     * @param Samples - number of sample points to be rendered in this audio
331     * fragment cycle
332     * @param pSrc - pointer to input sample data
333     * @param Skip - number of sample points to skip in output buffer
334     */
335     void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
336 iliev 2297 bool delay = false; // Whether the voice playback should be delayed for this call
337    
338     if (pSignalUnitRack != NULL) {
339     uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
340     if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
341     if (delaySteps >= Samples) {
342     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
343     delay = true;
344     } else {
345     pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
346     Samples -= delaySteps;
347     Skip += delaySteps;
348     }
349     }
350     }
351    
352 iliev 2015 AbstractEngineChannel* pChannel = pEngineChannel;
353 schoenebeck 2121 MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);
354 iliev 2015
355 schoenebeck 2121 const bool bVoiceRequiresDedicatedRouting =
356     pEngineChannel->GetFxSendCount() > 0 &&
357     (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
358 iliev 2296
359     const bool bEq =
360 iliev 2298 pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
361 schoenebeck 2121
362 iliev 2296 if (bEq) {
363 iliev 2298 pEq->GetInChannelLeft()->Clear();
364     pEq->GetInChannelRight()->Clear();
365     finalSynthesisParameters.pOutLeft = &pEq->GetInChannelLeft()->Buffer()[Skip];
366     finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
367     pSignalUnitRack->UpdateEqSettings(pEq);
368 iliev 2296 } else if (bVoiceRequiresDedicatedRouting) {
369 schoenebeck 2121 finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
370     finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
371     } else {
372     finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
373     finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
374     }
375     finalSynthesisParameters.pSrc = pSrc;
376    
377 iliev 2015 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
378     RTList<Event>::Iterator itNoteEvent;
379     GetFirstEventOnKey(MIDIKey, itNoteEvent);
380    
381 persson 2114 RTList<Event>::Iterator itGroupEvent;
382     if (pGroupEvents) itGroupEvent = pGroupEvents->first();
383    
384 iliev 2015 if (itTriggerEvent) { // skip events that happened before this voice was triggered
385     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
386 persson 2114 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
387    
388 iliev 2015 // we can't simply compare the timestamp here, because note events
389     // might happen on the same time stamp, so we have to deal on the
390     // actual sequence the note events arrived instead (see bug #112)
391     for (; itNoteEvent; ++itNoteEvent) {
392     if (itTriggerEvent == itNoteEvent) {
393     ++itNoteEvent;
394     break;
395     }
396     }
397     }
398    
399     uint killPos;
400     if (itKillEvent) {
401     int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
402     if (maxFadeOutPos < 0) {
403     // There's not enough space in buffer to do a fade out
404     // from max volume (this can only happen for audio
405     // drivers that use Samples < MaxSamplesPerCycle).
406     // End the EG1 here, at pos 0, with a shorter max fade
407     // out time.
408 iliev 2217 if (pSignalUnitRack == NULL) {
409 iliev 2205 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
410     } else {
411     // TODO:
412     }
413 iliev 2015 itKillEvent = Pool<Event>::Iterator();
414     } else {
415     killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
416     }
417     }
418    
419     uint i = Skip;
420     while (i < Samples) {
421     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
422    
423     // initialize all final synthesis parameters
424     fFinalCutoff = VCFCutoffCtrl.fvalue;
425     fFinalResonance = VCFResonanceCtrl.fvalue;
426    
427     // process MIDI control change and pitchbend events for this subfragment
428     processCCEvents(itCCEvent, iSubFragmentEnd);
429 iliev 2219 uint8_t pan = MIDIPan;
430     if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CaluclatePan(pan);
431    
432     PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]);
433     PanRightSmoother.update(AbstractEngine::PanCurve[pan]);
434 iliev 2015
435     finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;
436     float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
437     #ifdef CONFIG_PROCESS_MUTED_CHANNELS
438     if (pChannel->GetMute()) fFinalVolume = 0;
439     #endif
440    
441     // process transition events (note on, note off & sustain pedal)
442     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
443 persson 2114 processGroupEvents(itGroupEvent, iSubFragmentEnd);
444 iliev 2297
445 iliev 2217 if (pSignalUnitRack == NULL) {
446 iliev 2205 // if the voice was killed in this subfragment, or if the
447     // filter EG is finished, switch EG1 to fade out stage
448     if ((itKillEvent && killPos <= iSubFragmentEnd) ||
449     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
450     pEG2->getSegmentType() == EG::segment_end)) {
451     pEG1->enterFadeOutStage();
452     itKillEvent = Pool<Event>::Iterator();
453     }
454 iliev 2015
455 iliev 2205 // process envelope generators
456     switch (pEG1->getSegmentType()) {
457     case EG::segment_lin:
458     fFinalVolume *= pEG1->processLin();
459     break;
460     case EG::segment_exp:
461     fFinalVolume *= pEG1->processExp();
462     break;
463     case EG::segment_end:
464     fFinalVolume *= pEG1->getLevel();
465     break; // noop
466     case EG::segment_pow:
467     fFinalVolume *= pEG1->processPow();
468     break;
469     }
470     switch (pEG2->getSegmentType()) {
471     case EG::segment_lin:
472     fFinalCutoff *= pEG2->processLin();
473     break;
474     case EG::segment_exp:
475     fFinalCutoff *= pEG2->processExp();
476     break;
477     case EG::segment_end:
478     fFinalCutoff *= pEG2->getLevel();
479     break; // noop
480     case EG::segment_pow:
481     fFinalCutoff *= pEG2->processPow();
482     break;
483     }
484     if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
485 iliev 2015
486 iliev 2205 // process low frequency oscillators
487     if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
488     if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
489     if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
490     } else {
491     // if the voice was killed in this subfragment, or if the
492     // filter EG is finished, switch EG1 to fade out stage
493     /*if ((itKillEvent && killPos <= iSubFragmentEnd) ||
494     (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
495     pEG2->getSegmentType() == EG::segment_end)) {
496     pEG1->enterFadeOutStage();
497     itKillEvent = Pool<Event>::Iterator();
498     }*/
499     // TODO: ^^^
500 iliev 2015
501 iliev 2217 fFinalVolume *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
502     fFinalCutoff = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
503     fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
504 iliev 2205
505     finalSynthesisParameters.fFinalPitch =
506 iliev 2217 pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
507 iliev 2205
508     }
509    
510 iliev 2015 // limit the pitch so we don't read outside the buffer
511     finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
512    
513     // if filter enabled then update filter coefficients
514     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
515     finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
516     finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
517     }
518    
519     // do we need resampling?
520     const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
521     const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
522     const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
523     finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
524     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
525    
526     // prepare final synthesis parameters structure
527     finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
528     #ifdef CONFIG_INTERPOLATE_VOLUME
529     finalSynthesisParameters.fFinalVolumeDeltaLeft =
530     (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
531     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
532     finalSynthesisParameters.fFinalVolumeDeltaRight =
533     (fFinalVolume * VolumeRight * PanRightSmoother.render() -
534     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
535     #else
536     finalSynthesisParameters.fFinalVolumeLeft =
537     fFinalVolume * VolumeLeft * PanLeftSmoother.render();
538     finalSynthesisParameters.fFinalVolumeRight =
539     fFinalVolume * VolumeRight * PanRightSmoother.render();
540     #endif
541     // render audio for one subfragment
542 iliev 2297 if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
543 iliev 2015
544 iliev 2217 if (pSignalUnitRack == NULL) {
545 iliev 2205 // stop the rendering if volume EG is finished
546     if (pEG1->getSegmentType() == EG::segment_end) break;
547     } else {
548     // stop the rendering if the endpoint unit is not active
549 iliev 2217 if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
550 iliev 2205 }
551 iliev 2015
552     const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
553    
554 iliev 2217 if (pSignalUnitRack == NULL) {
555 iliev 2205 // increment envelopes' positions
556     if (pEG1->active()) {
557 iliev 2015
558 iliev 2205 // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage
559     if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
560     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
561     }
562    
563     pEG1->increment(1);
564     if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
565 iliev 2015 }
566 iliev 2205 if (pEG2->active()) {
567     pEG2->increment(1);
568     if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
569     }
570     EG3.increment(1);
571     if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
572     } else {
573     // 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
574     /*if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
575     pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
576     }*/
577     // TODO: ^^^
578    
579 iliev 2297 if (!delay) pSignalUnitRack->Increment();
580 iliev 2015 }
581    
582     Pos = newPos;
583     i = iSubFragmentEnd;
584     }
585 iliev 2297
586     if (delay) return;
587 schoenebeck 2121
588     if (bVoiceRequiresDedicatedRouting) {
589 iliev 2296 if (bEq) {
590 iliev 2298 pEq->RenderAudio(Samples);
591     pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
592     pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
593 iliev 2296 }
594 schoenebeck 2121 optional<float> effectSendLevels[2] = {
595     pMidiKeyInfo->ReverbSend,
596     pMidiKeyInfo->ChorusSend
597     };
598     GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
599 iliev 2296 } else if (bEq) {
600 iliev 2298 pEq->RenderAudio(Samples);
601     pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
602     pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
603 schoenebeck 2121 }
604 iliev 2015 }
605 persson 2045
606 iliev 2015 /**
607     * Process given list of MIDI control change and pitch bend events for
608     * the given time.
609     *
610     * @param itEvent - iterator pointing to the next event to be processed
611     * @param End - youngest time stamp where processing should be stopped
612     */
613     void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
614     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
615     if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
616     if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
617     ProcessCutoffEvent(itEvent);
618     }
619     if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
620     processResonanceEvent(itEvent);
621     }
622 iliev 2217 if (pSignalUnitRack == NULL) {
623 iliev 2205 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
624     pLFO1->update(itEvent->Param.CC.Value);
625     }
626     if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
627     pLFO2->update(itEvent->Param.CC.Value);
628     }
629     if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
630     pLFO3->update(itEvent->Param.CC.Value);
631     }
632 iliev 2015 }
633     if (itEvent->Param.CC.Controller == 7) { // volume
634     VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
635     } else if (itEvent->Param.CC.Controller == 10) { // panpot
636 iliev 2219 MIDIPan = itEvent->Param.CC.Value;
637 iliev 2015 }
638     } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
639     processPitchEvent(itEvent);
640     }
641    
642     ProcessCCEvent(itEvent);
643 iliev 2217 if (pSignalUnitRack != NULL) {
644     pSignalUnitRack->ProcessCCEvent(itEvent);
645 iliev 2205 }
646 iliev 2015 }
647     }
648    
649     void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
650     Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
651     }
652    
653     void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
654     // convert absolute controller value to differential
655     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
656     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
657     const float resonancedelta = (float) ctrldelta;
658     fFinalResonance += resonancedelta;
659     // needed for initialization of parameter
660     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
661     }
662    
663     /**
664     * Process given list of MIDI note on, note off and sustain pedal events
665     * for the given time.
666     *
667     * @param itEvent - iterator pointing to the next event to be processed
668     * @param End - youngest time stamp where processing should be stopped
669     */
670     void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
671     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
672 persson 2115 // some voice types ignore note off
673     if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
674 persson 2114 if (itEvent->Type == Event::type_release) {
675     EnterReleaseStage();
676     } else if (itEvent->Type == Event::type_cancel_release) {
677 iliev 2217 if (pSignalUnitRack == NULL) {
678 iliev 2205 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
679     pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
680     } else {
681 iliev 2217 pSignalUnitRack->CancelRelease();
682 iliev 2205 }
683 persson 2114 }
684 iliev 2015 }
685     }
686     }
687    
688 persson 2114 /**
689     * Process given list of events aimed at all voices in a key group.
690     *
691     * @param itEvent - iterator pointing to the next event to be processed
692     * @param End - youngest time stamp where processing should be stopped
693     */
694     void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
695     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
696     ProcessGroupEvent(itEvent);
697     }
698     }
699    
700 iliev 2015 /** @brief Update current portamento position.
701     *
702     * Will be called when portamento mode is enabled to get the final
703     * portamento position of this active voice from where the next voice(s)
704     * might continue to slide on.
705     *
706     * @param itNoteOffEvent - event which causes this voice to die soon
707     */
708     void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
709 iliev 2217 if (pSignalUnitRack == NULL) {
710 iliev 2205 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
711     pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
712     } else {
713     // TODO:
714     }
715 iliev 2015 }
716    
717     /**
718     * Kill the voice in regular sense. Let the voice render audio until
719     * the kill event actually occured and then fade down the volume level
720     * very quickly and let the voice die finally. Unlike a normal release
721     * of a voice, a kill process cannot be cancalled and is therefore
722     * usually used for voice stealing and key group conflicts.
723     *
724     * @param itKillEvent - event which caused the voice to be killed
725     */
726     void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
727     #if CONFIG_DEVMODE
728     if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
729     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
730     #endif // CONFIG_DEVMODE
731    
732     if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
733     this->itKillEvent = itKillEvent;
734     }
735    
736     Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
737     PitchInfo pitch;
738     double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey % 12];
739    
740     // GSt behaviour: maximum transpose up is 40 semitones. If
741     // MIDI key is more than 40 semitones above unity note,
742     // the transpose is not done.
743     if (!SmplInfo.Unpitched && (MIDIKey - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey - (int) RgnInfo.UnityNote) * 100;
744    
745     pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
746     pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
747     pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
748    
749     return pitch;
750     }
751    
752     double AbstractVoice::CalculateVolume(double velocityAttenuation) {
753     // For 16 bit samples, we downscale by 32768 to convert from
754     // int16 value range to DSP value range (which is
755     // -1.0..1.0). For 24 bit, we downscale from int32.
756     float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
757    
758     volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
759    
760     // the volume of release triggered samples depends on note length
761 persson 2115 if (Type & Voice::type_release_trigger) {
762 iliev 2015 float noteLength = float(GetEngine()->FrameTime + Delay -
763     GetNoteOnTime(MIDIKey) ) / GetEngine()->SampleRate;
764    
765 persson 2061 volume *= GetReleaseTriggerAttenuation(noteLength);
766 iliev 2015 }
767    
768     return volume;
769     }
770 persson 2061
771     float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
772     return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
773     }
774 persson 2114
775     void AbstractVoice::EnterReleaseStage() {
776 iliev 2217 if (pSignalUnitRack == NULL) {
777 iliev 2205 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
778     pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
779     } else {
780 iliev 2217 pSignalUnitRack->EnterReleaseStage();
781 iliev 2205 }
782 persson 2114 }
783    
784 iliev 2205 bool AbstractVoice::EG1Finished() {
785 iliev 2217 if (pSignalUnitRack == NULL) {
786 iliev 2205 return pEG1->getSegmentType() == EG::segment_end;
787     } else {
788 iliev 2217 return !pSignalUnitRack->GetEndpointUnit()->Active();
789 iliev 2205 }
790     }
791    
792 iliev 2015 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC