/[svn]/linuxsampler/trunk/src/engines/common/AbstractVoice.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/common/AbstractVoice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3246 - (show annotations) (download)
Sun May 28 22:22:56 2017 UTC (6 years, 11 months ago) by schoenebeck
File size: 45313 byte(s)
* NKSP: Implemented built-in script function "change_vol_curve()".
* NKSP: Implemented built-in script function "change_tune_curve()".
* NKSP: Added built-in script constant "$NKSP_LINEAR".
* NKSP: Added built-in script constant "$NKSP_EASE_IN_EASE_OUT".
* Bumped version (2.0.0.svn54).

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

  ViewVC Help
Powered by ViewVC