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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 64 - (hide annotations) (download)
Thu May 6 20:06:20 2004 UTC (19 years, 10 months ago) by schoenebeck
File size: 41850 byte(s)
* src/Sampler.cpp: fixed 3 stupid but fatal bugs that left in the rush (in
  method SamplerChannels(), CreateAudioOutputDevice() and
  CreateMidiInputDevice())
* src/network/lscpserver.cpp: implemented LSCP command
  'SET CHANNEL MIDI_INPUT_CHANNEL'
* src/Sampler.h: moved enums 'audio_output_type_t', 'midi_input_type_t'
  and 'engine_type_t' into the respective base classes
  ('AudioOutputDevice', 'MidiInputDevice', 'Engine')

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 53 * *
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 schoenebeck 64 dmsg(6,("Voice::SetEngine()\n"));
99 schoenebeck 53 }
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