/[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 2296 - (show annotations) (download)
Thu Dec 8 20:03:47 2011 UTC (12 years, 4 months ago) by iliev
File size: 48015 byte(s)
* fixed crash when trying to create an effect instance with controls
  which min and/or max values depend on the sample rate
* experimental support for per voice equalization (work in progress)
* sfz engine: implemented opcodes eq1_freq, eq2_freq, eq3_freq,
  eq1_freqccN, eq2_freqccN, eq3_freqccN, eq1_bw, eq2_bw, eq3_bw,
  eq1_bwccN, eq2_bwccN, eq3_bwccN, eq1_gain, eq2_gain, eq3_gain,
  eq1_gainccN, eq2_gainccN, eq3_gainccN

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2011 Grigor Iliev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "SfzSignalUnitRack.h"
24 #include "Engine.h"
25
26 #define _200TH_ROOT_OF_10 1.011579454259899
27
28 namespace LinuxSampler { namespace sfz {
29
30 double ToRatio(int Centibels) {
31 if (Centibels == 0) return 1.0;
32 return pow(_200TH_ROOT_OF_10, Centibels);
33 }
34
35 SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36
37 }
38
39 double SfzSignalUnit::GetSampleRate() {
40 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41 }
42
43 float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44 float f = 0;
45 for (int i = 0; i < cc.size(); i++) {
46 int val = pVoice->GetControllerValue(cc[i].Controller);
47 f += (val / 127.0f) * cc[i].Influence;
48 }
49 return f;
50 }
51
52 void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53 RemoveAllCCs();
54
55 for (int cc = 0; cc < 128; cc++) {
56 if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57 int i = loCCs[cc];
58 int j = hiCCs[cc];
59 if (j == 0) j = 127;
60 i += j << 8; // workaround to keep both values in the Influence parameter
61 AddCC(cc, i);
62 }
63 }
64
65 void XFInCCUnit::Calculate() {
66 float l = 1;
67
68 RTList<CC>::Iterator ctrl = pCtrls->first();
69 RTList<CC>::Iterator end = pCtrls->end();
70 for(; ctrl != end; ++ctrl) {
71 float c = 1;
72 int influence = (*ctrl).Influence;
73 int lo = influence & 0xff;
74 int hi = influence >> 8;
75 if ((*ctrl).Value <= lo) {
76 c = 0;
77 } else if ((*ctrl).Value >= hi) {
78 c = 1;
79 } else {
80 float xfVelSize = hi - lo;
81 float velPos = (*ctrl).Value - lo;
82 c = velPos / xfVelSize;
83 if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84 c = sin(c * M_PI / 2.0);
85 }
86 }
87
88 l *= c;
89 }
90
91 if (Level != l) {
92 Level = l;
93 if (pListener != NULL) pListener->ValueChanged(this);
94 }
95 }
96
97
98 void XFOutCCUnit::Calculate() {
99 float l = 1;
100
101 RTList<CC>::Iterator ctrl = pCtrls->first();
102 RTList<CC>::Iterator end = pCtrls->end();
103 for(; ctrl != end; ++ctrl) {
104 float c = 1;
105 int influence = (*ctrl).Influence;
106 int lo = influence & 0xff;
107 int hi = influence >> 8;
108 if ((*ctrl).Value >= hi) {
109 c = 0;
110 } else if ((*ctrl).Value <= lo) {
111 c = 1;
112 } else {
113 float xfVelSize = hi - lo;
114 float velPos = (*ctrl).Value - lo;
115 c = 1.0f - velPos / xfVelSize;
116 if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117 c = sin(c * M_PI / 2.0);
118 }
119 }
120
121 l *= c;
122 }
123
124 if (Level != l) {
125 Level = l;
126 if (pListener != NULL) pListener->ValueChanged(this);
127 }
128 }
129
130
131 EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132 : EGUnit< ::LinuxSampler::sfz::EG>(rack), suAmpOnCC(rack), suVolOnCC(rack),
133 suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134 { }
135
136 void EGv2Unit::Trigger() {
137 egInfo = *pEGInfo;
138 for (int i = 0; i < egInfo.node.size(); i++) {
139 float f = GetInfluence(egInfo.node[i].level_oncc);
140 egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
141
142 f = GetInfluence(egInfo.node[i].time_oncc);
143 egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144 }
145 EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity);
146 }
147
148
149 void PitchEGUnit::Trigger() {
150 ::sfz::Region* const pRegion = pVoice->pRegion;
151 depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152
153 // the length of the decay and release curves are dependent on the velocity
154 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
155
156 // set the delay trigger
157 float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158 delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159 uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160
161 float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162
163 float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164 attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165
166 float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167 hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168
169 float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170 decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171
172 float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173 sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174
175 float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176 release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177
178 EG.trigger (
179 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181 );
182 }
183
184
185 void FilEGUnit::Trigger() {
186 ::sfz::Region* const pRegion = pVoice->pRegion;
187 depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188
189 // the length of the decay and release curves are dependent on the velocity
190 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191
192 // set the delay trigger
193 float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194 delay += GetInfluence(pRegion->fileg_delay_oncc);
195 uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196
197 float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198
199 float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200 attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201
202 float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203 hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204
205 float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206 decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207
208 float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209 sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210
211 float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212 release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213
214 EG.trigger (
215 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217 );
218 }
219
220
221 void AmpEGUnit::Trigger() {
222 ::sfz::Region* const pRegion = pVoice->pRegion;
223
224 // the length of the decay and release curves are dependent on the velocity
225 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226
227 // set the delay trigger
228 float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229 delay += GetInfluence(pRegion->ampeg_delaycc);
230 uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231
232 float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233
234 float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235 attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236
237 float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238 hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239
240 float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241 decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242
243 float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244 sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245
246 float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247 release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248
249 EG.trigger (
250 uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252 );
253 }
254
255
256 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257 : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258 suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259 { }
260
261 LFOUnit::LFOUnit(const LFOUnit& Unit)
262 : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263 suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264 suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265 {
266 Copy(Unit);
267 }
268
269 void LFOUnit::Increment() {
270 if (DelayStage()) return;
271
272 SignalUnit::Increment();
273
274 Level = pLFO->Render();
275 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276 }
277
278 void LFOUnit::Trigger() {
279 //reset
280 Level = 0;
281
282 // set the delay trigger
283 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
284 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285 float f = pLfoInfo->fade;
286 f += GetInfluence(pLfoInfo->fade_oncc);
287
288 if (f != 0) {
289 suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
291 }
292 }
293 }
294
295 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296 if (pLFO == NULL) return;
297 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298 }
299
300
301 void LFOv1Unit::Trigger() {
302 LFOUnit::Trigger();
303
304 lfo.trigger (
305 pLfoInfo->freq + suFreqOnCC.GetLevel(),
306 start_level_mid,
307 1, 0, false, GetSampleRate()
308 );
309 lfo.update(0);
310 }
311
312
313 LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314 : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317 {
318 lfos.add(&lfo0);
319 lfos.add(&lfo1);
320 lfos.add(&lfo2);
321 lfos.add(&lfo3);
322 lfos.add(&lfo4);
323 lfos.add(&lfo5);
324 lfos.add(&lfo6);
325 lfos.add(&lfo7);
326 }
327
328 void LFOv2Unit::Trigger() {
329 LFOUnit::Trigger();
330
331 if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332 else pLFO = lfos[pLfoInfo->wave];
333
334 pLFO->Trigger (
335 pLfoInfo->freq + suFreqOnCC.GetLevel(),
336 start_level_mid,
337 1, 0, false, GetSampleRate()
338 );
339 pLFO->Update(0);
340
341 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
342 if (phase != 0) pLFO->SetPhase(phase);
343 }
344
345 void AmpLFOUnit::Trigger() {
346 bActive = true;
347 ::sfz::Region* const pRegion = pVoice->pRegion;
348 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349 pLfoInfo->freq = pRegion->amplfo_freq;
350 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351 pLfoInfo->volume = pRegion->amplfo_depth;
352
353 if (pLfoInfo->freq <= 0) {
354 if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
355 else bActive = false;
356 }
357
358 LFOv1Unit::Trigger();
359 }
360
361 void PitchLFOUnit::Trigger() {
362 bActive = true;
363 ::sfz::Region* const pRegion = pVoice->pRegion;
364 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365 pLfoInfo->freq = pRegion->pitchlfo_freq;
366 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367 pLfoInfo->pitch = pRegion->pitchlfo_depth;
368
369 if (pLfoInfo->freq <= 0) {
370 if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
371 else bActive = false;
372 }
373
374 LFOv1Unit::Trigger();
375 }
376
377 void FilLFOUnit::Trigger() {
378 bActive = true;
379 ::sfz::Region* const pRegion = pVoice->pRegion;
380 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381 pLfoInfo->freq = pRegion->fillfo_freq;
382 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383 pLfoInfo->cutoff = pRegion->fillfo_depth;
384
385 if (pLfoInfo->freq <= 0) {
386 if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
387 else bActive = false;
388 }
389
390 LFOv1Unit::Trigger();
391 }
392
393 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
394 pVoice = NULL;
395 }
396
397 void CCUnit::Trigger() {
398 RTList<CC>::Iterator ctrl = pCtrls->first();
399 RTList<CC>::Iterator end = pCtrls->end();
400 for(; ctrl != end; ++ctrl) {
401 (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402 if ((*ctrl).pSmoother != NULL) {
403 if ((*ctrl).Step > 0) {
404 float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405 (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406 } else {
407 (*ctrl).pSmoother->setValue((*ctrl).Value);
408 }
409 }
410 }
411 CCSignalUnit::Trigger();
412 }
413
414 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415 RemoveAllCCs();
416 for (int i = 0; i < 128; i++) {
417 if (cc[i] != 0) AddCC(i, cc[i]);
418 }
419 }
420
421 void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422 RemoveAllCCs();
423 for (int i = 0; i < 128; i++) {
424 if (cc[i] != 0) AddCC(i, cc[i]);
425 }
426 }
427
428 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
429 RemoveAllCCs();
430 for (int i = 0; i < cc.size(); i++) {
431 if (cc[i].Influence != 0) {
432 short int curve = cc[i].Curve;
433 if (curve >= GetCurveCount()) curve = -1;
434 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435 }
436 }
437 }
438
439 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440 AddCC(Controller, Influence, Curve, NULL, Step);
441 }
442
443 int CCUnit::GetCurveCount() {
444 return pVoice->pRegion->GetInstrument()->curves.size();
445 }
446
447 ::sfz::Curve* CCUnit::GetCurve(int idx) {
448 return &pVoice->pRegion->GetInstrument()->curves[idx];
449 }
450
451 double CCUnit::GetSampleRate() {
452 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
453 }
454
455
456 SmoothCCUnit::~SmoothCCUnit() {
457 if (pSmoothers != NULL) delete pSmoothers;
458 }
459
460 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461 if (Smooth > 0) {
462 if (pSmoothers->poolIsEmpty()) {
463 std::cerr << "Maximum number of smoothers reached" << std::endl;
464 return;
465 }
466 Smoother* smoother = &(*(pSmoothers->allocAppend()));
467 smoother->trigger(Smooth / 1000.0f, GetSampleRate());
468 AddCC(Controller, Influence, Curve, smoother, Step);
469 } else {
470 AddCC(Controller, Influence, Curve, NULL, Step);
471 }
472 }
473
474 void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
475 if (pSmoothers != NULL) delete pSmoothers;
476 pSmoothers = new RTList<Smoother>(pSmootherPool);
477 }
478
479 void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
480 CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
481 InitSmoothers(pSmootherPool);
482 }
483
484
485 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486 : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
487 {
488
489 }
490
491 SfzSignalUnitRack* const EndpointUnit::GetRack() {
492 return static_cast<SfzSignalUnitRack* const>(pRack);
493 }
494
495 void EndpointUnit::Trigger() {
496 float xfInVelCoeff = 1;
497
498 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
499 xfInVelCoeff = 0;
500 } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
501 xfInVelCoeff = 1;
502 } else {
503 float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
504 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
505 xfInVelCoeff = velPos / xfVelSize;
506 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
507 xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
508 }
509 }
510
511 float xfOutVelCoeff = 1;
512
513 if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
514 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
515 } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
516 xfOutVelCoeff = 1;
517 } else {
518 float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
519 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
520 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
521 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
522 xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
523 }
524 }
525
526 float xfInKeyCoeff = 1;
527
528 if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
529 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
530 } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
531 xfInKeyCoeff = 1;
532 } else {
533 float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
534 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
535 xfInKeyCoeff = keyPos / xfKeySize;
536 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
537 xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
538 }
539 }
540
541 float xfOutKeyCoeff = 1;
542
543 if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
544 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
545 } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
546 xfOutKeyCoeff = 1;
547 } else {
548 float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
549 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
550 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
551 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
552 xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
553 }
554 }
555
556 xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
557
558 suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
559 suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
560
561 suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
562
563 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
564 }
565
566 bool EndpointUnit::Active() {
567 if (GetRack()->suVolEG.Active()) return true;
568
569 bool b = false;
570 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
571 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
572 }
573
574 return b;
575 }
576
577 float EndpointUnit::GetVolume() {
578 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
579
580 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
581 EGv2Unit* eg = GetRack()->volEGs[i];
582 if (!eg->Active()) continue;
583
584 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
585 if (dB < -144) dB = eg->pEGInfo->volume;
586 else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
587
588 float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
589 amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
590
591 if (dB >= -144) {
592 if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
593 amp *= ToRatio(dB * 10.0);
594 }
595
596 vol += amp * eg->GetLevel();
597 }
598
599 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
600 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
601 float f = u2->Active() ? u2->GetLevel() : 0;
602 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
603
604 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
605
606 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
607 LFOv2Unit* lfo = GetRack()->volLFOs[i];
608 if (!lfo->Active()) continue;
609
610 float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
611 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
612 }
613
614 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
615 if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
616 return vol * xfCoeff;
617 }
618
619 float EndpointUnit::GetFilterCutoff() {
620 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
621
622 FilLFOUnit* u = &(GetRack()->suFilLFO);
623 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
624 float f = u1->Active() ? u1->GetLevel() : 0;
625 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
626
627 FilEGUnit* u2 = &(GetRack()->suFilEG);
628 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
629
630 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
631 EGv2Unit* eg = GetRack()->filEGs[i];
632 if (!eg->Active()) continue;
633
634 float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
635 f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
636 val *= RTMath::CentsToFreqRatioUnlimited(f);
637 }
638
639 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
640 LFOv2Unit* lfo = GetRack()->filLFOs[i];
641 if (!lfo->Active()) continue;
642
643 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
644 f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
645 val *= RTMath::CentsToFreqRatioUnlimited(f);
646 }
647
648 return val;
649 }
650
651 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
652 cutoff *= GetFilterCutoff();
653 float maxCutoff = 0.49 * pVoice->GetSampleRate();
654 return cutoff > maxCutoff ? maxCutoff : cutoff;
655 }
656
657 float EndpointUnit::GetPitch() {
658 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
659
660 EGv1Unit* u = &(GetRack()->suPitchEG);
661 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
662
663 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
664 EGv2Unit* eg = GetRack()->pitchEGs[i];
665 if (!eg->Active()) continue;
666
667 float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
668 p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
669 }
670
671 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
672 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
673 float f = u3->Active() ? u3->GetLevel() : 0;
674 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
675
676 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
677 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
678 if (!lfo->Active()) continue;
679
680 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
681 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
682 }
683
684 return p * pitchVeltrackRatio;
685 }
686
687 float EndpointUnit::GetResonance() {
688 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
689
690 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
691 EGv2Unit* eg = GetRack()->resEGs[i];
692 if (!eg->Active()) continue;
693
694 float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
695 val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
696 }
697
698 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
699 LFOv2Unit* lfo = GetRack()->resLFOs[i];
700 if (!lfo->Active()) continue;
701
702 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
703 val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
704 }
705
706 return val;
707 }
708
709 float EndpointUnit::GetPan() {
710 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
711
712 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
713 EGv2Unit* eg = GetRack()->panEGs[i];
714 if (!eg->Active()) continue;
715
716 float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
717
718 if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
719 uint8_t val = eg->GetLevel() * 127;
720 if (val > 127) val = 127;
721 pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
722 } else {
723 pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
724 }
725 }
726
727 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
728 LFOv2Unit* lfo = GetRack()->panLFOs[i];
729 if (!lfo->Active()) continue;
730
731 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
732 pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
733 }
734
735 if(pan < -100) return -100;
736 if(pan > 100) return 100;
737
738 return pan;
739 }
740
741
742 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
743 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
744 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
745 suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
746 suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
747 suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
748 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
749 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
750 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
751 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
752 {
753 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
754 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
755 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
756
757 suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
758 suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
759 suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
760
761 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
762 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
763 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
764 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
765
766 for (int i = 0; i < EGs.capacity(); i++) {
767 EGs[i] = new EGv2Unit(this);
768 EGs[i]->pVoice = voice;
769 EGs[i]->suAmpOnCC.pVoice = voice;
770 EGs[i]->suVolOnCC.pVoice = voice;
771 EGs[i]->suPitchOnCC.pVoice = voice;
772 EGs[i]->suCutoffOnCC.pVoice = voice;
773 EGs[i]->suResOnCC.pVoice = voice;
774 EGs[i]->suPanOnCC.pVoice = voice;
775 }
776
777 for (int i = 0; i < LFOs.capacity(); i++) {
778 LFOs[i] = new LFOv2Unit(this);
779 LFOs[i]->pVoice = voice;
780 LFOs[i]->suDepthOnCC.pVoice = voice;
781 LFOs[i]->suFreqOnCC.pVoice = voice;
782 LFOs[i]->suFadeEG.pVoice = voice;
783 LFOs[i]->suVolOnCC.pVoice = voice;
784 LFOs[i]->suPitchOnCC.pVoice = voice;
785 LFOs[i]->suFreqOnCC.pVoice = voice;
786 LFOs[i]->suPanOnCC.pVoice = voice;
787 LFOs[i]->suCutoffOnCC.pVoice = voice;
788 LFOs[i]->suResOnCC.pVoice = voice;
789 }
790 }
791
792 SfzSignalUnitRack::~SfzSignalUnitRack() {
793 for (int i = 0; i < EGs.capacity(); i++) {
794 delete EGs[i]; EGs[i] = NULL;
795 }
796
797 for (int i = 0; i < LFOs.capacity(); i++) {
798 delete LFOs[i]; LFOs[i] = NULL;
799 }
800 }
801
802 void SfzSignalUnitRack::InitRTLists() {
803 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
804 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
805
806 suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
807 suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
808 suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
809 suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
810 suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
811 suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
812 suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
813 suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
814 suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
815
816 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
817 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
818 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
819 suResOnCC.InitCCList(pCCPool, pSmootherPool);
820 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
821 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
822 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
823 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
824 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
825 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
826 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
827 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
828 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
829
830 for (int i = 0; i < EGs.capacity(); i++) {
831 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
832 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
833 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
834 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
835 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
836 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
837 }
838
839 for (int i = 0; i < LFOs.capacity(); i++) {
840 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
841 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
842 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
843 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
844 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
845 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
846 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
848 }
849 }
850
851 void SfzSignalUnitRack::Trigger() {
852 EGs.clear();
853 volEGs.clear();
854 pitchEGs.clear();
855 filEGs.clear();
856 resEGs.clear();
857 panEGs.clear();
858
859 LFOs.clear();
860 volLFOs.clear();
861 pitchLFOs.clear();
862 filLFOs.clear();
863 resLFOs.clear();
864 panLFOs.clear();
865
866 ::sfz::Region* const pRegion = pVoice->pRegion;
867
868 suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
869 suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
870 suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
871 suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
872 suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
873 suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
874 suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
875 suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
876 suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
877
878 bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
879 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
880
881 suVolOnCC.SetCCs(pRegion->volume_oncc);
882 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
883 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
884 suResOnCC.SetCCs(pRegion->resonance_oncc);
885
886 for (int i = 0; i < pRegion->eg.size(); i++) {
887 if (pRegion->eg[i].node.size() == 0) continue;
888
889 if(EGs.size() < EGs.capacity()) {
890 EGv2Unit eg(this);
891 eg.pEGInfo = &(pRegion->eg[i]);
892 EGs.increment()->Copy(eg);
893 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
894 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
895 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
896 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
897 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
898 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
899 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
900
901 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
902 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
903 ) {
904 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
905 else std::cerr << "Maximum number of EGs reached!" << std::endl;
906 }
907
908 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
909 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
910 else std::cerr << "Maximum number of EGs reached!" << std::endl;
911 }
912
913 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
914 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
915 else std::cerr << "Maximum number of EGs reached!" << std::endl;
916 }
917
918 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
919 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
920 else std::cerr << "Maximum number of EGs reached!" << std::endl;
921 }
922
923 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
924 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
925 else std::cerr << "Maximum number of EGs reached!" << std::endl;
926 }
927 }
928
929 if (pRegion->ampeg_sustain == -1) {
930 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
931 else pRegion->ampeg_sustain = 100;
932 }
933
934 // LFO
935 for (int i = 0; i < pRegion->lfos.size(); i++) {
936 if (pRegion->lfos[i].freq <= 0) {
937 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
938 else pRegion->lfos[i].freq = 0;
939 }
940
941 if(LFOs.size() < LFOs.capacity()) {
942 LFOv2Unit lfo(this);
943 lfo.pLfoInfo = &(pRegion->lfos[i]);
944 LFOs.increment()->Copy(lfo);
945 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
946 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
947 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
948 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
949 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
950 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
951 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
952
953 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
954 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
955 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
956 }
957
958 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
959 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
960 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
961 }
962
963 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
964 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
965 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
966 }
967
968 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
969 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
970 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
971 }
972
973 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
974 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
975 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
976 }
977 }
978
979 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
980 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
981
982 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
983 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
984
985 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
986 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
987
988 Units.clear();
989
990 Units.add(&suEq1GainOnCC);
991 Units.add(&suEq2GainOnCC);
992 Units.add(&suEq3GainOnCC);
993 Units.add(&suEq1FreqOnCC);
994 Units.add(&suEq2FreqOnCC);
995 Units.add(&suEq3FreqOnCC);
996 Units.add(&suEq1BwOnCC);
997 Units.add(&suEq2BwOnCC);
998 Units.add(&suEq3BwOnCC);
999
1000 Units.add(&suVolOnCC);
1001 Units.add(&suPitchOnCC);
1002 Units.add(&suCutoffOnCC);
1003 Units.add(&suResOnCC);
1004
1005 Units.add(&suVolEG);
1006 Units.add(&suFilEG);
1007 Units.add(&suPitchEG);
1008
1009 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1010 Units.add(&suPitchLFO);
1011 Units.add(&suPitchLFO.suDepthOnCC);
1012 Units.add(&suPitchLFO.suFadeEG);
1013
1014 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1015 Units.add(&suAmpLFO.suDepthOnCC);
1016 Units.add(&suAmpLFO);
1017 Units.add(&suAmpLFO.suFadeEG);
1018
1019 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1020 Units.add(&suFilLFO.suDepthOnCC);
1021 Units.add(&suFilLFO);
1022 Units.add(&suFilLFO.suFadeEG);
1023
1024 for (int i = 0; i < EGs.size(); i++) {
1025 Units.add(EGs[i]);
1026 Units.add(&(EGs[i]->suAmpOnCC));
1027 Units.add(&(EGs[i]->suVolOnCC));
1028 Units.add(&(EGs[i]->suPitchOnCC));
1029 Units.add(&(EGs[i]->suCutoffOnCC));
1030 Units.add(&(EGs[i]->suResOnCC));
1031 Units.add(&(EGs[i]->suPanOnCC));
1032 }
1033
1034 for (int i = 0; i < LFOs.size(); i++) {
1035 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1036 Units.add(LFOs[i]);
1037 Units.add(&(LFOs[i]->suFadeEG));
1038 Units.add(&(LFOs[i]->suVolOnCC));
1039 Units.add(&(LFOs[i]->suPitchOnCC));
1040 Units.add(&(LFOs[i]->suPanOnCC));
1041 Units.add(&(LFOs[i]->suCutoffOnCC));
1042 Units.add(&(LFOs[i]->suResOnCC));
1043 }
1044
1045 Units.add(&suEndpoint);
1046 Units.add(&suEndpoint.suXFInCC);
1047 Units.add(&suEndpoint.suXFOutCC);
1048 Units.add(&suEndpoint.suPanOnCC);
1049
1050 SignalUnitRack::Trigger();
1051 }
1052
1053 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1054 return &suEndpoint;
1055 }
1056
1057 void SfzSignalUnitRack::EnterFadeOutStage() {
1058 suVolEG.EG.enterFadeOutStage();
1059
1060 for (int i = 0; i < volEGs.size(); i++) {
1061 volEGs[i]->EG.enterFadeOutStage();
1062 }
1063 }
1064
1065 void SfzSignalUnitRack::Reset() {
1066 suEq1GainOnCC.RemoveAllCCs();
1067 suEq2GainOnCC.RemoveAllCCs();
1068 suEq3GainOnCC.RemoveAllCCs();
1069 suEq1FreqOnCC.RemoveAllCCs();
1070 suEq2FreqOnCC.RemoveAllCCs();
1071 suEq3FreqOnCC.RemoveAllCCs();
1072 suEq1BwOnCC.RemoveAllCCs();
1073 suEq2BwOnCC.RemoveAllCCs();
1074 suEq3BwOnCC.RemoveAllCCs();
1075
1076 suVolOnCC.RemoveAllCCs();
1077 suPitchOnCC.RemoveAllCCs();
1078 suCutoffOnCC.RemoveAllCCs();
1079 suResOnCC.RemoveAllCCs();
1080 suEndpoint.suXFInCC.RemoveAllCCs();
1081 suEndpoint.suXFOutCC.RemoveAllCCs();
1082 suEndpoint.suPanOnCC.RemoveAllCCs();
1083 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1084 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1085 suFilLFO.suDepthOnCC.RemoveAllCCs();
1086 suFilLFO.suFreqOnCC.RemoveAllCCs();
1087 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1088 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1089
1090 for (int i = 0; i < EGs.capacity(); i++) {
1091 EGs[i]->suAmpOnCC.RemoveAllCCs();
1092 EGs[i]->suVolOnCC.RemoveAllCCs();
1093 EGs[i]->suPitchOnCC.RemoveAllCCs();
1094 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1095 EGs[i]->suResOnCC.RemoveAllCCs();
1096 EGs[i]->suPanOnCC.RemoveAllCCs();
1097 }
1098
1099 for (int i = 0; i < LFOs.capacity(); i++) {
1100 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1101 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1102 LFOs[i]->suVolOnCC.RemoveAllCCs();
1103 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1104 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1105 LFOs[i]->suPanOnCC.RemoveAllCCs();
1106 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1107 LFOs[i]->suResOnCC.RemoveAllCCs();
1108 }
1109 }
1110
1111 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1112 if (!pEqSupport->HasSupport()) return;
1113 if (pEqSupport->GetBandCount() < 3) {
1114 std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1115 return;
1116 }
1117
1118 ::sfz::Region* const pRegion = pVoice->pRegion;
1119
1120 float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1121 pEqSupport->SetGain(0, dB);
1122
1123 dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1124 pEqSupport->SetGain(1, dB);
1125
1126 dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1127 pEqSupport->SetGain(2, dB);
1128
1129 float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1130 pEqSupport->SetFreq(0, freq);
1131
1132 freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1133 pEqSupport->SetFreq(1, freq);
1134
1135 freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1136 pEqSupport->SetFreq(2, freq);
1137
1138 float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1139 pEqSupport->SetBandwidth(0, bw);
1140
1141 bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1142 pEqSupport->SetBandwidth(1, bw);
1143
1144 bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1145 pEqSupport->SetBandwidth(2, bw);
1146 }
1147
1148 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC