/[svn]/linuxsampler/trunk/src/engines/sfz/Voice.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/sfz/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2176 - (show annotations) (download)
Sun May 1 15:19:38 2011 UTC (12 years, 11 months ago) by persson
File size: 23464 byte(s)
* sfz engine: added support for velocity effect on amplifier envelope
  time (ampeg_vel2attack, ampeg_vel2decay, ampeg_vel2sustain and
  ampeg_vel2release)

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2008 Christian Schoenebeck *
7 * Copyright (C) 2009 - 2011 Christian Schoenebeck and Grigor Iliev *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22 * MA 02111-1307 USA *
23 ***************************************************************************/
24
25 #include "Voice.h"
26
27 #include "Engine.h"
28 #include "EngineChannel.h"
29
30 #define LN_10_DIV_20 0.115129254649702
31
32 namespace LinuxSampler { namespace sfz {
33
34 Voice::Voice() {
35 pEngine = NULL;
36 }
37
38 Voice::~Voice() {
39
40 }
41
42 EngineChannel* Voice::GetSfzEngineChannel() {
43 return static_cast<EngineChannel*>(pEngineChannel);
44 }
45
46 void Voice::SetEngine(LinuxSampler::Engine* pEngine) {
47 Engine* engine = static_cast<Engine*>(pEngine);
48 this->pEngine = engine;
49 this->pDiskThread = engine->pDiskThread;
50 dmsg(6,("Voice::SetEngine()\n"));
51 }
52
53 Voice::SampleInfo Voice::GetSampleInfo() {
54 SampleInfo si;
55 si.SampleRate = pSample->GetSampleRate();
56 si.ChannelCount = pSample->GetChannelCount();
57 si.FrameSize = pSample->GetFrameSize();
58 si.BitDepth = (pSample->GetFrameSize() / pSample->GetChannelCount()) * 8;
59 si.TotalFrameCount = pSample->GetTotalFrameCount();
60
61 si.HasLoops = pRegion->HasLoop();
62 si.LoopStart = pRegion->GetLoopStart();
63 si.LoopLength = pRegion->GetLoopEnd() - pRegion->GetLoopStart();
64 si.LoopPlayCount = pRegion->GetLoopCount();
65 si.Unpitched = pRegion->pitch_keytrack == 0;
66 return si;
67 }
68
69 Voice::RegionInfo Voice::GetRegionInfo() {
70 RegionInfo ri;
71 ri.UnityNote = pRegion->pitch_keycenter;
72 ri.FineTune = pRegion->tune + pRegion->transpose * 100;
73 ri.Pan = int(pRegion->pan * 0.63); // convert from -100..100 to -64..63
74 ri.SampleStartOffset = 0; // TODO:
75
76 ri.EG1PreAttack = pRegion->ampeg_start * 10;
77 ri.EG1Attack = pRegion->ampeg_attack;
78 ri.EG1Hold = pRegion->ampeg_hold;
79 ri.EG1Decay1 = pRegion->ampeg_decay;
80 ri.EG1Decay2 = pRegion->ampeg_decay;
81 ri.EG1Sustain = pRegion->ampeg_sustain * 10;
82 ri.EG1InfiniteSustain = true;
83 ri.EG1Release = pRegion->ampeg_release;
84
85 ri.EG2PreAttack = pRegion->fileg_start * 10;
86 ri.EG2Attack = pRegion->fileg_attack;
87 //ri.EG2Hold = pRegion->fileg_hold; // TODO:
88 ri.EG2Decay1 = pRegion->fileg_decay;
89 ri.EG2Decay2 = pRegion->fileg_decay;
90 ri.EG2Sustain = pRegion->fileg_sustain * 10;
91 ri.EG2InfiniteSustain = true;
92 ri.EG2Release = pRegion->fileg_release;
93
94 ri.EG3Attack = pRegion->pitcheg_attack;
95 ri.EG3Depth = 0; // TODO:
96 ri.VCFEnabled = pRegion->cutoff;
97 switch (pRegion->fil_type) {
98 case ::sfz::LPF_1P:
99 ri.VCFType = Filter::vcf_type_1p_lowpass;
100 break;
101 case ::sfz::LPF_2P:
102 ri.VCFType = Filter::vcf_type_2p_lowpass;
103 break;
104 case ::sfz::LPF_4P:
105 ri.VCFType = Filter::vcf_type_4p_lowpass;
106 break;
107 case ::sfz::LPF_6P:
108 ri.VCFType = Filter::vcf_type_6p_lowpass;
109 break;
110 case ::sfz::HPF_1P:
111 ri.VCFType = Filter::vcf_type_1p_highpass;
112 break;
113 case ::sfz::HPF_2P:
114 ri.VCFType = Filter::vcf_type_2p_highpass;
115 break;
116 case ::sfz::HPF_4P:
117 ri.VCFType = Filter::vcf_type_4p_highpass;
118 break;
119 case ::sfz::HPF_6P:
120 ri.VCFType = Filter::vcf_type_6p_highpass;
121 break;
122 case ::sfz::BPF_1P:
123 case ::sfz::BPF_2P:
124 ri.VCFType = Filter::vcf_type_2p_bandpass;
125 break;
126 case ::sfz::BRF_1P:
127 case ::sfz::BRF_2P:
128 ri.VCFType = Filter::vcf_type_2p_bandreject;
129 break;
130 case ::sfz::APF_1P:
131 case ::sfz::PKF_2P:
132 default:
133 ri.VCFEnabled = false;
134 break;
135 }
136
137 ri.VCFResonance = pRegion->resonance;
138
139 // rt_decay is in dB. Precalculate a suitable value for exp in
140 // GetReleaseTriggerAttenuation: -ln(10) / 20 * rt_decay
141 ri.ReleaseTriggerDecay = -LN_10_DIV_20 * pRegion->rt_decay;
142
143 return ri;
144 }
145
146 Voice::InstrumentInfo Voice::GetInstrumentInfo() {
147 InstrumentInfo ii;
148 ii.FineTune = 0; // TODO:
149 ii.PitchbendRange = 2; // TODO:
150
151 return ii;
152 }
153
154 double Voice::GetSampleAttenuation() {
155 return exp(LN_10_DIV_20 * pRegion->volume);
156 }
157
158 double Voice::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
159 return pRegion->amp_velcurve[MIDIKeyVelocity];
160 }
161
162 double Voice::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
163 return 127.0 / MIDIKeyVelocity;
164 }
165
166 void Voice::ProcessCCEvent(RTList<Event>::Iterator& itEvent) {
167 /*if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
168 if (pRegion->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
169 itEvent->Param.CC.Controller == pRegion->AttenuationController.controller_number) {
170 CrossfadeSmoother.update(AbstractEngine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
171 }
172 }*/ // TODO: ^^^
173 }
174
175 void Voice::ProcessCutoffEvent(RTList<Event>::Iterator& itEvent) {
176 int ccvalue = itEvent->Param.CC.Value;
177 if (VCFCutoffCtrl.value == ccvalue) return;
178 VCFCutoffCtrl.value = ccvalue;
179
180 float cutoff = CutoffBase * RTMath::CentsToFreqRatioUnlimited(
181 ccvalue / 127.0f * pRegion->cutoff_oncc[VCFCutoffCtrl.controller]);
182 if (cutoff > 0.49 * pEngine->SampleRate) cutoff = 0.49 * pEngine->SampleRate;
183
184 VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
185 fFinalCutoff = cutoff;
186 }
187
188 double Voice::CalculateCrossfadeVolume(uint8_t MIDIKeyVelocity) {
189 /*float crossfadeVolume;
190 switch (pRegion->AttenuationController.type) {
191 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
192 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(GetSfzEngineChannel()->ControllerTable[128])];
193 break;
194 case ::gig::attenuation_ctrl_t::type_velocity:
195 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(MIDIKeyVelocity)];
196 break;
197 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
198 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(GetSfzEngineChannel()->ControllerTable[pRegion->AttenuationController.controller_number])];
199 break;
200 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
201 default:
202 crossfadeVolume = 1.0f;
203 }
204
205 return crossfadeVolume;*/ // TODO: ^^^
206 return 1.0f;
207 }
208
209 double Voice::GetEG1ControllerValue(uint8_t MIDIKeyVelocity) {
210 /*double eg1controllervalue = 0;
211 switch (pRegion->EG1Controller.type) {
212 case ::gig::eg1_ctrl_t::type_none: // no controller defined
213 eg1controllervalue = 0;
214 break;
215 case ::gig::eg1_ctrl_t::type_channelaftertouch:
216 eg1controllervalue = GetSfzEngineChannel()->ControllerTable[128];
217 break;
218 case ::gig::eg1_ctrl_t::type_velocity:
219 eg1controllervalue = MIDIKeyVelocity;
220 break;
221 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
222 eg1controllervalue = GetSfzEngineChannel()->ControllerTable[pRegion->EG1Controller.controller_number];
223 break;
224 }
225 if (pRegion->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
226
227 return eg1controllervalue;*/ // TODO: ^^^
228 return 0;
229 }
230
231 Voice::EGInfo Voice::CalculateEG1ControllerInfluence(double eg1ControllerValue) {
232 /*EGInfo eg;
233 // (eg1attack is different from the others)
234 eg.Attack = (pRegion->EG1ControllerAttackInfluence) ?
235 1 + 0.031 * (double) (pRegion->EG1ControllerAttackInfluence == 1 ?
236 1 : 1 << pRegion->EG1ControllerAttackInfluence) * eg1ControllerValue : 1.0;
237 eg.Decay = (pRegion->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerDecayInfluence) * eg1ControllerValue : 1.0;
238 eg.Release = (pRegion->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerReleaseInfluence) * eg1ControllerValue : 1.0;
239
240 return eg;*/ // TODO: ^^^
241 EGInfo eg;
242 eg.Attack = 1.0;
243 eg.Decay = 1.0;
244 eg.Release = 1.0;
245 return eg;
246 }
247
248 void Voice::TriggerEG1(const EGInfo& egInfo, double velrelease, double velocityAttenuation, uint sampleRate, uint8_t velocity) {
249
250 // TODO: controller modulation
251
252 // first check if there is a v2 EG for amplitude
253 for (int i = 0 ; i < pRegion->eg.size() ; i++) {
254 if (pRegion->eg[i].amplitude > 0) {
255 // TODO: actually use the value of the amplitude parameter
256 pEG1 = &EG1;
257 EG1.trigger(pRegion->eg[i], sampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE, velocity);
258 return;
259 }
260 }
261
262 // otherwise use the v1 EGADSR
263 pEG1 = &EGADSR1;
264 EGADSR1.trigger(uint(RgnInfo.EG1PreAttack),
265 std::max(0.0, RgnInfo.EG1Attack + pRegion->ampeg_vel2attack * velrelease),
266 std::max(0.0, RgnInfo.EG1Hold + pRegion->ampeg_vel2hold * velrelease),
267 std::max(0.0, RgnInfo.EG1Decay1 + pRegion->ampeg_vel2decay * velrelease),
268 uint(std::min(std::max(0.0, RgnInfo.EG1Sustain + 10 * pRegion->ampeg_vel2sustain * velrelease), 1000.0)),
269 std::max(0.0, RgnInfo.EG1Release + pRegion->ampeg_vel2release * velrelease),
270 sampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
271 }
272
273 double Voice::GetEG2ControllerValue(uint8_t MIDIKeyVelocity) {
274 /*double eg2controllervalue = 0;
275 switch (pRegion->EG2Controller.type) {
276 case ::gig::eg2_ctrl_t::type_none: // no controller defined
277 eg2controllervalue = 0;
278 break;
279 case ::gig::eg2_ctrl_t::type_channelaftertouch:
280 eg2controllervalue = GetSfzEngineChannel()->ControllerTable[128];
281 break;
282 case ::gig::eg2_ctrl_t::type_velocity:
283 eg2controllervalue = MIDIKeyVelocity;
284 break;
285 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
286 eg2controllervalue = GetSfzEngineChannel()->ControllerTable[pRegion->EG2Controller.controller_number];
287 break;
288 }
289 if (pRegion->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
290
291 return eg2controllervalue;*/ // TODO: ^^^
292 return 0;
293 }
294
295 Voice::EGInfo Voice::CalculateEG2ControllerInfluence(double eg2ControllerValue) {
296 /*EGInfo eg;
297 eg.Attack = (pRegion->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerAttackInfluence) * eg2ControllerValue : 1.0;
298 eg.Decay = (pRegion->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerDecayInfluence) * eg2ControllerValue : 1.0;
299 eg.Release = (pRegion->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerReleaseInfluence) * eg2ControllerValue : 1.0;
300
301 return eg;*/ // TODO: ^^^
302 EGInfo eg;
303 eg.Attack = 1.0;
304 eg.Decay = 1.0;
305 eg.Release = 1.0;
306 return eg;
307 }
308
309 void Voice::TriggerEG2(const EGInfo& egInfo, double velrelease, double velocityAttenuation, uint sampleRate, uint8_t velocity) {
310
311 // TODO: the sfz filter EG should modulate cents, not hertz,
312 // so we can't use the EG or EGADSR as it is. Disable for now.
313
314 pEG2 = &EGADSR2;
315 EGADSR2.trigger(0,
316 0,
317 false,
318 0,
319 1000,
320 0,
321 sampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
322 }
323
324 void Voice::InitLFO1() {
325 /*uint16_t lfo1_internal_depth;
326 switch (pRegion->LFO1Controller) {
327 case ::gig::lfo1_ctrl_internal:
328 lfo1_internal_depth = pRegion->LFO1InternalDepth;
329 pLFO1->ExtController = 0; // no external controller
330 bLFO1Enabled = (lfo1_internal_depth > 0);
331 break;
332 case ::gig::lfo1_ctrl_modwheel:
333 lfo1_internal_depth = 0;
334 pLFO1->ExtController = 1; // MIDI controller 1
335 bLFO1Enabled = (pRegion->LFO1ControlDepth > 0);
336 break;
337 case ::gig::lfo1_ctrl_breath:
338 lfo1_internal_depth = 0;
339 pLFO1->ExtController = 2; // MIDI controller 2
340 bLFO1Enabled = (pRegion->LFO1ControlDepth > 0);
341 break;
342 case ::gig::lfo1_ctrl_internal_modwheel:
343 lfo1_internal_depth = pRegion->LFO1InternalDepth;
344 pLFO1->ExtController = 1; // MIDI controller 1
345 bLFO1Enabled = (lfo1_internal_depth > 0 || pRegion->LFO1ControlDepth > 0);
346 break;
347 case ::gig::lfo1_ctrl_internal_breath:
348 lfo1_internal_depth = pRegion->LFO1InternalDepth;
349 pLFO1->ExtController = 2; // MIDI controller 2
350 bLFO1Enabled = (lfo1_internal_depth > 0 || pRegion->LFO1ControlDepth > 0);
351 break;
352 default:
353 lfo1_internal_depth = 0;
354 pLFO1->ExtController = 0; // no external controller
355 bLFO1Enabled = false;
356 }
357 if (bLFO1Enabled) {
358 pLFO1->trigger(pRegion->LFO1Frequency,
359 start_level_min,
360 lfo1_internal_depth,
361 pRegion->LFO1ControlDepth,
362 pRegion->LFO1FlipPhase,
363 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
364 pLFO1->update(pLFO1->ExtController ? GetSfzEngineChannel()->ControllerTable[pLFO1->ExtController] : 0);
365 }*/ // TODO: ^^^
366 bLFO1Enabled = false;
367 }
368
369 void Voice::InitLFO2() {
370 /*uint16_t lfo2_internal_depth;
371 switch (pRegion->LFO2Controller) {
372 case ::gig::lfo2_ctrl_internal:
373 lfo2_internal_depth = pRegion->LFO2InternalDepth;
374 pLFO2->ExtController = 0; // no external controller
375 bLFO2Enabled = (lfo2_internal_depth > 0);
376 break;
377 case ::gig::lfo2_ctrl_modwheel:
378 lfo2_internal_depth = 0;
379 pLFO2->ExtController = 1; // MIDI controller 1
380 bLFO2Enabled = (pRegion->LFO2ControlDepth > 0);
381 break;
382 case ::gig::lfo2_ctrl_foot:
383 lfo2_internal_depth = 0;
384 pLFO2->ExtController = 4; // MIDI controller 4
385 bLFO2Enabled = (pRegion->LFO2ControlDepth > 0);
386 break;
387 case ::gig::lfo2_ctrl_internal_modwheel:
388 lfo2_internal_depth = pRegion->LFO2InternalDepth;
389 pLFO2->ExtController = 1; // MIDI controller 1
390 bLFO2Enabled = (lfo2_internal_depth > 0 || pRegion->LFO2ControlDepth > 0);
391 break;
392 case ::gig::lfo2_ctrl_internal_foot:
393 lfo2_internal_depth = pRegion->LFO2InternalDepth;
394 pLFO2->ExtController = 4; // MIDI controller 4
395 bLFO2Enabled = (lfo2_internal_depth > 0 || pRegion->LFO2ControlDepth > 0);
396 break;
397 default:
398 lfo2_internal_depth = 0;
399 pLFO2->ExtController = 0; // no external controller
400 bLFO2Enabled = false;
401 }
402 if (bLFO2Enabled) {
403 pLFO2->trigger(pRegion->LFO2Frequency,
404 start_level_max,
405 lfo2_internal_depth,
406 pRegion->LFO2ControlDepth,
407 pRegion->LFO2FlipPhase,
408 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
409 pLFO2->update(pLFO2->ExtController ? GetSfzEngineChannel()->ControllerTable[pLFO2->ExtController] : 0);
410 }*/ // TODO: ^^^
411 bLFO2Enabled = false;
412 }
413
414 void Voice::InitLFO3() {
415 /*uint16_t lfo3_internal_depth;
416 switch (pRegion->LFO3Controller) {
417 case ::gig::lfo3_ctrl_internal:
418 lfo3_internal_depth = pRegion->LFO3InternalDepth;
419 pLFO3->ExtController = 0; // no external controller
420 bLFO3Enabled = (lfo3_internal_depth > 0);
421 break;
422 case ::gig::lfo3_ctrl_modwheel:
423 lfo3_internal_depth = 0;
424 pLFO3->ExtController = 1; // MIDI controller 1
425 bLFO3Enabled = (pRegion->LFO3ControlDepth > 0);
426 break;
427 case ::gig::lfo3_ctrl_aftertouch:
428 lfo3_internal_depth = 0;
429 pLFO3->ExtController = 128;
430 bLFO3Enabled = true;
431 break;
432 case ::gig::lfo3_ctrl_internal_modwheel:
433 lfo3_internal_depth = pRegion->LFO3InternalDepth;
434 pLFO3->ExtController = 1; // MIDI controller 1
435 bLFO3Enabled = (lfo3_internal_depth > 0 || pRegion->LFO3ControlDepth > 0);
436 break;
437 case ::gig::lfo3_ctrl_internal_aftertouch:
438 lfo3_internal_depth = pRegion->LFO3InternalDepth;
439 pLFO1->ExtController = 128;
440 bLFO3Enabled = (lfo3_internal_depth > 0 || pRegion->LFO3ControlDepth > 0);
441 break;
442 default:
443 lfo3_internal_depth = 0;
444 pLFO3->ExtController = 0; // no external controller
445 bLFO3Enabled = false;
446 }
447 if (bLFO3Enabled) {
448 pLFO3->trigger(pRegion->LFO3Frequency,
449 start_level_mid,
450 lfo3_internal_depth,
451 pRegion->LFO3ControlDepth,
452 false,
453 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
454 pLFO3->update(pLFO3->ExtController ? GetSfzEngineChannel()->ControllerTable[pLFO3->ExtController] : 0);
455 }*/ // TODO: ^^^
456 bLFO3Enabled = false;
457 }
458
459 float Voice::CalculateCutoffBase(uint8_t MIDIKeyVelocity) {
460 float cutoff = *pRegion->cutoff;
461 cutoff *= RTMath::CentsToFreqRatioUnlimited(
462 MIDIKeyVelocity / 127.0f * pRegion->fil_veltrack +
463 (MIDIKey - pRegion->fil_keycenter) * pRegion->fil_keytrack);
464 return cutoff;
465 }
466
467 float Voice::CalculateFinalCutoff(float cutoffBase) {
468 float cutoff;
469 if (VCFCutoffCtrl.controller) {
470 int ccvalue = GetSfzEngineChannel()->ControllerTable[VCFCutoffCtrl.controller];
471 cutoff = CutoffBase * RTMath::CentsToFreqRatioUnlimited(
472 ccvalue / 127.0f * pRegion->cutoff_oncc[VCFCutoffCtrl.controller]);
473 } else {
474 cutoff = cutoffBase;
475 }
476 if (cutoff > 0.49 * pEngine->SampleRate) cutoff = 0.49 * pEngine->SampleRate;
477 return cutoff;
478 }
479
480 uint8_t Voice::GetVCFCutoffCtrl() {
481 // TODO: the sfz format allows several CC for the same
482 // modulation destination. The Voice interface needs to be
483 // changed to support that.
484 if (pRegion->cutoff_cc) return pRegion->cutoff_cc;
485 else if (pRegion->cutoff_chanaft) return 128;
486 return 0;
487 }
488
489 uint8_t Voice::GetVCFResonanceCtrl() {
490 /*uint8_t ctrl;
491 switch (pRegion->VCFResonanceController) {
492 case ::gig::vcf_res_ctrl_genpurpose3:
493 ctrl = 18;
494 break;
495 case ::gig::vcf_res_ctrl_genpurpose4:
496 ctrl = 19;
497 break;
498 case ::gig::vcf_res_ctrl_genpurpose5:
499 ctrl = 80;
500 break;
501 case ::gig::vcf_res_ctrl_genpurpose6:
502 ctrl = 81;
503 break;
504 case ::gig::vcf_res_ctrl_none:
505 default:
506 ctrl = 0;
507 }
508
509 return ctrl;*/ // TODO: ^^^
510 return 0;
511 }
512
513 float Voice::GetReleaseTriggerAttenuation(float noteLength) {
514 // pow(10, -rt_decay * noteLength / 20):
515 return expf(RgnInfo.ReleaseTriggerDecay * noteLength);
516 }
517
518 void Voice::ProcessGroupEvent(RTList<Event>::Iterator& itEvent) {
519 dmsg(4,("Voice %x processGroupEvents event type=%d", this, itEvent->Type));
520 if (itEvent->Type == Event::type_control_change ||
521 (Type & Voice::type_controller_triggered) ||
522 itEvent->Param.Note.Key != MIDIKey) {
523 dmsg(4,("Voice %x - kill", this));
524 if (pRegion->off_mode == ::sfz::OFF_NORMAL) {
525 // turn off the voice by entering release envelope stage
526 EnterReleaseStage();
527 } else {
528 // kill the voice fast
529 pEG1->enterFadeOutStage();
530 }
531 }
532 }
533
534 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC