/[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 2879 - (hide annotations) (download)
Tue Apr 19 14:07:53 2016 UTC (8 years ago) by schoenebeck
File size: 39194 byte(s)
* All engines: Active voices are now internally grouped to "Note" objects,
  instead of being directly assigned to a keyboard key. This allows more
  fine graded processing of voices, which is i.e. required for certain
  instrument script features.
* Built-in script function "play_note()": Added support for passing
  special value -1 for "duration-us" argument, which will cause the
  triggered note to be released once the original note was released.
* Bumped version (2.0.0.svn3).

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

  ViewVC Help
Powered by ViewVC