/[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 239 - (hide annotations) (download)
Sun Sep 12 14:48:19 2004 UTC (19 years, 7 months ago) by schoenebeck
File size: 51972 byte(s)
* implemented key groups (a.k.a exclusive groups) which is important for
  drum patches and monphonic instruments
* src/engines/gig/Engine.cpp: bugfix in ProcessNoteOn() - did not always
  stick the note on event to the respective key's own event list although
  e.g. the EGADRS expects it to find there

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

  ViewVC Help
Powered by ViewVC