/[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 80 - (hide annotations) (download)
Sun May 23 19:16:33 2004 UTC (19 years, 10 months ago) by schoenebeck
File size: 44091 byte(s)
* biquad filter parameters are now calculated outside the interpolate
  loop for better performance
* couple of loop unroll optimizations
* filter is now enabled by default
* cubic interpolation is now enabled by default
* reduced debug level to 1 to lower verbosity
* raised default limit for voices to 128
* raised default limit for streams to 150
* added some compiler optimization flags (-ffast-math -march -mcpu)

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

  ViewVC Help
Powered by ViewVC