/[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 287 - (hide annotations) (download)
Sat Oct 16 17:38:03 2004 UTC (19 years, 5 months ago) by schoenebeck
File size: 50637 byte(s)
* fixed segfault which occured whenever a voice stole a voice and was in
  turn killed in the same audio fragment, to fix that the MIDI key
  informations are now updated only after all voices were processed

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

  ViewVC Help
Powered by ViewVC