/[svn]/linuxsampler/trunk/src/engines/sf2/Voice.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/sf2/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2012 - (show annotations) (download)
Fri Oct 23 17:53:17 2009 UTC (14 years, 5 months ago) by iliev
File size: 53212 byte(s)
* Refactoring: moved the independent code from
  the Gigasampler format engine to base classes
* SFZ format engine: experimental code (not usable yet)
* SoundFont format engine: experimental code (not usable yet)
* Fixed crash which may occur when MIDI key + transpose is out of range

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 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "../../common/Features.h"
25 #include "../gig/Synthesizer.h"
26 #include "../gig/Profiler.h"
27 #include "Engine.h"
28 #include "EngineChannel.h"
29
30 #include "Voice.h"
31
32 namespace LinuxSampler { namespace sf2 {
33
34 typedef LinuxSampler::gig::Profiler Profiler; // TODO: remove
35
36 Voice::Voice() {
37 pEngine = NULL;
38 pDiskThread = NULL;
39 PlaybackState = playback_state_end;
40 pLFO1 = new LFOUnsigned(1.0f); // amplitude EG (0..1 range)
41 pLFO2 = new LFOUnsigned(1.0f); // filter EG (0..1 range)
42 pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)
43 KeyGroup = 0;
44 SynthesisMode = 0; // set all mode bits to 0 first
45 // select synthesis implementation (asm core is not supported ATM)
46 #if 0 // CONFIG_ASM && ARCH_X86
47 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
48 #else
49 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
50 #endif
51 SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, Profiler::isEnabled());
52
53 finalSynthesisParameters.filterLeft.Reset();
54 finalSynthesisParameters.filterRight.Reset();
55 }
56
57 Voice::~Voice() {
58 if (pLFO1) delete pLFO1;
59 if (pLFO2) delete pLFO2;
60 if (pLFO3) delete pLFO3;
61 }
62
63 void Voice::SetEngine(LinuxSampler::Engine* pEngine) {
64 Engine* engine = static_cast<Engine*>(pEngine);
65 this->pEngine = engine;
66 this->pDiskThread = engine->pDiskThread;
67 dmsg(6,("Voice::SetEngine()\n"));
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 dimension 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 Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::sf2::Region* pRegion, type_t VoiceType, int iKeyGroup) {
85 this->pEngineChannel = pEngineChannel;
86 this->pRegion = pRegion;
87 Orphan = false;
88
89 #if CONFIG_DEVMODE
90 if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
91 dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
92 }
93 #endif // CONFIG_DEVMODE
94
95 Type = VoiceType;
96 MIDIKey = itNoteOnEvent->Param.Note.Key;
97 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
98 Delay = itNoteOnEvent->FragmentPos();
99 itTriggerEvent = itNoteOnEvent;
100 itKillEvent = Pool<Event>::Iterator();
101 KeyGroup = iKeyGroup;
102 pSample = pRegion->pSample; // sample won't change until the voice is finished
103
104 /*// calculate volume
105 const double velocityAttenuation = pRegion->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
106
107 // For 16 bit samples, we downscale by 32768 to convert from
108 // int16 value range to DSP value range (which is
109 // -1.0..1.0). For 24 bit, we downscale from int32.
110 float volume = velocityAttenuation / (pSample->BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
111
112 float volume = pRegion->SampleAttenuation * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
113 */ // TODO: ^^^
114 float volume = pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
115
116 // the volume of release triggered samples depends on note length
117 /**if (Type == type_release_trigger) {
118 float noteLength = float(pEngine->FrameTime + Delay -
119 pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
120 float attenuation = 1 - 0.01053 * (256 >> pRegion->ReleaseTriggerDecay) * noteLength;
121 if (attenuation <= 0) return -1;
122 volume *= attenuation;
123 }
124 */ // TODO: ^^^
125
126 // select channel mode (mono or stereo)
127 SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->GetChannelCount() == 2);
128 // select bit depth (16 or 24)
129 SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, (pSample->GetFrameSize() / pSample->GetChannelCount()) > 2);
130
131 // get starting crossfade volume level
132 /*float crossfadeVolume;
133 switch (pRegion->AttenuationController.type) {
134 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
135 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[128])];
136 break;
137 case ::gig::attenuation_ctrl_t::type_velocity:
138 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
139 break;
140 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
141 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[pRegion->AttenuationController.controller_number])];
142 break;
143 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
144 default:
145 crossfadeVolume = 1.0f;
146 }*/ // TODO: ^^^
147
148 VolumeLeft = volume * Engine::PanCurve[64 - pRegion->pan];
149 VolumeRight = volume * Engine::PanCurve[64 + pRegion->pan];
150
151 float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
152 //CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate); // TODO:
153 VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
154 PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
155 PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
156
157 /*finalSynthesisParameters.dPos = pRegion->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
158 Pos = pRegion->SampleStartOffset;*/ // TODO: ^^^
159 Pos = finalSynthesisParameters.dPos = 0;
160
161 // Check if the sample needs disk streaming or is too short for that
162 long cachedsamples = pSample->GetCache().Size / pSample->GetFrameSize();
163 DiskVoice = cachedsamples < pSample->GetTotalFrameCount();
164
165 //const DLS::sample_loop_t& loopinfo = pRegion->pSampleLoops[0]; // TODO:
166
167 if (DiskVoice) { // voice to be streamed from disk
168 if (cachedsamples > (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
169 MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->GetChannelCount(); //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)
170 } else {
171 // The cache is too small to fit a max sample buffer.
172 // Setting MaxRAMPos to 0 will probably cause a click
173 // in the audio, but it's better than not handling
174 // this case at all, which would have caused the
175 // unsigned MaxRAMPos to be set to a negative number.
176 MaxRAMPos = 0;
177 }
178
179 // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
180 //RAMLoop = (pRegion->SampleLoops && (loopinfo.LoopStart + loopinfo.LoopLength) <= MaxRAMPos); // TODO:
181 if (pDiskThread->OrderNewStream(&DiskStreamRef, pRegion, MaxRAMPos, false) < 0) {
182 dmsg(1,("Disk stream order failed!\n"));
183 KillImmediately();
184 return -1;
185 }
186 dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->GetTotalFrameCount(), MaxRAMPos, (RAMLoop) ? "yes" : "no"));
187 }
188 else { // RAM only voice
189 MaxRAMPos = cachedsamples;
190 /*RAMLoop = (pRegion->SampleLoops != 0);
191 dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no")); */ // TODO:
192 }
193 /*if (RAMLoop) {
194 loop.uiTotalCycles = pSample->LoopPlayCount;
195 loop.uiCyclesLeft = pSample->LoopPlayCount;
196 loop.uiStart = loopinfo.LoopStart;
197 loop.uiEnd = loopinfo.LoopStart + loopinfo.LoopLength;
198 loop.uiSize = loopinfo.LoopLength;
199 }*/ // TODO: ^^^
200
201 // calculate initial pitch value
202 {
203 double pitchbasecents = /* TODO: pEngineChannel->pInstrument->FineTune*/ + pRegion->fineTune + pEngine->ScaleTuning[MIDIKey % 12];
204
205 // GSt behaviour: maximum transpose up is 40 semitones. If
206 // MIDI key is more than 40 semitones above unity note,
207 // the transpose is not done.
208 /*if (pRegion->PitchTrack && (MIDIKey - (int) pRegion->UnityNote) < 40) pitchbasecents += (MIDIKey - (int) pRegion->UnityNote) * 100;
209
210 this->PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));
211 this->PitchBendRange = 1.0 / 8192.0 * 100.0 * pEngineChannel->pInstrument->PitchbendRange;
212 this->PitchBend = RTMath::CentsToFreqRatio(PitchBend * PitchBendRange);*/ // TODO: ^^^
213 }
214
215 // the length of the decay and release curves are dependent on the velocity
216 //const double velrelease = 1 / pRegion->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity); //TODO:
217
218 // setup EG 1 (VCA EG)
219 {
220 /* // get current value of EG1 controller
221 double eg1controllervalue;
222 switch (pRegion->EG1Controller.type) {
223 case ::gig::eg1_ctrl_t::type_none: // no controller defined
224 eg1controllervalue = 0;
225 break;
226 case ::gig::eg1_ctrl_t::type_channelaftertouch:
227 eg1controllervalue = pEngineChannel->ControllerTable[128];
228 break;
229 case ::gig::eg1_ctrl_t::type_velocity:
230 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
231 break;
232 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
233 eg1controllervalue = pEngineChannel->ControllerTable[pRegion->EG1Controller.controller_number];
234 break;
235 }
236 if (pRegion->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
237
238 // calculate influence of EG1 controller on EG1's parameters
239 // (eg1attack is different from the others)
240 double eg1attack = (pRegion->EG1ControllerAttackInfluence) ?
241 1 + 0.031 * (double) (pRegion->EG1ControllerAttackInfluence == 1 ?
242 1 : 1 << pRegion->EG1ControllerAttackInfluence) * eg1controllervalue : 1.0;
243 double eg1decay = (pRegion->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerDecayInfluence) * eg1controllervalue : 1.0;
244 double eg1release = (pRegion->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerReleaseInfluence) * eg1controllervalue : 1.0;
245
246 EG1.trigger(pRegion->EG1PreAttack,
247 pRegion->EG1Attack * eg1attack,
248 pRegion->EG1Hold,
249 pRegion->EG1Decay1 * eg1decay * velrelease,
250 pRegion->EG1Decay2 * eg1decay * velrelease,
251 pRegion->EG1InfiniteSustain,
252 pRegion->EG1Sustain,
253 pRegion->EG1Release * eg1release * velrelease,
254 velocityAttenuation,
255 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
256 }*/ // TODO: ^^^
257 EG1.trigger(0,
258 0,
259 false,
260 0,
261 0,
262 true,
263 100,
264 0,
265 1,
266 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
267 }
268
269 #ifdef CONFIG_INTERPOLATE_VOLUME
270 // setup initial volume in synthesis parameters
271 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
272 if (pEngineChannel->GetMute()) {
273 finalSynthesisParameters.fFinalVolumeLeft = 0;
274 finalSynthesisParameters.fFinalVolumeRight = 0;
275 }
276 else
277 #else
278 {
279 //float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel(); // TODO:
280 float finalVolume = pEngineChannel->MidiVolume;
281
282 finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * pEngineChannel->GlobalPanLeft;
283 finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
284 }
285 #endif
286 #endif
287
288 // setup EG 2 (VCF Cutoff EG)
289 /*{
290 // get current value of EG2 controller
291 double eg2controllervalue;
292 switch (pRegion->EG2Controller.type) {
293 case ::gig::eg2_ctrl_t::type_none: // no controller defined
294 eg2controllervalue = 0;
295 break;
296 case ::gig::eg2_ctrl_t::type_channelaftertouch:
297 eg2controllervalue = pEngineChannel->ControllerTable[128];
298 break;
299 case ::gig::eg2_ctrl_t::type_velocity:
300 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
301 break;
302 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
303 eg2controllervalue = pEngineChannel->ControllerTable[pRegion->EG2Controller.controller_number];
304 break;
305 }
306 if (pRegion->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
307
308 // calculate influence of EG2 controller on EG2's parameters
309 double eg2attack = (pRegion->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerAttackInfluence) * eg2controllervalue : 1.0;
310 double eg2decay = (pRegion->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerDecayInfluence) * eg2controllervalue : 1.0;
311 double eg2release = (pRegion->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerReleaseInfluence) * eg2controllervalue : 1.0;
312
313 EG2.trigger(pRegion->EG2PreAttack,
314 pRegion->EG2Attack * eg2attack,
315 false,
316 pRegion->EG2Decay1 * eg2decay * velrelease,
317 pRegion->EG2Decay2 * eg2decay * velrelease,
318 pRegion->EG2InfiniteSustain,
319 pRegion->EG2Sustain,
320 pRegion->EG2Release * eg2release * velrelease,
321 velocityAttenuation,
322 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
323 }
324
325
326 // setup EG 3 (VCO EG)
327 {
328 // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
329 bool bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
330 float eg3depth = (bPortamento)
331 ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
332 : RTMath::CentsToFreqRatio(pRegion->EG3Depth);
333 float eg3time = (bPortamento)
334 ? pEngineChannel->PortamentoTime
335 : pRegion->EG3Attack;
336 EG3.trigger(eg3depth, eg3time, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
337 dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
338 }
339
340
341 // setup LFO 1 (VCA LFO)
342 {
343 uint16_t lfo1_internal_depth;
344 switch (pRegion->LFO1Controller) {
345 case ::gig::lfo1_ctrl_internal:
346 lfo1_internal_depth = pRegion->LFO1InternalDepth;
347 pLFO1->ExtController = 0; // no external controller
348 bLFO1Enabled = (lfo1_internal_depth > 0);
349 break;
350 case ::gig::lfo1_ctrl_modwheel:
351 lfo1_internal_depth = 0;
352 pLFO1->ExtController = 1; // MIDI controller 1
353 bLFO1Enabled = (pRegion->LFO1ControlDepth > 0);
354 break;
355 case ::gig::lfo1_ctrl_breath:
356 lfo1_internal_depth = 0;
357 pLFO1->ExtController = 2; // MIDI controller 2
358 bLFO1Enabled = (pRegion->LFO1ControlDepth > 0);
359 break;
360 case ::gig::lfo1_ctrl_internal_modwheel:
361 lfo1_internal_depth = pRegion->LFO1InternalDepth;
362 pLFO1->ExtController = 1; // MIDI controller 1
363 bLFO1Enabled = (lfo1_internal_depth > 0 || pRegion->LFO1ControlDepth > 0);
364 break;
365 case ::gig::lfo1_ctrl_internal_breath:
366 lfo1_internal_depth = pRegion->LFO1InternalDepth;
367 pLFO1->ExtController = 2; // MIDI controller 2
368 bLFO1Enabled = (lfo1_internal_depth > 0 || pRegion->LFO1ControlDepth > 0);
369 break;
370 default:
371 lfo1_internal_depth = 0;
372 pLFO1->ExtController = 0; // no external controller
373 bLFO1Enabled = false;
374 }
375 if (bLFO1Enabled) {
376 pLFO1->trigger(pRegion->LFO1Frequency,
377 start_level_min,
378 lfo1_internal_depth,
379 pRegion->LFO1ControlDepth,
380 pRegion->LFO1FlipPhase,
381 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
382 pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
383 }
384 }
385
386
387 // setup LFO 2 (VCF Cutoff LFO)
388 {
389 uint16_t lfo2_internal_depth;
390 switch (pRegion->LFO2Controller) {
391 case ::gig::lfo2_ctrl_internal:
392 lfo2_internal_depth = pRegion->LFO2InternalDepth;
393 pLFO2->ExtController = 0; // no external controller
394 bLFO2Enabled = (lfo2_internal_depth > 0);
395 break;
396 case ::gig::lfo2_ctrl_modwheel:
397 lfo2_internal_depth = 0;
398 pLFO2->ExtController = 1; // MIDI controller 1
399 bLFO2Enabled = (pRegion->LFO2ControlDepth > 0);
400 break;
401 case ::gig::lfo2_ctrl_foot:
402 lfo2_internal_depth = 0;
403 pLFO2->ExtController = 4; // MIDI controller 4
404 bLFO2Enabled = (pRegion->LFO2ControlDepth > 0);
405 break;
406 case ::gig::lfo2_ctrl_internal_modwheel:
407 lfo2_internal_depth = pRegion->LFO2InternalDepth;
408 pLFO2->ExtController = 1; // MIDI controller 1
409 bLFO2Enabled = (lfo2_internal_depth > 0 || pRegion->LFO2ControlDepth > 0);
410 break;
411 case ::gig::lfo2_ctrl_internal_foot:
412 lfo2_internal_depth = pRegion->LFO2InternalDepth;
413 pLFO2->ExtController = 4; // MIDI controller 4
414 bLFO2Enabled = (lfo2_internal_depth > 0 || pRegion->LFO2ControlDepth > 0);
415 break;
416 default:
417 lfo2_internal_depth = 0;
418 pLFO2->ExtController = 0; // no external controller
419 bLFO2Enabled = false;
420 }
421 if (bLFO2Enabled) {
422 pLFO2->trigger(pRegion->LFO2Frequency,
423 start_level_max,
424 lfo2_internal_depth,
425 pRegion->LFO2ControlDepth,
426 pRegion->LFO2FlipPhase,
427 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
428 pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
429 }
430 }
431
432
433 // setup LFO 3 (VCO LFO)
434 {
435 uint16_t lfo3_internal_depth;
436 switch (pRegion->LFO3Controller) {
437 case ::gig::lfo3_ctrl_internal:
438 lfo3_internal_depth = pRegion->LFO3InternalDepth;
439 pLFO3->ExtController = 0; // no external controller
440 bLFO3Enabled = (lfo3_internal_depth > 0);
441 break;
442 case ::gig::lfo3_ctrl_modwheel:
443 lfo3_internal_depth = 0;
444 pLFO3->ExtController = 1; // MIDI controller 1
445 bLFO3Enabled = (pRegion->LFO3ControlDepth > 0);
446 break;
447 case ::gig::lfo3_ctrl_aftertouch:
448 lfo3_internal_depth = 0;
449 pLFO3->ExtController = 128;
450 bLFO3Enabled = true;
451 break;
452 case ::gig::lfo3_ctrl_internal_modwheel:
453 lfo3_internal_depth = pRegion->LFO3InternalDepth;
454 pLFO3->ExtController = 1; // MIDI controller 1
455 bLFO3Enabled = (lfo3_internal_depth > 0 || pRegion->LFO3ControlDepth > 0);
456 break;
457 case ::gig::lfo3_ctrl_internal_aftertouch:
458 lfo3_internal_depth = pRegion->LFO3InternalDepth;
459 pLFO1->ExtController = 128;
460 bLFO3Enabled = (lfo3_internal_depth > 0 || pRegion->LFO3ControlDepth > 0);
461 break;
462 default:
463 lfo3_internal_depth = 0;
464 pLFO3->ExtController = 0; // no external controller
465 bLFO3Enabled = false;
466 }
467 if (bLFO3Enabled) {
468 pLFO3->trigger(pRegion->LFO3Frequency,
469 start_level_mid,
470 lfo3_internal_depth,
471 pRegion->LFO3ControlDepth,
472 false,
473 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
474 pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
475 }
476 }*/ // TODO: ^^^
477
478
479 /*#if CONFIG_FORCE_FILTER
480 const bool bUseFilter = true;
481 #else // use filter only if instrument file told so
482 const bool bUseFilter = pRegion->VCFEnabled;
483 #endif // CONFIG_FORCE_FILTER
484 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
485 if (bUseFilter) {
486 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
487 VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
488 #else // use the one defined in the instrument file
489 switch (pRegion->VCFCutoffController) {
490 case ::gig::vcf_cutoff_ctrl_modwheel:
491 VCFCutoffCtrl.controller = 1;
492 break;
493 case ::gig::vcf_cutoff_ctrl_effect1:
494 VCFCutoffCtrl.controller = 12;
495 break;
496 case ::gig::vcf_cutoff_ctrl_effect2:
497 VCFCutoffCtrl.controller = 13;
498 break;
499 case ::gig::vcf_cutoff_ctrl_breath:
500 VCFCutoffCtrl.controller = 2;
501 break;
502 case ::gig::vcf_cutoff_ctrl_foot:
503 VCFCutoffCtrl.controller = 4;
504 break;
505 case ::gig::vcf_cutoff_ctrl_sustainpedal:
506 VCFCutoffCtrl.controller = 64;
507 break;
508 case ::gig::vcf_cutoff_ctrl_softpedal:
509 VCFCutoffCtrl.controller = 67;
510 break;
511 case ::gig::vcf_cutoff_ctrl_genpurpose7:
512 VCFCutoffCtrl.controller = 82;
513 break;
514 case ::gig::vcf_cutoff_ctrl_genpurpose8:
515 VCFCutoffCtrl.controller = 83;
516 break;
517 case ::gig::vcf_cutoff_ctrl_aftertouch:
518 VCFCutoffCtrl.controller = 128;
519 break;
520 case ::gig::vcf_cutoff_ctrl_none:
521 default:
522 VCFCutoffCtrl.controller = 0;
523 break;
524 }
525 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
526
527 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
528 VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
529 #else // use the one defined in the instrument file
530 switch (pRegion->VCFResonanceController) {
531 case ::gig::vcf_res_ctrl_genpurpose3:
532 VCFResonanceCtrl.controller = 18;
533 break;
534 case ::gig::vcf_res_ctrl_genpurpose4:
535 VCFResonanceCtrl.controller = 19;
536 break;
537 case ::gig::vcf_res_ctrl_genpurpose5:
538 VCFResonanceCtrl.controller = 80;
539 break;
540 case ::gig::vcf_res_ctrl_genpurpose6:
541 VCFResonanceCtrl.controller = 81;
542 break;
543 case ::gig::vcf_res_ctrl_none:
544 default:
545 VCFResonanceCtrl.controller = 0;
546 }
547 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
548
549 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
550 finalSynthesisParameters.filterLeft.SetType(pRegion->VCFType);
551 finalSynthesisParameters.filterRight.SetType(pRegion->VCFType);
552 #else // override filter type
553 finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
554 finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
555 #endif // CONFIG_OVERRIDE_FILTER_TYPE
556
557 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
558 VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
559
560 // calculate cutoff frequency
561 float cutoff = pRegion->GetVelocityCutoff(itNoteOnEvent->Param.Note.Velocity);
562 if (pRegion->VCFKeyboardTracking) {
563 cutoff *= exp((itNoteOnEvent->Param.Note.Key - pRegion->VCFKeyboardTrackingBreakpoint) * 0.057762265f); // (ln(2) / 12)
564 }
565 CutoffBase = cutoff;
566
567 int cvalue;
568 if (VCFCutoffCtrl.controller) {
569 cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
570 if (pRegion->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
571 // VCFVelocityScale in this case means Minimum cutoff
572 if (cvalue < pRegion->VCFVelocityScale) cvalue = pRegion->VCFVelocityScale;
573 }
574 else {
575 cvalue = pRegion->VCFCutoff;
576 }
577 cutoff *= float(cvalue);
578 if (cutoff > 127.0f) cutoff = 127.0f;
579
580 // calculate resonance
581 float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pRegion->VCFResonance);
582
583 VCFCutoffCtrl.fvalue = cutoff;
584 VCFResonanceCtrl.fvalue = resonance;
585 }
586 else {
587 VCFCutoffCtrl.controller = 0;
588 VCFResonanceCtrl.controller = 0;
589 }*/ // TODO: ^^^
590
591 return 0; // success
592 }
593
594 /**
595 * Renders the audio data for this voice for the current audio fragment.
596 * The sample input data can either come from RAM (cached sample or sample
597 * part) or directly from disk. The output signal will be rendered by
598 * resampling / interpolation. If this voice is a disk streaming voice and
599 * the voice completely played back the cached RAM part of the sample, it
600 * will automatically switch to disk playback for the next RenderAudio()
601 * call.
602 *
603 * @param Samples - number of samples to be rendered in this audio fragment cycle
604 */
605 void Voice::Render(uint Samples) {
606 // select default values for synthesis mode bits
607 SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
608
609 switch (this->PlaybackState) {
610
611 case playback_state_init:
612 this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
613 // no break - continue with playback_state_ram
614
615 case playback_state_ram: {
616 //if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
617
618 // render current fragment
619 Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
620 /*uint8_t* pBuf = (uint8_t*)pSample->GetCache().pStart;
621 pBuf += pRegion->startAddrsOffset * pSample->GetFrameSize();
622 Synthesize(Samples, (sample_t*) pBuf, Delay);*/ // TODO: implement startAddrsOffset
623
624 if (DiskVoice) {
625 // check if we reached the allowed limit of the sample RAM cache
626 if (finalSynthesisParameters.dPos > MaxRAMPos) {
627 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", finalSynthesisParameters.dPos));
628 this->PlaybackState = playback_state_disk;
629 }
630 } else if (finalSynthesisParameters.dPos >= pSample->GetCache().Size / pSample->GetFrameSize()) {
631 this->PlaybackState = playback_state_end;
632 }
633 }
634 break;
635
636 case playback_state_disk: {
637 if (!DiskStreamRef.pStream) {
638 // check if the disk thread created our ordered disk stream in the meantime
639 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
640 if (!DiskStreamRef.pStream) {
641 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
642 KillImmediately();
643 return;
644 }
645 DiskStreamRef.pStream->IncrementReadPos(pSample->GetChannelCount() * (int(finalSynthesisParameters.dPos) - MaxRAMPos));
646 finalSynthesisParameters.dPos -= int(finalSynthesisParameters.dPos);
647 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
648 }
649
650 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
651
652 // add silence sample at the end if we reached the end of the stream (for the interpolator)
653 if (DiskStreamRef.State == Stream::state_end) {
654 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->GetChannelCount() + 6; // +6 for the interpolator algorithm
655 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
656 // remember how many sample words there are before any silence has been added
657 if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
658 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
659 }
660 }
661
662 sample_t* ptr = (sample_t*)DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
663
664 // render current audio fragment
665 Synthesize(Samples, ptr, Delay);
666
667 const int iPos = (int) finalSynthesisParameters.dPos;
668 const int readSampleWords = iPos * pSample->GetChannelCount(); // amount of sample words actually been read
669 DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
670 finalSynthesisParameters.dPos -= iPos; // just keep fractional part of playback position
671
672 // change state of voice to 'end' if we really reached the end of the sample data
673 if (RealSampleWordsLeftToRead >= 0) {
674 RealSampleWordsLeftToRead -= readSampleWords;
675 if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
676 }
677 }
678 break;
679
680 case playback_state_end:
681 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
682 break;
683 }
684
685 // Reset delay
686 Delay = 0;
687
688 itTriggerEvent = Pool<Event>::Iterator();
689
690 // If sample stream or release stage finished, kill the voice
691 if (PlaybackState == playback_state_end || EG1.getSegmentType() == EGADSR::segment_end) KillImmediately();
692 }
693
694 /**
695 * Resets voice variables. Should only be called if rendering process is
696 * suspended / not running.
697 */
698 void Voice::Reset() {
699 finalSynthesisParameters.filterLeft.Reset();
700 finalSynthesisParameters.filterRight.Reset();
701 DiskStreamRef.pStream = NULL;
702 DiskStreamRef.hStream = 0;
703 DiskStreamRef.State = Stream::state_unused;
704 DiskStreamRef.OrderID = 0;
705 PlaybackState = playback_state_end;
706 itTriggerEvent = Pool<Event>::Iterator();
707 itKillEvent = Pool<Event>::Iterator();
708 }
709
710 /**
711 * Process given list of MIDI note on, note off and sustain pedal events
712 * for the given time.
713 *
714 * @param itEvent - iterator pointing to the next event to be processed
715 * @param End - youngest time stamp where processing should be stopped
716 */
717 void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
718 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
719 if (itEvent->Type == Event::type_release) {
720 EG1.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
721 EG2.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
722 } else if (itEvent->Type == Event::type_cancel_release) {
723 EG1.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
724 EG2.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
725 }
726 }
727 }
728
729 /**
730 * Process given list of MIDI control change and pitch bend events for
731 * the given time.
732 *
733 * @param itEvent - iterator pointing to the next event to be processed
734 * @param End - youngest time stamp where processing should be stopped
735 */
736 void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
737 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
738 if (itEvent->Type == Event::type_control_change &&
739 itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
740 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
741 processCutoffEvent(itEvent);
742 }
743 if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
744 processResonanceEvent(itEvent);
745 }
746 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
747 pLFO1->update(itEvent->Param.CC.Value);
748 }
749 if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
750 pLFO2->update(itEvent->Param.CC.Value);
751 }
752 if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
753 pLFO3->update(itEvent->Param.CC.Value);
754 }
755 /*if (pRegion->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
756 itEvent->Param.CC.Controller == pRegion->AttenuationController.controller_number) {
757 CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
758 }*/ // TODO:
759 if (itEvent->Param.CC.Controller == 7) { // volume
760 VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]);
761 } else if (itEvent->Param.CC.Controller == 10) { // panpot
762 PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
763 PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
764 }
765 } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
766 processPitchEvent(itEvent);
767 }
768 }
769 }
770
771 void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
772 PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch * PitchBendRange);
773 }
774
775 void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
776 /*int ccvalue = itEvent->Param.CC.Value;
777 if (VCFCutoffCtrl.value == ccvalue) return;
778 VCFCutoffCtrl.value == ccvalue;
779 if (pRegion->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
780 if (ccvalue < pRegion->VCFVelocityScale) ccvalue = pRegion->VCFVelocityScale;
781 float cutoff = CutoffBase * float(ccvalue);
782 if (cutoff > 127.0f) cutoff = 127.0f;
783
784 VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
785 fFinalCutoff = cutoff;*/ // TODO: ^^^
786 }
787
788 void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
789 // convert absolute controller value to differential
790 const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
791 VCFResonanceCtrl.value = itEvent->Param.CC.Value;
792 const float resonancedelta = (float) ctrldelta;
793 fFinalResonance += resonancedelta;
794 // needed for initialization of parameter
795 VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
796 }
797
798 /**
799 * Synthesizes the current audio fragment for this voice.
800 *
801 * @param Samples - number of sample points to be rendered in this audio
802 * fragment cycle
803 * @param pSrc - pointer to input sample data
804 * @param Skip - number of sample points to skip in output buffer
805 */
806 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
807 finalSynthesisParameters.pOutLeft = &pEngineChannel->pChannelLeft->Buffer()[Skip];
808 finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip];
809 finalSynthesisParameters.pSrc = pSrc;
810
811 RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
812 RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
813
814
815 if (itTriggerEvent) { // skip events that happened before this voice was triggered
816 while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
817 // we can't simply compare the timestamp here, because note events
818 // might happen on the same time stamp, so we have to deal on the
819 // actual sequence the note events arrived instead (see bug #112)
820 for (; itNoteEvent; ++itNoteEvent) {
821 if (itTriggerEvent == itNoteEvent) {
822 ++itNoteEvent;
823 break;
824 }
825 }
826 }
827
828 uint killPos;
829 if (itKillEvent) {
830 int maxFadeOutPos = Samples - pEngine->MinFadeOutSamples;
831 if (maxFadeOutPos < 0) {
832 // There's not enough space in buffer to do a fade out
833 // from max volume (this can only happen for audio
834 // drivers that use Samples < MaxSamplesPerCycle).
835 // End the EG1 here, at pos 0, with a shorter max fade
836 // out time.
837 EG1.enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
838 itKillEvent = Pool<Event>::Iterator();
839 } else {
840 killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
841 }
842 }
843
844 uint i = Skip;
845 /*while (i < Samples) {
846 int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
847
848 // initialize all final synthesis parameters
849 fFinalCutoff = VCFCutoffCtrl.fvalue;
850 fFinalResonance = VCFResonanceCtrl.fvalue;
851
852 // process MIDI control change and pitchbend events for this subfragment
853 processCCEvents(itCCEvent, iSubFragmentEnd);
854
855 finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
856 float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
857 #ifdef CONFIG_PROCESS_MUTED_CHANNELS
858 if (pEngineChannel->GetMute()) fFinalVolume = 0;
859 #endif
860
861 // process transition events (note on, note off & sustain pedal)
862 processTransitionEvents(itNoteEvent, iSubFragmentEnd);
863
864 // if the voice was killed in this subfragment, or if the
865 // filter EG is finished, switch EG1 to fade out stage
866 if ((itKillEvent && killPos <= iSubFragmentEnd) ||
867 (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
868 EG2.getSegmentType() == EGADSR::segment_end)) {
869 EG1.enterFadeOutStage();
870 itKillEvent = Pool<Event>::Iterator();
871 }
872
873 // process envelope generators
874 switch (EG1.getSegmentType()) {
875 case EGADSR::segment_lin:
876 fFinalVolume *= EG1.processLin();
877 break;
878 case EGADSR::segment_exp:
879 fFinalVolume *= EG1.processExp();
880 break;
881 case EGADSR::segment_end:
882 fFinalVolume *= EG1.getLevel();
883 break; // noop
884 }
885 switch (EG2.getSegmentType()) {
886 case EGADSR::segment_lin:
887 fFinalCutoff *= EG2.processLin();
888 break;
889 case EGADSR::segment_exp:
890 fFinalCutoff *= EG2.processExp();
891 break;
892 case EGADSR::segment_end:
893 fFinalCutoff *= EG2.getLevel();
894 break; // noop
895 }
896 if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
897
898 // process low frequency oscillators
899 if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
900 if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
901 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
902
903 // limit the pitch so we don't read outside the buffer
904 finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
905
906 // if filter enabled then update filter coefficients
907 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
908 finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
909 finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
910 }
911
912 // do we need resampling?
913 const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
914 const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
915 const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
916 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
917 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
918
919 fFinalVolume = 1.0;
920 // prepare final synthesis parameters structure
921 finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
922 #ifdef CONFIG_INTERPOLATE_VOLUME
923 finalSynthesisParameters.fFinalVolumeDeltaLeft = 1;
924 finalSynthesisParameters.fFinalVolumeDeltaRight = 1;
925 #else
926 finalSynthesisParameters.fFinalVolumeLeft =1;
927 finalSynthesisParameters.fFinalVolumeRight =1;
928 #endif
929 // render audio for one subfragment
930 //RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
931
932 // stop the rendering if volume EG is finished
933 if (EG1.getSegmentType() == EGADSR::segment_end) break;
934
935 const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
936
937 // increment envelopes' positions
938 if (EG1.active()) {
939
940 // 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
941 if (pRegion->SampleLoops && Pos <= pRegion->pSampleLoops[0].LoopStart && pRegion->pSampleLoops[0].LoopStart < newPos) {
942 EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
943 } // TODO:
944
945 EG1.increment(1);
946 if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
947 }
948 if (EG2.active()) {
949 EG2.increment(1);
950 if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
951 }
952 EG3.increment(1);
953 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
954
955 Pos = newPos;
956 i = iSubFragmentEnd;
957 }*/
958
959 int32_t* pSrc2 = NULL;
960 if((pSample->GetFrameSize() / pSample->GetChannelCount()) == 4) pSrc2 = (int32_t*)pSrc;
961 for(int j = 0; j < Samples; j++) {
962 int lp, rp;
963 if(pSample->GetChannelCount() == 1) {
964 lp = (int)(finalSynthesisParameters.dPos + j);
965 rp = (int)(finalSynthesisParameters.dPos + j);
966 } else {
967 lp = (int)(finalSynthesisParameters.dPos + j) * 2;
968 rp = (int)(finalSynthesisParameters.dPos + j) * 2 + 1;
969 }
970 float left, right;
971 if(pSrc2 != NULL) {
972 left = pSrc2[lp]; right = pSrc2[rp];
973 } else {
974 left = pSrc[lp]; right = pSrc[rp];
975 }
976 float f = (pSrc2 == NULL ? 32768.0f : 32768.0f * 65536.0f);
977 left /= f; right /= f;
978 finalSynthesisParameters.pOutLeft[j] += left;
979 finalSynthesisParameters.pOutRight[j] += right;
980 }
981 finalSynthesisParameters.dPos += Samples;
982 }
983
984 /** @brief Update current portamento position.
985 *
986 * Will be called when portamento mode is enabled to get the final
987 * portamento position of this active voice from where the next voice(s)
988 * might continue to slide on.
989 *
990 * @param itNoteOffEvent - event which causes this voice to die soon
991 */
992 void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
993 const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
994 pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
995 }
996
997 /**
998 * Immediately kill the voice. This method should not be used to kill
999 * a normal, active voice, because it doesn't take care of things like
1000 * fading down the volume level to avoid clicks and regular processing
1001 * until the kill event actually occured!
1002 *
1003 * If it's necessary to know when the voice's disk stream was actually
1004 * deleted, then one can set the optional @a bRequestNotification
1005 * parameter and this method will then return the handle of the disk
1006 * stream (unique identifier) and one can use this handle to poll the
1007 * disk thread if this stream has been deleted. In any case this method
1008 * will return immediately and will not block until the stream actually
1009 * was deleted.
1010 *
1011 * @param bRequestNotification - (optional) whether the disk thread shall
1012 * provide a notification once it deleted
1013 * the respective disk stream
1014 * (default=false)
1015 * @returns handle to the voice's disk stream or @c Stream::INVALID_HANDLE
1016 * if the voice did not use a disk stream at all
1017 * @see Kill()
1018 */
1019 Stream::Handle Voice::KillImmediately(bool bRequestNotification) {
1020 Stream::Handle hStream = Stream::INVALID_HANDLE;
1021 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1022 pDiskThread->OrderDeletionOfStream(&DiskStreamRef, bRequestNotification);
1023 hStream = DiskStreamRef.hStream;
1024 }
1025 Reset();
1026 return hStream;
1027 }
1028
1029 /**
1030 * Kill the voice in regular sense. Let the voice render audio until
1031 * the kill event actually occured and then fade down the volume level
1032 * very quickly and let the voice die finally. Unlike a normal release
1033 * of a voice, a kill process cannot be cancalled and is therefore
1034 * usually used for voice stealing and key group conflicts.
1035 *
1036 * @param itKillEvent - event which caused the voice to be killed
1037 */
1038 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1039 #if CONFIG_DEVMODE
1040 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1041 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1042 #endif // CONFIG_DEVMODE
1043
1044 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1045 this->itKillEvent = itKillEvent;
1046 }
1047
1048 }} // namespace LinuxSampler::sf2

  ViewVC Help
Powered by ViewVC