/[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 225 - (show annotations) (download)
Sun Aug 22 14:46:47 2004 UTC (19 years, 7 months ago) by schoenebeck
File size: 43756 byte(s)
* set default volume to 1.0 in Gigasampler engine (was 0.0)
* implemented "SET CHANNEL AUDIO_OUTPUT_CHANNEL" LSCP command
* fixed "GET ENGINE INFO" LSCP command
* fixed "GET CHANNEL INFO" LSCP command
* src/network/lscp.y: fixed 'stringval' rule (returned string with formal
  apostrophes), fixed 'dotnum' rule (ignored position after decimal point)

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

  ViewVC Help
Powered by ViewVC