/[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 230 - (show annotations) (download)
Thu Sep 2 21:52:29 2004 UTC (15 years, 1 month ago) by schoenebeck
File size: 48007 byte(s)
* src/engines/gig/Voice.cpp: dimension region selection takes current
  MIDI controller values into account

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

  ViewVC Help
Powered by ViewVC