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

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

  ViewVC Help
Powered by ViewVC