/[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 3316 - (show annotations) (download)
Thu Jul 20 12:05:53 2017 UTC (6 years, 9 months ago) by schoenebeck
File size: 46187 byte(s)
* NKSP: Implemented built-in script function "change_sustain()".
* Bumped version (2.0.0.svn72).

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 double pos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample
352
353 // if another sample playback start position was requested by instrument
354 // script (built-in script function play_note())
355 if (pNote && pNote->Override.SampleOffset >= 0) {
356 double overridePos =
357 double(SmplInfo.SampleRate) * double(pNote->Override.SampleOffset) / 1000000.0;
358 if (overridePos < SmplInfo.TotalFrameCount)
359 pos = overridePos;
360 }
361
362 finalSynthesisParameters.dPos = pos;
363 Pos = pos;
364 }
365
366 /**
367 * Synthesizes the current audio fragment for this voice.
368 *
369 * @param Samples - number of sample points to be rendered in this audio
370 * fragment cycle
371 * @param pSrc - pointer to input sample data
372 * @param Skip - number of sample points to skip in output buffer
373 */
374 void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
375 bool delay = false; // Whether the voice playback should be delayed for this call
376
377 if (pSignalUnitRack != NULL) {
378 uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
379 if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
380 if (delaySteps >= Samples) {
381 pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
382 delay = true;
383 } else {
384 pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
385 Samples -= delaySteps;
386 Skip += delaySteps;
387 }
388 }
389 }
390
391 AbstractEngineChannel* pChannel = pEngineChannel;
392 MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey());
393
394 const bool bVoiceRequiresDedicatedRouting =
395 pEngineChannel->GetFxSendCount() > 0 &&
396 (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
397
398 const bool bEq =
399 pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
400
401 if (bEq) {
402 pEq->GetInChannelLeft()->Clear();
403 pEq->GetInChannelRight()->Clear();
404 finalSynthesisParameters.pOutLeft = &pEq->GetInChannelLeft()->Buffer()[Skip];
405 finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
406 pSignalUnitRack->UpdateEqSettings(pEq);
407 } else if (bVoiceRequiresDedicatedRouting) {
408 finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
409 finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
410 } else {
411 finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
412 finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
413 }
414 finalSynthesisParameters.pSrc = pSrc;
415
416 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
417 RTList<Event>::Iterator itNoteEvent;
418 GetFirstEventOnKey(HostKey(), itNoteEvent);
419
420 RTList<Event>::Iterator itGroupEvent;
421 if (pGroupEvents && !Orphan) itGroupEvent = pGroupEvents->first();
422
423 if (itTriggerEvent) { // skip events that happened before this voice was triggered
424 while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
425 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
426
427 // we can't simply compare the timestamp here, because note events
428 // might happen on the same time stamp, so we have to deal on the
429 // actual sequence the note events arrived instead (see bug #112)
430 for (; itNoteEvent; ++itNoteEvent) {
431 if (itTriggerEvent == itNoteEvent) {
432 ++itNoteEvent;
433 break;
434 }
435 }
436 }
437
438 uint killPos = 0;
439 if (itKillEvent) {
440 int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
441 if (maxFadeOutPos < 0) {
442 // There's not enough space in buffer to do a fade out
443 // from max volume (this can only happen for audio
444 // drivers that use Samples < MaxSamplesPerCycle).
445 // End the EG1 here, at pos 0, with a shorter max fade
446 // out time.
447 if (pSignalUnitRack == NULL) {
448 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
449 } else {
450 pSignalUnitRack->EnterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
451 }
452 itKillEvent = Pool<Event>::Iterator();
453 } else {
454 killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
455 }
456 }
457
458 uint i = Skip;
459 while (i < Samples) {
460 int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
461
462 // initialize all final synthesis parameters
463 fFinalCutoff = VCFCutoffCtrl.fvalue;
464 fFinalResonance = VCFResonanceCtrl.fvalue;
465
466 // process MIDI control change, aftertouch and pitchbend events for this subfragment
467 processCCEvents(itCCEvent, iSubFragmentEnd);
468 uint8_t pan = MIDIPan;
469 if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
470
471 PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan] * NotePanLeft);
472 PanRightSmoother.update(AbstractEngine::PanCurve[pan] * NotePanRight);
473
474 finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend * NotePitch.render();
475
476 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render() * NoteVolume.render();
477 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
478 if (pChannel->GetMute()) fFinalVolume = 0;
479 #endif
480
481 // process transition events (note on, note off & sustain pedal)
482 processTransitionEvents(itNoteEvent, iSubFragmentEnd);
483 processGroupEvents(itGroupEvent, iSubFragmentEnd);
484
485 if (pSignalUnitRack == NULL) {
486 // if the voice was killed in this subfragment, or if the
487 // filter EG is finished, switch EG1 to fade out stage
488 if ((itKillEvent && killPos <= iSubFragmentEnd) ||
489 (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
490 pEG2->getSegmentType() == EG::segment_end)) {
491 pEG1->enterFadeOutStage();
492 itKillEvent = Pool<Event>::Iterator();
493 }
494
495 // process envelope generators
496 switch (pEG1->getSegmentType()) {
497 case EG::segment_lin:
498 fFinalVolume *= pEG1->processLin();
499 break;
500 case EG::segment_exp:
501 fFinalVolume *= pEG1->processExp();
502 break;
503 case EG::segment_end:
504 fFinalVolume *= pEG1->getLevel();
505 break; // noop
506 case EG::segment_pow:
507 fFinalVolume *= pEG1->processPow();
508 break;
509 }
510 switch (pEG2->getSegmentType()) {
511 case EG::segment_lin:
512 fFinalCutoff *= pEG2->processLin();
513 break;
514 case EG::segment_exp:
515 fFinalCutoff *= pEG2->processExp();
516 break;
517 case EG::segment_end:
518 fFinalCutoff *= pEG2->getLevel();
519 break; // noop
520 case EG::segment_pow:
521 fFinalCutoff *= pEG2->processPow();
522 break;
523 }
524 if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
525
526 // process low frequency oscillators
527 if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
528 if (bLFO2Enabled) fFinalCutoff *= (1.0f - pLFO2->render());
529 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
530 } else {
531 // if the voice was killed in this subfragment, enter fade out stage
532 if (itKillEvent && killPos <= iSubFragmentEnd) {
533 pSignalUnitRack->EnterFadeOutStage();
534 itKillEvent = Pool<Event>::Iterator();
535 }
536
537 // if the filter EG is finished, switch EG1 to fade out stage
538 /*if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
539 pEG2->getSegmentType() == EG::segment_end) {
540 pEG1->enterFadeOutStage();
541 itKillEvent = Pool<Event>::Iterator();
542 }*/
543 // TODO: ^^^
544
545 fFinalVolume *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
546 fFinalCutoff = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
547 fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
548
549 finalSynthesisParameters.fFinalPitch =
550 pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
551
552 }
553
554 fFinalCutoff *= NoteCutoff;
555 fFinalResonance *= NoteResonance;
556
557 // limit the pitch so we don't read outside the buffer
558 finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
559
560 // if filter enabled then update filter coefficients
561 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
562 finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
563 finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
564 }
565
566 // do we need resampling?
567 const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
568 const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
569 const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
570 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
571 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
572
573 // prepare final synthesis parameters structure
574 finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
575 #ifdef CONFIG_INTERPOLATE_VOLUME
576 finalSynthesisParameters.fFinalVolumeDeltaLeft =
577 (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
578 finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
579 finalSynthesisParameters.fFinalVolumeDeltaRight =
580 (fFinalVolume * VolumeRight * PanRightSmoother.render() -
581 finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
582 #else
583 finalSynthesisParameters.fFinalVolumeLeft =
584 fFinalVolume * VolumeLeft * PanLeftSmoother.render();
585 finalSynthesisParameters.fFinalVolumeRight =
586 fFinalVolume * VolumeRight * PanRightSmoother.render();
587 #endif
588 // render audio for one subfragment
589 if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
590
591 if (pSignalUnitRack == NULL) {
592 // stop the rendering if volume EG is finished
593 if (pEG1->getSegmentType() == EG::segment_end) break;
594 } else {
595 // stop the rendering if the endpoint unit is not active
596 if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
597 }
598
599 const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
600
601 if (pSignalUnitRack == NULL) {
602 // increment envelopes' positions
603 if (pEG1->active()) {
604
605 // 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
606 if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
607 pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
608 }
609
610 pEG1->increment(1);
611 if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
612 }
613 if (pEG2->active()) {
614 pEG2->increment(1);
615 if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
616 }
617 EG3.increment(1);
618 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
619 } else {
620 // 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
621 /*if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
622 pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
623 }*/
624 // TODO: ^^^
625
626 if (!delay) pSignalUnitRack->Increment();
627 }
628
629 Pos = newPos;
630 i = iSubFragmentEnd;
631 }
632
633 if (delay) return;
634
635 if (bVoiceRequiresDedicatedRouting) {
636 if (bEq) {
637 pEq->RenderAudio(Samples);
638 pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
639 pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
640 }
641 optional<float> effectSendLevels[2] = {
642 pMidiKeyInfo->ReverbSend,
643 pMidiKeyInfo->ChorusSend
644 };
645 GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
646 } else if (bEq) {
647 pEq->RenderAudio(Samples);
648 pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
649 pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
650 }
651 }
652
653 /**
654 * Process given list of MIDI control change, aftertouch and pitch bend
655 * events for the given time.
656 *
657 * @param itEvent - iterator pointing to the next event to be processed
658 * @param End - youngest time stamp where processing should be stopped
659 */
660 void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
661 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
662 if ((itEvent->Type == Event::type_control_change || itEvent->Type == Event::type_channel_pressure)
663 && itEvent->Param.CC.Controller) // if (valid) MIDI control change event
664 {
665 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
666 ProcessCutoffEvent(itEvent);
667 }
668 if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
669 processResonanceEvent(itEvent);
670 }
671 if (itEvent->Param.CC.Controller == CTRL_TABLE_IDX_AFTERTOUCH ||
672 itEvent->Type == Event::type_channel_pressure)
673 {
674 ProcessChannelPressureEvent(itEvent);
675 }
676 if (pSignalUnitRack == NULL) {
677 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
678 pLFO1->updateByMIDICtrlValue(itEvent->Param.CC.Value);
679 }
680 if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
681 pLFO2->updateByMIDICtrlValue(itEvent->Param.CC.Value);
682 }
683 if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
684 pLFO3->updateByMIDICtrlValue(itEvent->Param.CC.Value);
685 }
686 }
687 if (itEvent->Param.CC.Controller == 7) { // volume
688 VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
689 } else if (itEvent->Param.CC.Controller == 10) { // panpot
690 MIDIPan = CalculatePan(itEvent->Param.CC.Value);
691 }
692 } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
693 processPitchEvent(itEvent);
694 } else if (itEvent->Type == Event::type_note_pressure) {
695 ProcessPolyphonicKeyPressureEvent(itEvent);
696 }
697
698 ProcessCCEvent(itEvent);
699 if (pSignalUnitRack != NULL) {
700 pSignalUnitRack->ProcessCCEvent(itEvent);
701 }
702 }
703 }
704
705 void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
706 Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
707 }
708
709 void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
710 // convert absolute controller value to differential
711 const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
712 VCFResonanceCtrl.value = itEvent->Param.CC.Value;
713 const float resonancedelta = (float) ctrldelta;
714 fFinalResonance += resonancedelta;
715 // needed for initialization of parameter
716 VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
717 }
718
719 /**
720 * Process given list of MIDI note on, note off, sustain pedal events and
721 * note synthesis parameter events for the given time.
722 *
723 * @param itEvent - iterator pointing to the next event to be processed
724 * @param End - youngest time stamp where processing should be stopped
725 */
726 void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
727 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
728 // some voice types ignore note off
729 if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
730 if (itEvent->Type == Event::type_release_key) {
731 EnterReleaseStage();
732 } else if (itEvent->Type == Event::type_cancel_release_key) {
733 if (pSignalUnitRack == NULL) {
734 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
735 pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
736 } else {
737 pSignalUnitRack->CancelRelease();
738 }
739 }
740 }
741 // process stop-note events (caused by built-in instrument script function note_off())
742 if (itEvent->Type == Event::type_release_note && pNote &&
743 pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
744 {
745 EnterReleaseStage();
746 }
747 // process kill-note events (caused by built-in instrument script function fade_out())
748 if (itEvent->Type == Event::type_kill_note && pNote &&
749 pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
750 {
751 Kill(itEvent);
752 }
753 // process synthesis parameter events (caused by built-in realt-time instrument script functions)
754 if (itEvent->Type == Event::type_note_synth_param && pNote &&
755 pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
756 {
757 switch (itEvent->Param.NoteSynthParam.Type) {
758 case Event::synth_param_volume:
759 NoteVolume.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
760 break;
761 case Event::synth_param_volume_time:
762 NoteVolume.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
763 break;
764 case Event::synth_param_volume_curve:
765 NoteVolume.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
766 break;
767 case Event::synth_param_pitch:
768 NotePitch.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
769 break;
770 case Event::synth_param_pitch_time:
771 NotePitch.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
772 break;
773 case Event::synth_param_pitch_curve:
774 NotePitch.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
775 break;
776 case Event::synth_param_pan:
777 NotePanLeft = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);
778 NotePanRight = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 1 /*right*/);
779 break;
780 case Event::synth_param_cutoff:
781 NoteCutoff = itEvent->Param.NoteSynthParam.AbsValue;
782 break;
783 case Event::synth_param_resonance:
784 NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;
785 break;
786 case Event::synth_param_amp_lfo_depth:
787 pLFO1->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
788 break;
789 case Event::synth_param_amp_lfo_freq:
790 pLFO1->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
791 break;
792 case Event::synth_param_pitch_lfo_depth:
793 pLFO3->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
794 break;
795 case Event::synth_param_pitch_lfo_freq:
796 pLFO3->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
797 break;
798
799 case Event::synth_param_attack:
800 case Event::synth_param_decay:
801 case Event::synth_param_sustain:
802 case Event::synth_param_release:
803 break; // noop
804 }
805 }
806 }
807 }
808
809 /**
810 * Process given list of events aimed at all voices in a key group.
811 *
812 * @param itEvent - iterator pointing to the next event to be processed
813 * @param End - youngest time stamp where processing should be stopped
814 */
815 void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
816 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
817 ProcessGroupEvent(itEvent);
818 }
819 }
820
821 /** @brief Update current portamento position.
822 *
823 * Will be called when portamento mode is enabled to get the final
824 * portamento position of this active voice from where the next voice(s)
825 * might continue to slide on.
826 *
827 * @param itNoteOffEvent - event which causes this voice to die soon
828 */
829 void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
830 if (pSignalUnitRack == NULL) {
831 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
832 pEngineChannel->PortamentoPos = (float) MIDIKey() + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
833 } else {
834 // TODO:
835 }
836 }
837
838 /**
839 * Kill the voice in regular sense. Let the voice render audio until
840 * the kill event actually occured and then fade down the volume level
841 * very quickly and let the voice die finally. Unlike a normal release
842 * of a voice, a kill process cannot be cancalled and is therefore
843 * usually used for voice stealing and key group conflicts.
844 *
845 * @param itKillEvent - event which caused the voice to be killed
846 */
847 void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
848 #if CONFIG_DEVMODE
849 if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
850 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
851 #endif // CONFIG_DEVMODE
852
853 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
854 this->itKillEvent = itKillEvent;
855 }
856
857 Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
858 PitchInfo pitch;
859 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
860
861 // GSt behaviour: maximum transpose up is 40 semitones. If
862 // MIDI key is more than 40 semitones above unity note,
863 // the transpose is not done.
864 //
865 // Update: Removed this GSt misbehavior. I don't think that any stock
866 // gig sound requires it to resemble its original sound.
867 // -- Christian, 2017-07-09
868 if (!SmplInfo.Unpitched /* && (MIDIKey() - (int) RgnInfo.UnityNote) < 40*/)
869 pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
870
871 pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
872 pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
873 pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
874
875 return pitch;
876 }
877
878 void AbstractVoice::onScaleTuningChanged() {
879 PitchInfo pitch = this->Pitch;
880 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey() % 12];
881
882 // GSt behaviour: maximum transpose up is 40 semitones. If
883 // MIDI key is more than 40 semitones above unity note,
884 // the transpose is not done.
885 //
886 // Update: Removed this GSt misbehavior. I don't think that any stock
887 // gig sound requires it to resemble its original sound.
888 // -- Christian, 2017-07-09
889 if (!SmplInfo.Unpitched /* && (MIDIKey() - (int) RgnInfo.UnityNote) < 40*/)
890 pitchbasecents += (MIDIKey() - (int) RgnInfo.UnityNote) * 100;
891
892 pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
893 this->Pitch = pitch;
894 }
895
896 double AbstractVoice::CalculateVolume(double velocityAttenuation) {
897 // For 16 bit samples, we downscale by 32768 to convert from
898 // int16 value range to DSP value range (which is
899 // -1.0..1.0). For 24 bit, we downscale from int32.
900 float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
901
902 volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
903
904 // the volume of release triggered samples depends on note length
905 if (Type & Voice::type_release_trigger) {
906 float noteLength = float(GetEngine()->FrameTime + Delay -
907 GetNoteOnTime(MIDIKey()) ) / GetEngine()->SampleRate;
908
909 volume *= GetReleaseTriggerAttenuation(noteLength);
910 }
911
912 return volume;
913 }
914
915 float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
916 return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
917 }
918
919 void AbstractVoice::EnterReleaseStage() {
920 if (pSignalUnitRack == NULL) {
921 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
922 pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
923 } else {
924 pSignalUnitRack->EnterReleaseStage();
925 }
926 }
927
928 bool AbstractVoice::EG1Finished() {
929 if (pSignalUnitRack == NULL) {
930 return pEG1->getSegmentType() == EG::segment_end;
931 } else {
932 return !pSignalUnitRack->GetEndpointUnit()->Active();
933 }
934 }
935
936 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC