/[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 2175 - (show annotations) (download)
Mon Apr 25 08:12:36 2011 UTC (12 years, 11 months ago) by persson
File size: 31460 byte(s)
* sfz engine: implemeted filters. Filter types: lowpass, bandpass,
  bandreject and highpass. 1, 2, 4 and 6 pole filters. Opcodes:
  fil_type, cutoff, resonance, fil_veltrack, fil_keytrack,
  fil_keycenter, cutoff_cc, cutoff_chanaft.
* sfz engine: bugfix: zero ampeg_sustain didn't work
* gig engine: bugfix: pitch LFO controller "internal+aftertouch" was broken
* gig engine: bugfix: filter keyboard tracking was broken
* gig engine: filter performance fix (an unnecessary copy was made of
  the filter parameters in each sub fragment)
* ASIO driver: fixes for newer gcc versions (fix from PortAudio)

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-2011 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 LFO (0..1 range)
32 pLFO2 = new LFOUnsigned(1.0f); // filter LFO (0..1 range)
33 pLFO3 = new LFOSigned(1200.0f); // pitch LFO (-1200..+1200 range)
34 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 TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
217 }
218
219
220 // setup EG 3 (VCO EG)
221 {
222 // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
223 bool bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
224 float eg3depth = (bPortamento)
225 ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
226 : RTMath::CentsToFreqRatio(RgnInfo.EG3Depth);
227 float eg3time = (bPortamento)
228 ? pEngineChannel->PortamentoTime
229 : RgnInfo.EG3Attack;
230 EG3.trigger(eg3depth, eg3time, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
231 dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
232 }
233
234
235 // setup LFO 1 (VCA LFO)
236 InitLFO1();
237 // setup LFO 2 (VCF Cutoff LFO)
238 InitLFO2();
239 // setup LFO 3 (VCO LFO)
240 InitLFO3();
241
242
243 #if CONFIG_FORCE_FILTER
244 const bool bUseFilter = true;
245 #else // use filter only if instrument file told so
246 const bool bUseFilter = RgnInfo.VCFEnabled;
247 #endif // CONFIG_FORCE_FILTER
248 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
249 if (bUseFilter) {
250 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
251 VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
252 #else // use the one defined in the instrument file
253 VCFCutoffCtrl.controller = GetVCFCutoffCtrl();
254 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
255
256 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
257 VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
258 #else // use the one defined in the instrument file
259 VCFResonanceCtrl.controller = GetVCFResonanceCtrl();
260 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
261
262 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
263 finalSynthesisParameters.filterLeft.SetType(RgnInfo.VCFType);
264 finalSynthesisParameters.filterRight.SetType(RgnInfo.VCFType);
265 #else // override filter type
266 finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
267 finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
268 #endif // CONFIG_OVERRIDE_FILTER_TYPE
269
270 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
271 VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
272
273 // calculate cutoff frequency
274 CutoffBase = CalculateCutoffBase(itNoteOnEvent->Param.Note.Velocity);
275
276 VCFCutoffCtrl.fvalue = CalculateFinalCutoff(CutoffBase);
277
278 // calculate resonance
279 float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : RgnInfo.VCFResonance);
280 VCFResonanceCtrl.fvalue = resonance;
281 } else {
282 VCFCutoffCtrl.controller = 0;
283 VCFResonanceCtrl.controller = 0;
284 }
285
286 return 0; // success
287 }
288
289 /**
290 * Synthesizes the current audio fragment for this voice.
291 *
292 * @param Samples - number of sample points to be rendered in this audio
293 * fragment cycle
294 * @param pSrc - pointer to input sample data
295 * @param Skip - number of sample points to skip in output buffer
296 */
297 void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
298 AbstractEngineChannel* pChannel = pEngineChannel;
299 MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);
300
301 const bool bVoiceRequiresDedicatedRouting =
302 pEngineChannel->GetFxSendCount() > 0 &&
303 (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
304
305 if (bVoiceRequiresDedicatedRouting) {
306 finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
307 finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
308 } else {
309 finalSynthesisParameters.pOutLeft = &pChannel->pChannelLeft->Buffer()[Skip];
310 finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
311 }
312 finalSynthesisParameters.pSrc = pSrc;
313
314 RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
315 RTList<Event>::Iterator itNoteEvent;
316 GetFirstEventOnKey(MIDIKey, itNoteEvent);
317
318 RTList<Event>::Iterator itGroupEvent;
319 if (pGroupEvents) itGroupEvent = pGroupEvents->first();
320
321 if (itTriggerEvent) { // skip events that happened before this voice was triggered
322 while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
323 while (itGroupEvent && itGroupEvent->FragmentPos() <= Skip) ++itGroupEvent;
324
325 // we can't simply compare the timestamp here, because note events
326 // might happen on the same time stamp, so we have to deal on the
327 // actual sequence the note events arrived instead (see bug #112)
328 for (; itNoteEvent; ++itNoteEvent) {
329 if (itTriggerEvent == itNoteEvent) {
330 ++itNoteEvent;
331 break;
332 }
333 }
334 }
335
336 uint killPos;
337 if (itKillEvent) {
338 int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
339 if (maxFadeOutPos < 0) {
340 // There's not enough space in buffer to do a fade out
341 // from max volume (this can only happen for audio
342 // drivers that use Samples < MaxSamplesPerCycle).
343 // End the EG1 here, at pos 0, with a shorter max fade
344 // out time.
345 pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
346 itKillEvent = Pool<Event>::Iterator();
347 } else {
348 killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
349 }
350 }
351
352 uint i = Skip;
353 while (i < Samples) {
354 int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
355
356 // initialize all final synthesis parameters
357 fFinalCutoff = VCFCutoffCtrl.fvalue;
358 fFinalResonance = VCFResonanceCtrl.fvalue;
359
360 // process MIDI control change and pitchbend events for this subfragment
361 processCCEvents(itCCEvent, iSubFragmentEnd);
362
363 finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;
364 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
365 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
366 if (pChannel->GetMute()) fFinalVolume = 0;
367 #endif
368
369 // process transition events (note on, note off & sustain pedal)
370 processTransitionEvents(itNoteEvent, iSubFragmentEnd);
371 processGroupEvents(itGroupEvent, iSubFragmentEnd);
372
373 // if the voice was killed in this subfragment, or if the
374 // filter EG is finished, switch EG1 to fade out stage
375 if ((itKillEvent && killPos <= iSubFragmentEnd) ||
376 (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
377 pEG2->getSegmentType() == EG::segment_end)) {
378 pEG1->enterFadeOutStage();
379 itKillEvent = Pool<Event>::Iterator();
380 }
381
382 // process envelope generators
383 switch (pEG1->getSegmentType()) {
384 case EG::segment_lin:
385 fFinalVolume *= pEG1->processLin();
386 break;
387 case EG::segment_exp:
388 fFinalVolume *= pEG1->processExp();
389 break;
390 case EG::segment_end:
391 fFinalVolume *= pEG1->getLevel();
392 break; // noop
393 case EG::segment_pow:
394 fFinalVolume *= pEG1->processPow();
395 break;
396 }
397 switch (pEG2->getSegmentType()) {
398 case EG::segment_lin:
399 fFinalCutoff *= pEG2->processLin();
400 break;
401 case EG::segment_exp:
402 fFinalCutoff *= pEG2->processExp();
403 break;
404 case EG::segment_end:
405 fFinalCutoff *= pEG2->getLevel();
406 break; // noop
407 case EG::segment_pow:
408 fFinalCutoff *= pEG2->processPow();
409 break;
410 }
411 if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
412
413 // process low frequency oscillators
414 if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
415 if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
416 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
417
418 // limit the pitch so we don't read outside the buffer
419 finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
420
421 // if filter enabled then update filter coefficients
422 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
423 finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
424 finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, GetEngine()->SampleRate);
425 }
426
427 // do we need resampling?
428 const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
429 const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
430 const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
431 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
432 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
433
434 // prepare final synthesis parameters structure
435 finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
436 #ifdef CONFIG_INTERPOLATE_VOLUME
437 finalSynthesisParameters.fFinalVolumeDeltaLeft =
438 (fFinalVolume * VolumeLeft * PanLeftSmoother.render() -
439 finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
440 finalSynthesisParameters.fFinalVolumeDeltaRight =
441 (fFinalVolume * VolumeRight * PanRightSmoother.render() -
442 finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
443 #else
444 finalSynthesisParameters.fFinalVolumeLeft =
445 fFinalVolume * VolumeLeft * PanLeftSmoother.render();
446 finalSynthesisParameters.fFinalVolumeRight =
447 fFinalVolume * VolumeRight * PanRightSmoother.render();
448 #endif
449 // render audio for one subfragment
450 RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
451
452 // stop the rendering if volume EG is finished
453 if (pEG1->getSegmentType() == EG::segment_end) break;
454
455 const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
456
457 // increment envelopes' positions
458 if (pEG1->active()) {
459
460 // 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
461 if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
462 pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
463 }
464
465 pEG1->increment(1);
466 if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
467 }
468 if (pEG2->active()) {
469 pEG2->increment(1);
470 if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
471 }
472 EG3.increment(1);
473 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
474
475 Pos = newPos;
476 i = iSubFragmentEnd;
477 }
478
479 if (bVoiceRequiresDedicatedRouting) {
480 optional<float> effectSendLevels[2] = {
481 pMidiKeyInfo->ReverbSend,
482 pMidiKeyInfo->ChorusSend
483 };
484 GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
485 }
486 }
487
488 /**
489 * Process given list of MIDI control change and pitch bend events for
490 * the given time.
491 *
492 * @param itEvent - iterator pointing to the next event to be processed
493 * @param End - youngest time stamp where processing should be stopped
494 */
495 void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
496 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
497 if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
498 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
499 ProcessCutoffEvent(itEvent);
500 }
501 if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
502 processResonanceEvent(itEvent);
503 }
504 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
505 pLFO1->update(itEvent->Param.CC.Value);
506 }
507 if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
508 pLFO2->update(itEvent->Param.CC.Value);
509 }
510 if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
511 pLFO3->update(itEvent->Param.CC.Value);
512 }
513 if (itEvent->Param.CC.Controller == 7) { // volume
514 VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
515 } else if (itEvent->Param.CC.Controller == 10) { // panpot
516 PanLeftSmoother.update(AbstractEngine::PanCurve[128 - itEvent->Param.CC.Value]);
517 PanRightSmoother.update(AbstractEngine::PanCurve[itEvent->Param.CC.Value]);
518 }
519 } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
520 processPitchEvent(itEvent);
521 }
522
523 ProcessCCEvent(itEvent);
524 }
525 }
526
527 void AbstractVoice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
528 Pitch.PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * Pitch.PitchBendRange);
529 }
530
531 void AbstractVoice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
532 // convert absolute controller value to differential
533 const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
534 VCFResonanceCtrl.value = itEvent->Param.CC.Value;
535 const float resonancedelta = (float) ctrldelta;
536 fFinalResonance += resonancedelta;
537 // needed for initialization of parameter
538 VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
539 }
540
541 /**
542 * Process given list of MIDI note on, note off and sustain pedal events
543 * for the given time.
544 *
545 * @param itEvent - iterator pointing to the next event to be processed
546 * @param End - youngest time stamp where processing should be stopped
547 */
548 void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
549 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
550 // some voice types ignore note off
551 if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
552 if (itEvent->Type == Event::type_release) {
553 EnterReleaseStage();
554 } else if (itEvent->Type == Event::type_cancel_release) {
555 pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
556 pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
557 }
558 }
559 }
560 }
561
562 /**
563 * Process given list of events aimed at all voices in a key group.
564 *
565 * @param itEvent - iterator pointing to the next event to be processed
566 * @param End - youngest time stamp where processing should be stopped
567 */
568 void AbstractVoice::processGroupEvents(RTList<Event>::Iterator& itEvent, uint End) {
569 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
570 ProcessGroupEvent(itEvent);
571 }
572 }
573
574 /** @brief Update current portamento position.
575 *
576 * Will be called when portamento mode is enabled to get the final
577 * portamento position of this active voice from where the next voice(s)
578 * might continue to slide on.
579 *
580 * @param itNoteOffEvent - event which causes this voice to die soon
581 */
582 void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
583 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
584 pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
585 }
586
587 /**
588 * Kill the voice in regular sense. Let the voice render audio until
589 * the kill event actually occured and then fade down the volume level
590 * very quickly and let the voice die finally. Unlike a normal release
591 * of a voice, a kill process cannot be cancalled and is therefore
592 * usually used for voice stealing and key group conflicts.
593 *
594 * @param itKillEvent - event which caused the voice to be killed
595 */
596 void AbstractVoice::Kill(Pool<Event>::Iterator& itKillEvent) {
597 #if CONFIG_DEVMODE
598 if (!itKillEvent) dmsg(1,("AbstractVoice::Kill(): ERROR, !itKillEvent !!!\n"));
599 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("AbstractVoice::Kill(): ERROR, itKillEvent invalid !!!\n"));
600 #endif // CONFIG_DEVMODE
601
602 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
603 this->itKillEvent = itKillEvent;
604 }
605
606 Voice::PitchInfo AbstractVoice::CalculatePitchInfo(int PitchBend) {
607 PitchInfo pitch;
608 double pitchbasecents = InstrInfo.FineTune + RgnInfo.FineTune + GetEngine()->ScaleTuning[MIDIKey % 12];
609
610 // GSt behaviour: maximum transpose up is 40 semitones. If
611 // MIDI key is more than 40 semitones above unity note,
612 // the transpose is not done.
613 if (!SmplInfo.Unpitched && (MIDIKey - (int) RgnInfo.UnityNote) < 40) pitchbasecents += (MIDIKey - (int) RgnInfo.UnityNote) * 100;
614
615 pitch.PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(SmplInfo.SampleRate) / double(GetEngine()->SampleRate));
616 pitch.PitchBendRange = 1.0 / 8192.0 * 100.0 * InstrInfo.PitchbendRange;
617 pitch.PitchBend = RTMath::CentsToFreqRatio(PitchBend * pitch.PitchBendRange);
618
619 return pitch;
620 }
621
622 double AbstractVoice::CalculateVolume(double velocityAttenuation) {
623 // For 16 bit samples, we downscale by 32768 to convert from
624 // int16 value range to DSP value range (which is
625 // -1.0..1.0). For 24 bit, we downscale from int32.
626 float volume = velocityAttenuation / (SmplInfo.BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
627
628 volume *= GetSampleAttenuation() * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
629
630 // the volume of release triggered samples depends on note length
631 if (Type & Voice::type_release_trigger) {
632 float noteLength = float(GetEngine()->FrameTime + Delay -
633 GetNoteOnTime(MIDIKey) ) / GetEngine()->SampleRate;
634
635 volume *= GetReleaseTriggerAttenuation(noteLength);
636 }
637
638 return volume;
639 }
640
641 float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
642 return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
643 }
644
645 void AbstractVoice::EnterReleaseStage() {
646 pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
647 pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
648 }
649
650 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC