/[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 3561 - (show annotations) (download)
Fri Aug 23 11:44:00 2019 UTC (4 years, 7 months ago) by schoenebeck
File size: 26585 byte(s)
NKSP: Added standard units support for numbers and final "!" operator:

* NKSP strictness: Variable names, function names and preprocessor condition
  names must start with a regular character (a-z or A-Z); starting them with
  a digit or underscore is no longer allowed.

* NKSP parser fix: equal comparison operator "=" and not equal comparison
  operator "#" must only accept integer operands.

* NKSP language: Implemented support for standard units like Hertz, seconds,
  Bel including support for metric unit prefixes; so one can now e.g.
  conveniently use numbers in scripts like "5us" meaning "5 microseconds",
  or e.g. "12kHz" meaning "12 kilo Hertz", or e.g. "-14mdB" meaning
  "minus 14 Millidecibel", or e.g. "28c" meaning "28 cents" (for tuning).

* NKSP language: Introduced "final" operator "!" which is specifically
  intended for synthesis parameter values to denote that the synthesis
  parameter value is intended to be the "final" value for that synthesis
  parameter that should explicitly be used by the engine and thus causing
  the sampler engine to ignore all other modulation sources for the same
  synthesis parameter (like e.g. LFO, EG); by simply prefixing a value,
  variable or formula with this new "!" operator the expression is marked as
  being "final".

* Bumped version (2.1.1.svn4).

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

  ViewVC Help
Powered by ViewVC