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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2559 - (show annotations) (download)
Sun May 18 17:38:25 2014 UTC (9 years, 11 months ago) by schoenebeck
File size: 23183 byte(s)
* Aftertouch: extended API to explicitly handle channel pressure and
  polyphonic key pressure events (so far polyphonic pressure was not
  supported at all, and channel pressure was rerouted as CC128 but not
  used so far).
* Gig Engine: Fixed support for 'aftertouch' attenuation controller.
* Bumped version (1.0.0.svn39).

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 - 2013 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 "../../common/Features.h"
26 #include "Synthesizer.h"
27 #include "Profiler.h"
28 #include "Engine.h"
29 #include "EngineChannel.h"
30
31 #include "Voice.h"
32
33 namespace LinuxSampler { namespace gig {
34
35 Voice::Voice() {
36 pEngine = NULL;
37 pEG1 = &EG1;
38 pEG2 = &EG2;
39 }
40
41 Voice::~Voice() {
42 }
43
44 EngineChannel* Voice::GetGigEngineChannel() {
45 return static_cast<EngineChannel*>(pEngineChannel);
46 }
47
48 void Voice::SetEngine(LinuxSampler::Engine* pEngine) {
49 Engine* engine = static_cast<Engine*>(pEngine);
50 this->pEngine = engine;
51 this->pDiskThread = engine->pDiskThread;
52 dmsg(6,("Voice::SetEngine()\n"));
53 }
54
55 Voice::SampleInfo Voice::GetSampleInfo() {
56 SampleInfo si;
57 si.SampleRate = pSample->SamplesPerSecond;
58 si.ChannelCount = pSample->Channels;
59 si.FrameSize = pSample->FrameSize;
60 si.BitDepth = pSample->BitDepth;
61 si.TotalFrameCount = pSample->SamplesTotal;
62
63 si.HasLoops = pRegion->SampleLoops;
64 si.LoopStart = (si.HasLoops) ? pRegion->pSampleLoops[0].LoopStart : 0;
65 si.LoopLength = (si.HasLoops) ? pRegion->pSampleLoops[0].LoopLength : 0;
66 si.LoopPlayCount = pSample->LoopPlayCount;
67 si.Unpitched = !pRegion->PitchTrack;
68
69 return si;
70 }
71
72 Voice::RegionInfo Voice::GetRegionInfo() {
73 RegionInfo ri;
74 ri.UnityNote = pRegion->UnityNote;
75 ri.FineTune = pRegion->FineTune;
76 ri.Pan = pRegion->Pan;
77 ri.SampleStartOffset = pRegion->SampleStartOffset;
78
79 ri.EG2PreAttack = pRegion->EG2PreAttack;
80 ri.EG2Attack = pRegion->EG2Attack;
81 ri.EG2Decay1 = pRegion->EG2Decay1;
82 ri.EG2Decay2 = pRegion->EG2Decay2;
83 ri.EG2Sustain = pRegion->EG2Sustain;
84 ri.EG2InfiniteSustain = pRegion->EG2InfiniteSustain;
85 ri.EG2Release = pRegion->EG2Release;
86
87 ri.EG3Attack = pRegion->EG3Attack;
88 ri.EG3Depth = pRegion->EG3Depth;
89 ri.VCFEnabled = pRegion->VCFEnabled;
90 ri.VCFType = Filter::vcf_type_t(pRegion->VCFType);
91 ri.VCFResonance = pRegion->VCFResonance;
92
93 ri.ReleaseTriggerDecay = 0.01053 * (256 >> pRegion->ReleaseTriggerDecay);
94
95 return ri;
96 }
97
98 Voice::InstrumentInfo Voice::GetInstrumentInfo() {
99 InstrumentInfo ii;
100 ii.FineTune = GetGigEngineChannel()->pInstrument->FineTune;
101 ii.PitchbendRange = GetGigEngineChannel()->pInstrument->PitchbendRange;
102
103 return ii;
104 }
105
106 double Voice::GetSampleAttenuation() {
107 return pRegion->SampleAttenuation;
108 }
109
110 double Voice::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
111 return pRegion->GetVelocityAttenuation(MIDIKeyVelocity);
112 }
113
114 double Voice::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
115 return pRegion->GetVelocityRelease(MIDIKeyVelocity);
116 }
117
118 void Voice::ProcessCCEvent(RTList<Event>::Iterator& itEvent) {
119 if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
120 if (pRegion->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
121 itEvent->Param.CC.Controller == pRegion->AttenuationController.controller_number) {
122 CrossfadeSmoother.update(AbstractEngine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
123 }
124 }
125 }
126
127 void Voice::ProcessChannelPressureEvent(RTList<Event>::Iterator& itEvent) {
128 if (itEvent->Type == Event::type_channel_pressure) { // if (valid) MIDI channel pressure (aftertouch) event
129 if (pRegion->AttenuationController.type == ::gig::attenuation_ctrl_t::type_channelaftertouch) {
130 CrossfadeSmoother.update(AbstractEngine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.ChannelPressure.Value)]);
131 }
132 }
133 }
134
135 void Voice::ProcessPolyphonicKeyPressureEvent(RTList<Event>::Iterator& itEvent) {
136 // Not used so far
137 }
138
139 void Voice::ProcessCutoffEvent(RTList<Event>::Iterator& itEvent) {
140 int ccvalue = itEvent->Param.CC.Value;
141 if (VCFCutoffCtrl.value == ccvalue) return;
142 VCFCutoffCtrl.value = ccvalue;
143 if (pRegion->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
144 if (ccvalue < pRegion->VCFVelocityScale) ccvalue = pRegion->VCFVelocityScale;
145 float cutoff = CutoffBase * float(ccvalue);
146 if (cutoff > 127.0f) cutoff = 127.0f;
147
148 VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
149 fFinalCutoff = cutoff;
150 }
151
152 double Voice::CalculateCrossfadeVolume(uint8_t MIDIKeyVelocity) {
153 float crossfadeVolume;
154 switch (pRegion->AttenuationController.type) {
155 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
156 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(GetGigEngineChannel()->ControllerTable[128])];
157 break;
158 case ::gig::attenuation_ctrl_t::type_velocity:
159 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(MIDIKeyVelocity)];
160 break;
161 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
162 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(GetGigEngineChannel()->ControllerTable[pRegion->AttenuationController.controller_number])];
163 break;
164 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
165 default:
166 crossfadeVolume = 1.0f;
167 }
168
169 return crossfadeVolume;
170 }
171
172 double Voice::GetEG1ControllerValue(uint8_t MIDIKeyVelocity) {
173 double eg1controllervalue = 0;
174 switch (pRegion->EG1Controller.type) {
175 case ::gig::eg1_ctrl_t::type_none: // no controller defined
176 eg1controllervalue = 0;
177 break;
178 case ::gig::eg1_ctrl_t::type_channelaftertouch:
179 eg1controllervalue = GetGigEngineChannel()->ControllerTable[128];
180 break;
181 case ::gig::eg1_ctrl_t::type_velocity:
182 eg1controllervalue = MIDIKeyVelocity;
183 break;
184 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
185 eg1controllervalue = GetGigEngineChannel()->ControllerTable[pRegion->EG1Controller.controller_number];
186 break;
187 }
188 if (pRegion->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
189
190 return eg1controllervalue;
191 }
192
193 Voice::EGInfo Voice::CalculateEG1ControllerInfluence(double eg1ControllerValue) {
194 EGInfo eg;
195 // (eg1attack is different from the others)
196 if (pRegion->EG1Attack < 1e-8 && // attack in gig == 0
197 (pRegion->EG1ControllerAttackInfluence == 0 ||
198 eg1ControllerValue <= 10)) { // strange GSt special case
199 eg.Attack = 0; // this will force the attack to be 0 in the call to EG1.trigger
200 } else {
201 eg.Attack = (pRegion->EG1ControllerAttackInfluence) ?
202 1 + 0.031 * (double) (pRegion->EG1ControllerAttackInfluence == 1 ?
203 1 : 1 << pRegion->EG1ControllerAttackInfluence) * eg1ControllerValue : 1.0;
204 }
205 eg.Decay = (pRegion->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerDecayInfluence) * eg1ControllerValue : 1.0;
206 eg.Release = (pRegion->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerReleaseInfluence) * eg1ControllerValue : 1.0;
207
208 return eg;
209 }
210
211 double Voice::GetEG2ControllerValue(uint8_t MIDIKeyVelocity) {
212 double eg2controllervalue = 0;
213 switch (pRegion->EG2Controller.type) {
214 case ::gig::eg2_ctrl_t::type_none: // no controller defined
215 eg2controllervalue = 0;
216 break;
217 case ::gig::eg2_ctrl_t::type_channelaftertouch:
218 eg2controllervalue = GetGigEngineChannel()->ControllerTable[128];
219 break;
220 case ::gig::eg2_ctrl_t::type_velocity:
221 eg2controllervalue = MIDIKeyVelocity;
222 break;
223 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
224 eg2controllervalue = GetGigEngineChannel()->ControllerTable[pRegion->EG2Controller.controller_number];
225 break;
226 }
227 if (pRegion->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
228
229 return eg2controllervalue;
230 }
231
232 Voice::EGInfo Voice::CalculateEG2ControllerInfluence(double eg2ControllerValue) {
233 EGInfo eg;
234 eg.Attack = (pRegion->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerAttackInfluence) * eg2ControllerValue : 1.0;
235 eg.Decay = (pRegion->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerDecayInfluence) * eg2ControllerValue : 1.0;
236 eg.Release = (pRegion->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerReleaseInfluence) * eg2ControllerValue : 1.0;
237
238 return eg;
239 }
240
241 void Voice::InitLFO1() {
242 uint16_t lfo1_internal_depth;
243 switch (pRegion->LFO1Controller) {
244 case ::gig::lfo1_ctrl_internal:
245 lfo1_internal_depth = pRegion->LFO1InternalDepth;
246 pLFO1->ExtController = 0; // no external controller
247 bLFO1Enabled = (lfo1_internal_depth > 0);
248 break;
249 case ::gig::lfo1_ctrl_modwheel:
250 lfo1_internal_depth = 0;
251 pLFO1->ExtController = 1; // MIDI controller 1
252 bLFO1Enabled = (pRegion->LFO1ControlDepth > 0);
253 break;
254 case ::gig::lfo1_ctrl_breath:
255 lfo1_internal_depth = 0;
256 pLFO1->ExtController = 2; // MIDI controller 2
257 bLFO1Enabled = (pRegion->LFO1ControlDepth > 0);
258 break;
259 case ::gig::lfo1_ctrl_internal_modwheel:
260 lfo1_internal_depth = pRegion->LFO1InternalDepth;
261 pLFO1->ExtController = 1; // MIDI controller 1
262 bLFO1Enabled = (lfo1_internal_depth > 0 || pRegion->LFO1ControlDepth > 0);
263 break;
264 case ::gig::lfo1_ctrl_internal_breath:
265 lfo1_internal_depth = pRegion->LFO1InternalDepth;
266 pLFO1->ExtController = 2; // MIDI controller 2
267 bLFO1Enabled = (lfo1_internal_depth > 0 || pRegion->LFO1ControlDepth > 0);
268 break;
269 default:
270 lfo1_internal_depth = 0;
271 pLFO1->ExtController = 0; // no external controller
272 bLFO1Enabled = false;
273 }
274 if (bLFO1Enabled) {
275 pLFO1->trigger(pRegion->LFO1Frequency,
276 start_level_min,
277 lfo1_internal_depth,
278 pRegion->LFO1ControlDepth,
279 pRegion->LFO1FlipPhase,
280 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
281 pLFO1->update(pLFO1->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO1->ExtController] : 0);
282 }
283 }
284
285 void Voice::InitLFO2() {
286 uint16_t lfo2_internal_depth;
287 switch (pRegion->LFO2Controller) {
288 case ::gig::lfo2_ctrl_internal:
289 lfo2_internal_depth = pRegion->LFO2InternalDepth;
290 pLFO2->ExtController = 0; // no external controller
291 bLFO2Enabled = (lfo2_internal_depth > 0);
292 break;
293 case ::gig::lfo2_ctrl_modwheel:
294 lfo2_internal_depth = 0;
295 pLFO2->ExtController = 1; // MIDI controller 1
296 bLFO2Enabled = (pRegion->LFO2ControlDepth > 0);
297 break;
298 case ::gig::lfo2_ctrl_foot:
299 lfo2_internal_depth = 0;
300 pLFO2->ExtController = 4; // MIDI controller 4
301 bLFO2Enabled = (pRegion->LFO2ControlDepth > 0);
302 break;
303 case ::gig::lfo2_ctrl_internal_modwheel:
304 lfo2_internal_depth = pRegion->LFO2InternalDepth;
305 pLFO2->ExtController = 1; // MIDI controller 1
306 bLFO2Enabled = (lfo2_internal_depth > 0 || pRegion->LFO2ControlDepth > 0);
307 break;
308 case ::gig::lfo2_ctrl_internal_foot:
309 lfo2_internal_depth = pRegion->LFO2InternalDepth;
310 pLFO2->ExtController = 4; // MIDI controller 4
311 bLFO2Enabled = (lfo2_internal_depth > 0 || pRegion->LFO2ControlDepth > 0);
312 break;
313 default:
314 lfo2_internal_depth = 0;
315 pLFO2->ExtController = 0; // no external controller
316 bLFO2Enabled = false;
317 }
318 if (bLFO2Enabled) {
319 pLFO2->trigger(pRegion->LFO2Frequency,
320 start_level_max,
321 lfo2_internal_depth,
322 pRegion->LFO2ControlDepth,
323 pRegion->LFO2FlipPhase,
324 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
325 pLFO2->update(pLFO2->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO2->ExtController] : 0);
326 }
327 }
328
329 void Voice::InitLFO3() {
330 uint16_t lfo3_internal_depth;
331 switch (pRegion->LFO3Controller) {
332 case ::gig::lfo3_ctrl_internal:
333 lfo3_internal_depth = pRegion->LFO3InternalDepth;
334 pLFO3->ExtController = 0; // no external controller
335 bLFO3Enabled = (lfo3_internal_depth > 0);
336 break;
337 case ::gig::lfo3_ctrl_modwheel:
338 lfo3_internal_depth = 0;
339 pLFO3->ExtController = 1; // MIDI controller 1
340 bLFO3Enabled = (pRegion->LFO3ControlDepth > 0);
341 break;
342 case ::gig::lfo3_ctrl_aftertouch:
343 lfo3_internal_depth = 0;
344 pLFO3->ExtController = 128;
345 bLFO3Enabled = true;
346 break;
347 case ::gig::lfo3_ctrl_internal_modwheel:
348 lfo3_internal_depth = pRegion->LFO3InternalDepth;
349 pLFO3->ExtController = 1; // MIDI controller 1
350 bLFO3Enabled = (lfo3_internal_depth > 0 || pRegion->LFO3ControlDepth > 0);
351 break;
352 case ::gig::lfo3_ctrl_internal_aftertouch:
353 lfo3_internal_depth = pRegion->LFO3InternalDepth;
354 pLFO3->ExtController = 128;
355 bLFO3Enabled = (lfo3_internal_depth > 0 || pRegion->LFO3ControlDepth > 0);
356 break;
357 default:
358 lfo3_internal_depth = 0;
359 pLFO3->ExtController = 0; // no external controller
360 bLFO3Enabled = false;
361 }
362 if (bLFO3Enabled) {
363 pLFO3->trigger(pRegion->LFO3Frequency,
364 start_level_mid,
365 lfo3_internal_depth,
366 pRegion->LFO3ControlDepth,
367 false,
368 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
369 pLFO3->update(pLFO3->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO3->ExtController] : 0);
370 }
371 }
372
373 float Voice::CalculateCutoffBase(uint8_t MIDIKeyVelocity) {
374 float cutoff = pRegion->GetVelocityCutoff(MIDIKeyVelocity);
375 if (pRegion->VCFKeyboardTracking) {
376 cutoff *= RTMath::CentsToFreqRatioUnlimited((MIDIKey - pRegion->VCFKeyboardTrackingBreakpoint) * 100);
377 }
378 return cutoff;
379 }
380
381 float Voice::CalculateFinalCutoff(float cutoffBase) {
382 int cvalue;
383 if (VCFCutoffCtrl.controller) {
384 cvalue = GetGigEngineChannel()->ControllerTable[VCFCutoffCtrl.controller];
385 if (pRegion->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
386 // VCFVelocityScale in this case means Minimum cutoff
387 if (cvalue < pRegion->VCFVelocityScale) cvalue = pRegion->VCFVelocityScale;
388 }
389 else {
390 cvalue = pRegion->VCFCutoff;
391 }
392 float fco = cutoffBase * float(cvalue);
393 if (fco > 127.0f) fco = 127.0f;
394
395 return fco;
396 }
397
398 uint8_t Voice::GetVCFCutoffCtrl() {
399 uint8_t ctrl;
400 switch (pRegion->VCFCutoffController) {
401 case ::gig::vcf_cutoff_ctrl_modwheel:
402 ctrl = 1;
403 break;
404 case ::gig::vcf_cutoff_ctrl_effect1:
405 ctrl = 12;
406 break;
407 case ::gig::vcf_cutoff_ctrl_effect2:
408 ctrl = 13;
409 break;
410 case ::gig::vcf_cutoff_ctrl_breath:
411 ctrl = 2;
412 break;
413 case ::gig::vcf_cutoff_ctrl_foot:
414 ctrl = 4;
415 break;
416 case ::gig::vcf_cutoff_ctrl_sustainpedal:
417 ctrl = 64;
418 break;
419 case ::gig::vcf_cutoff_ctrl_softpedal:
420 ctrl = 67;
421 break;
422 case ::gig::vcf_cutoff_ctrl_genpurpose7:
423 ctrl = 82;
424 break;
425 case ::gig::vcf_cutoff_ctrl_genpurpose8:
426 ctrl = 83;
427 break;
428 case ::gig::vcf_cutoff_ctrl_aftertouch:
429 ctrl = 128;
430 break;
431 case ::gig::vcf_cutoff_ctrl_none:
432 default:
433 ctrl = 0;
434 break;
435 }
436
437 return ctrl;
438 }
439
440 uint8_t Voice::GetVCFResonanceCtrl() {
441 uint8_t ctrl;
442 switch (pRegion->VCFResonanceController) {
443 case ::gig::vcf_res_ctrl_genpurpose3:
444 ctrl = 18;
445 break;
446 case ::gig::vcf_res_ctrl_genpurpose4:
447 ctrl = 19;
448 break;
449 case ::gig::vcf_res_ctrl_genpurpose5:
450 ctrl = 80;
451 break;
452 case ::gig::vcf_res_ctrl_genpurpose6:
453 ctrl = 81;
454 break;
455 case ::gig::vcf_res_ctrl_none:
456 default:
457 ctrl = 0;
458 }
459
460 return ctrl;
461 }
462
463 void Voice::TriggerEG1(const EGInfo& egInfo, double velrelease, double velocityAttenuation, uint sampleRate, uint8_t velocity) {
464 EG1.trigger(pRegion->EG1PreAttack,
465 RTMath::Max(pRegion->EG1Attack, 0.0316) * egInfo.Attack,
466 pRegion->EG1Hold,
467 pRegion->EG1Decay1 * egInfo.Decay * velrelease,
468 pRegion->EG1Decay2 * egInfo.Decay * velrelease,
469 pRegion->EG1InfiniteSustain,
470 pRegion->EG1Sustain,
471 RTMath::Max(pRegion->EG1Release * velrelease, 0.014) * egInfo.Release,
472 velocityAttenuation,
473 sampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
474 }
475
476 void Voice::TriggerEG2(const EGInfo& egInfo, double velrelease, double velocityAttenuation, uint sampleRate, uint8_t velocity) {
477 EG2.trigger(uint(RgnInfo.EG2PreAttack),
478 RgnInfo.EG2Attack * egInfo.Attack,
479 false,
480 RgnInfo.EG2Decay1 * egInfo.Decay * velrelease,
481 RgnInfo.EG2Decay2 * egInfo.Decay * velrelease,
482 RgnInfo.EG2InfiniteSustain,
483 uint(RgnInfo.EG2Sustain),
484 RgnInfo.EG2Release * egInfo.Release * velrelease,
485 velocityAttenuation,
486 sampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
487 }
488
489 void Voice::ProcessGroupEvent(RTList<Event>::Iterator& itEvent) {
490 dmsg(4,("Voice %x processGroupEvents event type=%d", this, itEvent->Type));
491
492 // TODO: The SustainPedal condition could be wrong, maybe the
493 // check should be if this Voice is in release stage or is a
494 // release sample instead. Need to test this in GSt.
495 // -- Andreas
496 //
497 // Commented sustain pedal check out. I don't think voices of the same
498 // note should be stopped at all, because it doesn't sound naturally
499 // with a drumkit.
500 // -- Christian, 2013-01-08
501 if (itEvent->Param.Note.Key != MIDIKey /*||
502 !GetGigEngineChannel()->SustainPedal*/) {
503 dmsg(4,("Voice %x - kill", this));
504
505 // kill the voice fast
506 pEG1->enterFadeOutStage();
507 }
508 }
509
510 void Voice::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
511 EG1.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
512 }
513
514 int Voice::CalculatePan(uint8_t pan) {
515 int p;
516 // Gst behaviour: -64 and 63 are special cases
517 if (RgnInfo.Pan == -64) p = pan * 2 - 127;
518 else if (RgnInfo.Pan == 63) p = pan * 2;
519 else p = pan + RgnInfo.Pan;
520
521 if (p < 0) return 0;
522 if (p > 127) return 127;
523 return p;
524 }
525
526 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC