/[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 245 - (hide annotations) (download)
Sat Sep 18 14:12:36 2004 UTC (19 years, 6 months ago) by schoenebeck
File size: 49438 byte(s)
* support patch panorama info

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

  ViewVC Help
Powered by ViewVC