/[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 225 - (hide 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 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 schoenebeck 80 const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
35    
36 schoenebeck 53 float Voice::CalculateFilterCutoffCoeff() {
37     return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);
38     }
39    
40 schoenebeck 80 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 schoenebeck 53 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 schoenebeck 64 dmsg(6,("Voice::SetEngine()\n"));
101 schoenebeck 53 }
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 schoenebeck 225 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 schoenebeck 53
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 schoenebeck 225 pEngine->SampleRate,
311 schoenebeck 53 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 schoenebeck 225 pEngine->SampleRate,
349 schoenebeck 53 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 schoenebeck 225 pEngine->SampleRate,
387 schoenebeck 53 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 schoenebeck 225 FilterLeft.SetParameters(cutoff, resonance, pEngine->SampleRate);
485     FilterRight.SetParameters(cutoff, resonance, pEngine->SampleRate);
486 schoenebeck 53
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 schoenebeck 111 pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * pEngine->GlobalVolume);
517 schoenebeck 53 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 schoenebeck 80 #if ENABLE_FILTER
542     CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
543     #endif // ENABLE_FILTER
544    
545    
546 schoenebeck 53 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 schoenebeck 225 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 schoenebeck 53 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 schoenebeck 80 #if ENABLE_FILTER
760 schoenebeck 53 /**
761 schoenebeck 80 * 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 schoenebeck 225 FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
773 schoenebeck 80 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 schoenebeck 225 FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
784 schoenebeck 80 }
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 schoenebeck 53 * 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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
823     pEngine->pMainFilterParameters[i]);
824 schoenebeck 53 }
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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
832     pEngine->pMainFilterParameters[i]);
833 schoenebeck 53 }
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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
857     pEngine->pMainFilterParameters[i]);
858 schoenebeck 53 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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
869     pEngine->pMainFilterParameters[i]);
870 schoenebeck 53 }
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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
878     pEngine->pMainFilterParameters[i]);
879 schoenebeck 53 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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
893     pEngine->pMainFilterParameters[i]);
894 schoenebeck 53 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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
905     pEngine->pMainFilterParameters[i]);
906 schoenebeck 53 }
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 schoenebeck 80 pEngine->pBasicFilterParameters[i],
914     pEngine->pMainFilterParameters[i]);
915 schoenebeck 53 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