/[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 53 - (show annotations) (download)
Mon Apr 26 17:15:51 2004 UTC (19 years, 11 months ago) by schoenebeck
File size: 41850 byte(s)
* completely restructured source tree
* implemented multi channel support
* implemented instrument manager, which controls sharing of instruments
  between multiple sampler engines / sampler channels
* created abstract classes 'AudioOutputDevice' and 'MidiInputDevice' for
  convenient implementation of further audio output driver and MIDI input
  driver for LinuxSampler
* implemented following LSCP commands: 'SET CHANNEL MIDI INPUT TYPE',
  'LOAD ENGINE', 'GET CHANNELS', 'ADD CHANNEL', 'REMOVE CHANNEL',
  'SET CHANNEL AUDIO OUTPUT TYPE'
* temporarily removed all command line options
* LSCP server is now launched by default

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

  ViewVC Help
Powered by ViewVC