/[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 2251 - (show annotations) (download)
Sat Aug 20 10:38:31 2011 UTC (12 years, 7 months ago) by iliev
File size: 42568 byte(s)
* sfz engine: *lfo_freqccN wasn't working when the respective *lfo_freq
  was not set or was set to zero
* sfz engine: lfoN_freq_onccX wasn't working when lfoN_freq
  was not set or was set to zero

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) (*ctrl).pSmoother->setValue((*ctrl).Value);
403 }
404 CCSignalUnit::Trigger();
405 }
406
407 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
408 RemoveAllCCs();
409 for (int i = 0; i < 128; i++) {
410 if (cc[i] != 0) AddCC(i, cc[i]);
411 }
412 }
413
414 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
415 RemoveAllCCs();
416 for (int i = 0; i < cc.size(); i++) {
417 if (cc[i].Influence != 0) {
418 short int curve = cc[i].Curve;
419 if (curve >= GetCurveCount()) curve = -1;
420 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
421 }
422 }
423 }
424
425 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
426 AddCC(Controller, Influence, Curve);
427 }
428
429 int CCUnit::GetCurveCount() {
430 return pVoice->pRegion->GetInstrument()->curves.size();
431 }
432
433 ::sfz::Curve* CCUnit::GetCurve(int idx) {
434 return &pVoice->pRegion->GetInstrument()->curves[idx];
435 }
436
437 double CCUnit::GetSampleRate() {
438 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
439 }
440
441
442 SmoothCCUnit::~SmoothCCUnit() {
443 if (pSmoothers != NULL) delete pSmoothers;
444 }
445
446 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
447 if (Smooth > 0) {
448 if (pSmoothers->poolIsEmpty()) {
449 std::cerr << "Maximum number of smoothers reached" << std::endl;
450 return;
451 }
452 Smoother* smoother = &(*(pSmoothers->allocAppend()));
453 smoother->trigger(Smooth / 1000.0f, GetSampleRate());
454 AddCC(Controller, Influence, Curve, smoother);
455 } else {
456 AddCC(Controller, Influence, Curve);
457 }
458 }
459
460 void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
461 if (pSmoothers != NULL) delete pSmoothers;
462 pSmoothers = new RTList<Smoother>(pSmootherPool);
463 }
464
465 void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
466 CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
467 InitSmoothers(pSmootherPool);
468 }
469
470
471 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
472 : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
473 {
474
475 }
476
477 SfzSignalUnitRack* const EndpointUnit::GetRack() {
478 return static_cast<SfzSignalUnitRack* const>(pRack);
479 }
480
481 void EndpointUnit::Trigger() {
482 float xfInVelCoeff = 1;
483
484 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
485 xfInVelCoeff = 0;
486 } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
487 xfInVelCoeff = 1;
488 } else {
489 float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
490 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
491 xfInVelCoeff = velPos / xfVelSize;
492 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
493 xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
494 }
495 }
496
497 float xfOutVelCoeff = 1;
498
499 if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
500 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
501 } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
502 xfOutVelCoeff = 1;
503 } else {
504 float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
505 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
506 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
507 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
508 xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
509 }
510 }
511
512 float xfInKeyCoeff = 1;
513
514 if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
515 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
516 } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
517 xfInKeyCoeff = 1;
518 } else {
519 float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
520 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
521 xfInKeyCoeff = keyPos / xfKeySize;
522 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
523 xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
524 }
525 }
526
527 float xfOutKeyCoeff = 1;
528
529 if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
530 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
531 } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
532 xfOutKeyCoeff = 1;
533 } else {
534 float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
535 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
536 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
537 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
538 xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
539 }
540 }
541
542 xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
543
544 suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
545 suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
546
547 suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
548
549 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
550 }
551
552 bool EndpointUnit::Active() {
553 if (GetRack()->suVolEG.Active()) return true;
554
555 bool b = false;
556 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
557 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
558 }
559
560 return b;
561 }
562
563 float EndpointUnit::GetVolume() {
564 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
565
566 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
567 EGv2Unit* eg = GetRack()->volEGs[i];
568 if (!eg->Active()) continue;
569
570 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
571 if (dB < -144) dB = eg->pEGInfo->volume;
572 else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
573
574 float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
575 amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
576
577 if (dB >= -144) {
578 if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
579 amp *= ToRatio(dB * 10.0);
580 }
581
582 vol += amp * eg->GetLevel();
583 }
584
585 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
586 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
587 float f = u2->Active() ? u2->GetLevel() : 0;
588 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
589
590 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
591
592 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
593 LFOv2Unit* lfo = GetRack()->volLFOs[i];
594 if (!lfo->Active()) continue;
595
596 float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
597 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
598 }
599
600 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
601 if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
602 return vol * xfCoeff;
603 }
604
605 float EndpointUnit::GetFilterCutoff() {
606 float val;
607
608 FilLFOUnit* u = &(GetRack()->suFilLFO);
609 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
610 float f = u1->Active() ? u1->GetLevel() : 0;
611 val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
612
613 FilEGUnit* u2 = &(GetRack()->suFilEG);
614 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
615
616 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
617 EGv2Unit* eg = GetRack()->filEGs[i];
618 if (!eg->Active()) continue;
619
620 float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
621 f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
622 val *= RTMath::CentsToFreqRatioUnlimited(f);
623 }
624
625 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
626 LFOv2Unit* lfo = GetRack()->filLFOs[i];
627 if (!lfo->Active()) continue;
628
629 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
630 f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
631 val *= RTMath::CentsToFreqRatioUnlimited(f);
632 }
633
634 return val;
635 }
636
637 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
638 cutoff *= GetFilterCutoff();
639 float maxCutoff = 0.49 * pVoice->GetSampleRate();
640 return cutoff > maxCutoff ? maxCutoff : cutoff;
641 }
642
643 float EndpointUnit::GetPitch() {
644 double p;
645 EGv1Unit* u = &(GetRack()->suPitchEG);
646 p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
647
648 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
649 EGv2Unit* eg = GetRack()->pitchEGs[i];
650 if (!eg->Active()) continue;
651
652 float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
653 p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
654 }
655
656 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
657 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
658 float f = u3->Active() ? u3->GetLevel() : 0;
659 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
660
661 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
662 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
663 if (!lfo->Active()) continue;
664
665 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
666 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
667 }
668
669 return p * pitchVeltrackRatio;
670 }
671
672 float EndpointUnit::GetResonance() {
673 float val = 0;
674
675 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
676 EGv2Unit* eg = GetRack()->resEGs[i];
677 if (!eg->Active()) continue;
678
679 float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
680 val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
681 }
682
683 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
684 LFOv2Unit* lfo = GetRack()->resLFOs[i];
685 if (!lfo->Active()) continue;
686
687 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
688 val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
689 }
690
691 return val;
692 }
693
694 float EndpointUnit::GetPan() {
695 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
696
697 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
698 EGv2Unit* eg = GetRack()->panEGs[i];
699 if (!eg->Active()) continue;
700
701 float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
702
703 if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
704 uint8_t val = eg->GetLevel() * 127;
705 if (val > 127) val = 127;
706 pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
707 } else {
708 pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
709 }
710 }
711
712 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
713 LFOv2Unit* lfo = GetRack()->panLFOs[i];
714 if (!lfo->Active()) continue;
715
716 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
717 pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
718 }
719
720 if(pan < -100) return -100;
721 if(pan > 100) return 100;
722
723 return pan;
724 }
725
726
727 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
728 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
729 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
730 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
731 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
732 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
733 {
734 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
735 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
736 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
737 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
738 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
739 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
740
741 for (int i = 0; i < EGs.capacity(); i++) {
742 EGs[i] = new EGv2Unit(this);
743 EGs[i]->pVoice = voice;
744 EGs[i]->suAmpOnCC.pVoice = voice;
745 EGs[i]->suVolOnCC.pVoice = voice;
746 EGs[i]->suPitchOnCC.pVoice = voice;
747 EGs[i]->suCutoffOnCC.pVoice = voice;
748 EGs[i]->suResOnCC.pVoice = voice;
749 EGs[i]->suPanOnCC.pVoice = voice;
750 }
751
752 for (int i = 0; i < LFOs.capacity(); i++) {
753 LFOs[i] = new LFOv2Unit(this);
754 LFOs[i]->pVoice = voice;
755 LFOs[i]->suDepthOnCC.pVoice = voice;
756 LFOs[i]->suFreqOnCC.pVoice = voice;
757 LFOs[i]->suFadeEG.pVoice = voice;
758 LFOs[i]->suVolOnCC.pVoice = voice;
759 LFOs[i]->suPitchOnCC.pVoice = voice;
760 LFOs[i]->suFreqOnCC.pVoice = voice;
761 LFOs[i]->suPanOnCC.pVoice = voice;
762 LFOs[i]->suCutoffOnCC.pVoice = voice;
763 LFOs[i]->suResOnCC.pVoice = voice;
764 }
765 }
766
767 SfzSignalUnitRack::~SfzSignalUnitRack() {
768 for (int i = 0; i < EGs.capacity(); i++) {
769 delete EGs[i]; EGs[i] = NULL;
770 }
771
772 for (int i = 0; i < LFOs.capacity(); i++) {
773 delete LFOs[i]; LFOs[i] = NULL;
774 }
775 }
776
777 void SfzSignalUnitRack::InitRTLists() {
778 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
779 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
780
781 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
782 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
783 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
784 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
785 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
786 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
787 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
788 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
789 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
790 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
791
792 for (int i = 0; i < EGs.capacity(); i++) {
793 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
794 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
795 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
796 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
797 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
798 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
799 }
800
801 for (int i = 0; i < LFOs.capacity(); i++) {
802 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
803 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
804 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
805 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
806 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
807 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
808 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
809 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
810 }
811 }
812
813 void SfzSignalUnitRack::Trigger() {
814 EGs.clear();
815 volEGs.clear();
816 pitchEGs.clear();
817 filEGs.clear();
818 resEGs.clear();
819 panEGs.clear();
820
821 LFOs.clear();
822 volLFOs.clear();
823 pitchLFOs.clear();
824 filLFOs.clear();
825 resLFOs.clear();
826 panLFOs.clear();
827
828 ::sfz::Region* const pRegion = pVoice->pRegion;
829
830 suVolOnCC.SetCCs(pRegion->volume_oncc);
831
832 for (int i = 0; i < pRegion->eg.size(); i++) {
833 if (pRegion->eg[i].node.size() == 0) continue;
834
835 if(EGs.size() < EGs.capacity()) {
836 EGv2Unit eg(this);
837 eg.pEGInfo = &(pRegion->eg[i]);
838 EGs.increment()->Copy(eg);
839 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
840 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
841 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
842 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
843 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
844 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
845 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
846
847 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
848 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
849 ) {
850 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
851 else std::cerr << "Maximum number of EGs reached!" << std::endl;
852 }
853
854 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
855 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
856 else std::cerr << "Maximum number of EGs reached!" << std::endl;
857 }
858
859 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
860 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
861 else std::cerr << "Maximum number of EGs reached!" << std::endl;
862 }
863
864 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
865 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
866 else std::cerr << "Maximum number of EGs reached!" << std::endl;
867 }
868
869 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
870 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
871 else std::cerr << "Maximum number of EGs reached!" << std::endl;
872 }
873 }
874
875 if (pRegion->ampeg_sustain == -1) {
876 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
877 else pRegion->ampeg_sustain = 100;
878 }
879
880 // LFO
881 for (int i = 0; i < pRegion->lfos.size(); i++) {
882 if (pRegion->lfos[i].freq <= 0) {
883 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
884 else pRegion->lfos[i].freq = 0;
885 }
886
887 if(LFOs.size() < LFOs.capacity()) {
888 LFOv2Unit lfo(this);
889 lfo.pLfoInfo = &(pRegion->lfos[i]);
890 LFOs.increment()->Copy(lfo);
891 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
892 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
893 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
894 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
895 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
896 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
897 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
898
899 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
900 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
901 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
902 }
903
904 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
905 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
906 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
907 }
908
909 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
910 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
911 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
912 }
913
914 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
915 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
916 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
917 }
918
919 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
920 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
921 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
922 }
923 }
924
925 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
926 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
927
928 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
929 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
930
931 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
932 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
933
934 Units.clear();
935
936 Units.add(&suVolOnCC);
937
938 Units.add(&suVolEG);
939 Units.add(&suFilEG);
940 Units.add(&suPitchEG);
941
942 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
943 Units.add(&suPitchLFO);
944 Units.add(&suPitchLFO.suDepthOnCC);
945 Units.add(&suPitchLFO.suFadeEG);
946
947 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
948 Units.add(&suAmpLFO.suDepthOnCC);
949 Units.add(&suAmpLFO);
950 Units.add(&suAmpLFO.suFadeEG);
951
952 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
953 Units.add(&suFilLFO.suDepthOnCC);
954 Units.add(&suFilLFO);
955 Units.add(&suFilLFO.suFadeEG);
956
957 for (int i = 0; i < EGs.size(); i++) {
958 Units.add(EGs[i]);
959 Units.add(&(EGs[i]->suAmpOnCC));
960 Units.add(&(EGs[i]->suVolOnCC));
961 Units.add(&(EGs[i]->suPitchOnCC));
962 Units.add(&(EGs[i]->suCutoffOnCC));
963 Units.add(&(EGs[i]->suResOnCC));
964 Units.add(&(EGs[i]->suPanOnCC));
965 }
966
967 for (int i = 0; i < LFOs.size(); i++) {
968 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
969 Units.add(LFOs[i]);
970 Units.add(&(LFOs[i]->suFadeEG));
971 Units.add(&(LFOs[i]->suVolOnCC));
972 Units.add(&(LFOs[i]->suPitchOnCC));
973 Units.add(&(LFOs[i]->suPanOnCC));
974 Units.add(&(LFOs[i]->suCutoffOnCC));
975 Units.add(&(LFOs[i]->suResOnCC));
976 }
977
978 Units.add(&suEndpoint);
979 Units.add(&suEndpoint.suXFInCC);
980 Units.add(&suEndpoint.suXFOutCC);
981 Units.add(&suEndpoint.suPanOnCC);
982
983 SignalUnitRack::Trigger();
984 }
985
986 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
987 return &suEndpoint;
988 }
989
990 void SfzSignalUnitRack::EnterFadeOutStage() {
991 suVolEG.EG.enterFadeOutStage();
992
993 for (int i = 0; i < volEGs.size(); i++) {
994 volEGs[i]->EG.enterFadeOutStage();
995 }
996 }
997
998 void SfzSignalUnitRack::Reset() {
999 suVolOnCC.RemoveAllCCs();
1000 suEndpoint.suXFInCC.RemoveAllCCs();
1001 suEndpoint.suXFOutCC.RemoveAllCCs();
1002 suEndpoint.suPanOnCC.RemoveAllCCs();
1003 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1004 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1005 suFilLFO.suDepthOnCC.RemoveAllCCs();
1006 suFilLFO.suFreqOnCC.RemoveAllCCs();
1007 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1008 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1009
1010 for (int i = 0; i < EGs.capacity(); i++) {
1011 EGs[i]->suAmpOnCC.RemoveAllCCs();
1012 EGs[i]->suVolOnCC.RemoveAllCCs();
1013 EGs[i]->suPitchOnCC.RemoveAllCCs();
1014 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1015 EGs[i]->suResOnCC.RemoveAllCCs();
1016 EGs[i]->suPanOnCC.RemoveAllCCs();
1017 }
1018
1019 for (int i = 0; i < LFOs.capacity(); i++) {
1020 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1021 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1022 LFOs[i]->suVolOnCC.RemoveAllCCs();
1023 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1024 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1025 LFOs[i]->suPanOnCC.RemoveAllCCs();
1026 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1027 LFOs[i]->suResOnCC.RemoveAllCCs();
1028 }
1029 }
1030
1031 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC