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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3316 - (show annotations) (download)
Thu Jul 20 12:05:53 2017 UTC (6 years, 9 months ago) by schoenebeck
File size: 57129 byte(s)
* NKSP: Implemented built-in script function "change_sustain()".
* Bumped version (2.0.0.svn72).

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2011 - 2012 Grigor Iliev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "SfzSignalUnitRack.h"
24 #include "Engine.h"
25
26 #define _200TH_ROOT_OF_10 1.011579454259899
27
28 namespace LinuxSampler { namespace sfz {
29
30 double ToRatio(int Centibels) {
31 if (Centibels == 0) return 1.0;
32 return pow(_200TH_ROOT_OF_10, Centibels);
33 }
34
35 SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36
37 }
38
39 double SfzSignalUnit::GetSampleRate() {
40 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41 }
42
43 float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44 float f = 0;
45 for (int i = 0; i < cc.size(); i++) {
46 int val = pVoice->GetControllerValue(cc[i].Controller);
47 f += (val / 127.0f) * cc[i].Influence;
48 }
49 return f;
50 }
51
52 void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53 RemoveAllCCs();
54
55 for (int cc = 0; cc < 128; cc++) {
56 if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57 int i = loCCs[cc];
58 int j = hiCCs[cc];
59 if (j == 0) j = 127;
60 i += j << 8; // workaround to keep both values in the Influence parameter
61 AddCC(cc, i);
62 }
63 }
64
65 void XFInCCUnit::Calculate() {
66 float l = 1;
67
68 RTList<CC>::Iterator ctrl = pCtrls->first();
69 RTList<CC>::Iterator end = pCtrls->end();
70 for(; ctrl != end; ++ctrl) {
71 float c = 1;
72 int influence = (*ctrl).Influence;
73 int lo = influence & 0xff;
74 int hi = influence >> 8;
75 if ((*ctrl).Value <= lo) {
76 c = 0;
77 } else if ((*ctrl).Value >= hi) {
78 c = 1;
79 } else {
80 float xfVelSize = hi - lo;
81 float velPos = (*ctrl).Value - lo;
82 c = velPos / xfVelSize;
83 if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84 c = sin(c * M_PI / 2.0);
85 }
86 }
87
88 l *= c;
89 }
90
91 if (Level != l) {
92 Level = l;
93 if (pListener != NULL) pListener->ValueChanged(this);
94 }
95 }
96
97
98 void XFOutCCUnit::Calculate() {
99 float l = 1;
100
101 RTList<CC>::Iterator ctrl = pCtrls->first();
102 RTList<CC>::Iterator end = pCtrls->end();
103 for(; ctrl != end; ++ctrl) {
104 float c = 1;
105 int influence = (*ctrl).Influence;
106 int lo = influence & 0xff;
107 int hi = influence >> 8;
108 if ((*ctrl).Value >= hi) {
109 c = 0;
110 } else if ((*ctrl).Value <= lo) {
111 c = 1;
112 } else {
113 float xfVelSize = hi - lo;
114 float velPos = (*ctrl).Value - lo;
115 c = 1.0f - velPos / xfVelSize;
116 if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117 c = sin(c * M_PI / 2.0);
118 }
119 }
120
121 l *= c;
122 }
123
124 if (Level != l) {
125 Level = l;
126 if (pListener != NULL) pListener->ValueChanged(this);
127 }
128 }
129
130
131 EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132 : EGUnit< ::LinuxSampler::sfz::EG>(rack), EqUnitSupport(rack), suAmpOnCC(rack), suVolOnCC(rack),
133 suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134 { }
135
136 void EGv2Unit::Trigger() {
137 egInfo = *pEGInfo;
138 for (int i = 0; i < egInfo.node.size(); i++) {
139 float f = GetInfluence(egInfo.node[i].level_oncc);
140 egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
141
142 f = GetInfluence(egInfo.node[i].time_oncc);
143 egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144 }
145 EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity());
146 }
147
148
149 void PitchEGUnit::Trigger() {
150 ::sfz::Region* const pRegion = pVoice->pRegion;
151 depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152
153 // the length of the decay and release curves are dependent on the velocity
154 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
155
156 // set the delay trigger
157 float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158 delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159 uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160
161 float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162
163 float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164 attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165
166 float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167 hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168
169 float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170 decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171
172 float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173 sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174
175 float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176 release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177
178 EG.trigger (
179 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
181 );
182 }
183
184
185 void FilEGUnit::Trigger() {
186 ::sfz::Region* const pRegion = pVoice->pRegion;
187 depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188
189 // the length of the decay and release curves are dependent on the velocity
190 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
191
192 // set the delay trigger
193 float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194 delay += GetInfluence(pRegion->fileg_delay_oncc);
195 uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196
197 float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198
199 float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200 attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201
202 float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203 hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204
205 float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206 decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207
208 float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209 sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210
211 float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212 release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213
214 EG.trigger (
215 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
217 );
218 }
219
220
221 void AmpEGUnit::Trigger() {
222 ::sfz::Region* const pRegion = pVoice->pRegion;
223
224 // the length of the decay and release curves are dependent on the velocity
225 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
226
227 // set the delay trigger
228 float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229 delay += GetInfluence(pRegion->ampeg_delaycc);
230 uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231
232 float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233
234 float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235 attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236
237 float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238 hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239
240 float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241 decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242
243 float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244 sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245 if (pVoice->pNote)
246 sustain *= pVoice->pNote->Override.Sustain;
247
248 float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
249 release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
250
251 EG.trigger (
252 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
253 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
254 );
255 }
256
257
258 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
259 : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
260 suFadeEG(rack), suDepthOnCC(rack), suFreqOnCC(rack, this)
261 { }
262
263 LFOUnit::LFOUnit(const LFOUnit& Unit)
264 : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
265 suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
266 suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
267 {
268 Copy(Unit);
269 }
270
271 void LFOUnit::Increment() {
272 if (DelayStage()) return;
273
274 SignalUnit::Increment();
275
276 Level = pLFO->Render();
277 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
278 }
279
280 void LFOUnit::Trigger() {
281 //reset
282 Level = 0;
283
284 // set the delay trigger
285 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
286 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
287 float f = pLfoInfo->fade;
288 f += GetInfluence(pLfoInfo->fade_oncc);
289
290 if (f != 0) {
291 suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
292 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
293 }
294 }
295 }
296
297 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
298 if (pLFO == NULL) return;
299 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
300 }
301
302
303 void LFOv1Unit::Trigger() {
304 LFOUnit::Trigger();
305
306 lfo.trigger (
307 pLfoInfo->freq + suFreqOnCC.GetLevel(),
308 start_level_mid,
309 1, 0, false, GetSampleRate()
310 );
311 lfo.updateByMIDICtrlValue(0);
312 }
313
314
315 LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
316 : LFOUnit(rack), EqUnitSupport(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
317 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
318 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
319 {
320 lfos.add(&lfo0);
321 lfos.add(&lfo1);
322 lfos.add(&lfo2);
323 lfos.add(&lfo3);
324 lfos.add(&lfo4);
325 lfos.add(&lfo5);
326 lfos.add(&lfo6);
327 lfos.add(&lfo7);
328 }
329
330 void LFOv2Unit::Trigger() {
331 LFOUnit::Trigger();
332
333 if (/*pLfoInfo->wave < 0 ||*/ pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
334 else pLFO = lfos[pLfoInfo->wave];
335
336 pLFO->Trigger (
337 pLfoInfo->freq + suFreqOnCC.GetLevel(),
338 start_level_mid,
339 1, 0, false, GetSampleRate()
340 );
341 pLFO->Update(0);
342
343 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
344 if (phase != 0) pLFO->SetPhase(phase);
345 }
346
347 void AmpLFOUnit::Trigger() {
348 bActive = true;
349 ::sfz::Region* const pRegion = pVoice->pRegion;
350 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
351 pLfoInfo->freq = pRegion->amplfo_freq;
352 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
353 pLfoInfo->volume = pRegion->amplfo_depth;
354
355 if (pLfoInfo->freq <= 0) {
356 if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
357 else bActive = false;
358 }
359
360 LFOv1Unit::Trigger();
361 }
362
363 void PitchLFOUnit::Trigger() {
364 bActive = true;
365 ::sfz::Region* const pRegion = pVoice->pRegion;
366 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
367 pLfoInfo->freq = pRegion->pitchlfo_freq;
368 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
369 pLfoInfo->pitch = pRegion->pitchlfo_depth;
370
371 if (pLfoInfo->freq <= 0) {
372 if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
373 else bActive = false;
374 }
375
376 LFOv1Unit::Trigger();
377 }
378
379 void FilLFOUnit::Trigger() {
380 bActive = true;
381 ::sfz::Region* const pRegion = pVoice->pRegion;
382 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
383 pLfoInfo->freq = pRegion->fillfo_freq;
384 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
385 pLfoInfo->cutoff = pRegion->fillfo_depth;
386
387 if (pLfoInfo->freq <= 0) {
388 if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
389 else bActive = false;
390 }
391
392 LFOv1Unit::Trigger();
393 }
394
395 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
396 pVoice = NULL;
397 }
398
399 void CCUnit::Trigger() {
400 RTList<CC>::Iterator ctrl = pCtrls->first();
401 RTList<CC>::Iterator end = pCtrls->end();
402 for(; ctrl != end; ++ctrl) {
403 (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
404 if ((*ctrl).pSmoother != NULL) {
405 if ((*ctrl).Step > 0) {
406 float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
407 (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
408 } else {
409 (*ctrl).pSmoother->setValue((*ctrl).Value);
410 }
411 }
412 }
413 CCSignalUnit::Trigger();
414 }
415
416 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
417 RemoveAllCCs();
418 for (int i = 0; i < 128; i++) {
419 if (cc[i] != 0) AddCC(i, cc[i]);
420 }
421 }
422
423 void CCUnit::SetCCs(::sfz::Array<float>& cc) {
424 RemoveAllCCs();
425 for (int i = 0; i < 128; i++) {
426 if (cc[i] != 0) AddCC(i, cc[i]);
427 }
428 }
429
430 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
431 RemoveAllCCs();
432 for (int i = 0; i < cc.size(); i++) {
433 if (cc[i].Influence != 0) {
434 short int curve = cc[i].Curve;
435 if (curve >= GetCurveCount()) curve = -1;
436 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
437 }
438 }
439 }
440
441 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
442 AddCC(Controller, Influence, Curve, NULL, Step);
443 }
444
445 int CCUnit::GetCurveCount() {
446 return pVoice->pRegion->GetInstrument()->curves.size();
447 }
448
449 ::sfz::Curve* CCUnit::GetCurve(int idx) {
450 return &pVoice->pRegion->GetInstrument()->curves[idx];
451 }
452
453 double CCUnit::GetSampleRate() {
454 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
455 }
456
457
458 SmoothCCUnit::~SmoothCCUnit() {
459 if (pSmoothers != NULL) delete pSmoothers;
460 }
461
462 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
463 if (Smooth > 0) {
464 if (pSmoothers->poolIsEmpty()) {
465 std::cerr << "Maximum number of smoothers reached" << std::endl;
466 return;
467 }
468 Smoother* smoother = &(*(pSmoothers->allocAppend()));
469 smoother->trigger(Smooth / 1000.0f, GetSampleRate());
470 AddCC(Controller, Influence, Curve, smoother, Step);
471 } else {
472 AddCC(Controller, Influence, Curve, NULL, Step);
473 }
474 }
475
476 void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
477 if (pSmoothers != NULL) delete pSmoothers;
478 pSmoothers = new RTList<Smoother>(pSmootherPool);
479 }
480
481 void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
482 CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
483 InitSmoothers(pSmootherPool);
484 }
485
486
487 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
488 : EndpointSignalUnit(rack), pitchVeltrackRatio(0), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack)
489 {
490
491 }
492
493 float EndpointUnit::GetInfluence(::sfz::Array< optional<float> >& cc) {
494 float f = 0;
495 for (int i = 0; i < 128; i++) {
496 if (cc[i]) {
497 f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
498 }
499 }
500 return f;
501 }
502
503 float EndpointUnit::GetInfluence(::sfz::Array< optional<int> >& cc) {
504 float f = 0;
505 for (int i = 0; i < 128; i++) {
506 if (cc[i]) {
507 f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
508 }
509 }
510 return f;
511 }
512
513 SfzSignalUnitRack* const EndpointUnit::GetRack() {
514 return static_cast<SfzSignalUnitRack* const>(pRack);
515 }
516
517 void EndpointUnit::Trigger() {
518 uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
519 if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
520
521 if (pVoice->pRegion->delay) {
522 /* here we use the device sample rate */
523 uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
524 }
525
526 if (pVoice->pRegion->delay_random) {
527 float r = pVoice->GetEngine()->Random();
528 uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
529 }
530
531 uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
532
533 float xfInVelCoeff = 1;
534
535 if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
536 xfInVelCoeff = 0;
537 } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
538 xfInVelCoeff = 1;
539 } else {
540 float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
541 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
542 xfInVelCoeff = velPos / xfVelSize;
543 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
544 xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
545 }
546 }
547
548 float xfOutVelCoeff = 1;
549
550 if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
551 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
552 } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
553 xfOutVelCoeff = 1;
554 } else {
555 float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
556 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
557 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
558 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
559 xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
560 }
561 }
562
563 float xfInKeyCoeff = 1;
564
565 if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
566 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
567 } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
568 xfInKeyCoeff = 1;
569 } else {
570 float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
571 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
572 xfInKeyCoeff = keyPos / xfKeySize;
573 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
574 xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
575 }
576 }
577
578 float xfOutKeyCoeff = 1;
579
580 if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
581 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
582 } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
583 xfOutKeyCoeff = 1;
584 } else {
585 float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
586 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
587 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
588 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
589 xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
590 }
591 }
592
593 xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
594
595 suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
596 suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
597
598 suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
599
600 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
601 }
602
603 bool EndpointUnit::Active() {
604 if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
605 return false; // The key was released before the delay end, so the voice won't play at all.
606 }
607
608 if (GetRack()->suVolEG.Active()) return true;
609
610 bool b = false;
611 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
612 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
613 }
614
615 return b;
616 }
617
618 float EndpointUnit::GetVolume() {
619 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
620
621 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
622 EGv2Unit* eg = GetRack()->volEGs[i];
623 if (!eg->Active()) continue;
624
625 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
626 if (dB < -144) dB = eg->pEGInfo->volume;
627 else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
628
629 float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
630 amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
631
632 if (dB >= -144) {
633 if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
634 amp *= ToRatio(dB * 10.0);
635 }
636
637 vol += amp * eg->GetLevel();
638 }
639
640 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
641 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
642 float f = u2->Active() ? u2->GetLevel() : 0;
643 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
644
645 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
646
647 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
648 LFOv2Unit* lfo = GetRack()->volLFOs[i];
649 if (!lfo->Active()) continue;
650
651 float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
652 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
653 }
654
655 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
656 if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
657 return vol * xfCoeff;
658 }
659
660 float EndpointUnit::GetFilterCutoff() {
661 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
662
663 FilLFOUnit* u = &(GetRack()->suFilLFO);
664 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
665 float f = u1->Active() ? u1->GetLevel() : 0;
666 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
667
668 FilEGUnit* u2 = &(GetRack()->suFilEG);
669 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
670
671 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
672 EGv2Unit* eg = GetRack()->filEGs[i];
673 if (!eg->Active()) continue;
674
675 float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
676 f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
677 val *= RTMath::CentsToFreqRatioUnlimited(f);
678 }
679
680 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
681 LFOv2Unit* lfo = GetRack()->filLFOs[i];
682 if (!lfo->Active()) continue;
683
684 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
685 f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
686 val *= RTMath::CentsToFreqRatioUnlimited(f);
687 }
688
689 return val;
690 }
691
692 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
693 cutoff *= GetFilterCutoff();
694 float maxCutoff = 0.49 * pVoice->GetSampleRate();
695 return cutoff > maxCutoff ? maxCutoff : cutoff;
696 }
697
698 float EndpointUnit::GetPitch() {
699 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
700
701 EGv1Unit* u = &(GetRack()->suPitchEG);
702 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
703
704 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
705 EGv2Unit* eg = GetRack()->pitchEGs[i];
706 if (!eg->Active()) continue;
707
708 float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
709 p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
710 }
711
712 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
713 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
714 float f = u3->Active() ? u3->GetLevel() : 0;
715 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
716
717 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
718 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
719 if (!lfo->Active()) continue;
720
721 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
722 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
723 }
724
725 return p * pitchVeltrackRatio;
726 }
727
728 float EndpointUnit::GetResonance() {
729 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
730
731 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
732 EGv2Unit* eg = GetRack()->resEGs[i];
733 if (!eg->Active()) continue;
734
735 float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
736 val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
737 }
738
739 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
740 LFOv2Unit* lfo = GetRack()->resLFOs[i];
741 if (!lfo->Active()) continue;
742
743 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
744 val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
745 }
746
747 return val;
748 }
749
750 float EndpointUnit::GetPan() {
751 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
752
753 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
754 EGv2Unit* eg = GetRack()->panEGs[i];
755 if (!eg->Active()) continue;
756
757 float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
758
759 if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
760 uint8_t val = eg->GetLevel() * 127;
761 if (val > 127) val = 127;
762 pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
763 } else {
764 pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
765 }
766 }
767
768 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
769 LFOv2Unit* lfo = GetRack()->panLFOs[i];
770 if (!lfo->Active()) continue;
771
772 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
773 pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
774 }
775
776 return pan;
777 }
778
779
780 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
781 : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice),
782 suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
783 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
784 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
785 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
786 resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
787 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
788 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount),
789 pVoice(voice)
790 {
791 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
792 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
793 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
794
795 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
796 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
797 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
798 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
799
800 for (int i = 0; i < EGs.capacity(); i++) {
801 EGs[i] = new EGv2Unit(this);
802 EGs[i]->pVoice = voice;
803 EGs[i]->suAmpOnCC.pVoice = voice;
804 EGs[i]->suVolOnCC.pVoice = voice;
805 EGs[i]->suPitchOnCC.pVoice = voice;
806 EGs[i]->suCutoffOnCC.pVoice = voice;
807 EGs[i]->suResOnCC.pVoice = voice;
808 EGs[i]->suPanOnCC.pVoice = voice;
809 EGs[i]->SetVoice(voice); // class EqUnitSupport
810 }
811
812 for (int i = 0; i < LFOs.capacity(); i++) {
813 LFOs[i] = new LFOv2Unit(this);
814 LFOs[i]->pVoice = voice;
815 LFOs[i]->suDepthOnCC.pVoice = voice;
816 LFOs[i]->suFreqOnCC.pVoice = voice;
817 LFOs[i]->suFadeEG.pVoice = voice;
818 LFOs[i]->suVolOnCC.pVoice = voice;
819 LFOs[i]->suPitchOnCC.pVoice = voice;
820 LFOs[i]->suFreqOnCC.pVoice = voice;
821 LFOs[i]->suPanOnCC.pVoice = voice;
822 LFOs[i]->suCutoffOnCC.pVoice = voice;
823 LFOs[i]->suResOnCC.pVoice = voice;
824 LFOs[i]->SetVoice(voice); // class EqUnitSupport
825 }
826 }
827
828 SfzSignalUnitRack::~SfzSignalUnitRack() {
829 for (int i = 0; i < EGs.capacity(); i++) {
830 delete EGs[i]; EGs[i] = NULL;
831 }
832
833 for (int i = 0; i < LFOs.capacity(); i++) {
834 delete LFOs[i]; LFOs[i] = NULL;
835 }
836 }
837
838 void SfzSignalUnitRack::InitRTLists() {
839 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
840 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
841
842 EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
843
844 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
845 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
846 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847 suResOnCC.InitCCList(pCCPool, pSmootherPool);
848 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
849 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
850 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
851 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
852 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
853 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
854 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
855 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
856 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
857
858 for (int i = 0; i < EGs.capacity(); i++) {
859 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
860 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
861 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
862 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
863 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
864 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
865 EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
866 }
867
868 for (int i = 0; i < LFOs.capacity(); i++) {
869 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
870 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
871 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
874 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
875 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
876 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
877 LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
878 }
879 }
880
881 void SfzSignalUnitRack::Trigger() {
882 EGs.clear();
883 volEGs.clear();
884 pitchEGs.clear();
885 filEGs.clear();
886 resEGs.clear();
887 panEGs.clear();
888 eqEGs.clear();
889
890 LFOs.clear();
891 volLFOs.clear();
892 pitchLFOs.clear();
893 filLFOs.clear();
894 resLFOs.clear();
895 panLFOs.clear();
896 eqLFOs.clear();
897
898 ::sfz::Region* const pRegion = pVoice->pRegion;
899
900 suVolOnCC.SetCCs(pRegion->volume_oncc);
901 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
902 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
903 suResOnCC.SetCCs(pRegion->resonance_oncc);
904
905 for (int i = 0; i < pRegion->eg.size(); i++) {
906 if (pRegion->eg[i].node.size() == 0) continue;
907
908 if(EGs.size() < EGs.capacity()) {
909 EGv2Unit eg(this);
910 eg.pEGInfo = &(pRegion->eg[i]);
911 EGs.increment()->Copy(eg);
912 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
913 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
914 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
915 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
916 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
917 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
918 if (pVoice->bEqSupport) {
919 EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
920 EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
921 EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
922 EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
923 EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
924 EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
925 EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
926 EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
927 EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
928 }
929 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
930
931 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
932 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
933 ) {
934 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
935 else std::cerr << "Maximum number of EGs reached!" << std::endl;
936 }
937
938 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
939 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
940 else std::cerr << "Maximum number of EGs reached!" << std::endl;
941 }
942
943 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
944 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
945 else std::cerr << "Maximum number of EGs reached!" << std::endl;
946 }
947
948 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
949 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
950 else std::cerr << "Maximum number of EGs reached!" << std::endl;
951 }
952
953 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
954 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
955 else std::cerr << "Maximum number of EGs reached!" << std::endl;
956 }
957
958 if (pRegion->eg[i].HasEq()) {
959 if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
960 else std::cerr << "Maximum number of EGs reached!" << std::endl;
961 }
962 }
963
964 if (pRegion->ampeg_sustain == -1) {
965 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
966 else pRegion->ampeg_sustain = 100;
967 }
968
969 // LFO
970 for (int i = 0; i < pRegion->lfos.size(); i++) {
971 if (pRegion->lfos[i].freq <= 0) {
972 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
973 else pRegion->lfos[i].freq = 0;
974 }
975
976 if(LFOs.size() < LFOs.capacity()) {
977 LFOv2Unit lfo(this);
978 lfo.pLfoInfo = &(pRegion->lfos[i]);
979 LFOs.increment()->Copy(lfo);
980 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
981 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
982 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
983 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
984 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
985 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
986 if (pVoice->bEqSupport) {
987 LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
988 LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
989 LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
990 LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
991 LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
992 LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
993 LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
994 LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
995 LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
996 }
997 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
998
999 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
1000 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
1001 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1002 }
1003
1004 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1005 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1006 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1007 }
1008
1009 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1010 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1011 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1012 }
1013
1014 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1015 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1016 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1017 }
1018
1019 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1020 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1021 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1022 }
1023
1024 if (pRegion->lfos[i].HasEq()) {
1025 if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1026 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1027 }
1028 }
1029
1030 if (!pVoice->bEqSupport) {
1031 bHasEq = false;
1032 } else {
1033 suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1034 suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1035 suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1036 suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1037 suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1038 suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1039 suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1040 suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1041 suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1042
1043 bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1044 pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1045 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1046 eqEGs.size() > 0 || eqLFOs.size() > 0;
1047 }
1048
1049 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1050 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1051
1052 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1053 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1054
1055 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1056 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1057
1058 Units.clear();
1059
1060 EqUnitSupport::ImportUnits(this);
1061
1062 Units.add(&suVolOnCC);
1063 Units.add(&suPitchOnCC);
1064 Units.add(&suCutoffOnCC);
1065 Units.add(&suResOnCC);
1066
1067 Units.add(&suVolEG);
1068 Units.add(&suFilEG);
1069 Units.add(&suPitchEG);
1070
1071 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1072 Units.add(&suPitchLFO);
1073 Units.add(&suPitchLFO.suDepthOnCC);
1074 Units.add(&suPitchLFO.suFadeEG);
1075
1076 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1077 Units.add(&suAmpLFO.suDepthOnCC);
1078 Units.add(&suAmpLFO);
1079 Units.add(&suAmpLFO.suFadeEG);
1080
1081 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1082 Units.add(&suFilLFO.suDepthOnCC);
1083 Units.add(&suFilLFO);
1084 Units.add(&suFilLFO.suFadeEG);
1085
1086 for (int i = 0; i < EGs.size(); i++) {
1087 Units.add(EGs[i]);
1088 Units.add(&(EGs[i]->suAmpOnCC));
1089 Units.add(&(EGs[i]->suVolOnCC));
1090 Units.add(&(EGs[i]->suPitchOnCC));
1091 Units.add(&(EGs[i]->suCutoffOnCC));
1092 Units.add(&(EGs[i]->suResOnCC));
1093 Units.add(&(EGs[i]->suPanOnCC));
1094 EGs[i]->ImportUnits(this); // class EqUnitSupport
1095 }
1096
1097 for (int i = 0; i < LFOs.size(); i++) {
1098 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1099 Units.add(LFOs[i]);
1100 Units.add(&(LFOs[i]->suFadeEG));
1101 Units.add(&(LFOs[i]->suVolOnCC));
1102 Units.add(&(LFOs[i]->suPitchOnCC));
1103 Units.add(&(LFOs[i]->suPanOnCC));
1104 Units.add(&(LFOs[i]->suCutoffOnCC));
1105 Units.add(&(LFOs[i]->suResOnCC));
1106 LFOs[i]->ImportUnits(this); // class EqUnitSupport
1107 }
1108
1109 Units.add(&suEndpoint);
1110 Units.add(&suEndpoint.suXFInCC);
1111 Units.add(&suEndpoint.suXFOutCC);
1112 Units.add(&suEndpoint.suPanOnCC);
1113
1114 SignalUnitRack::Trigger();
1115 }
1116
1117 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1118 return &suEndpoint;
1119 }
1120
1121 void SfzSignalUnitRack::EnterFadeOutStage() {
1122 suVolEG.EG.enterFadeOutStage();
1123
1124 for (int i = 0; i < volEGs.size(); i++) {
1125 volEGs[i]->EG.enterFadeOutStage();
1126 }
1127 }
1128
1129 void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1130 suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1131 for (int i = 0; i < volEGs.size(); i++) {
1132 volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1133 }
1134 }
1135
1136 void SfzSignalUnitRack::Reset() {
1137 EqUnitSupport::ResetUnits();
1138
1139 suVolOnCC.RemoveAllCCs();
1140 suPitchOnCC.RemoveAllCCs();
1141 suCutoffOnCC.RemoveAllCCs();
1142 suResOnCC.RemoveAllCCs();
1143 suEndpoint.suXFInCC.RemoveAllCCs();
1144 suEndpoint.suXFOutCC.RemoveAllCCs();
1145 suEndpoint.suPanOnCC.RemoveAllCCs();
1146 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1147 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1148 suFilLFO.suDepthOnCC.RemoveAllCCs();
1149 suFilLFO.suFreqOnCC.RemoveAllCCs();
1150 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1151 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1152
1153 for (int i = 0; i < EGs.capacity(); i++) {
1154 EGs[i]->suAmpOnCC.RemoveAllCCs();
1155 EGs[i]->suVolOnCC.RemoveAllCCs();
1156 EGs[i]->suPitchOnCC.RemoveAllCCs();
1157 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1158 EGs[i]->suResOnCC.RemoveAllCCs();
1159 EGs[i]->suPanOnCC.RemoveAllCCs();
1160 EGs[i]->ResetUnits(); // class EqUnitSupport
1161 }
1162
1163 for (int i = 0; i < LFOs.capacity(); i++) {
1164 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1165 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1166 LFOs[i]->suVolOnCC.RemoveAllCCs();
1167 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1168 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1169 LFOs[i]->suPanOnCC.RemoveAllCCs();
1170 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1171 LFOs[i]->suResOnCC.RemoveAllCCs();
1172 LFOs[i]->ResetUnits(); // class EqUnitSupport
1173 }
1174 }
1175
1176 void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1177 suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1178 for (int i = 0; i < EGs.capacity(); i++) {
1179 EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1180 }
1181 }
1182
1183 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1184 if (!pEqSupport->HasSupport()) return;
1185 if (pEqSupport->GetBandCount() < 3) {
1186 std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1187 return;
1188 }
1189
1190 ::sfz::Region* const pRegion = pVoice->pRegion;
1191
1192 float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1193 float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1194 float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1195
1196 float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1197 float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1198 float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1199
1200 float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1201 float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1202 float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1203
1204 const float vel = pVoice->MIDIVelocity() / 127.0f;
1205
1206 dB1 += pRegion->eq1_vel2gain * vel;
1207 dB2 += pRegion->eq2_vel2gain * vel;
1208 dB3 += pRegion->eq3_vel2gain * vel;
1209
1210 freq1 += pRegion->eq1_vel2freq * vel;
1211 freq2 += pRegion->eq2_vel2freq * vel;
1212 freq3 += pRegion->eq3_vel2freq * vel;
1213
1214 for (int i = 0; i < eqEGs.size(); i++) {
1215 EGv2Unit* eg = eqEGs[i];
1216 if (!eg->Active()) continue;
1217
1218 float l = eg->GetLevel();
1219 dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1220 dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1221 dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1222
1223 freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1224 freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1225 freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1226
1227 bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1228 bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1229 bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1230 }
1231
1232 for (int i = 0; i < eqLFOs.size(); i++) {
1233 LFOv2Unit* lfo = eqLFOs[i];
1234 if (!lfo->Active()) continue;
1235
1236 float l = lfo->GetLevel();
1237 dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1238 dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1239 dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1240
1241 freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1242 freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1243 freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1244
1245 bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1246 bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1247 bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1248 }
1249
1250 pEqSupport->SetGain(0, dB1);
1251 pEqSupport->SetGain(1, dB2);
1252 pEqSupport->SetGain(2, dB3);
1253
1254 pEqSupport->SetFreq(0, freq1);
1255 pEqSupport->SetFreq(1, freq2);
1256 pEqSupport->SetFreq(2, freq3);
1257
1258 pEqSupport->SetBandwidth(0, bw1);
1259 pEqSupport->SetBandwidth(1, bw2);
1260 pEqSupport->SetBandwidth(2, bw3);
1261 }
1262
1263 EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1264 : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1265 suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1266 suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1267 {
1268 SetVoice(pVoice);
1269 }
1270
1271 void EqUnitSupport::SetVoice(Voice* pVoice) {
1272 suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1273 suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1274 suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1275 }
1276
1277 void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1278 if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1279 if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1280 if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1281 if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1282 if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1283 if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1284 if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1285 if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1286 if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1287 }
1288
1289 void EqUnitSupport::ResetUnits() {
1290 suEq1GainOnCC.RemoveAllCCs();
1291 suEq2GainOnCC.RemoveAllCCs();
1292 suEq3GainOnCC.RemoveAllCCs();
1293 suEq1FreqOnCC.RemoveAllCCs();
1294 suEq2FreqOnCC.RemoveAllCCs();
1295 suEq3FreqOnCC.RemoveAllCCs();
1296 suEq1BwOnCC.RemoveAllCCs();
1297 suEq2BwOnCC.RemoveAllCCs();
1298 suEq3BwOnCC.RemoveAllCCs();
1299 }
1300
1301 void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1302 suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1303 suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1304 suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1305 suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1306 suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1307 suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1308 suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1309 suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1310 suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1311 }
1312
1313 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC