/[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 768 - (hide annotations) (download)
Fri Sep 2 20:11:55 2005 UTC (18 years, 6 months ago) by persson
File size: 42932 byte(s)
* bug fixes for the new EG implementation

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 411 * Copyright (C) 2005 Christian Schoenebeck *
7 schoenebeck 53 * *
8     * This program is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this program; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24 schoenebeck 319 #include "../../common/Features.h"
25     #include "Synthesizer.h"
26 schoenebeck 53
27     #include "Voice.h"
28    
29     namespace LinuxSampler { namespace gig {
30    
31     const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
32    
33     float Voice::CalculateFilterCutoffCoeff() {
34 persson 729 return log(CONFIG_FILTER_CUTOFF_MAX / CONFIG_FILTER_CUTOFF_MIN);
35 schoenebeck 53 }
36    
37     Voice::Voice() {
38     pEngine = NULL;
39     pDiskThread = NULL;
40 schoenebeck 285 PlaybackState = playback_state_end;
41 schoenebeck 738 pLFO1 = new LFOUnsigned(1.0f); // amplitude EG (0..1 range)
42     pLFO2 = new LFOUnsigned(1.0f); // filter EG (0..1 range)
43     pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)
44 schoenebeck 239 KeyGroup = 0;
45 schoenebeck 361 SynthesisMode = 0; // set all mode bits to 0 first
46 schoenebeck 319 // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
47 schoenebeck 617 #if CONFIG_ASM && ARCH_X86
48 schoenebeck 319 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
49 schoenebeck 361 #else
50     SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
51     #endif
52 senkov 325 SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
53 schoenebeck 368
54     FilterLeft.Reset();
55     FilterRight.Reset();
56 schoenebeck 53 }
57    
58     Voice::~Voice() {
59     if (pLFO1) delete pLFO1;
60     if (pLFO2) delete pLFO2;
61     if (pLFO3) delete pLFO3;
62     }
63    
64     void Voice::SetEngine(Engine* pEngine) {
65 schoenebeck 738 this->pEngine = pEngine;
66 schoenebeck 53 this->pDiskThread = pEngine->pDiskThread;
67 schoenebeck 64 dmsg(6,("Voice::SetEngine()\n"));
68 schoenebeck 53 }
69    
70     /**
71     * Initializes and triggers the voice, a disk stream will be launched if
72     * needed.
73     *
74 schoenebeck 669 * @param pEngineChannel - engine channel on which this voice was ordered
75     * @param itNoteOnEvent - event that caused triggering of this voice
76     * @param PitchBend - MIDI detune factor (-8192 ... +8191)
77     * @param pDimRgn - points to the dimension region which provides sample wave(s) and articulation data
78     * @param VoiceType - type of this voice
79     * @param iKeyGroup - a value > 0 defines a key group in which this voice is member of
80 schoenebeck 354 * @returns 0 on success, a value < 0 if the voice wasn't triggered
81     * (either due to an error or e.g. because no region is
82     * defined for the given key)
83 schoenebeck 53 */
84 schoenebeck 669 int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
85 schoenebeck 411 this->pEngineChannel = pEngineChannel;
86 schoenebeck 669 this->pDimRgn = pDimRgn;
87    
88 schoenebeck 563 #if CONFIG_DEVMODE
89     if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
90 schoenebeck 319 dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
91     }
92 schoenebeck 563 #endif // CONFIG_DEVMODE
93 schoenebeck 53
94 schoenebeck 669 Type = VoiceType;
95 schoenebeck 271 MIDIKey = itNoteOnEvent->Param.Note.Key;
96 schoenebeck 563 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
97 schoenebeck 271 Delay = itNoteOnEvent->FragmentPos();
98     itTriggerEvent = itNoteOnEvent;
99     itKillEvent = Pool<Event>::Iterator();
100 schoenebeck 669 KeyGroup = iKeyGroup;
101     pSample = pDimRgn->pSample; // sample won't change until the voice is finished
102 schoenebeck 53
103 persson 630 // calculate volume
104     const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
105    
106     Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
107    
108     Volume *= pDimRgn->SampleAttenuation;
109    
110     // the volume of release triggered samples depends on note length
111 schoenebeck 669 if (Type == type_release_trigger) {
112 persson 630 float noteLength = float(pEngine->FrameTime + Delay -
113     pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
114     float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
115     if (attenuation <= 0) return -1;
116     Volume *= attenuation;
117     }
118    
119 schoenebeck 319 // select channel mode (mono or stereo)
120     SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
121    
122 schoenebeck 236 // get starting crossfade volume level
123     switch (pDimRgn->AttenuationController.type) {
124     case ::gig::attenuation_ctrl_t::type_channelaftertouch:
125     CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
126     break;
127     case ::gig::attenuation_ctrl_t::type_velocity:
128 schoenebeck 271 CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
129 schoenebeck 236 break;
130     case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
131 schoenebeck 411 CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
132 schoenebeck 236 break;
133     case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
134     default:
135     CrossfadeVolume = 1.0f;
136     }
137    
138 schoenebeck 271 PanLeft = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) / 63.0f;
139     PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
140 schoenebeck 245
141 schoenebeck 236 Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
142    
143 schoenebeck 53 // Check if the sample needs disk streaming or is too short for that
144     long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
145     DiskVoice = cachedsamples < pSample->SamplesTotal;
146    
147     if (DiskVoice) { // voice to be streamed from disk
148 schoenebeck 554 MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_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)
149 schoenebeck 53
150     // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
151     if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
152     RAMLoop = true;
153     LoopCyclesLeft = pSample->LoopPlayCount;
154     }
155     else RAMLoop = false;
156    
157     if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
158     dmsg(1,("Disk stream order failed!\n"));
159 schoenebeck 239 KillImmediately();
160 schoenebeck 53 return -1;
161     }
162     dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
163     }
164     else { // RAM only voice
165     MaxRAMPos = cachedsamples;
166     if (pSample->Loops) {
167     RAMLoop = true;
168     LoopCyclesLeft = pSample->LoopPlayCount;
169     }
170     else RAMLoop = false;
171     dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
172     }
173    
174    
175     // calculate initial pitch value
176     {
177 senkov 335 double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
178 schoenebeck 53 if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
179 schoenebeck 738 this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));
180 schoenebeck 53 this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
181     }
182    
183 persson 614 // the length of the decay and release curves are dependent on the velocity
184     const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
185    
186 schoenebeck 53 // setup EG 1 (VCA EG)
187     {
188     // get current value of EG1 controller
189     double eg1controllervalue;
190     switch (pDimRgn->EG1Controller.type) {
191     case ::gig::eg1_ctrl_t::type_none: // no controller defined
192     eg1controllervalue = 0;
193     break;
194     case ::gig::eg1_ctrl_t::type_channelaftertouch:
195     eg1controllervalue = 0; // TODO: aftertouch not yet supported
196     break;
197     case ::gig::eg1_ctrl_t::type_velocity:
198 schoenebeck 271 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
199 schoenebeck 53 break;
200     case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
201 schoenebeck 411 eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
202 schoenebeck 53 break;
203     }
204     if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
205    
206 persson 696 // calculate influence of EG1 controller on EG1's parameters
207     // (eg1attack is different from the others)
208     double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ?
209     1 + 0.031 * (double) (pDimRgn->EG1ControllerAttackInfluence == 1 ?
210     1 : 1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 1.0;
211     double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 1.0;
212     double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 1.0;
213 schoenebeck 53
214 schoenebeck 738 EG1.trigger(pDimRgn->EG1PreAttack,
215     pDimRgn->EG1Attack * eg1attack,
216     pDimRgn->EG1Hold,
217     pSample->LoopStart,
218     pDimRgn->EG1Decay1 * eg1decay * velrelease,
219     pDimRgn->EG1Decay2 * eg1decay * velrelease,
220     pDimRgn->EG1InfiniteSustain,
221     pDimRgn->EG1Sustain,
222     pDimRgn->EG1Release * eg1release * velrelease,
223     velocityAttenuation,
224     pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
225 schoenebeck 53 }
226    
227    
228     // setup EG 2 (VCF Cutoff EG)
229     {
230     // get current value of EG2 controller
231     double eg2controllervalue;
232     switch (pDimRgn->EG2Controller.type) {
233     case ::gig::eg2_ctrl_t::type_none: // no controller defined
234     eg2controllervalue = 0;
235     break;
236     case ::gig::eg2_ctrl_t::type_channelaftertouch:
237     eg2controllervalue = 0; // TODO: aftertouch not yet supported
238     break;
239     case ::gig::eg2_ctrl_t::type_velocity:
240 schoenebeck 271 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
241 schoenebeck 53 break;
242     case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
243 schoenebeck 411 eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
244 schoenebeck 53 break;
245     }
246     if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
247    
248 persson 696 // calculate influence of EG2 controller on EG2's parameters
249     double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 1.0;
250     double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 1.0;
251     double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 1.0;
252 schoenebeck 53
253 schoenebeck 738 EG2.trigger(pDimRgn->EG2PreAttack,
254     pDimRgn->EG2Attack * eg2attack,
255     false,
256     pSample->LoopStart,
257     pDimRgn->EG2Decay1 * eg2decay * velrelease,
258     pDimRgn->EG2Decay2 * eg2decay * velrelease,
259     pDimRgn->EG2InfiniteSustain,
260     pDimRgn->EG2Sustain,
261     pDimRgn->EG2Release * eg2release * velrelease,
262     velocityAttenuation,
263     pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
264 schoenebeck 53 }
265    
266    
267     // setup EG 3 (VCO EG)
268     {
269     double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
270 schoenebeck 738 EG3.trigger(eg3depth, pDimRgn->EG3Attack, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
271 schoenebeck 53 }
272    
273    
274     // setup LFO 1 (VCA LFO)
275     {
276     uint16_t lfo1_internal_depth;
277     switch (pDimRgn->LFO1Controller) {
278     case ::gig::lfo1_ctrl_internal:
279     lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
280     pLFO1->ExtController = 0; // no external controller
281 schoenebeck 687 bLFO1Enabled = (lfo1_internal_depth > 0);
282 schoenebeck 53 break;
283     case ::gig::lfo1_ctrl_modwheel:
284     lfo1_internal_depth = 0;
285     pLFO1->ExtController = 1; // MIDI controller 1
286 schoenebeck 687 bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0);
287 schoenebeck 53 break;
288     case ::gig::lfo1_ctrl_breath:
289     lfo1_internal_depth = 0;
290     pLFO1->ExtController = 2; // MIDI controller 2
291 schoenebeck 687 bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0);
292 schoenebeck 53 break;
293     case ::gig::lfo1_ctrl_internal_modwheel:
294     lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
295     pLFO1->ExtController = 1; // MIDI controller 1
296 schoenebeck 687 bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
297 schoenebeck 53 break;
298     case ::gig::lfo1_ctrl_internal_breath:
299     lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
300     pLFO1->ExtController = 2; // MIDI controller 2
301 schoenebeck 687 bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
302 schoenebeck 53 break;
303     default:
304     lfo1_internal_depth = 0;
305     pLFO1->ExtController = 0; // no external controller
306 schoenebeck 687 bLFO1Enabled = false;
307 schoenebeck 53 }
308 schoenebeck 738 if (bLFO1Enabled) pLFO1->trigger(pDimRgn->LFO1Frequency,
309     start_level_max,
310 schoenebeck 687 lfo1_internal_depth,
311     pDimRgn->LFO1ControlDepth,
312     pDimRgn->LFO1FlipPhase,
313 schoenebeck 738 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
314 schoenebeck 53 }
315    
316 schoenebeck 319
317 schoenebeck 53 // setup LFO 2 (VCF Cutoff LFO)
318     {
319     uint16_t lfo2_internal_depth;
320     switch (pDimRgn->LFO2Controller) {
321     case ::gig::lfo2_ctrl_internal:
322     lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
323     pLFO2->ExtController = 0; // no external controller
324 schoenebeck 687 bLFO2Enabled = (lfo2_internal_depth > 0);
325 schoenebeck 53 break;
326     case ::gig::lfo2_ctrl_modwheel:
327     lfo2_internal_depth = 0;
328     pLFO2->ExtController = 1; // MIDI controller 1
329 schoenebeck 687 bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0);
330 schoenebeck 53 break;
331     case ::gig::lfo2_ctrl_foot:
332     lfo2_internal_depth = 0;
333     pLFO2->ExtController = 4; // MIDI controller 4
334 schoenebeck 687 bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0);
335 schoenebeck 53 break;
336     case ::gig::lfo2_ctrl_internal_modwheel:
337     lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
338     pLFO2->ExtController = 1; // MIDI controller 1
339 schoenebeck 687 bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
340 schoenebeck 53 break;
341     case ::gig::lfo2_ctrl_internal_foot:
342     lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
343     pLFO2->ExtController = 4; // MIDI controller 4
344 schoenebeck 687 bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
345 schoenebeck 53 break;
346     default:
347     lfo2_internal_depth = 0;
348     pLFO2->ExtController = 0; // no external controller
349 schoenebeck 687 bLFO2Enabled = false;
350 schoenebeck 53 }
351 schoenebeck 738 if (bLFO2Enabled) pLFO2->trigger(pDimRgn->LFO2Frequency,
352     start_level_max,
353 schoenebeck 687 lfo2_internal_depth,
354     pDimRgn->LFO2ControlDepth,
355     pDimRgn->LFO2FlipPhase,
356 schoenebeck 738 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
357 schoenebeck 53 }
358    
359 schoenebeck 319
360 schoenebeck 53 // setup LFO 3 (VCO LFO)
361     {
362     uint16_t lfo3_internal_depth;
363     switch (pDimRgn->LFO3Controller) {
364     case ::gig::lfo3_ctrl_internal:
365     lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
366     pLFO3->ExtController = 0; // no external controller
367 schoenebeck 687 bLFO3Enabled = (lfo3_internal_depth > 0);
368 schoenebeck 53 break;
369     case ::gig::lfo3_ctrl_modwheel:
370     lfo3_internal_depth = 0;
371     pLFO3->ExtController = 1; // MIDI controller 1
372 schoenebeck 687 bLFO3Enabled = (pDimRgn->LFO3ControlDepth > 0);
373 schoenebeck 53 break;
374     case ::gig::lfo3_ctrl_aftertouch:
375     lfo3_internal_depth = 0;
376     pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
377 schoenebeck 687 bLFO3Enabled = false; // see TODO comment in line above
378 schoenebeck 53 break;
379     case ::gig::lfo3_ctrl_internal_modwheel:
380     lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
381     pLFO3->ExtController = 1; // MIDI controller 1
382 schoenebeck 687 bLFO3Enabled = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
383 schoenebeck 53 break;
384     case ::gig::lfo3_ctrl_internal_aftertouch:
385     lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
386     pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
387 schoenebeck 687 bLFO3Enabled = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above
388 schoenebeck 53 break;
389     default:
390     lfo3_internal_depth = 0;
391     pLFO3->ExtController = 0; // no external controller
392 schoenebeck 687 bLFO3Enabled = false;
393 schoenebeck 53 }
394 schoenebeck 738 if (bLFO3Enabled) pLFO3->trigger(pDimRgn->LFO3Frequency,
395     start_level_mid,
396 schoenebeck 687 lfo3_internal_depth,
397     pDimRgn->LFO3ControlDepth,
398     false,
399 schoenebeck 738 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
400 schoenebeck 53 }
401    
402 schoenebeck 319
403 schoenebeck 554 #if CONFIG_FORCE_FILTER
404 schoenebeck 368 const bool bUseFilter = true;
405 schoenebeck 53 #else // use filter only if instrument file told so
406 schoenebeck 368 const bool bUseFilter = pDimRgn->VCFEnabled;
407 schoenebeck 554 #endif // CONFIG_FORCE_FILTER
408 schoenebeck 368 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
409     if (bUseFilter) {
410 schoenebeck 554 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
411     VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
412 schoenebeck 53 #else // use the one defined in the instrument file
413     switch (pDimRgn->VCFCutoffController) {
414     case ::gig::vcf_cutoff_ctrl_modwheel:
415     VCFCutoffCtrl.controller = 1;
416     break;
417     case ::gig::vcf_cutoff_ctrl_effect1:
418     VCFCutoffCtrl.controller = 12;
419     break;
420     case ::gig::vcf_cutoff_ctrl_effect2:
421     VCFCutoffCtrl.controller = 13;
422     break;
423     case ::gig::vcf_cutoff_ctrl_breath:
424     VCFCutoffCtrl.controller = 2;
425     break;
426     case ::gig::vcf_cutoff_ctrl_foot:
427     VCFCutoffCtrl.controller = 4;
428     break;
429     case ::gig::vcf_cutoff_ctrl_sustainpedal:
430     VCFCutoffCtrl.controller = 64;
431     break;
432     case ::gig::vcf_cutoff_ctrl_softpedal:
433     VCFCutoffCtrl.controller = 67;
434     break;
435     case ::gig::vcf_cutoff_ctrl_genpurpose7:
436     VCFCutoffCtrl.controller = 82;
437     break;
438     case ::gig::vcf_cutoff_ctrl_genpurpose8:
439     VCFCutoffCtrl.controller = 83;
440     break;
441     case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet
442     case ::gig::vcf_cutoff_ctrl_none:
443     default:
444     VCFCutoffCtrl.controller = 0;
445     break;
446     }
447 schoenebeck 554 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
448 schoenebeck 53
449 schoenebeck 554 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
450     VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
451 schoenebeck 53 #else // use the one defined in the instrument file
452     switch (pDimRgn->VCFResonanceController) {
453     case ::gig::vcf_res_ctrl_genpurpose3:
454     VCFResonanceCtrl.controller = 18;
455     break;
456     case ::gig::vcf_res_ctrl_genpurpose4:
457     VCFResonanceCtrl.controller = 19;
458     break;
459     case ::gig::vcf_res_ctrl_genpurpose5:
460     VCFResonanceCtrl.controller = 80;
461     break;
462     case ::gig::vcf_res_ctrl_genpurpose6:
463     VCFResonanceCtrl.controller = 81;
464     break;
465     case ::gig::vcf_res_ctrl_none:
466     default:
467     VCFResonanceCtrl.controller = 0;
468     }
469 schoenebeck 554 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
470 schoenebeck 53
471 schoenebeck 554 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
472 schoenebeck 53 FilterLeft.SetType(pDimRgn->VCFType);
473     FilterRight.SetType(pDimRgn->VCFType);
474     #else // override filter type
475 schoenebeck 554 FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
476     FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
477     #endif // CONFIG_OVERRIDE_FILTER_TYPE
478 schoenebeck 53
479 schoenebeck 411 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
480     VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
481 schoenebeck 53
482     // calculate cutoff frequency
483 persson 729 float cutoff = pDimRgn->GetVelocityCutoff(itNoteOnEvent->Param.Note.Velocity);
484     if (pDimRgn->VCFKeyboardTracking) {
485     cutoff *= exp((itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.057762265f); // (ln(2) / 12)
486     }
487     CutoffBase = cutoff;
488 schoenebeck 53
489 persson 729 int cvalue;
490     if (VCFCutoffCtrl.controller) {
491     cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
492     if (pDimRgn->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
493     if (cvalue < pDimRgn->VCFVelocityScale) cvalue = pDimRgn->VCFVelocityScale;
494     }
495     else {
496     cvalue = pDimRgn->VCFCutoff;
497     }
498     cutoff *= float(cvalue) * 0.00787402f; // (1 / 127)
499     if (cutoff > 1.0) cutoff = 1.0;
500     cutoff = exp(cutoff * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MIN;
501    
502 schoenebeck 53 // calculate resonance
503     float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0
504     if (pDimRgn->VCFKeyboardTracking) {
505 schoenebeck 271 resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
506 schoenebeck 53 }
507     Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
508    
509 schoenebeck 554 VCFCutoffCtrl.fvalue = cutoff - CONFIG_FILTER_CUTOFF_MIN;
510 schoenebeck 53 VCFResonanceCtrl.fvalue = resonance;
511     }
512     else {
513     VCFCutoffCtrl.controller = 0;
514     VCFResonanceCtrl.controller = 0;
515     }
516    
517     return 0; // success
518     }
519    
520     /**
521     * Renders the audio data for this voice for the current audio fragment.
522     * The sample input data can either come from RAM (cached sample or sample
523     * part) or directly from disk. The output signal will be rendered by
524     * resampling / interpolation. If this voice is a disk streaming voice and
525     * the voice completely played back the cached RAM part of the sample, it
526     * will automatically switch to disk playback for the next RenderAudio()
527     * call.
528     *
529     * @param Samples - number of samples to be rendered in this audio fragment cycle
530     */
531     void Voice::Render(uint Samples) {
532    
533 schoenebeck 319 // select default values for synthesis mode bits
534     SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
535    
536     switch (this->PlaybackState) {
537 schoenebeck 80
538 schoenebeck 563 case playback_state_init:
539     this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
540     // no break - continue with playback_state_ram
541    
542 schoenebeck 319 case playback_state_ram: {
543     if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
544 schoenebeck 80
545 schoenebeck 319 // render current fragment
546     Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
547 schoenebeck 53
548     if (DiskVoice) {
549     // check if we reached the allowed limit of the sample RAM cache
550     if (Pos > MaxRAMPos) {
551     dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", Pos));
552     this->PlaybackState = playback_state_disk;
553     }
554     }
555     else if (Pos >= pSample->GetCache().Size / pSample->FrameSize) {
556     this->PlaybackState = playback_state_end;
557     }
558     }
559     break;
560    
561     case playback_state_disk: {
562     if (!DiskStreamRef.pStream) {
563     // check if the disk thread created our ordered disk stream in the meantime
564     DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
565     if (!DiskStreamRef.pStream) {
566     std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
567 schoenebeck 239 KillImmediately();
568 schoenebeck 53 return;
569     }
570 schoenebeck 319 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
571     Pos -= int(Pos);
572 schoenebeck 330 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
573 schoenebeck 53 }
574    
575 schoenebeck 323 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
576    
577 schoenebeck 53 // add silence sample at the end if we reached the end of the stream (for the interpolator)
578 schoenebeck 323 if (DiskStreamRef.State == Stream::state_end) {
579 schoenebeck 554 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
580 schoenebeck 323 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
581 schoenebeck 330 // remember how many sample words there are before any silence has been added
582     if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
583 schoenebeck 323 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
584     }
585 schoenebeck 53 }
586    
587     sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
588 schoenebeck 319
589     // render current audio fragment
590     Synthesize(Samples, ptr, Delay);
591    
592 schoenebeck 323 const int iPos = (int) Pos;
593     const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
594     DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
595     Pos -= iPos; // just keep fractional part of Pos
596    
597     // change state of voice to 'end' if we really reached the end of the sample data
598 schoenebeck 330 if (RealSampleWordsLeftToRead >= 0) {
599     RealSampleWordsLeftToRead -= readSampleWords;
600     if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
601     }
602 schoenebeck 53 }
603     break;
604    
605     case playback_state_end:
606 schoenebeck 285 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
607 schoenebeck 53 break;
608     }
609    
610 schoenebeck 738 // Reset synthesis event lists
611     pEngineChannel->pEvents->clear();
612 schoenebeck 53
613     // Reset delay
614     Delay = 0;
615    
616 schoenebeck 271 itTriggerEvent = Pool<Event>::Iterator();
617 schoenebeck 53
618 schoenebeck 285 // If sample stream or release stage finished, kill the voice
619 schoenebeck 738 if (PlaybackState == playback_state_end || EG1.getSegmentType() == EGADSR::segment_end) KillImmediately();
620 schoenebeck 53 }
621    
622     /**
623     * Resets voice variables. Should only be called if rendering process is
624     * suspended / not running.
625     */
626     void Voice::Reset() {
627 schoenebeck 319 FilterLeft.Reset();
628     FilterRight.Reset();
629 schoenebeck 53 DiskStreamRef.pStream = NULL;
630     DiskStreamRef.hStream = 0;
631     DiskStreamRef.State = Stream::state_unused;
632     DiskStreamRef.OrderID = 0;
633 schoenebeck 285 PlaybackState = playback_state_end;
634     itTriggerEvent = Pool<Event>::Iterator();
635     itKillEvent = Pool<Event>::Iterator();
636 schoenebeck 53 }
637    
638     /**
639 schoenebeck 738 * Process given list of MIDI note on, note off and sustain pedal events
640     * for the given time.
641 schoenebeck 53 *
642 schoenebeck 738 * @param itEvent - iterator pointing to the next event to be processed
643     * @param End - youngest time stamp where processing should be stopped
644 schoenebeck 53 */
645 schoenebeck 738 void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
646     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
647     if (itEvent->Type == Event::type_release) {
648     EG1.update(EGADSR::event_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
649     EG2.update(EGADSR::event_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
650     } else if (itEvent->Type == Event::type_cancel_release) {
651     EG1.update(EGADSR::event_cancel_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
652     EG2.update(EGADSR::event_cancel_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
653     }
654     }
655     }
656 schoenebeck 53
657 schoenebeck 738 /**
658     * Process given list of MIDI control change and pitch bend events for
659     * the given time.
660     *
661     * @param itEvent - iterator pointing to the next event to be processed
662     * @param End - youngest time stamp where processing should be stopped
663     */
664     void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
665     for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
666     if (itEvent->Type == Event::type_control_change &&
667     itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
668     if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
669     processCutoffEvent(itEvent);
670 schoenebeck 53 }
671 schoenebeck 738 if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
672     processResonanceEvent(itEvent);
673 schoenebeck 53 }
674 schoenebeck 738 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
675     pLFO1->update(itEvent->Param.CC.Value);
676 schoenebeck 53 }
677 schoenebeck 738 if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
678     pLFO2->update(itEvent->Param.CC.Value);
679 schoenebeck 53 }
680 schoenebeck 738 if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
681     pLFO3->update(itEvent->Param.CC.Value);
682 schoenebeck 53 }
683 schoenebeck 236 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
684 schoenebeck 738 itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
685     processCrossFadeEvent(itEvent);
686 schoenebeck 236 }
687 schoenebeck 738 } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
688     processPitchEvent(itEvent);
689 schoenebeck 53 }
690     }
691 schoenebeck 738 }
692 schoenebeck 53
693 schoenebeck 738 void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
694     const float pitch = RTMath::CentsToFreqRatio(((double) itEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
695     fFinalPitch *= pitch;
696     }
697 schoenebeck 53
698 schoenebeck 738 void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {
699     CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);
700     #if CONFIG_PROCESS_MUTED_CHANNELS
701     const float effectiveVolume = CrossfadeVolume * Volume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);
702     #else
703     const float effectiveVolume = CrossfadeVolume * Volume * pEngineChannel->GlobalVolume;
704     #endif
705     fFinalVolume = effectiveVolume;
706     }
707 schoenebeck 53
708 schoenebeck 738 void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
709     int ccvalue = itEvent->Param.CC.Value;
710     if (VCFCutoffCtrl.value == ccvalue) return;
711     VCFCutoffCtrl.value == ccvalue;
712     if (pDimRgn->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
713     if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
714     float cutoff = CutoffBase * float(ccvalue) * 0.00787402f; // (1 / 127)
715     if (cutoff > 1.0) cutoff = 1.0;
716     cutoff = exp(cutoff * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MIN - CONFIG_FILTER_CUTOFF_MIN;
717     VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
718     fFinalCutoff = cutoff;
719     }
720 schoenebeck 53
721 schoenebeck 738 void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
722     // convert absolute controller value to differential
723     const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
724     VCFResonanceCtrl.value = itEvent->Param.CC.Value;
725     const float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
726     fFinalResonance += resonancedelta;
727     // needed for initialization of parameter
728     VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value * 0.00787f;
729     }
730 schoenebeck 53
731 schoenebeck 738 /**
732     * Synthesizes the current audio fragment for this voice.
733     *
734     * @param Samples - number of sample points to be rendered in this audio
735     * fragment cycle
736     * @param pSrc - pointer to input sample data
737     * @param Skip - number of sample points to skip in output buffer
738     */
739     void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
740     RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
741     RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
742 persson 768
743 schoenebeck 738 if (Skip) { // skip events that happened before this voice was triggered
744     while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
745     while (itNoteEvent && itNoteEvent->FragmentPos() <= Skip) ++itNoteEvent;
746 schoenebeck 53 }
747 persson 768
748 schoenebeck 738 uint i = Skip;
749     while (i < Samples) {
750     int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
751 persson 768
752 schoenebeck 738 // initialize all final synthesis parameters
753     fFinalPitch = PitchBase * PitchBend;
754     #if CONFIG_PROCESS_MUTED_CHANNELS
755 persson 768 fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);
756 schoenebeck 738 #else
757     fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume;
758     #endif
759     fFinalCutoff = VCFCutoffCtrl.fvalue;
760     fFinalResonance = VCFResonanceCtrl.fvalue;
761 persson 768
762 schoenebeck 738 // process MIDI control change and pitchbend events for this subfragment
763     processCCEvents(itCCEvent, iSubFragmentEnd);
764 schoenebeck 53
765 schoenebeck 738 // process transition events (note on, note off & sustain pedal)
766     processTransitionEvents(itNoteEvent, iSubFragmentEnd);
767 persson 768
768 schoenebeck 738 // process envelope generators
769     switch (EG1.getSegmentType()) {
770     case EGADSR::segment_lin:
771     fFinalVolume *= EG1.processLin();
772     break;
773     case EGADSR::segment_exp:
774     fFinalVolume *= EG1.processExp();
775     break;
776     case EGADSR::segment_end:
777     fFinalVolume *= EG1.getLevel();
778     break; // noop
779 schoenebeck 236 }
780 schoenebeck 738 switch (EG2.getSegmentType()) {
781     case EGADSR::segment_lin:
782     fFinalCutoff *= EG2.processLin();
783     break;
784     case EGADSR::segment_exp:
785     fFinalCutoff *= EG2.processExp();
786     break;
787     case EGADSR::segment_end:
788     fFinalCutoff *= EG2.getLevel();
789     break; // noop
790 schoenebeck 236 }
791 schoenebeck 738 fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render());
792 persson 768
793 schoenebeck 738 // process low frequency oscillators
794     if (bLFO1Enabled) fFinalVolume *= pLFO1->render();
795     if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
796     if (bLFO3Enabled) fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
797 schoenebeck 236
798 schoenebeck 738 // if filter enabled then update filter coefficients
799     if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
800     FilterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
801     FilterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
802 schoenebeck 53 }
803    
804 schoenebeck 738 // how many steps do we calculate for this next subfragment
805     const int steps = iSubFragmentEnd - i;
806 persson 768
807 schoenebeck 738 // select the appropriate synthesis mode
808     SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, fFinalPitch != 1.0f);
809 persson 768
810 schoenebeck 738 // render audio for one subfragment
811     RunSynthesisFunction(SynthesisMode, *this, iSubFragmentEnd, pSrc, i);
812 schoenebeck 53
813 persson 768 // increment envelopes' positions
814 schoenebeck 738 if (EG1.active()) {
815 persson 768 EG1.increment(1);
816 schoenebeck 738 if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
817 schoenebeck 53 }
818 schoenebeck 738 if (EG2.active()) {
819 persson 768 EG2.increment(1);
820 schoenebeck 738 if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
821 schoenebeck 53 }
822 persson 768 EG3.increment(1);
823 schoenebeck 738 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
824 persson 768
825     i = iSubFragmentEnd;
826 schoenebeck 53 }
827     }
828    
829     /**
830 schoenebeck 239 * Immediately kill the voice. This method should not be used to kill
831     * a normal, active voice, because it doesn't take care of things like
832     * fading down the volume level to avoid clicks and regular processing
833     * until the kill event actually occured!
834     *
835     * @see Kill()
836 schoenebeck 53 */
837 schoenebeck 239 void Voice::KillImmediately() {
838 schoenebeck 53 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
839     pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
840     }
841     Reset();
842     }
843    
844 schoenebeck 239 /**
845     * Kill the voice in regular sense. Let the voice render audio until
846     * the kill event actually occured and then fade down the volume level
847     * very quickly and let the voice die finally. Unlike a normal release
848     * of a voice, a kill process cannot be cancalled and is therefore
849     * usually used for voice stealing and key group conflicts.
850     *
851 schoenebeck 271 * @param itKillEvent - event which caused the voice to be killed
852 schoenebeck 239 */
853 schoenebeck 271 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
854 schoenebeck 554 #if CONFIG_DEVMODE
855 schoenebeck 287 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
856     if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
857 schoenebeck 554 #endif // CONFIG_DEVMODE
858 schoenebeck 287
859 schoenebeck 271 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
860     this->itKillEvent = itKillEvent;
861 schoenebeck 239 }
862    
863 schoenebeck 53 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC