/[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 3706 - (show annotations) (download)
Wed Jan 8 20:39:59 2020 UTC (4 years, 3 months ago) by schoenebeck
File size: 57163 byte(s)
Fixed compiler warnings about implied type casts.

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 pVoice->pNote->Override.Sustain.applyTo(sustain);
247 }
248
249 float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
250 release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
251
252 EG.trigger (
253 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
254 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
255 );
256 }
257
258
259 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
260 : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
261 suFadeEG(rack), suDepthOnCC(rack), suFreqOnCC(rack, this)
262 { }
263
264 LFOUnit::LFOUnit(const LFOUnit& Unit)
265 : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
266 suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
267 suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
268 {
269 Copy(Unit);
270 }
271
272 void LFOUnit::Increment() {
273 if (DelayStage()) return;
274
275 SignalUnit::Increment();
276
277 Level = pLFO->Render();
278 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
279 }
280
281 void LFOUnit::Trigger() {
282 //reset
283 Level = 0;
284
285 // set the delay trigger
286 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
287 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
288 float f = pLfoInfo->fade;
289 f += GetInfluence(pLfoInfo->fade_oncc);
290
291 if (f != 0) {
292 suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
293 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
294 }
295 }
296 }
297
298 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
299 if (pLFO == NULL) return;
300 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
301 }
302
303
304 void LFOv1Unit::Trigger() {
305 LFOUnit::Trigger();
306
307 lfo.trigger (
308 pLfoInfo->freq + suFreqOnCC.GetLevel(),
309 LFO::start_level_mid,
310 1, 0, false, GetSampleRate()
311 );
312 lfo.updateByMIDICtrlValue(0);
313 }
314
315
316 LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
317 : LFOUnit(rack), EqUnitSupport(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
318 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
319 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
320 {
321 lfos.add(&lfo0);
322 lfos.add(&lfo1);
323 lfos.add(&lfo2);
324 lfos.add(&lfo3);
325 lfos.add(&lfo4);
326 lfos.add(&lfo5);
327 lfos.add(&lfo6);
328 lfos.add(&lfo7);
329 }
330
331 void LFOv2Unit::Trigger() {
332 LFOUnit::Trigger();
333
334 if (/*pLfoInfo->wave < 0 ||*/ pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
335 else pLFO = lfos[pLfoInfo->wave];
336
337 pLFO->Trigger (
338 pLfoInfo->freq + suFreqOnCC.GetLevel(),
339 LFO::start_level_mid,
340 1, 0, false, GetSampleRate()
341 );
342 pLFO->Update(0);
343
344 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
345 if (phase != 0) pLFO->SetPhase(phase);
346 }
347
348 void AmpLFOUnit::Trigger() {
349 bActive = true;
350 ::sfz::Region* const pRegion = pVoice->pRegion;
351 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
352 pLfoInfo->freq = pRegion->amplfo_freq;
353 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
354 pLfoInfo->volume = pRegion->amplfo_depth;
355
356 if (pLfoInfo->freq <= 0) {
357 if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
358 else bActive = false;
359 }
360
361 LFOv1Unit::Trigger();
362 }
363
364 void PitchLFOUnit::Trigger() {
365 bActive = true;
366 ::sfz::Region* const pRegion = pVoice->pRegion;
367 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
368 pLfoInfo->freq = pRegion->pitchlfo_freq;
369 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
370 pLfoInfo->pitch = pRegion->pitchlfo_depth;
371
372 if (pLfoInfo->freq <= 0) {
373 if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
374 else bActive = false;
375 }
376
377 LFOv1Unit::Trigger();
378 }
379
380 void FilLFOUnit::Trigger() {
381 bActive = true;
382 ::sfz::Region* const pRegion = pVoice->pRegion;
383 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
384 pLfoInfo->freq = pRegion->fillfo_freq;
385 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
386 pLfoInfo->cutoff = pRegion->fillfo_depth;
387
388 if (pLfoInfo->freq <= 0) {
389 if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
390 else bActive = false;
391 }
392
393 LFOv1Unit::Trigger();
394 }
395
396 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
397 pVoice = NULL;
398 }
399
400 void CCUnit::Trigger() {
401 RTList<CC>::Iterator ctrl = pCtrls->first();
402 RTList<CC>::Iterator end = pCtrls->end();
403 for(; ctrl != end; ++ctrl) {
404 (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
405 if ((*ctrl).pSmoother != NULL) {
406 if ((*ctrl).Step > 0) {
407 float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
408 (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
409 } else {
410 (*ctrl).pSmoother->setValue((*ctrl).Value);
411 }
412 }
413 }
414 CCSignalUnit::Trigger();
415 }
416
417 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
418 RemoveAllCCs();
419 for (int i = 0; i < 128; i++) {
420 if (cc[i] != 0) AddCC(i, cc[i]);
421 }
422 }
423
424 void CCUnit::SetCCs(::sfz::Array<float>& cc) {
425 RemoveAllCCs();
426 for (int i = 0; i < 128; i++) {
427 if (cc[i] != 0) AddCC(i, cc[i]);
428 }
429 }
430
431 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
432 RemoveAllCCs();
433 for (int i = 0; i < cc.size(); i++) {
434 if (cc[i].Influence != 0) {
435 short int curve = cc[i].Curve;
436 if (curve >= GetCurveCount()) curve = -1;
437 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
438 }
439 }
440 }
441
442 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
443 AddCC(Controller, Influence, Curve, NULL, Step);
444 }
445
446 int CCUnit::GetCurveCount() {
447 return (int) pVoice->pRegion->GetInstrument()->curves.size();
448 }
449
450 ::sfz::Curve* CCUnit::GetCurve(int idx) {
451 return &pVoice->pRegion->GetInstrument()->curves[idx];
452 }
453
454 double CCUnit::GetSampleRate() {
455 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
456 }
457
458
459 SmoothCCUnit::~SmoothCCUnit() {
460 if (pSmoothers != NULL) delete pSmoothers;
461 }
462
463 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
464 if (Smooth > 0) {
465 if (pSmoothers->poolIsEmpty()) {
466 std::cerr << "Maximum number of smoothers reached" << std::endl;
467 return;
468 }
469 Smoother* smoother = &(*(pSmoothers->allocAppend()));
470 smoother->trigger(Smooth / 1000.0f, GetSampleRate());
471 AddCC(Controller, Influence, Curve, smoother, Step);
472 } else {
473 AddCC(Controller, Influence, Curve, NULL, Step);
474 }
475 }
476
477 void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
478 if (pSmoothers != NULL) delete pSmoothers;
479 pSmoothers = new RTList<Smoother>(pSmootherPool);
480 }
481
482 void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
483 CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
484 InitSmoothers(pSmootherPool);
485 }
486
487
488 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
489 : EndpointSignalUnit(rack), pitchVeltrackRatio(0), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack)
490 {
491
492 }
493
494 float EndpointUnit::GetInfluence(::sfz::Array< optional<float> >& cc) {
495 float f = 0;
496 for (int i = 0; i < 128; i++) {
497 if (cc[i]) {
498 f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
499 }
500 }
501 return f;
502 }
503
504 float EndpointUnit::GetInfluence(::sfz::Array< optional<int> >& cc) {
505 float f = 0;
506 for (int i = 0; i < 128; i++) {
507 if (cc[i]) {
508 f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
509 }
510 }
511 return f;
512 }
513
514 SfzSignalUnitRack* const EndpointUnit::GetRack() {
515 return static_cast<SfzSignalUnitRack* const>(pRack);
516 }
517
518 void EndpointUnit::Trigger() {
519 uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
520 if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
521
522 if (pVoice->pRegion->delay) {
523 /* here we use the device sample rate */
524 uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
525 }
526
527 if (pVoice->pRegion->delay_random) {
528 float r = pVoice->GetEngine()->Random();
529 uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
530 }
531
532 uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
533
534 float xfInVelCoeff = 1;
535
536 if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
537 xfInVelCoeff = 0;
538 } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
539 xfInVelCoeff = 1;
540 } else {
541 float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
542 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
543 xfInVelCoeff = velPos / xfVelSize;
544 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
545 xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
546 }
547 }
548
549 float xfOutVelCoeff = 1;
550
551 if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
552 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
553 } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
554 xfOutVelCoeff = 1;
555 } else {
556 float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
557 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
558 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
559 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
560 xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
561 }
562 }
563
564 float xfInKeyCoeff = 1;
565
566 if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
567 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
568 } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
569 xfInKeyCoeff = 1;
570 } else {
571 float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
572 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
573 xfInKeyCoeff = keyPos / xfKeySize;
574 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
575 xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
576 }
577 }
578
579 float xfOutKeyCoeff = 1;
580
581 if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
582 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
583 } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
584 xfOutKeyCoeff = 1;
585 } else {
586 float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
587 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
588 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
589 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
590 xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
591 }
592 }
593
594 xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
595
596 suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
597 suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
598
599 suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
600
601 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
602 }
603
604 bool EndpointUnit::Active() {
605 if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
606 return false; // The key was released before the delay end, so the voice won't play at all.
607 }
608
609 if (GetRack()->suVolEG.Active()) return true;
610
611 bool b = false;
612 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
613 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
614 }
615
616 return b;
617 }
618
619 float EndpointUnit::GetVolume() {
620 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
621
622 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
623 EGv2Unit* eg = GetRack()->volEGs[i];
624 if (!eg->Active()) continue;
625
626 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
627 if (dB < -144) dB = eg->pEGInfo->volume;
628 else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
629
630 float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
631 amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
632
633 if (dB >= -144) {
634 if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
635 amp *= ToRatio(dB * 10.0);
636 }
637
638 vol += amp * eg->GetLevel();
639 }
640
641 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
642 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
643 float f = u2->Active() ? u2->GetLevel() : 0;
644 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
645
646 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
647
648 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
649 LFOv2Unit* lfo = GetRack()->volLFOs[i];
650 if (!lfo->Active()) continue;
651
652 float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
653 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
654 }
655
656 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
657 if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
658 return vol * xfCoeff;
659 }
660
661 float EndpointUnit::GetFilterCutoff() {
662 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
663
664 FilLFOUnit* u = &(GetRack()->suFilLFO);
665 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
666 float f = u1->Active() ? u1->GetLevel() : 0;
667 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
668
669 FilEGUnit* u2 = &(GetRack()->suFilEG);
670 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
671
672 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
673 EGv2Unit* eg = GetRack()->filEGs[i];
674 if (!eg->Active()) continue;
675
676 float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
677 f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
678 val *= RTMath::CentsToFreqRatioUnlimited(f);
679 }
680
681 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
682 LFOv2Unit* lfo = GetRack()->filLFOs[i];
683 if (!lfo->Active()) continue;
684
685 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
686 f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
687 val *= RTMath::CentsToFreqRatioUnlimited(f);
688 }
689
690 return val;
691 }
692
693 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
694 cutoff *= GetFilterCutoff();
695 float maxCutoff = 0.49 * pVoice->GetSampleRate();
696 return cutoff > maxCutoff ? maxCutoff : cutoff;
697 }
698
699 float EndpointUnit::GetPitch() {
700 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
701
702 EGv1Unit* u = &(GetRack()->suPitchEG);
703 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
704
705 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
706 EGv2Unit* eg = GetRack()->pitchEGs[i];
707 if (!eg->Active()) continue;
708
709 float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
710 p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
711 }
712
713 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
714 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
715 float f = u3->Active() ? u3->GetLevel() : 0;
716 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
717
718 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
719 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
720 if (!lfo->Active()) continue;
721
722 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
723 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
724 }
725
726 return p * pitchVeltrackRatio;
727 }
728
729 float EndpointUnit::GetResonance() {
730 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
731
732 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
733 EGv2Unit* eg = GetRack()->resEGs[i];
734 if (!eg->Active()) continue;
735
736 float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
737 val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
738 }
739
740 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
741 LFOv2Unit* lfo = GetRack()->resLFOs[i];
742 if (!lfo->Active()) continue;
743
744 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
745 val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
746 }
747
748 return val;
749 }
750
751 float EndpointUnit::GetPan() {
752 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
753
754 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
755 EGv2Unit* eg = GetRack()->panEGs[i];
756 if (!eg->Active()) continue;
757
758 float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
759
760 if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
761 uint8_t val = eg->GetLevel() * 127;
762 if (val > 127) val = 127;
763 pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
764 } else {
765 pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
766 }
767 }
768
769 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
770 LFOv2Unit* lfo = GetRack()->panLFOs[i];
771 if (!lfo->Active()) continue;
772
773 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
774 pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
775 }
776
777 return pan;
778 }
779
780
781 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
782 : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice),
783 suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
784 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
785 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
786 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
787 resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
788 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
789 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount),
790 pVoice(voice)
791 {
792 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
793 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
794 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
795
796 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
797 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
798 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
799 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
800
801 for (int i = 0; i < EGs.capacity(); i++) {
802 EGs[i] = new EGv2Unit(this);
803 EGs[i]->pVoice = voice;
804 EGs[i]->suAmpOnCC.pVoice = voice;
805 EGs[i]->suVolOnCC.pVoice = voice;
806 EGs[i]->suPitchOnCC.pVoice = voice;
807 EGs[i]->suCutoffOnCC.pVoice = voice;
808 EGs[i]->suResOnCC.pVoice = voice;
809 EGs[i]->suPanOnCC.pVoice = voice;
810 EGs[i]->SetVoice(voice); // class EqUnitSupport
811 }
812
813 for (int i = 0; i < LFOs.capacity(); i++) {
814 LFOs[i] = new LFOv2Unit(this);
815 LFOs[i]->pVoice = voice;
816 LFOs[i]->suDepthOnCC.pVoice = voice;
817 LFOs[i]->suFreqOnCC.pVoice = voice;
818 LFOs[i]->suFadeEG.pVoice = voice;
819 LFOs[i]->suVolOnCC.pVoice = voice;
820 LFOs[i]->suPitchOnCC.pVoice = voice;
821 LFOs[i]->suFreqOnCC.pVoice = voice;
822 LFOs[i]->suPanOnCC.pVoice = voice;
823 LFOs[i]->suCutoffOnCC.pVoice = voice;
824 LFOs[i]->suResOnCC.pVoice = voice;
825 LFOs[i]->SetVoice(voice); // class EqUnitSupport
826 }
827 }
828
829 SfzSignalUnitRack::~SfzSignalUnitRack() {
830 for (int i = 0; i < EGs.capacity(); i++) {
831 delete EGs[i]; EGs[i] = NULL;
832 }
833
834 for (int i = 0; i < LFOs.capacity(); i++) {
835 delete LFOs[i]; LFOs[i] = NULL;
836 }
837 }
838
839 void SfzSignalUnitRack::InitRTLists() {
840 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
841 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
842
843 EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
844
845 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
846 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
847 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
848 suResOnCC.InitCCList(pCCPool, pSmootherPool);
849 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
850 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
851 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
852 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
853 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
854 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
855 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
856 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
857 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
858
859 for (int i = 0; i < EGs.capacity(); i++) {
860 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
861 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
862 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
863 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
864 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
865 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
866 EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
867 }
868
869 for (int i = 0; i < LFOs.capacity(); i++) {
870 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
871 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
872 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
873 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
874 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
875 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
876 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
877 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
878 LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
879 }
880 }
881
882 void SfzSignalUnitRack::Trigger() {
883 EGs.clear();
884 volEGs.clear();
885 pitchEGs.clear();
886 filEGs.clear();
887 resEGs.clear();
888 panEGs.clear();
889 eqEGs.clear();
890
891 LFOs.clear();
892 volLFOs.clear();
893 pitchLFOs.clear();
894 filLFOs.clear();
895 resLFOs.clear();
896 panLFOs.clear();
897 eqLFOs.clear();
898
899 ::sfz::Region* const pRegion = pVoice->pRegion;
900
901 suVolOnCC.SetCCs(pRegion->volume_oncc);
902 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
903 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
904 suResOnCC.SetCCs(pRegion->resonance_oncc);
905
906 for (int i = 0; i < pRegion->eg.size(); i++) {
907 if (pRegion->eg[i].node.size() == 0) continue;
908
909 if(EGs.size() < EGs.capacity()) {
910 EGv2Unit eg(this);
911 eg.pEGInfo = &(pRegion->eg[i]);
912 EGs.increment()->Copy(eg);
913 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
914 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
915 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
916 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
917 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
918 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
919 if (pVoice->bEqSupport) {
920 EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
921 EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
922 EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
923 EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
924 EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
925 EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
926 EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
927 EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
928 EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
929 }
930 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
931
932 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
933 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
934 ) {
935 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
936 else std::cerr << "Maximum number of EGs reached!" << std::endl;
937 }
938
939 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
940 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
941 else std::cerr << "Maximum number of EGs reached!" << std::endl;
942 }
943
944 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
945 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
946 else std::cerr << "Maximum number of EGs reached!" << std::endl;
947 }
948
949 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
950 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
951 else std::cerr << "Maximum number of EGs reached!" << std::endl;
952 }
953
954 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
955 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
956 else std::cerr << "Maximum number of EGs reached!" << std::endl;
957 }
958
959 if (pRegion->eg[i].HasEq()) {
960 if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
961 else std::cerr << "Maximum number of EGs reached!" << std::endl;
962 }
963 }
964
965 if (pRegion->ampeg_sustain == -1) {
966 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
967 else pRegion->ampeg_sustain = 100;
968 }
969
970 // LFO
971 for (int i = 0; i < pRegion->lfos.size(); i++) {
972 if (pRegion->lfos[i].freq <= 0) {
973 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
974 else pRegion->lfos[i].freq = 0;
975 }
976
977 if(LFOs.size() < LFOs.capacity()) {
978 LFOv2Unit lfo(this);
979 lfo.pLfoInfo = &(pRegion->lfos[i]);
980 LFOs.increment()->Copy(lfo);
981 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
982 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
983 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
984 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
985 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
986 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
987 if (pVoice->bEqSupport) {
988 LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
989 LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
990 LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
991 LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
992 LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
993 LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
994 LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
995 LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
996 LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
997 }
998 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
999
1000 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
1001 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
1002 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1003 }
1004
1005 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1006 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1007 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1008 }
1009
1010 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1011 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1012 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1013 }
1014
1015 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1016 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1017 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1018 }
1019
1020 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1021 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1022 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1023 }
1024
1025 if (pRegion->lfos[i].HasEq()) {
1026 if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1027 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1028 }
1029 }
1030
1031 if (!pVoice->bEqSupport) {
1032 bHasEq = false;
1033 } else {
1034 suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1035 suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1036 suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1037 suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1038 suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1039 suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1040 suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1041 suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1042 suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1043
1044 bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1045 pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1046 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1047 eqEGs.size() > 0 || eqLFOs.size() > 0;
1048 }
1049
1050 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1051 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1052
1053 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1054 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1055
1056 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1057 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1058
1059 Units.clear();
1060
1061 EqUnitSupport::ImportUnits(this);
1062
1063 Units.add(&suVolOnCC);
1064 Units.add(&suPitchOnCC);
1065 Units.add(&suCutoffOnCC);
1066 Units.add(&suResOnCC);
1067
1068 Units.add(&suVolEG);
1069 Units.add(&suFilEG);
1070 Units.add(&suPitchEG);
1071
1072 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1073 Units.add(&suPitchLFO);
1074 Units.add(&suPitchLFO.suDepthOnCC);
1075 Units.add(&suPitchLFO.suFadeEG);
1076
1077 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1078 Units.add(&suAmpLFO.suDepthOnCC);
1079 Units.add(&suAmpLFO);
1080 Units.add(&suAmpLFO.suFadeEG);
1081
1082 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1083 Units.add(&suFilLFO.suDepthOnCC);
1084 Units.add(&suFilLFO);
1085 Units.add(&suFilLFO.suFadeEG);
1086
1087 for (int i = 0; i < EGs.size(); i++) {
1088 Units.add(EGs[i]);
1089 Units.add(&(EGs[i]->suAmpOnCC));
1090 Units.add(&(EGs[i]->suVolOnCC));
1091 Units.add(&(EGs[i]->suPitchOnCC));
1092 Units.add(&(EGs[i]->suCutoffOnCC));
1093 Units.add(&(EGs[i]->suResOnCC));
1094 Units.add(&(EGs[i]->suPanOnCC));
1095 EGs[i]->ImportUnits(this); // class EqUnitSupport
1096 }
1097
1098 for (int i = 0; i < LFOs.size(); i++) {
1099 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1100 Units.add(LFOs[i]);
1101 Units.add(&(LFOs[i]->suFadeEG));
1102 Units.add(&(LFOs[i]->suVolOnCC));
1103 Units.add(&(LFOs[i]->suPitchOnCC));
1104 Units.add(&(LFOs[i]->suPanOnCC));
1105 Units.add(&(LFOs[i]->suCutoffOnCC));
1106 Units.add(&(LFOs[i]->suResOnCC));
1107 LFOs[i]->ImportUnits(this); // class EqUnitSupport
1108 }
1109
1110 Units.add(&suEndpoint);
1111 Units.add(&suEndpoint.suXFInCC);
1112 Units.add(&suEndpoint.suXFOutCC);
1113 Units.add(&suEndpoint.suPanOnCC);
1114
1115 SignalUnitRack::Trigger();
1116 }
1117
1118 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1119 return &suEndpoint;
1120 }
1121
1122 void SfzSignalUnitRack::EnterFadeOutStage() {
1123 suVolEG.EG.enterFadeOutStage();
1124
1125 for (int i = 0; i < volEGs.size(); i++) {
1126 volEGs[i]->EG.enterFadeOutStage();
1127 }
1128 }
1129
1130 void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1131 suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1132 for (int i = 0; i < volEGs.size(); i++) {
1133 volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1134 }
1135 }
1136
1137 void SfzSignalUnitRack::Reset() {
1138 EqUnitSupport::ResetUnits();
1139
1140 suVolOnCC.RemoveAllCCs();
1141 suPitchOnCC.RemoveAllCCs();
1142 suCutoffOnCC.RemoveAllCCs();
1143 suResOnCC.RemoveAllCCs();
1144 suEndpoint.suXFInCC.RemoveAllCCs();
1145 suEndpoint.suXFOutCC.RemoveAllCCs();
1146 suEndpoint.suPanOnCC.RemoveAllCCs();
1147 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1148 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1149 suFilLFO.suDepthOnCC.RemoveAllCCs();
1150 suFilLFO.suFreqOnCC.RemoveAllCCs();
1151 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1152 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1153
1154 for (int i = 0; i < EGs.capacity(); i++) {
1155 EGs[i]->suAmpOnCC.RemoveAllCCs();
1156 EGs[i]->suVolOnCC.RemoveAllCCs();
1157 EGs[i]->suPitchOnCC.RemoveAllCCs();
1158 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1159 EGs[i]->suResOnCC.RemoveAllCCs();
1160 EGs[i]->suPanOnCC.RemoveAllCCs();
1161 EGs[i]->ResetUnits(); // class EqUnitSupport
1162 }
1163
1164 for (int i = 0; i < LFOs.capacity(); i++) {
1165 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1166 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1167 LFOs[i]->suVolOnCC.RemoveAllCCs();
1168 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1169 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1170 LFOs[i]->suPanOnCC.RemoveAllCCs();
1171 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1172 LFOs[i]->suResOnCC.RemoveAllCCs();
1173 LFOs[i]->ResetUnits(); // class EqUnitSupport
1174 }
1175 }
1176
1177 void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1178 suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1179 for (int i = 0; i < EGs.capacity(); i++) {
1180 EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1181 }
1182 }
1183
1184 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1185 if (!pEqSupport->HasSupport()) return;
1186 if (pEqSupport->GetBandCount() < 3) {
1187 std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1188 return;
1189 }
1190
1191 ::sfz::Region* const pRegion = pVoice->pRegion;
1192
1193 float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1194 float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1195 float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1196
1197 float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1198 float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1199 float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1200
1201 float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1202 float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1203 float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1204
1205 const float vel = pVoice->MIDIVelocity() / 127.0f;
1206
1207 dB1 += pRegion->eq1_vel2gain * vel;
1208 dB2 += pRegion->eq2_vel2gain * vel;
1209 dB3 += pRegion->eq3_vel2gain * vel;
1210
1211 freq1 += pRegion->eq1_vel2freq * vel;
1212 freq2 += pRegion->eq2_vel2freq * vel;
1213 freq3 += pRegion->eq3_vel2freq * vel;
1214
1215 for (int i = 0; i < eqEGs.size(); i++) {
1216 EGv2Unit* eg = eqEGs[i];
1217 if (!eg->Active()) continue;
1218
1219 float l = eg->GetLevel();
1220 dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1221 dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1222 dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1223
1224 freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1225 freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1226 freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1227
1228 bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1229 bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1230 bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1231 }
1232
1233 for (int i = 0; i < eqLFOs.size(); i++) {
1234 LFOv2Unit* lfo = eqLFOs[i];
1235 if (!lfo->Active()) continue;
1236
1237 float l = lfo->GetLevel();
1238 dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1239 dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1240 dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1241
1242 freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1243 freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1244 freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1245
1246 bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1247 bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1248 bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1249 }
1250
1251 pEqSupport->SetGain(0, dB1);
1252 pEqSupport->SetGain(1, dB2);
1253 pEqSupport->SetGain(2, dB3);
1254
1255 pEqSupport->SetFreq(0, freq1);
1256 pEqSupport->SetFreq(1, freq2);
1257 pEqSupport->SetFreq(2, freq3);
1258
1259 pEqSupport->SetBandwidth(0, bw1);
1260 pEqSupport->SetBandwidth(1, bw2);
1261 pEqSupport->SetBandwidth(2, bw3);
1262 }
1263
1264 EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1265 : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1266 suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1267 suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1268 {
1269 SetVoice(pVoice);
1270 }
1271
1272 void EqUnitSupport::SetVoice(Voice* pVoice) {
1273 suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1274 suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1275 suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1276 }
1277
1278 void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1279 if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1280 if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1281 if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1282 if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1283 if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1284 if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1285 if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1286 if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1287 if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1288 }
1289
1290 void EqUnitSupport::ResetUnits() {
1291 suEq1GainOnCC.RemoveAllCCs();
1292 suEq2GainOnCC.RemoveAllCCs();
1293 suEq3GainOnCC.RemoveAllCCs();
1294 suEq1FreqOnCC.RemoveAllCCs();
1295 suEq2FreqOnCC.RemoveAllCCs();
1296 suEq3FreqOnCC.RemoveAllCCs();
1297 suEq1BwOnCC.RemoveAllCCs();
1298 suEq2BwOnCC.RemoveAllCCs();
1299 suEq3BwOnCC.RemoveAllCCs();
1300 }
1301
1302 void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1303 suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1304 suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1305 suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1306 suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1307 suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1308 suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1309 suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1310 suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1311 suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1312 }
1313
1314 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC