/[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 247 - (hide annotations) (download)
Sun Sep 19 23:44:23 2004 UTC (15 years, 1 month ago) by senkov
File size: 49675 byte(s)
* Small fix to pan coeff. calculation.
* (LS was silent with gigs where pan was 0).

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 242 * @param pNoteOnEvent - event that caused triggering of this voice
107     * @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 242 int Voice::Trigger(Event* pNoteOnEvent, 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 246 MIDIKey = pNoteOnEvent->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     Delay = pNoteOnEvent->FragmentPos();
125     pTriggerEvent = pNoteOnEvent;
126 schoenebeck 239 pKillEvent = NULL;
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 242 pEngine->LaunchVoice(pNoteOnEvent, iNewLayer, ReleaseTriggerVoice);
150 schoenebeck 230 break;
151     case ::gig::dimension_velocity:
152 schoenebeck 246 DimValues[i] = pNoteOnEvent->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 246 DimValues[i] = (uint) pNoteOnEvent->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 246 CrossfadeVolume = CrossfadeAttenuation(pNoteOnEvent->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 senkov 247 const float fpan = float(RTMath::Max(RTMath::Min(pDimRgn->Pan, 63), -64)) / 64.0f;
259     PanLeft = 1.0f - fpan;
260     PanRight = 1.0f + fpan;
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 246 Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->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 246 eg1controllervalue = pNoteOnEvent->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 246 eg2controllervalue = pNoteOnEvent->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 246 ? exp((float) (127 - pNoteOnEvent->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 246 resonance += (float) (pNoteOnEvent->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 239 pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, pKillEvent);
644 schoenebeck 53 #if ENABLE_FILTER
645     pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
646     #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 239 KillImmediately(); // free voice
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     pTriggerEvent = NULL;
721    
722     // If release stage finished, let the voice be killed
723     if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;
724     }
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     Active = false;
739     }
740    
741     /**
742     * Process the control change event lists of the engine for the current
743     * audio fragment. Event values will be applied to the synthesis parameter
744     * matrix.
745     *
746     * @param Samples - number of samples to be rendered in this audio fragment cycle
747     */
748     void Voice::ProcessEvents(uint Samples) {
749    
750     // dispatch control change events
751     Event* pCCEvent = pEngine->pCCEvents->first();
752     if (Delay) { // skip events that happened before this voice was triggered
753     while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();
754     }
755     while (pCCEvent) {
756 schoenebeck 246 if (pCCEvent->Param.CC.Controller) { // if valid MIDI controller
757 schoenebeck 53 #if ENABLE_FILTER
758 schoenebeck 246 if (pCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
759 schoenebeck 53 pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);
760     }
761 schoenebeck 246 if (pCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
762 schoenebeck 53 pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);
763     }
764     #endif // ENABLE_FILTER
765 schoenebeck 246 if (pCCEvent->Param.CC.Controller == pLFO1->ExtController) {
766 schoenebeck 53 pLFO1->SendEvent(pCCEvent);
767     }
768     #if ENABLE_FILTER
769 schoenebeck 246 if (pCCEvent->Param.CC.Controller == pLFO2->ExtController) {
770 schoenebeck 53 pLFO2->SendEvent(pCCEvent);
771     }
772     #endif // ENABLE_FILTER
773 schoenebeck 246 if (pCCEvent->Param.CC.Controller == pLFO3->ExtController) {
774 schoenebeck 53 pLFO3->SendEvent(pCCEvent);
775     }
776 schoenebeck 236 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
777 schoenebeck 246 pCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
778 schoenebeck 236 pEngine->pSynthesisEvents[Event::destination_vca]->alloc_assign(*pCCEvent);
779     }
780 schoenebeck 53 }
781    
782     pCCEvent = pEngine->pCCEvents->next();
783     }
784    
785    
786     // process pitch events
787     {
788     RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
789     Event* pVCOEvent = pVCOEventList->first();
790     if (Delay) { // skip events that happened before this voice was triggered
791     while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();
792     }
793     // apply old pitchbend value until first pitch event occurs
794     if (this->PitchBend != 1.0) {
795     uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;
796     for (uint i = Delay; i < end; i++) {
797     pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
798     }
799     }
800     float pitch;
801     while (pVCOEvent) {
802     Event* pNextVCOEvent = pVCOEventList->next();
803    
804     // calculate the influence length of this event (in sample points)
805     uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;
806    
807 schoenebeck 246 pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
808 schoenebeck 53
809     // apply pitch value to the pitch parameter sequence
810     for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {
811     pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
812     }
813    
814     pVCOEvent = pNextVCOEvent;
815     }
816     if (pVCOEventList->last()) this->PitchBend = pitch;
817     }
818    
819 schoenebeck 236 // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
820     {
821     RTEList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
822     Event* pVCAEvent = pVCAEventList->first();
823     if (Delay) { // skip events that happened before this voice was triggered
824     while (pVCAEvent && pVCAEvent->FragmentPos() <= Delay) pVCAEvent = pVCAEventList->next();
825     }
826     float crossfadevolume;
827     while (pVCAEvent) {
828     Event* pNextVCAEvent = pVCAEventList->next();
829 schoenebeck 53
830 schoenebeck 236 // calculate the influence length of this event (in sample points)
831     uint end = (pNextVCAEvent) ? pNextVCAEvent->FragmentPos() : Samples;
832    
833 schoenebeck 246 crossfadevolume = CrossfadeAttenuation(pVCAEvent->Param.CC.Value);
834 schoenebeck 236
835     float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;
836    
837     // apply volume value to the volume parameter sequence
838     for (uint i = pVCAEvent->FragmentPos(); i < end; i++) {
839     pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
840     }
841    
842     pVCAEvent = pNextVCAEvent;
843     }
844     if (pVCAEventList->last()) this->CrossfadeVolume = crossfadevolume;
845     }
846    
847 schoenebeck 53 #if ENABLE_FILTER
848     // process filter cutoff events
849     {
850     RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
851     Event* pCutoffEvent = pCutoffEventList->first();
852     if (Delay) { // skip events that happened before this voice was triggered
853     while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();
854     }
855     float cutoff;
856     while (pCutoffEvent) {
857     Event* pNextCutoffEvent = pCutoffEventList->next();
858    
859     // calculate the influence length of this event (in sample points)
860     uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;
861    
862 schoenebeck 246 cutoff = exp((float) pCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
863 schoenebeck 53
864     // apply cutoff frequency to the cutoff parameter sequence
865     for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {
866     pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
867     }
868    
869     pCutoffEvent = pNextCutoffEvent;
870     }
871     if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
872     }
873    
874     // process filter resonance events
875     {
876     RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
877     Event* pResonanceEvent = pResonanceEventList->first();
878     if (Delay) { // skip events that happened before this voice was triggered
879     while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();
880     }
881     while (pResonanceEvent) {
882     Event* pNextResonanceEvent = pResonanceEventList->next();
883    
884     // calculate the influence length of this event (in sample points)
885     uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;
886    
887     // convert absolute controller value to differential
888 schoenebeck 246 int ctrldelta = pResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
889     VCFResonanceCtrl.value = pResonanceEvent->Param.CC.Value;
890 schoenebeck 53
891     float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
892    
893     // apply cutoff frequency to the cutoff parameter sequence
894     for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {
895     pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
896     }
897    
898     pResonanceEvent = pNextResonanceEvent;
899     }
900 schoenebeck 246 if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
901 schoenebeck 53 }
902     #endif // ENABLE_FILTER
903     }
904    
905 schoenebeck 80 #if ENABLE_FILTER
906 schoenebeck 53 /**
907 schoenebeck 80 * Calculate all necessary, final biquad filter parameters.
908     *
909     * @param Samples - number of samples to be rendered in this audio fragment cycle
910     */
911     void Voice::CalculateBiquadParameters(uint Samples) {
912     if (!FilterLeft.Enabled) return;
913    
914     biquad_param_t bqbase;
915     biquad_param_t bqmain;
916     float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
917     float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
918 schoenebeck 225 FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
919 schoenebeck 80 pEngine->pBasicFilterParameters[0] = bqbase;
920     pEngine->pMainFilterParameters[0] = bqmain;
921    
922     float* bq;
923     for (int i = 1; i < Samples; i++) {
924     // recalculate biquad parameters if cutoff or resonance differ from previous sample point
925     if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
926     pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {
927     prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
928     prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
929 schoenebeck 225 FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
930 schoenebeck 80 }
931    
932     //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
933     bq = (float*) &pEngine->pBasicFilterParameters[i];
934     bq[0] = bqbase.a1;
935     bq[1] = bqbase.a2;
936     bq[2] = bqbase.b0;
937     bq[3] = bqbase.b1;
938     bq[4] = bqbase.b2;
939    
940     // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
941     bq = (float*) &pEngine->pMainFilterParameters[i];
942     bq[0] = bqmain.a1;
943     bq[1] = bqmain.a2;
944     bq[2] = bqmain.b0;
945     bq[3] = bqmain.b1;
946     bq[4] = bqmain.b2;
947     }
948     }
949     #endif // ENABLE_FILTER
950    
951     /**
952 schoenebeck 245 * Interpolates the input audio data (without looping).
953 schoenebeck 53 *
954     * @param Samples - number of sample points to be rendered in this audio
955     * fragment cycle
956     * @param pSrc - pointer to input sample data
957     * @param Skip - number of sample points to skip in output buffer
958     */
959 schoenebeck 245 void Voice::InterpolateNoLoop(uint Samples, sample_t* pSrc, uint Skip) {
960 schoenebeck 53 int i = Skip;
961    
962     // FIXME: assuming either mono or stereo
963     if (this->pSample->Channels == 2) { // Stereo Sample
964 schoenebeck 245 while (i < Samples) InterpolateStereo(pSrc, i);
965 schoenebeck 53 }
966     else { // Mono Sample
967 schoenebeck 245 while (i < Samples) InterpolateMono(pSrc, i);
968 schoenebeck 53 }
969     }
970    
971     /**
972     * Interpolates the input audio data, this method honors looping.
973     *
974     * @param Samples - number of sample points to be rendered in this audio
975     * fragment cycle
976     * @param pSrc - pointer to input sample data
977     * @param Skip - number of sample points to skip in output buffer
978     */
979     void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {
980     int i = Skip;
981    
982     // FIXME: assuming either mono or stereo
983     if (pSample->Channels == 2) { // Stereo Sample
984     if (pSample->LoopPlayCount) {
985     // render loop (loop count limited)
986     while (i < Samples && LoopCyclesLeft) {
987 schoenebeck 245 InterpolateStereo(pSrc, i);
988 schoenebeck 53 if (Pos > pSample->LoopEnd) {
989     Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
990     LoopCyclesLeft--;
991     }
992     }
993     // render on without loop
994 schoenebeck 245 while (i < Samples) InterpolateStereo(pSrc, i);
995 schoenebeck 53 }
996     else { // render loop (endless loop)
997     while (i < Samples) {
998 schoenebeck 245 InterpolateStereo(pSrc, i);
999 schoenebeck 53 if (Pos > pSample->LoopEnd) {
1000     Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);
1001     }
1002     }
1003     }
1004     }
1005     else { // Mono Sample
1006     if (pSample->LoopPlayCount) {
1007     // render loop (loop count limited)
1008     while (i < Samples && LoopCyclesLeft) {
1009 schoenebeck 245 InterpolateMono(pSrc, i);
1010 schoenebeck 53 if (Pos > pSample->LoopEnd) {
1011     Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
1012     LoopCyclesLeft--;
1013     }
1014     }
1015     // render on without loop
1016 schoenebeck 245 while (i < Samples) InterpolateMono(pSrc, i);
1017 schoenebeck 53 }
1018     else { // render loop (endless loop)
1019     while (i < Samples) {
1020 schoenebeck 245 InterpolateMono(pSrc, i);
1021 schoenebeck 53 if (Pos > pSample->LoopEnd) {
1022     Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
1023     }
1024     }
1025     }
1026     }
1027     }
1028    
1029     /**
1030 schoenebeck 239 * Immediately kill the voice. This method should not be used to kill
1031     * a normal, active voice, because it doesn't take care of things like
1032     * fading down the volume level to avoid clicks and regular processing
1033     * until the kill event actually occured!
1034     *
1035     * @see Kill()
1036 schoenebeck 53 */
1037 schoenebeck 239 void Voice::KillImmediately() {
1038 schoenebeck 53 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1039     pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
1040     }
1041     Reset();
1042     }
1043    
1044 schoenebeck 239 /**
1045     * Kill the voice in regular sense. Let the voice render audio until
1046     * the kill event actually occured and then fade down the volume level
1047     * very quickly and let the voice die finally. Unlike a normal release
1048     * of a voice, a kill process cannot be cancalled and is therefore
1049     * usually used for voice stealing and key group conflicts.
1050     *
1051     * @param pKillEvent - event which caused the voice to be killed
1052     */
1053     void Voice::Kill(Event* pKillEvent) {
1054 schoenebeck 242 if (pTriggerEvent && pKillEvent->FragmentPos() <= pTriggerEvent->FragmentPos()) return;
1055 schoenebeck 239 this->pKillEvent = pKillEvent;
1056     }
1057    
1058 schoenebeck 53 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC