/[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 2115 - (show annotations) (download)
Thu Aug 12 15:36:15 2010 UTC (13 years, 8 months ago) by persson
File size: 30851 byte(s)
* sfz engine: added support for controller triggered regions
  (on_locc/on_hicc)
* sfz engine: added support for loop_mode=one_shot

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

  ViewVC Help
Powered by ViewVC