/[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 2015 - (show annotations) (download)
Sun Oct 25 22:22:52 2009 UTC (14 years, 5 months ago) by iliev
File size: 30091 byte(s)
* Refactoring: moved the independent code from gig::Voice to base classes
* SoundFont format engine: implemented EG1 & EG2

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

  ViewVC Help
Powered by ViewVC