/[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 2297 - (show annotations) (download)
Fri Dec 9 15:04:55 2011 UTC (12 years, 4 months ago) by iliev
File size: 49514 byte(s)
* implemented opcodes delay, delay_onccN, delay_random,
  delay_samples, delay_samples_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 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 float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<float> >& cc) {
492 float f = 0;
493 for (int i = 0; i < 128; i++) {
494 if (cc[i]) {
495 f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
496 }
497 }
498 return f;
499 }
500
501 float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<int> >& cc) {
502 float f = 0;
503 for (int i = 0; i < 128; i++) {
504 if (cc[i]) {
505 f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
506 }
507 }
508 return f;
509 }
510
511 SfzSignalUnitRack* const EndpointUnit::GetRack() {
512 return static_cast<SfzSignalUnitRack* const>(pRack);
513 }
514
515 void EndpointUnit::Trigger() {
516 uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
517 if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
518
519 if (pVoice->pRegion->delay) {
520 /* here we use the device sample rate */
521 uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
522 }
523
524 if (pVoice->pRegion->delay_random) {
525 float r = pVoice->GetEngine()->Random();
526 uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
527 }
528
529 uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
530
531 float xfInVelCoeff = 1;
532
533 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
534 xfInVelCoeff = 0;
535 } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
536 xfInVelCoeff = 1;
537 } else {
538 float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
539 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
540 xfInVelCoeff = velPos / xfVelSize;
541 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
542 xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
543 }
544 }
545
546 float xfOutVelCoeff = 1;
547
548 if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
549 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
550 } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
551 xfOutVelCoeff = 1;
552 } else {
553 float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
554 float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
555 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
556 if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
557 xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
558 }
559 }
560
561 float xfInKeyCoeff = 1;
562
563 if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
564 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
565 } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
566 xfInKeyCoeff = 1;
567 } else {
568 float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
569 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
570 xfInKeyCoeff = keyPos / xfKeySize;
571 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
572 xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
573 }
574 }
575
576 float xfOutKeyCoeff = 1;
577
578 if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
579 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
580 } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
581 xfOutKeyCoeff = 1;
582 } else {
583 float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
584 float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
585 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
586 if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
587 xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
588 }
589 }
590
591 xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
592
593 suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
594 suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
595
596 suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
597
598 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
599 }
600
601 bool EndpointUnit::Active() {
602 if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
603 return false; // The key was released before the delay end, so the voice won't play at all.
604 }
605
606 if (GetRack()->suVolEG.Active()) return true;
607
608 bool b = false;
609 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
610 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
611 }
612
613 return b;
614 }
615
616 float EndpointUnit::GetVolume() {
617 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
618
619 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
620 EGv2Unit* eg = GetRack()->volEGs[i];
621 if (!eg->Active()) continue;
622
623 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
624 if (dB < -144) dB = eg->pEGInfo->volume;
625 else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
626
627 float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
628 amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
629
630 if (dB >= -144) {
631 if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
632 amp *= ToRatio(dB * 10.0);
633 }
634
635 vol += amp * eg->GetLevel();
636 }
637
638 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
639 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
640 float f = u2->Active() ? u2->GetLevel() : 0;
641 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
642
643 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
644
645 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
646 LFOv2Unit* lfo = GetRack()->volLFOs[i];
647 if (!lfo->Active()) continue;
648
649 float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
650 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
651 }
652
653 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
654 if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
655 return vol * xfCoeff;
656 }
657
658 float EndpointUnit::GetFilterCutoff() {
659 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660
661 FilLFOUnit* u = &(GetRack()->suFilLFO);
662 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663 float f = u1->Active() ? u1->GetLevel() : 0;
664 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
665
666 FilEGUnit* u2 = &(GetRack()->suFilEG);
667 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
668
669 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
670 EGv2Unit* eg = GetRack()->filEGs[i];
671 if (!eg->Active()) continue;
672
673 float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
674 f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
675 val *= RTMath::CentsToFreqRatioUnlimited(f);
676 }
677
678 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
679 LFOv2Unit* lfo = GetRack()->filLFOs[i];
680 if (!lfo->Active()) continue;
681
682 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
683 f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
684 val *= RTMath::CentsToFreqRatioUnlimited(f);
685 }
686
687 return val;
688 }
689
690 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691 cutoff *= GetFilterCutoff();
692 float maxCutoff = 0.49 * pVoice->GetSampleRate();
693 return cutoff > maxCutoff ? maxCutoff : cutoff;
694 }
695
696 float EndpointUnit::GetPitch() {
697 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698
699 EGv1Unit* u = &(GetRack()->suPitchEG);
700 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701
702 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
703 EGv2Unit* eg = GetRack()->pitchEGs[i];
704 if (!eg->Active()) continue;
705
706 float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
707 p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
708 }
709
710 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
711 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
712 float f = u3->Active() ? u3->GetLevel() : 0;
713 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
714
715 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
716 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
717 if (!lfo->Active()) continue;
718
719 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
720 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
721 }
722
723 return p * pitchVeltrackRatio;
724 }
725
726 float EndpointUnit::GetResonance() {
727 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
728
729 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
730 EGv2Unit* eg = GetRack()->resEGs[i];
731 if (!eg->Active()) continue;
732
733 float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
734 val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
735 }
736
737 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
738 LFOv2Unit* lfo = GetRack()->resLFOs[i];
739 if (!lfo->Active()) continue;
740
741 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
742 val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
743 }
744
745 return val;
746 }
747
748 float EndpointUnit::GetPan() {
749 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
750
751 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
752 EGv2Unit* eg = GetRack()->panEGs[i];
753 if (!eg->Active()) continue;
754
755 float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
756
757 if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
758 uint8_t val = eg->GetLevel() * 127;
759 if (val > 127) val = 127;
760 pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
761 } else {
762 pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
763 }
764 }
765
766 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
767 LFOv2Unit* lfo = GetRack()->panLFOs[i];
768 if (!lfo->Active()) continue;
769
770 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
771 pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772 }
773
774 if(pan < -100) return -100;
775 if(pan > 100) return 100;
776
777 return pan;
778 }
779
780
781 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
782 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
783 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
784 suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
785 suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
786 suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
787 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
788 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
789 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
790 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
791 {
792 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
793 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
794 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
795
796 suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
797 suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
798 suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
799
800 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
801 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
802 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
803 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
804
805 for (int i = 0; i < EGs.capacity(); i++) {
806 EGs[i] = new EGv2Unit(this);
807 EGs[i]->pVoice = voice;
808 EGs[i]->suAmpOnCC.pVoice = voice;
809 EGs[i]->suVolOnCC.pVoice = voice;
810 EGs[i]->suPitchOnCC.pVoice = voice;
811 EGs[i]->suCutoffOnCC.pVoice = voice;
812 EGs[i]->suResOnCC.pVoice = voice;
813 EGs[i]->suPanOnCC.pVoice = voice;
814 }
815
816 for (int i = 0; i < LFOs.capacity(); i++) {
817 LFOs[i] = new LFOv2Unit(this);
818 LFOs[i]->pVoice = voice;
819 LFOs[i]->suDepthOnCC.pVoice = voice;
820 LFOs[i]->suFreqOnCC.pVoice = voice;
821 LFOs[i]->suFadeEG.pVoice = voice;
822 LFOs[i]->suVolOnCC.pVoice = voice;
823 LFOs[i]->suPitchOnCC.pVoice = voice;
824 LFOs[i]->suFreqOnCC.pVoice = voice;
825 LFOs[i]->suPanOnCC.pVoice = voice;
826 LFOs[i]->suCutoffOnCC.pVoice = voice;
827 LFOs[i]->suResOnCC.pVoice = voice;
828 }
829 }
830
831 SfzSignalUnitRack::~SfzSignalUnitRack() {
832 for (int i = 0; i < EGs.capacity(); i++) {
833 delete EGs[i]; EGs[i] = NULL;
834 }
835
836 for (int i = 0; i < LFOs.capacity(); i++) {
837 delete LFOs[i]; LFOs[i] = NULL;
838 }
839 }
840
841 void SfzSignalUnitRack::InitRTLists() {
842 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
843 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
844
845 suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
846 suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
847 suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
848 suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
849 suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
850 suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
851 suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
852 suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
853 suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
854
855 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
856 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
857 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
858 suResOnCC.InitCCList(pCCPool, pSmootherPool);
859 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
860 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
861 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
862 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
863 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
864 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
865 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
866 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
867 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
868
869 for (int i = 0; i < EGs.capacity(); i++) {
870 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
871 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
874 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
875 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
876 }
877
878 for (int i = 0; i < LFOs.capacity(); i++) {
879 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
880 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
881 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
882 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
883 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
884 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
885 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
886 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
887 }
888 }
889
890 void SfzSignalUnitRack::Trigger() {
891 EGs.clear();
892 volEGs.clear();
893 pitchEGs.clear();
894 filEGs.clear();
895 resEGs.clear();
896 panEGs.clear();
897
898 LFOs.clear();
899 volLFOs.clear();
900 pitchLFOs.clear();
901 filLFOs.clear();
902 resLFOs.clear();
903 panLFOs.clear();
904
905 ::sfz::Region* const pRegion = pVoice->pRegion;
906
907 suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
908 suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
909 suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
910 suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
911 suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
912 suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
913 suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
914 suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
915 suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
916
917 bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
918 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
919
920 suVolOnCC.SetCCs(pRegion->volume_oncc);
921 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
922 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
923 suResOnCC.SetCCs(pRegion->resonance_oncc);
924
925 for (int i = 0; i < pRegion->eg.size(); i++) {
926 if (pRegion->eg[i].node.size() == 0) continue;
927
928 if(EGs.size() < EGs.capacity()) {
929 EGv2Unit eg(this);
930 eg.pEGInfo = &(pRegion->eg[i]);
931 EGs.increment()->Copy(eg);
932 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
933 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
934 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
935 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
936 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
937 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
938 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
939
940 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
941 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
942 ) {
943 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
944 else std::cerr << "Maximum number of EGs reached!" << std::endl;
945 }
946
947 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
948 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
949 else std::cerr << "Maximum number of EGs reached!" << std::endl;
950 }
951
952 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
953 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
954 else std::cerr << "Maximum number of EGs reached!" << std::endl;
955 }
956
957 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
958 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
959 else std::cerr << "Maximum number of EGs reached!" << std::endl;
960 }
961
962 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
963 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
964 else std::cerr << "Maximum number of EGs reached!" << std::endl;
965 }
966 }
967
968 if (pRegion->ampeg_sustain == -1) {
969 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
970 else pRegion->ampeg_sustain = 100;
971 }
972
973 // LFO
974 for (int i = 0; i < pRegion->lfos.size(); i++) {
975 if (pRegion->lfos[i].freq <= 0) {
976 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
977 else pRegion->lfos[i].freq = 0;
978 }
979
980 if(LFOs.size() < LFOs.capacity()) {
981 LFOv2Unit lfo(this);
982 lfo.pLfoInfo = &(pRegion->lfos[i]);
983 LFOs.increment()->Copy(lfo);
984 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
985 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
986 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
987 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
988 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
989 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
990 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
991
992 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
993 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
994 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
995 }
996
997 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
998 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
999 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1000 }
1001
1002 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1003 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1004 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1005 }
1006
1007 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1008 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1009 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1010 }
1011
1012 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1013 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1014 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1015 }
1016 }
1017
1018 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1019 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1020
1021 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1022 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1023
1024 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1025 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1026
1027 Units.clear();
1028
1029 Units.add(&suEq1GainOnCC);
1030 Units.add(&suEq2GainOnCC);
1031 Units.add(&suEq3GainOnCC);
1032 Units.add(&suEq1FreqOnCC);
1033 Units.add(&suEq2FreqOnCC);
1034 Units.add(&suEq3FreqOnCC);
1035 Units.add(&suEq1BwOnCC);
1036 Units.add(&suEq2BwOnCC);
1037 Units.add(&suEq3BwOnCC);
1038
1039 Units.add(&suVolOnCC);
1040 Units.add(&suPitchOnCC);
1041 Units.add(&suCutoffOnCC);
1042 Units.add(&suResOnCC);
1043
1044 Units.add(&suVolEG);
1045 Units.add(&suFilEG);
1046 Units.add(&suPitchEG);
1047
1048 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1049 Units.add(&suPitchLFO);
1050 Units.add(&suPitchLFO.suDepthOnCC);
1051 Units.add(&suPitchLFO.suFadeEG);
1052
1053 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1054 Units.add(&suAmpLFO.suDepthOnCC);
1055 Units.add(&suAmpLFO);
1056 Units.add(&suAmpLFO.suFadeEG);
1057
1058 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1059 Units.add(&suFilLFO.suDepthOnCC);
1060 Units.add(&suFilLFO);
1061 Units.add(&suFilLFO.suFadeEG);
1062
1063 for (int i = 0; i < EGs.size(); i++) {
1064 Units.add(EGs[i]);
1065 Units.add(&(EGs[i]->suAmpOnCC));
1066 Units.add(&(EGs[i]->suVolOnCC));
1067 Units.add(&(EGs[i]->suPitchOnCC));
1068 Units.add(&(EGs[i]->suCutoffOnCC));
1069 Units.add(&(EGs[i]->suResOnCC));
1070 Units.add(&(EGs[i]->suPanOnCC));
1071 }
1072
1073 for (int i = 0; i < LFOs.size(); i++) {
1074 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1075 Units.add(LFOs[i]);
1076 Units.add(&(LFOs[i]->suFadeEG));
1077 Units.add(&(LFOs[i]->suVolOnCC));
1078 Units.add(&(LFOs[i]->suPitchOnCC));
1079 Units.add(&(LFOs[i]->suPanOnCC));
1080 Units.add(&(LFOs[i]->suCutoffOnCC));
1081 Units.add(&(LFOs[i]->suResOnCC));
1082 }
1083
1084 Units.add(&suEndpoint);
1085 Units.add(&suEndpoint.suXFInCC);
1086 Units.add(&suEndpoint.suXFOutCC);
1087 Units.add(&suEndpoint.suPanOnCC);
1088
1089 SignalUnitRack::Trigger();
1090 }
1091
1092 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1093 return &suEndpoint;
1094 }
1095
1096 void SfzSignalUnitRack::EnterFadeOutStage() {
1097 suVolEG.EG.enterFadeOutStage();
1098
1099 for (int i = 0; i < volEGs.size(); i++) {
1100 volEGs[i]->EG.enterFadeOutStage();
1101 }
1102 }
1103
1104 void SfzSignalUnitRack::Reset() {
1105 suEq1GainOnCC.RemoveAllCCs();
1106 suEq2GainOnCC.RemoveAllCCs();
1107 suEq3GainOnCC.RemoveAllCCs();
1108 suEq1FreqOnCC.RemoveAllCCs();
1109 suEq2FreqOnCC.RemoveAllCCs();
1110 suEq3FreqOnCC.RemoveAllCCs();
1111 suEq1BwOnCC.RemoveAllCCs();
1112 suEq2BwOnCC.RemoveAllCCs();
1113 suEq3BwOnCC.RemoveAllCCs();
1114
1115 suVolOnCC.RemoveAllCCs();
1116 suPitchOnCC.RemoveAllCCs();
1117 suCutoffOnCC.RemoveAllCCs();
1118 suResOnCC.RemoveAllCCs();
1119 suEndpoint.suXFInCC.RemoveAllCCs();
1120 suEndpoint.suXFOutCC.RemoveAllCCs();
1121 suEndpoint.suPanOnCC.RemoveAllCCs();
1122 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1123 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1124 suFilLFO.suDepthOnCC.RemoveAllCCs();
1125 suFilLFO.suFreqOnCC.RemoveAllCCs();
1126 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1127 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1128
1129 for (int i = 0; i < EGs.capacity(); i++) {
1130 EGs[i]->suAmpOnCC.RemoveAllCCs();
1131 EGs[i]->suVolOnCC.RemoveAllCCs();
1132 EGs[i]->suPitchOnCC.RemoveAllCCs();
1133 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1134 EGs[i]->suResOnCC.RemoveAllCCs();
1135 EGs[i]->suPanOnCC.RemoveAllCCs();
1136 }
1137
1138 for (int i = 0; i < LFOs.capacity(); i++) {
1139 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1140 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1141 LFOs[i]->suVolOnCC.RemoveAllCCs();
1142 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1143 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1144 LFOs[i]->suPanOnCC.RemoveAllCCs();
1145 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1146 LFOs[i]->suResOnCC.RemoveAllCCs();
1147 }
1148 }
1149
1150 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1151 if (!pEqSupport->HasSupport()) return;
1152 if (pEqSupport->GetBandCount() < 3) {
1153 std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1154 return;
1155 }
1156
1157 ::sfz::Region* const pRegion = pVoice->pRegion;
1158
1159 float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1160 pEqSupport->SetGain(0, dB);
1161
1162 dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1163 pEqSupport->SetGain(1, dB);
1164
1165 dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1166 pEqSupport->SetGain(2, dB);
1167
1168 float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1169 pEqSupport->SetFreq(0, freq);
1170
1171 freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1172 pEqSupport->SetFreq(1, freq);
1173
1174 freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1175 pEqSupport->SetFreq(2, freq);
1176
1177 float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1178 pEqSupport->SetBandwidth(0, bw);
1179
1180 bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1181 pEqSupport->SetBandwidth(1, bw);
1182
1183 bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1184 pEqSupport->SetBandwidth(2, bw);
1185 }
1186
1187 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC