/[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 244 - (hide annotations) (download)
Fri Sep 17 01:01:11 2004 UTC (19 years, 6 months ago) by schoenebeck
File size: 52393 byte(s)
* added support for scale tuning via MIDI GS system exclusive message

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

  ViewVC Help
Powered by ViewVC