/[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 2249 - (show annotations) (download)
Fri Aug 19 18:29:29 2011 UTC (12 years, 7 months ago) by iliev
File size: 41870 byte(s)
* sfz engine: implemented opcodes fileg_delay_onccN,
  fileg_start_onccN, fileg_attack_onccN, fileg_hold_onccN,
  fileg_decay_onccN, fileg_sustain_onccN, fileg_release_onccN,
  fileg_depth_onccN, pitcheg_delay_onccN, pitcheg_start_onccN,
  pitcheg_attack_onccN, pitcheg_hold_onccN, pitcheg_decay_onccN,
  pitcheg_sustain_onccN, pitcheg_release_onccN, pitcheg_depth_onccN

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

  ViewVC Help
Powered by ViewVC