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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 111 - (show annotations) (download)
Sat Jun 5 20:55:50 2004 UTC (19 years, 9 months ago) by schoenebeck
File size: 44058 byte(s)
* LSCP allows now comment lines, that is lines starting with a hash ('#')
  character
* src/engines/gig/Voice.cpp: fixed "SET CHANNEL VOLUME" bug

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "EGADSR.h"
24 #include "Manipulator.h"
25
26 #include "Voice.h"
27
28 namespace LinuxSampler { namespace gig {
29
30 // FIXME: no support for layers (nor crossfades) yet
31
32 const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
33
34 const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
35
36 float Voice::CalculateFilterCutoffCoeff() {
37 return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);
38 }
39
40 int Voice::CalculateFilterUpdateMask() {
41 if (FILTER_UPDATE_PERIOD <= 0) return 0;
42 int power_of_two;
43 for (power_of_two = 0; 1<<power_of_two < FILTER_UPDATE_PERIOD; power_of_two++);
44 return (1 << power_of_two) - 1;
45 }
46
47 Voice::Voice() {
48 pEngine = NULL;
49 pDiskThread = NULL;
50 Active = false;
51 pEG1 = NULL;
52 pEG2 = NULL;
53 pEG3 = NULL;
54 pVCAManipulator = NULL;
55 pVCFCManipulator = NULL;
56 pVCOManipulator = NULL;
57 pLFO1 = NULL;
58 pLFO2 = NULL;
59 pLFO3 = NULL;
60 }
61
62 Voice::~Voice() {
63 if (pEG1) delete pEG1;
64 if (pEG2) delete pEG2;
65 if (pEG3) delete pEG3;
66 if (pLFO1) delete pLFO1;
67 if (pLFO2) delete pLFO2;
68 if (pLFO3) delete pLFO3;
69 if (pVCAManipulator) delete pVCAManipulator;
70 if (pVCFCManipulator) delete pVCFCManipulator;
71 if (pVCOManipulator) delete pVCOManipulator;
72 }
73
74 void Voice::SetOutput(AudioOutputDevice* pAudioOutputDevice) {
75 this->pOutputLeft = pAudioOutputDevice->Channel(0)->Buffer();
76 this->pOutputRight = pAudioOutputDevice->Channel(1)->Buffer();
77 this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();
78 this->SampleRate = pAudioOutputDevice->SampleRate();
79 }
80
81 void Voice::SetEngine(Engine* pEngine) {
82 this->pEngine = pEngine;
83
84 // delete old objects
85 if (pEG1) delete pEG1;
86 if (pEG2) delete pEG2;
87 if (pEG3) delete pEG3;
88 if (pVCAManipulator) delete pVCAManipulator;
89 if (pVCFCManipulator) delete pVCFCManipulator;
90 if (pVCOManipulator) delete pVCOManipulator;
91 if (pLFO1) delete pLFO1;
92 if (pLFO2) delete pLFO2;
93 if (pLFO3) delete pLFO3;
94
95 // create new ones
96 pEG1 = new EGADSR(pEngine, Event::destination_vca);
97 pEG2 = new EGADSR(pEngine, Event::destination_vcfc);
98 pEG3 = new EGDecay(pEngine, Event::destination_vco);
99 pVCAManipulator = new VCAManipulator(pEngine);
100 pVCFCManipulator = new VCFCManipulator(pEngine);
101 pVCOManipulator = new VCOManipulator(pEngine);
102 pLFO1 = new LFO<gig::VCAManipulator>(0.0f, 1.0f, LFO<VCAManipulator>::propagation_top_down, pVCAManipulator, pEngine->pEventPool);
103 pLFO2 = new LFO<gig::VCFCManipulator>(0.0f, 1.0f, LFO<VCFCManipulator>::propagation_top_down, pVCFCManipulator, pEngine->pEventPool);
104 pLFO3 = new LFO<gig::VCOManipulator>(-1200.0f, 1200.0f, LFO<VCOManipulator>::propagation_middle_balanced, pVCOManipulator, pEngine->pEventPool); // +-1 octave (+-1200 cents) max.
105
106 this->pDiskThread = pEngine->pDiskThread;
107 dmsg(6,("Voice::SetEngine()\n"));
108 }
109
110 /**
111 * Initializes and triggers the voice, a disk stream will be launched if
112 * needed.
113 *
114 * @param pNoteOnEvent - event that caused triggering of this voice
115 * @param PitchBend - MIDI detune factor (-8192 ... +8191)
116 * @param pInstrument - points to the loaded instrument which provides sample wave(s) and articulation data
117 * @returns 0 on success, a value < 0 if something failed
118 */
119 int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument) {
120 if (!pInstrument) {
121 dmsg(1,("voice::trigger: !pInstrument\n"));
122 exit(EXIT_FAILURE);
123 }
124
125 Active = true;
126 MIDIKey = pNoteOnEvent->Key;
127 pRegion = pInstrument->GetRegion(MIDIKey);
128 PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
129 Pos = 0;
130 Delay = pNoteOnEvent->FragmentPos();
131 pTriggerEvent = pNoteOnEvent;
132
133 if (!pRegion) {
134 std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;
135 Kill();
136 return -1;
137 }
138
139 //TODO: current MIDI controller values are not taken into account yet
140 ::gig::DimensionRegion* pDimRgn = NULL;
141 for (int i = pRegion->Dimensions - 1; i >= 0; i--) { // Check if instrument has a velocity split
142 if (pRegion->pDimensionDefinitions[i].dimension == ::gig::dimension_velocity) {
143 uint DimValues[5] = {0,0,0,0,0};
144 DimValues[i] = pNoteOnEvent->Velocity;
145 pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);
146 break;
147 }
148 }
149 if (!pDimRgn) { // if there was no velocity split
150 pDimRgn = pRegion->GetDimensionRegionByValue(0,0,0,0,0);
151 }
152
153 pSample = pDimRgn->pSample; // sample won't change until the voice is finished
154
155 // Check if the sample needs disk streaming or is too short for that
156 long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
157 DiskVoice = cachedsamples < pSample->SamplesTotal;
158
159 if (DiskVoice) { // voice to be streamed from disk
160 MaxRAMPos = cachedsamples - (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels; //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)
161
162 // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
163 if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
164 RAMLoop = true;
165 LoopCyclesLeft = pSample->LoopPlayCount;
166 }
167 else RAMLoop = false;
168
169 if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
170 dmsg(1,("Disk stream order failed!\n"));
171 Kill();
172 return -1;
173 }
174 dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
175 }
176 else { // RAM only voice
177 MaxRAMPos = cachedsamples;
178 if (pSample->Loops) {
179 RAMLoop = true;
180 LoopCyclesLeft = pSample->LoopPlayCount;
181 }
182 else RAMLoop = false;
183 dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
184 }
185
186
187 // calculate initial pitch value
188 {
189 double pitchbasecents = pDimRgn->FineTune * 10;
190 if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
191 this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents);
192 this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
193 }
194
195
196 Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
197
198
199 // setup EG 1 (VCA EG)
200 {
201 // get current value of EG1 controller
202 double eg1controllervalue;
203 switch (pDimRgn->EG1Controller.type) {
204 case ::gig::eg1_ctrl_t::type_none: // no controller defined
205 eg1controllervalue = 0;
206 break;
207 case ::gig::eg1_ctrl_t::type_channelaftertouch:
208 eg1controllervalue = 0; // TODO: aftertouch not yet supported
209 break;
210 case ::gig::eg1_ctrl_t::type_velocity:
211 eg1controllervalue = pNoteOnEvent->Velocity;
212 break;
213 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
214 eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];
215 break;
216 }
217 if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
218
219 // calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned)
220 double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 0.0;
221 double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 0.0;
222 double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0;
223
224 pEG1->Trigger(pDimRgn->EG1PreAttack,
225 pDimRgn->EG1Attack + eg1attack,
226 pDimRgn->EG1Hold,
227 pSample->LoopStart,
228 pDimRgn->EG1Decay1 + eg1decay,
229 pDimRgn->EG1Decay2 + eg1decay,
230 pDimRgn->EG1InfiniteSustain,
231 pDimRgn->EG1Sustain,
232 pDimRgn->EG1Release + eg1release,
233 Delay);
234 }
235
236
237 #if ENABLE_FILTER
238 // setup EG 2 (VCF Cutoff EG)
239 {
240 // get current value of EG2 controller
241 double eg2controllervalue;
242 switch (pDimRgn->EG2Controller.type) {
243 case ::gig::eg2_ctrl_t::type_none: // no controller defined
244 eg2controllervalue = 0;
245 break;
246 case ::gig::eg2_ctrl_t::type_channelaftertouch:
247 eg2controllervalue = 0; // TODO: aftertouch not yet supported
248 break;
249 case ::gig::eg2_ctrl_t::type_velocity:
250 eg2controllervalue = pNoteOnEvent->Velocity;
251 break;
252 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
253 eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];
254 break;
255 }
256 if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
257
258 // calculate influence of EG2 controller on EG2's parameters (TODO: needs to be fine tuned)
259 double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 0.0;
260 double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 0.0;
261 double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 0.0;
262
263 pEG2->Trigger(pDimRgn->EG2PreAttack,
264 pDimRgn->EG2Attack + eg2attack,
265 false,
266 pSample->LoopStart,
267 pDimRgn->EG2Decay1 + eg2decay,
268 pDimRgn->EG2Decay2 + eg2decay,
269 pDimRgn->EG2InfiniteSustain,
270 pDimRgn->EG2Sustain,
271 pDimRgn->EG2Release + eg2release,
272 Delay);
273 }
274 #endif // ENABLE_FILTER
275
276
277 // setup EG 3 (VCO EG)
278 {
279 double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
280 pEG3->Trigger(eg3depth, pDimRgn->EG3Attack, Delay);
281 }
282
283
284 // setup LFO 1 (VCA LFO)
285 {
286 uint16_t lfo1_internal_depth;
287 switch (pDimRgn->LFO1Controller) {
288 case ::gig::lfo1_ctrl_internal:
289 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
290 pLFO1->ExtController = 0; // no external controller
291 break;
292 case ::gig::lfo1_ctrl_modwheel:
293 lfo1_internal_depth = 0;
294 pLFO1->ExtController = 1; // MIDI controller 1
295 break;
296 case ::gig::lfo1_ctrl_breath:
297 lfo1_internal_depth = 0;
298 pLFO1->ExtController = 2; // MIDI controller 2
299 break;
300 case ::gig::lfo1_ctrl_internal_modwheel:
301 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
302 pLFO1->ExtController = 1; // MIDI controller 1
303 break;
304 case ::gig::lfo1_ctrl_internal_breath:
305 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
306 pLFO1->ExtController = 2; // MIDI controller 2
307 break;
308 default:
309 lfo1_internal_depth = 0;
310 pLFO1->ExtController = 0; // no external controller
311 }
312 pLFO1->Trigger(pDimRgn->LFO1Frequency,
313 lfo1_internal_depth,
314 pDimRgn->LFO1ControlDepth,
315 pEngine->ControllerTable[pLFO1->ExtController],
316 pDimRgn->LFO1FlipPhase,
317 this->SampleRate,
318 Delay);
319 }
320
321 #if ENABLE_FILTER
322 // setup LFO 2 (VCF Cutoff LFO)
323 {
324 uint16_t lfo2_internal_depth;
325 switch (pDimRgn->LFO2Controller) {
326 case ::gig::lfo2_ctrl_internal:
327 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
328 pLFO2->ExtController = 0; // no external controller
329 break;
330 case ::gig::lfo2_ctrl_modwheel:
331 lfo2_internal_depth = 0;
332 pLFO2->ExtController = 1; // MIDI controller 1
333 break;
334 case ::gig::lfo2_ctrl_foot:
335 lfo2_internal_depth = 0;
336 pLFO2->ExtController = 4; // MIDI controller 4
337 break;
338 case ::gig::lfo2_ctrl_internal_modwheel:
339 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
340 pLFO2->ExtController = 1; // MIDI controller 1
341 break;
342 case ::gig::lfo2_ctrl_internal_foot:
343 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
344 pLFO2->ExtController = 4; // MIDI controller 4
345 break;
346 default:
347 lfo2_internal_depth = 0;
348 pLFO2->ExtController = 0; // no external controller
349 }
350 pLFO2->Trigger(pDimRgn->LFO2Frequency,
351 lfo2_internal_depth,
352 pDimRgn->LFO2ControlDepth,
353 pEngine->ControllerTable[pLFO2->ExtController],
354 pDimRgn->LFO2FlipPhase,
355 this->SampleRate,
356 Delay);
357 }
358 #endif // ENABLE_FILTER
359
360 // setup LFO 3 (VCO LFO)
361 {
362 uint16_t lfo3_internal_depth;
363 switch (pDimRgn->LFO3Controller) {
364 case ::gig::lfo3_ctrl_internal:
365 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
366 pLFO3->ExtController = 0; // no external controller
367 break;
368 case ::gig::lfo3_ctrl_modwheel:
369 lfo3_internal_depth = 0;
370 pLFO3->ExtController = 1; // MIDI controller 1
371 break;
372 case ::gig::lfo3_ctrl_aftertouch:
373 lfo3_internal_depth = 0;
374 pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
375 break;
376 case ::gig::lfo3_ctrl_internal_modwheel:
377 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
378 pLFO3->ExtController = 1; // MIDI controller 1
379 break;
380 case ::gig::lfo3_ctrl_internal_aftertouch:
381 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
382 pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
383 break;
384 default:
385 lfo3_internal_depth = 0;
386 pLFO3->ExtController = 0; // no external controller
387 }
388 pLFO3->Trigger(pDimRgn->LFO3Frequency,
389 lfo3_internal_depth,
390 pDimRgn->LFO3ControlDepth,
391 pEngine->ControllerTable[pLFO3->ExtController],
392 false,
393 this->SampleRate,
394 Delay);
395 }
396
397 #if ENABLE_FILTER
398 #if FORCE_FILTER_USAGE
399 FilterLeft.Enabled = FilterRight.Enabled = true;
400 #else // use filter only if instrument file told so
401 FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;
402 #endif // FORCE_FILTER_USAGE
403 if (pDimRgn->VCFEnabled) {
404 #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
405 VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;
406 #else // use the one defined in the instrument file
407 switch (pDimRgn->VCFCutoffController) {
408 case ::gig::vcf_cutoff_ctrl_modwheel:
409 VCFCutoffCtrl.controller = 1;
410 break;
411 case ::gig::vcf_cutoff_ctrl_effect1:
412 VCFCutoffCtrl.controller = 12;
413 break;
414 case ::gig::vcf_cutoff_ctrl_effect2:
415 VCFCutoffCtrl.controller = 13;
416 break;
417 case ::gig::vcf_cutoff_ctrl_breath:
418 VCFCutoffCtrl.controller = 2;
419 break;
420 case ::gig::vcf_cutoff_ctrl_foot:
421 VCFCutoffCtrl.controller = 4;
422 break;
423 case ::gig::vcf_cutoff_ctrl_sustainpedal:
424 VCFCutoffCtrl.controller = 64;
425 break;
426 case ::gig::vcf_cutoff_ctrl_softpedal:
427 VCFCutoffCtrl.controller = 67;
428 break;
429 case ::gig::vcf_cutoff_ctrl_genpurpose7:
430 VCFCutoffCtrl.controller = 82;
431 break;
432 case ::gig::vcf_cutoff_ctrl_genpurpose8:
433 VCFCutoffCtrl.controller = 83;
434 break;
435 case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet
436 case ::gig::vcf_cutoff_ctrl_none:
437 default:
438 VCFCutoffCtrl.controller = 0;
439 break;
440 }
441 #endif // OVERRIDE_FILTER_CUTOFF_CTRL
442
443 #ifdef OVERRIDE_FILTER_RES_CTRL
444 VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;
445 #else // use the one defined in the instrument file
446 switch (pDimRgn->VCFResonanceController) {
447 case ::gig::vcf_res_ctrl_genpurpose3:
448 VCFResonanceCtrl.controller = 18;
449 break;
450 case ::gig::vcf_res_ctrl_genpurpose4:
451 VCFResonanceCtrl.controller = 19;
452 break;
453 case ::gig::vcf_res_ctrl_genpurpose5:
454 VCFResonanceCtrl.controller = 80;
455 break;
456 case ::gig::vcf_res_ctrl_genpurpose6:
457 VCFResonanceCtrl.controller = 81;
458 break;
459 case ::gig::vcf_res_ctrl_none:
460 default:
461 VCFResonanceCtrl.controller = 0;
462 }
463 #endif // OVERRIDE_FILTER_RES_CTRL
464
465 #ifndef OVERRIDE_FILTER_TYPE
466 FilterLeft.SetType(pDimRgn->VCFType);
467 FilterRight.SetType(pDimRgn->VCFType);
468 #else // override filter type
469 FilterLeft.SetType(OVERRIDE_FILTER_TYPE);
470 FilterRight.SetType(OVERRIDE_FILTER_TYPE);
471 #endif // OVERRIDE_FILTER_TYPE
472
473 VCFCutoffCtrl.value = pEngine->ControllerTable[VCFCutoffCtrl.controller];
474 VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];
475
476 // calculate cutoff frequency
477 float cutoff = (!VCFCutoffCtrl.controller)
478 ? exp((float) (127 - pNoteOnEvent->Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX
479 : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
480
481 // calculate resonance
482 float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0
483 if (pDimRgn->VCFKeyboardTracking) {
484 resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
485 }
486 Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
487
488 VCFCutoffCtrl.fvalue = cutoff - FILTER_CUTOFF_MIN;
489 VCFResonanceCtrl.fvalue = resonance;
490
491 FilterLeft.SetParameters(cutoff, resonance, SampleRate);
492 FilterRight.SetParameters(cutoff, resonance, SampleRate);
493
494 FilterUpdateCounter = -1;
495 }
496 else {
497 VCFCutoffCtrl.controller = 0;
498 VCFResonanceCtrl.controller = 0;
499 }
500 #endif // ENABLE_FILTER
501
502 // ************************************************
503 // TODO: ARTICULATION DATA HANDLING IS MISSING HERE
504 // ************************************************
505
506 return 0; // success
507 }
508
509 /**
510 * Renders the audio data for this voice for the current audio fragment.
511 * The sample input data can either come from RAM (cached sample or sample
512 * part) or directly from disk. The output signal will be rendered by
513 * resampling / interpolation. If this voice is a disk streaming voice and
514 * the voice completely played back the cached RAM part of the sample, it
515 * will automatically switch to disk playback for the next RenderAudio()
516 * call.
517 *
518 * @param Samples - number of samples to be rendered in this audio fragment cycle
519 */
520 void Voice::Render(uint Samples) {
521
522 // Reset the synthesis parameter matrix
523 pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * pEngine->GlobalVolume);
524 pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
525 #if ENABLE_FILTER
526 pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
527 pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
528 #endif // ENABLE_FILTER
529
530
531 // Apply events to the synthesis parameter matrix
532 ProcessEvents(Samples);
533
534
535 // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
536 pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
537 #if ENABLE_FILTER
538 pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
539 #endif // ENABLE_FILTER
540 pEG3->Process(Samples);
541 pLFO1->Process(Samples);
542 #if ENABLE_FILTER
543 pLFO2->Process(Samples);
544 #endif // ENABLE_FILTER
545 pLFO3->Process(Samples);
546
547
548 #if ENABLE_FILTER
549 CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
550 #endif // ENABLE_FILTER
551
552
553 switch (this->PlaybackState) {
554
555 case playback_state_ram: {
556 if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
557 else Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
558 if (DiskVoice) {
559 // check if we reached the allowed limit of the sample RAM cache
560 if (Pos > MaxRAMPos) {
561 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", Pos));
562 this->PlaybackState = playback_state_disk;
563 }
564 }
565 else if (Pos >= pSample->GetCache().Size / pSample->FrameSize) {
566 this->PlaybackState = playback_state_end;
567 }
568 }
569 break;
570
571 case playback_state_disk: {
572 if (!DiskStreamRef.pStream) {
573 // check if the disk thread created our ordered disk stream in the meantime
574 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
575 if (!DiskStreamRef.pStream) {
576 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
577 Kill();
578 return;
579 }
580 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));
581 Pos -= RTMath::DoubleToInt(Pos);
582 }
583
584 // add silence sample at the end if we reached the end of the stream (for the interpolator)
585 if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {
586 DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);
587 this->PlaybackState = playback_state_end;
588 }
589
590 sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
591 Interpolate(Samples, ptr, Delay);
592 DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);
593 Pos -= RTMath::DoubleToInt(Pos);
594 }
595 break;
596
597 case playback_state_end:
598 Kill(); // free voice
599 break;
600 }
601
602
603 #if ENABLE_FILTER
604 // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
605 pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();
606 pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();
607 #endif // ENABLE_FILTER
608
609 // Reset delay
610 Delay = 0;
611
612 pTriggerEvent = NULL;
613
614 // If release stage finished, let the voice be killed
615 if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;
616 }
617
618 /**
619 * Resets voice variables. Should only be called if rendering process is
620 * suspended / not running.
621 */
622 void Voice::Reset() {
623 pLFO1->Reset();
624 pLFO2->Reset();
625 pLFO3->Reset();
626 DiskStreamRef.pStream = NULL;
627 DiskStreamRef.hStream = 0;
628 DiskStreamRef.State = Stream::state_unused;
629 DiskStreamRef.OrderID = 0;
630 Active = false;
631 }
632
633 /**
634 * Process the control change event lists of the engine for the current
635 * audio fragment. Event values will be applied to the synthesis parameter
636 * matrix.
637 *
638 * @param Samples - number of samples to be rendered in this audio fragment cycle
639 */
640 void Voice::ProcessEvents(uint Samples) {
641
642 // dispatch control change events
643 Event* pCCEvent = pEngine->pCCEvents->first();
644 if (Delay) { // skip events that happened before this voice was triggered
645 while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();
646 }
647 while (pCCEvent) {
648 if (pCCEvent->Controller) { // if valid MIDI controller
649 #if ENABLE_FILTER
650 if (pCCEvent->Controller == VCFCutoffCtrl.controller) {
651 pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);
652 }
653 if (pCCEvent->Controller == VCFResonanceCtrl.controller) {
654 pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);
655 }
656 #endif // ENABLE_FILTER
657 if (pCCEvent->Controller == pLFO1->ExtController) {
658 pLFO1->SendEvent(pCCEvent);
659 }
660 #if ENABLE_FILTER
661 if (pCCEvent->Controller == pLFO2->ExtController) {
662 pLFO2->SendEvent(pCCEvent);
663 }
664 #endif // ENABLE_FILTER
665 if (pCCEvent->Controller == pLFO3->ExtController) {
666 pLFO3->SendEvent(pCCEvent);
667 }
668 }
669
670 pCCEvent = pEngine->pCCEvents->next();
671 }
672
673
674 // process pitch events
675 {
676 RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
677 Event* pVCOEvent = pVCOEventList->first();
678 if (Delay) { // skip events that happened before this voice was triggered
679 while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();
680 }
681 // apply old pitchbend value until first pitch event occurs
682 if (this->PitchBend != 1.0) {
683 uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;
684 for (uint i = Delay; i < end; i++) {
685 pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
686 }
687 }
688 float pitch;
689 while (pVCOEvent) {
690 Event* pNextVCOEvent = pVCOEventList->next();
691
692 // calculate the influence length of this event (in sample points)
693 uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;
694
695 pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
696
697 // apply pitch value to the pitch parameter sequence
698 for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {
699 pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
700 }
701
702 pVCOEvent = pNextVCOEvent;
703 }
704 if (pVCOEventList->last()) this->PitchBend = pitch;
705 }
706
707
708 #if ENABLE_FILTER
709 // process filter cutoff events
710 {
711 RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
712 Event* pCutoffEvent = pCutoffEventList->first();
713 if (Delay) { // skip events that happened before this voice was triggered
714 while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();
715 }
716 float cutoff;
717 while (pCutoffEvent) {
718 Event* pNextCutoffEvent = pCutoffEventList->next();
719
720 // calculate the influence length of this event (in sample points)
721 uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;
722
723 cutoff = exp((float) pCutoffEvent->Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
724
725 // apply cutoff frequency to the cutoff parameter sequence
726 for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {
727 pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
728 }
729
730 pCutoffEvent = pNextCutoffEvent;
731 }
732 if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
733 }
734
735 // process filter resonance events
736 {
737 RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
738 Event* pResonanceEvent = pResonanceEventList->first();
739 if (Delay) { // skip events that happened before this voice was triggered
740 while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();
741 }
742 while (pResonanceEvent) {
743 Event* pNextResonanceEvent = pResonanceEventList->next();
744
745 // calculate the influence length of this event (in sample points)
746 uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;
747
748 // convert absolute controller value to differential
749 int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;
750 VCFResonanceCtrl.value = pResonanceEvent->Value;
751
752 float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
753
754 // apply cutoff frequency to the cutoff parameter sequence
755 for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {
756 pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
757 }
758
759 pResonanceEvent = pNextResonanceEvent;
760 }
761 if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Value * 0.00787f; // needed for initialization of parameter matrix next time
762 }
763 #endif // ENABLE_FILTER
764 }
765
766 #if ENABLE_FILTER
767 /**
768 * Calculate all necessary, final biquad filter parameters.
769 *
770 * @param Samples - number of samples to be rendered in this audio fragment cycle
771 */
772 void Voice::CalculateBiquadParameters(uint Samples) {
773 if (!FilterLeft.Enabled) return;
774
775 biquad_param_t bqbase;
776 biquad_param_t bqmain;
777 float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
778 float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
779 FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate);
780 pEngine->pBasicFilterParameters[0] = bqbase;
781 pEngine->pMainFilterParameters[0] = bqmain;
782
783 float* bq;
784 for (int i = 1; i < Samples; i++) {
785 // recalculate biquad parameters if cutoff or resonance differ from previous sample point
786 if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
787 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {
788 prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
789 prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
790 FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate);
791 }
792
793 //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
794 bq = (float*) &pEngine->pBasicFilterParameters[i];
795 bq[0] = bqbase.a1;
796 bq[1] = bqbase.a2;
797 bq[2] = bqbase.b0;
798 bq[3] = bqbase.b1;
799 bq[4] = bqbase.b2;
800
801 // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
802 bq = (float*) &pEngine->pMainFilterParameters[i];
803 bq[0] = bqmain.a1;
804 bq[1] = bqmain.a2;
805 bq[2] = bqmain.b0;
806 bq[3] = bqmain.b1;
807 bq[4] = bqmain.b2;
808 }
809 }
810 #endif // ENABLE_FILTER
811
812 /**
813 * Interpolates the input audio data (no loop).
814 *
815 * @param Samples - number of sample points to be rendered in this audio
816 * fragment cycle
817 * @param pSrc - pointer to input sample data
818 * @param Skip - number of sample points to skip in output buffer
819 */
820 void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {
821 int i = Skip;
822
823 // FIXME: assuming either mono or stereo
824 if (this->pSample->Channels == 2) { // Stereo Sample
825 while (i < Samples) {
826 InterpolateOneStep_Stereo(pSrc, i,
827 pEngine->pSynthesisParameters[Event::destination_vca][i],
828 pEngine->pSynthesisParameters[Event::destination_vco][i],
829 pEngine->pBasicFilterParameters[i],
830 pEngine->pMainFilterParameters[i]);
831 }
832 }
833 else { // Mono Sample
834 while (i < Samples) {
835 InterpolateOneStep_Mono(pSrc, i,
836 pEngine->pSynthesisParameters[Event::destination_vca][i],
837 pEngine->pSynthesisParameters[Event::destination_vco][i],
838 pEngine->pBasicFilterParameters[i],
839 pEngine->pMainFilterParameters[i]);
840 }
841 }
842 }
843
844 /**
845 * Interpolates the input audio data, this method honors looping.
846 *
847 * @param Samples - number of sample points to be rendered in this audio
848 * fragment cycle
849 * @param pSrc - pointer to input sample data
850 * @param Skip - number of sample points to skip in output buffer
851 */
852 void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {
853 int i = Skip;
854
855 // FIXME: assuming either mono or stereo
856 if (pSample->Channels == 2) { // Stereo Sample
857 if (pSample->LoopPlayCount) {
858 // render loop (loop count limited)
859 while (i < Samples && LoopCyclesLeft) {
860 InterpolateOneStep_Stereo(pSrc, i,
861 pEngine->pSynthesisParameters[Event::destination_vca][i],
862 pEngine->pSynthesisParameters[Event::destination_vco][i],
863 pEngine->pBasicFilterParameters[i],
864 pEngine->pMainFilterParameters[i]);
865 if (Pos > pSample->LoopEnd) {
866 Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
867 LoopCyclesLeft--;
868 }
869 }
870 // render on without loop
871 while (i < Samples) {
872 InterpolateOneStep_Stereo(pSrc, i,
873 pEngine->pSynthesisParameters[Event::destination_vca][i],
874 pEngine->pSynthesisParameters[Event::destination_vco][i],
875 pEngine->pBasicFilterParameters[i],
876 pEngine->pMainFilterParameters[i]);
877 }
878 }
879 else { // render loop (endless loop)
880 while (i < Samples) {
881 InterpolateOneStep_Stereo(pSrc, i,
882 pEngine->pSynthesisParameters[Event::destination_vca][i],
883 pEngine->pSynthesisParameters[Event::destination_vco][i],
884 pEngine->pBasicFilterParameters[i],
885 pEngine->pMainFilterParameters[i]);
886 if (Pos > pSample->LoopEnd) {
887 Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);
888 }
889 }
890 }
891 }
892 else { // Mono Sample
893 if (pSample->LoopPlayCount) {
894 // render loop (loop count limited)
895 while (i < Samples && LoopCyclesLeft) {
896 InterpolateOneStep_Mono(pSrc, i,
897 pEngine->pSynthesisParameters[Event::destination_vca][i],
898 pEngine->pSynthesisParameters[Event::destination_vco][i],
899 pEngine->pBasicFilterParameters[i],
900 pEngine->pMainFilterParameters[i]);
901 if (Pos > pSample->LoopEnd) {
902 Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
903 LoopCyclesLeft--;
904 }
905 }
906 // render on without loop
907 while (i < Samples) {
908 InterpolateOneStep_Mono(pSrc, i,
909 pEngine->pSynthesisParameters[Event::destination_vca][i],
910 pEngine->pSynthesisParameters[Event::destination_vco][i],
911 pEngine->pBasicFilterParameters[i],
912 pEngine->pMainFilterParameters[i]);
913 }
914 }
915 else { // render loop (endless loop)
916 while (i < Samples) {
917 InterpolateOneStep_Mono(pSrc, i,
918 pEngine->pSynthesisParameters[Event::destination_vca][i],
919 pEngine->pSynthesisParameters[Event::destination_vco][i],
920 pEngine->pBasicFilterParameters[i],
921 pEngine->pMainFilterParameters[i]);
922 if (Pos > pSample->LoopEnd) {
923 Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
924 }
925 }
926 }
927 }
928 }
929
930 /**
931 * Immediately kill the voice.
932 */
933 void Voice::Kill() {
934 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
935 pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
936 }
937 Reset();
938 }
939
940 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC