/[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 2264 - (show annotations) (download)
Mon Aug 22 10:00:01 2011 UTC (12 years, 7 months ago) by iliev
File size: 43900 byte(s)
* sfz engine: implemented opcodes pitch_onccN,
  pitch_curveccN, pitch_smoothccN, pitch_stepccN

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2011 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), 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()
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()
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
246 float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247 release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248
249 EG.trigger (
250 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252 );
253 }
254
255
256 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257 : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258 suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259 { }
260
261 LFOUnit::LFOUnit(const LFOUnit& Unit)
262 : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263 suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264 suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265 {
266 Copy(Unit);
267 }
268
269 void LFOUnit::Increment() {
270 if (DelayStage()) return;
271
272 SignalUnit::Increment();
273
274 Level = pLFO->Render();
275 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276 }
277
278 void LFOUnit::Trigger() {
279 //reset
280 Level = 0;
281
282 // set the delay trigger
283 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
284 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285 float f = pLfoInfo->fade;
286 f += GetInfluence(pLfoInfo->fade_oncc);
287
288 if (f != 0) {
289 suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
291 }
292 }
293 }
294
295 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296 if (pLFO == NULL) return;
297 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298 }
299
300
301 void LFOv1Unit::Trigger() {
302 LFOUnit::Trigger();
303
304 lfo.trigger (
305 pLfoInfo->freq + suFreqOnCC.GetLevel(),
306 start_level_mid,
307 1, 0, false, GetSampleRate()
308 );
309 lfo.update(0);
310 }
311
312
313 LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314 : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317 {
318 lfos.add(&lfo0);
319 lfos.add(&lfo1);
320 lfos.add(&lfo2);
321 lfos.add(&lfo3);
322 lfos.add(&lfo4);
323 lfos.add(&lfo5);
324 lfos.add(&lfo6);
325 lfos.add(&lfo7);
326 }
327
328 void LFOv2Unit::Trigger() {
329 LFOUnit::Trigger();
330
331 if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332 else pLFO = lfos[pLfoInfo->wave];
333
334 pLFO->Trigger (
335 pLfoInfo->freq + suFreqOnCC.GetLevel(),
336 start_level_mid,
337 1, 0, false, GetSampleRate()
338 );
339 pLFO->Update(0);
340
341 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
342 if (phase != 0) pLFO->SetPhase(phase);
343 }
344
345 void AmpLFOUnit::Trigger() {
346 bActive = true;
347 ::sfz::Region* const pRegion = pVoice->pRegion;
348 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349 pLfoInfo->freq = pRegion->amplfo_freq;
350 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351 pLfoInfo->volume = pRegion->amplfo_depth;
352
353 if (pLfoInfo->freq <= 0) {
354 if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
355 else bActive = false;
356 }
357
358 LFOv1Unit::Trigger();
359 }
360
361 void PitchLFOUnit::Trigger() {
362 bActive = true;
363 ::sfz::Region* const pRegion = pVoice->pRegion;
364 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365 pLfoInfo->freq = pRegion->pitchlfo_freq;
366 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367 pLfoInfo->pitch = pRegion->pitchlfo_depth;
368
369 if (pLfoInfo->freq <= 0) {
370 if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
371 else bActive = false;
372 }
373
374 LFOv1Unit::Trigger();
375 }
376
377 void FilLFOUnit::Trigger() {
378 bActive = true;
379 ::sfz::Region* const pRegion = pVoice->pRegion;
380 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381 pLfoInfo->freq = pRegion->fillfo_freq;
382 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383 pLfoInfo->cutoff = pRegion->fillfo_depth;
384
385 if (pLfoInfo->freq <= 0) {
386 if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
387 else bActive = false;
388 }
389
390 LFOv1Unit::Trigger();
391 }
392
393 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
394 pVoice = NULL;
395 }
396
397 void CCUnit::Trigger() {
398 RTList<CC>::Iterator ctrl = pCtrls->first();
399 RTList<CC>::Iterator end = pCtrls->end();
400 for(; ctrl != end; ++ctrl) {
401 (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402 if ((*ctrl).pSmoother != NULL) {
403 if ((*ctrl).Step > 0) {
404 float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405 (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406 } else {
407 (*ctrl).pSmoother->setValue((*ctrl).Value);
408 }
409 }
410 }
411 CCSignalUnit::Trigger();
412 }
413
414 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415 RemoveAllCCs();
416 for (int i = 0; i < 128; i++) {
417 if (cc[i] != 0) AddCC(i, cc[i]);
418 }
419 }
420
421 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
422 RemoveAllCCs();
423 for (int i = 0; i < cc.size(); i++) {
424 if (cc[i].Influence != 0) {
425 short int curve = cc[i].Curve;
426 if (curve >= GetCurveCount()) curve = -1;
427 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
428 }
429 }
430 }
431
432 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
433 AddCC(Controller, Influence, Curve, NULL, Step);
434 }
435
436 int CCUnit::GetCurveCount() {
437 return pVoice->pRegion->GetInstrument()->curves.size();
438 }
439
440 ::sfz::Curve* CCUnit::GetCurve(int idx) {
441 return &pVoice->pRegion->GetInstrument()->curves[idx];
442 }
443
444 double CCUnit::GetSampleRate() {
445 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
446 }
447
448
449 SmoothCCUnit::~SmoothCCUnit() {
450 if (pSmoothers != NULL) delete pSmoothers;
451 }
452
453 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
454 if (Smooth > 0) {
455 if (pSmoothers->poolIsEmpty()) {
456 std::cerr << "Maximum number of smoothers reached" << std::endl;
457 return;
458 }
459 Smoother* smoother = &(*(pSmoothers->allocAppend()));
460 smoother->trigger(Smooth / 1000.0f, GetSampleRate());
461 AddCC(Controller, Influence, Curve, smoother, Step);
462 } else {
463 AddCC(Controller, Influence, Curve, NULL, Step);
464 }
465 }
466
467 void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
468 if (pSmoothers != NULL) delete pSmoothers;
469 pSmoothers = new RTList<Smoother>(pSmootherPool);
470 }
471
472 void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
473 CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
474 InitSmoothers(pSmootherPool);
475 }
476
477
478 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
479 : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
480 {
481
482 }
483
484 SfzSignalUnitRack* const EndpointUnit::GetRack() {
485 return static_cast<SfzSignalUnitRack* const>(pRack);
486 }
487
488 void EndpointUnit::Trigger() {
489 float xfInVelCoeff = 1;
490
491 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
492 xfInVelCoeff = 0;
493 } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
494 xfInVelCoeff = 1;
495 } else {
496 float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
497 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
498 xfInVelCoeff = velPos / xfVelSize;
499 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
500 xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
501 }
502 }
503
504 float xfOutVelCoeff = 1;
505
506 if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
507 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
508 } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
509 xfOutVelCoeff = 1;
510 } else {
511 float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
512 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
513 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
514 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
515 xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
516 }
517 }
518
519 float xfInKeyCoeff = 1;
520
521 if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
522 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
523 } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
524 xfInKeyCoeff = 1;
525 } else {
526 float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
527 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
528 xfInKeyCoeff = keyPos / xfKeySize;
529 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
530 xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
531 }
532 }
533
534 float xfOutKeyCoeff = 1;
535
536 if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
537 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
538 } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
539 xfOutKeyCoeff = 1;
540 } else {
541 float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
542 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
543 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
544 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
545 xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
546 }
547 }
548
549 xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
550
551 suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
552 suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
553
554 suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
555
556 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
557 }
558
559 bool EndpointUnit::Active() {
560 if (GetRack()->suVolEG.Active()) return true;
561
562 bool b = false;
563 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
564 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
565 }
566
567 return b;
568 }
569
570 float EndpointUnit::GetVolume() {
571 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
572
573 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
574 EGv2Unit* eg = GetRack()->volEGs[i];
575 if (!eg->Active()) continue;
576
577 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
578 if (dB < -144) dB = eg->pEGInfo->volume;
579 else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
580
581 float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
582 amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
583
584 if (dB >= -144) {
585 if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
586 amp *= ToRatio(dB * 10.0);
587 }
588
589 vol += amp * eg->GetLevel();
590 }
591
592 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
593 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
594 float f = u2->Active() ? u2->GetLevel() : 0;
595 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
596
597 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
598
599 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
600 LFOv2Unit* lfo = GetRack()->volLFOs[i];
601 if (!lfo->Active()) continue;
602
603 float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
604 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
605 }
606
607 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
608 if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
609 return vol * xfCoeff;
610 }
611
612 float EndpointUnit::GetFilterCutoff() {
613 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
614
615 FilLFOUnit* u = &(GetRack()->suFilLFO);
616 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
617 float f = u1->Active() ? u1->GetLevel() : 0;
618 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
619
620 FilEGUnit* u2 = &(GetRack()->suFilEG);
621 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
622
623 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
624 EGv2Unit* eg = GetRack()->filEGs[i];
625 if (!eg->Active()) continue;
626
627 float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
628 f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
629 val *= RTMath::CentsToFreqRatioUnlimited(f);
630 }
631
632 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
633 LFOv2Unit* lfo = GetRack()->filLFOs[i];
634 if (!lfo->Active()) continue;
635
636 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
637 f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
638 val *= RTMath::CentsToFreqRatioUnlimited(f);
639 }
640
641 return val;
642 }
643
644 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
645 cutoff *= GetFilterCutoff();
646 float maxCutoff = 0.49 * pVoice->GetSampleRate();
647 return cutoff > maxCutoff ? maxCutoff : cutoff;
648 }
649
650 float EndpointUnit::GetPitch() {
651 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
652
653 EGv1Unit* u = &(GetRack()->suPitchEG);
654 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
655
656 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
657 EGv2Unit* eg = GetRack()->pitchEGs[i];
658 if (!eg->Active()) continue;
659
660 float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
661 p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
662 }
663
664 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
665 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
666 float f = u3->Active() ? u3->GetLevel() : 0;
667 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
668
669 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
670 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
671 if (!lfo->Active()) continue;
672
673 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
674 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
675 }
676
677 return p * pitchVeltrackRatio;
678 }
679
680 float EndpointUnit::GetResonance() {
681 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
682
683 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
684 EGv2Unit* eg = GetRack()->resEGs[i];
685 if (!eg->Active()) continue;
686
687 float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
688 val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
689 }
690
691 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
692 LFOv2Unit* lfo = GetRack()->resLFOs[i];
693 if (!lfo->Active()) continue;
694
695 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
696 val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
697 }
698
699 return val;
700 }
701
702 float EndpointUnit::GetPan() {
703 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
704
705 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
706 EGv2Unit* eg = GetRack()->panEGs[i];
707 if (!eg->Active()) continue;
708
709 float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
710
711 if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
712 uint8_t val = eg->GetLevel() * 127;
713 if (val > 127) val = 127;
714 pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
715 } else {
716 pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
717 }
718 }
719
720 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
721 LFOv2Unit* lfo = GetRack()->panLFOs[i];
722 if (!lfo->Active()) continue;
723
724 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
725 pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
726 }
727
728 if(pan < -100) return -100;
729 if(pan > 100) return 100;
730
731 return pan;
732 }
733
734
735 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
736 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
737 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
738 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
739 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
740 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
741 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
742 {
743 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
744 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
745 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
746 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
747 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
748 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
749 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
750
751 for (int i = 0; i < EGs.capacity(); i++) {
752 EGs[i] = new EGv2Unit(this);
753 EGs[i]->pVoice = voice;
754 EGs[i]->suAmpOnCC.pVoice = voice;
755 EGs[i]->suVolOnCC.pVoice = voice;
756 EGs[i]->suPitchOnCC.pVoice = voice;
757 EGs[i]->suCutoffOnCC.pVoice = voice;
758 EGs[i]->suResOnCC.pVoice = voice;
759 EGs[i]->suPanOnCC.pVoice = voice;
760 }
761
762 for (int i = 0; i < LFOs.capacity(); i++) {
763 LFOs[i] = new LFOv2Unit(this);
764 LFOs[i]->pVoice = voice;
765 LFOs[i]->suDepthOnCC.pVoice = voice;
766 LFOs[i]->suFreqOnCC.pVoice = voice;
767 LFOs[i]->suFadeEG.pVoice = voice;
768 LFOs[i]->suVolOnCC.pVoice = voice;
769 LFOs[i]->suPitchOnCC.pVoice = voice;
770 LFOs[i]->suFreqOnCC.pVoice = voice;
771 LFOs[i]->suPanOnCC.pVoice = voice;
772 LFOs[i]->suCutoffOnCC.pVoice = voice;
773 LFOs[i]->suResOnCC.pVoice = voice;
774 }
775 }
776
777 SfzSignalUnitRack::~SfzSignalUnitRack() {
778 for (int i = 0; i < EGs.capacity(); i++) {
779 delete EGs[i]; EGs[i] = NULL;
780 }
781
782 for (int i = 0; i < LFOs.capacity(); i++) {
783 delete LFOs[i]; LFOs[i] = NULL;
784 }
785 }
786
787 void SfzSignalUnitRack::InitRTLists() {
788 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
789 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
790
791 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
792 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
793 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
794 suResOnCC.InitCCList(pCCPool, pSmootherPool);
795 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
796 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
797 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
798 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
799 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
800 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
801 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
802 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
803 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
804
805 for (int i = 0; i < EGs.capacity(); i++) {
806 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
807 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
808 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
809 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
810 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
811 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
812 }
813
814 for (int i = 0; i < LFOs.capacity(); i++) {
815 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
816 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
817 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
818 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
819 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
820 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
821 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
822 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
823 }
824 }
825
826 void SfzSignalUnitRack::Trigger() {
827 EGs.clear();
828 volEGs.clear();
829 pitchEGs.clear();
830 filEGs.clear();
831 resEGs.clear();
832 panEGs.clear();
833
834 LFOs.clear();
835 volLFOs.clear();
836 pitchLFOs.clear();
837 filLFOs.clear();
838 resLFOs.clear();
839 panLFOs.clear();
840
841 ::sfz::Region* const pRegion = pVoice->pRegion;
842
843 suVolOnCC.SetCCs(pRegion->volume_oncc);
844 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
845 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
846 suResOnCC.SetCCs(pRegion->resonance_oncc);
847
848 for (int i = 0; i < pRegion->eg.size(); i++) {
849 if (pRegion->eg[i].node.size() == 0) continue;
850
851 if(EGs.size() < EGs.capacity()) {
852 EGv2Unit eg(this);
853 eg.pEGInfo = &(pRegion->eg[i]);
854 EGs.increment()->Copy(eg);
855 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
856 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
857 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
858 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
859 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
860 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
861 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
862
863 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
864 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
865 ) {
866 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
867 else std::cerr << "Maximum number of EGs reached!" << std::endl;
868 }
869
870 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
871 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
872 else std::cerr << "Maximum number of EGs reached!" << std::endl;
873 }
874
875 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
876 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
877 else std::cerr << "Maximum number of EGs reached!" << std::endl;
878 }
879
880 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
881 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
882 else std::cerr << "Maximum number of EGs reached!" << std::endl;
883 }
884
885 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
886 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
887 else std::cerr << "Maximum number of EGs reached!" << std::endl;
888 }
889 }
890
891 if (pRegion->ampeg_sustain == -1) {
892 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
893 else pRegion->ampeg_sustain = 100;
894 }
895
896 // LFO
897 for (int i = 0; i < pRegion->lfos.size(); i++) {
898 if (pRegion->lfos[i].freq <= 0) {
899 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
900 else pRegion->lfos[i].freq = 0;
901 }
902
903 if(LFOs.size() < LFOs.capacity()) {
904 LFOv2Unit lfo(this);
905 lfo.pLfoInfo = &(pRegion->lfos[i]);
906 LFOs.increment()->Copy(lfo);
907 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
908 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
909 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
910 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
911 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
912 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
913 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
914
915 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
916 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
917 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
918 }
919
920 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
921 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
922 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
923 }
924
925 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
926 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
927 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
928 }
929
930 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
931 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
932 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
933 }
934
935 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
936 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
937 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
938 }
939 }
940
941 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
942 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
943
944 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
945 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
946
947 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
948 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
949
950 Units.clear();
951
952 Units.add(&suVolOnCC);
953 Units.add(&suPitchOnCC);
954 Units.add(&suCutoffOnCC);
955 Units.add(&suResOnCC);
956
957 Units.add(&suVolEG);
958 Units.add(&suFilEG);
959 Units.add(&suPitchEG);
960
961 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
962 Units.add(&suPitchLFO);
963 Units.add(&suPitchLFO.suDepthOnCC);
964 Units.add(&suPitchLFO.suFadeEG);
965
966 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
967 Units.add(&suAmpLFO.suDepthOnCC);
968 Units.add(&suAmpLFO);
969 Units.add(&suAmpLFO.suFadeEG);
970
971 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
972 Units.add(&suFilLFO.suDepthOnCC);
973 Units.add(&suFilLFO);
974 Units.add(&suFilLFO.suFadeEG);
975
976 for (int i = 0; i < EGs.size(); i++) {
977 Units.add(EGs[i]);
978 Units.add(&(EGs[i]->suAmpOnCC));
979 Units.add(&(EGs[i]->suVolOnCC));
980 Units.add(&(EGs[i]->suPitchOnCC));
981 Units.add(&(EGs[i]->suCutoffOnCC));
982 Units.add(&(EGs[i]->suResOnCC));
983 Units.add(&(EGs[i]->suPanOnCC));
984 }
985
986 for (int i = 0; i < LFOs.size(); i++) {
987 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
988 Units.add(LFOs[i]);
989 Units.add(&(LFOs[i]->suFadeEG));
990 Units.add(&(LFOs[i]->suVolOnCC));
991 Units.add(&(LFOs[i]->suPitchOnCC));
992 Units.add(&(LFOs[i]->suPanOnCC));
993 Units.add(&(LFOs[i]->suCutoffOnCC));
994 Units.add(&(LFOs[i]->suResOnCC));
995 }
996
997 Units.add(&suEndpoint);
998 Units.add(&suEndpoint.suXFInCC);
999 Units.add(&suEndpoint.suXFOutCC);
1000 Units.add(&suEndpoint.suPanOnCC);
1001
1002 SignalUnitRack::Trigger();
1003 }
1004
1005 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1006 return &suEndpoint;
1007 }
1008
1009 void SfzSignalUnitRack::EnterFadeOutStage() {
1010 suVolEG.EG.enterFadeOutStage();
1011
1012 for (int i = 0; i < volEGs.size(); i++) {
1013 volEGs[i]->EG.enterFadeOutStage();
1014 }
1015 }
1016
1017 void SfzSignalUnitRack::Reset() {
1018 suVolOnCC.RemoveAllCCs();
1019 suPitchOnCC.RemoveAllCCs();
1020 suCutoffOnCC.RemoveAllCCs();
1021 suResOnCC.RemoveAllCCs();
1022 suEndpoint.suXFInCC.RemoveAllCCs();
1023 suEndpoint.suXFOutCC.RemoveAllCCs();
1024 suEndpoint.suPanOnCC.RemoveAllCCs();
1025 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1026 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1027 suFilLFO.suDepthOnCC.RemoveAllCCs();
1028 suFilLFO.suFreqOnCC.RemoveAllCCs();
1029 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1030 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1031
1032 for (int i = 0; i < EGs.capacity(); i++) {
1033 EGs[i]->suAmpOnCC.RemoveAllCCs();
1034 EGs[i]->suVolOnCC.RemoveAllCCs();
1035 EGs[i]->suPitchOnCC.RemoveAllCCs();
1036 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1037 EGs[i]->suResOnCC.RemoveAllCCs();
1038 EGs[i]->suPanOnCC.RemoveAllCCs();
1039 }
1040
1041 for (int i = 0; i < LFOs.capacity(); i++) {
1042 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1043 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1044 LFOs[i]->suVolOnCC.RemoveAllCCs();
1045 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1046 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1047 LFOs[i]->suPanOnCC.RemoveAllCCs();
1048 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1049 LFOs[i]->suResOnCC.RemoveAllCCs();
1050 }
1051 }
1052
1053 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC