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

  ViewVC Help
Powered by ViewVC