/[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 271 - (hide annotations) (download)
Fri Oct 8 20:51:39 2004 UTC (19 years, 6 months ago) by schoenebeck
File size: 49959 byte(s)
* libgig: fixed panorama value in DimensionRegion (invalid conversion
  from signed 7 bit to signed 8 bit)
* src/linuxsampler.cpp: stacktrace is now automatically shown on fatal
  errors (that is  segmentation faults, etc.), gdb should be installed for
  this to work
* gig::Voice: tiny accuracy fix of pan calculation
* replaced old pool classes by completely new ones which now offer
  Iterator abstraction

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

  ViewVC Help
Powered by ViewVC