/[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 2299 - (show annotations) (download)
Sun Dec 11 20:50:31 2011 UTC (12 years, 3 months ago) by iliev
File size: 56066 byte(s)
* implemented opcodes egN_eq1gain, egN_eq2gain, egN_eq3gain,
  egN_eq1gain_onccX, egN_eq2gain_onccX, egN_eq3gain_onccX, egN_eq1freq,
  egN_eq2freq, egN_eq3freq, egN_eq1freq_onccX, egN_eq2freq_onccX,
  egN_eq3freq_onccX, egN_eq1bw, egN_eq2bw, egN_eq3bw, egN_eq1bw_onccX,
  egN_eq2bw_onccX, egN_eq3bw_onccX, lfoN_eq1gain, lfoN_eq2gain,
  lfoN_eq3gain, lfoN_eq1gain_onccX, lfoN_eq2gain_onccX, lfoN_eq3gain_onccX,
  lfoN_eq1gain_smoothccX, lfoN_eq2gain_smoothccX, lfoN_eq3gain_smoothccX,
  lfoN_eq1gain_stepccX, lfoN_eq2gain_stepccX, lfoN_eq3gain_stepccX,
  lfoN_eq1freq, lfoN_eq2freq, lfoN_eq3freq, lfoN_eq1freq_onccX,
  lfoN_eq2freq_onccX, lfoN_eq3freq_onccX, lfoN_eq1freq_smoothccX,
  lfoN_eq2freq_smoothccX, lfoN_eq3freq_smoothccX, lfoN_eq1freq_stepccX,
  lfoN_eq2freq_stepccX, lfoN_eq3freq_stepccX, lfoN_eq1bw, lfoN_eq2bw,
  lfoN_eq3bw, lfoN_eq1bw_onccX, lfoN_eq2bw_onccX, lfoN_eq3bw_onccX,
  lfoN_eq1bw_smoothccX, lfoN_eq2bw_smoothccX, lfoN_eq3bw_smoothccX,
  lfoN_eq1bw_stepccX, lfoN_eq2bw_stepccX, lfoN_eq3bw_stepccX

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), EqUnitSupport(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), EqUnitSupport(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), EqUnitSupport(this, voice), pVoice(voice),
783 suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
784 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
785 resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
786 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
787 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
788 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
789 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount)
790 {
791 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
792 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
793 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
794
795 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
796 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
797 suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
798 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
799
800 for (int i = 0; i < EGs.capacity(); i++) {
801 EGs[i] = new EGv2Unit(this);
802 EGs[i]->pVoice = voice;
803 EGs[i]->suAmpOnCC.pVoice = voice;
804 EGs[i]->suVolOnCC.pVoice = voice;
805 EGs[i]->suPitchOnCC.pVoice = voice;
806 EGs[i]->suCutoffOnCC.pVoice = voice;
807 EGs[i]->suResOnCC.pVoice = voice;
808 EGs[i]->suPanOnCC.pVoice = voice;
809 EGs[i]->SetVoice(voice); // class EqUnitSupport
810 }
811
812 for (int i = 0; i < LFOs.capacity(); i++) {
813 LFOs[i] = new LFOv2Unit(this);
814 LFOs[i]->pVoice = voice;
815 LFOs[i]->suDepthOnCC.pVoice = voice;
816 LFOs[i]->suFreqOnCC.pVoice = voice;
817 LFOs[i]->suFadeEG.pVoice = voice;
818 LFOs[i]->suVolOnCC.pVoice = voice;
819 LFOs[i]->suPitchOnCC.pVoice = voice;
820 LFOs[i]->suFreqOnCC.pVoice = voice;
821 LFOs[i]->suPanOnCC.pVoice = voice;
822 LFOs[i]->suCutoffOnCC.pVoice = voice;
823 LFOs[i]->suResOnCC.pVoice = voice;
824 LFOs[i]->SetVoice(voice); // class EqUnitSupport
825 }
826 }
827
828 SfzSignalUnitRack::~SfzSignalUnitRack() {
829 for (int i = 0; i < EGs.capacity(); i++) {
830 delete EGs[i]; EGs[i] = NULL;
831 }
832
833 for (int i = 0; i < LFOs.capacity(); i++) {
834 delete LFOs[i]; LFOs[i] = NULL;
835 }
836 }
837
838 void SfzSignalUnitRack::InitRTLists() {
839 Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
840 Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
841
842 EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
843
844 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
845 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
846 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847 suResOnCC.InitCCList(pCCPool, pSmootherPool);
848 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
849 suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
850 suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
851 suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
852 suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
853 suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
854 suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
855 suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
856 suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
857
858 for (int i = 0; i < EGs.capacity(); i++) {
859 EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
860 EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
861 EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
862 EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
863 EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
864 EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
865 EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
866 }
867
868 for (int i = 0; i < LFOs.capacity(); i++) {
869 LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
870 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
871 LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872 LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873 LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
874 LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
875 LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
876 LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
877 LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
878 }
879 }
880
881 void SfzSignalUnitRack::Trigger() {
882 EGs.clear();
883 volEGs.clear();
884 pitchEGs.clear();
885 filEGs.clear();
886 resEGs.clear();
887 panEGs.clear();
888 eqEGs.clear();
889
890 LFOs.clear();
891 volLFOs.clear();
892 pitchLFOs.clear();
893 filLFOs.clear();
894 resLFOs.clear();
895 panLFOs.clear();
896 eqLFOs.clear();
897
898 ::sfz::Region* const pRegion = pVoice->pRegion;
899
900 suVolOnCC.SetCCs(pRegion->volume_oncc);
901 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
902 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
903 suResOnCC.SetCCs(pRegion->resonance_oncc);
904
905 for (int i = 0; i < pRegion->eg.size(); i++) {
906 if (pRegion->eg[i].node.size() == 0) continue;
907
908 if(EGs.size() < EGs.capacity()) {
909 EGv2Unit eg(this);
910 eg.pEGInfo = &(pRegion->eg[i]);
911 EGs.increment()->Copy(eg);
912 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
913 EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
914 EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
915 EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
916 EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
917 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
918 if (pVoice->bEqSupport) {
919 EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
920 EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
921 EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
922 EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
923 EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
924 EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
925 EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
926 EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
927 EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
928 }
929 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
930
931 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
932 pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
933 ) {
934 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
935 else std::cerr << "Maximum number of EGs reached!" << std::endl;
936 }
937
938 if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
939 if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
940 else std::cerr << "Maximum number of EGs reached!" << std::endl;
941 }
942
943 if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
944 if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
945 else std::cerr << "Maximum number of EGs reached!" << std::endl;
946 }
947
948 if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
949 if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
950 else std::cerr << "Maximum number of EGs reached!" << std::endl;
951 }
952
953 if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
954 if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
955 else std::cerr << "Maximum number of EGs reached!" << std::endl;
956 }
957
958 if (pRegion->eg[i].HasEq()) {
959 if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
960 else std::cerr << "Maximum number of EGs reached!" << std::endl;
961 }
962 }
963
964 if (pRegion->ampeg_sustain == -1) {
965 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
966 else pRegion->ampeg_sustain = 100;
967 }
968
969 // LFO
970 for (int i = 0; i < pRegion->lfos.size(); i++) {
971 if (pRegion->lfos[i].freq <= 0) {
972 if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
973 else pRegion->lfos[i].freq = 0;
974 }
975
976 if(LFOs.size() < LFOs.capacity()) {
977 LFOv2Unit lfo(this);
978 lfo.pLfoInfo = &(pRegion->lfos[i]);
979 LFOs.increment()->Copy(lfo);
980 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
981 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
982 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
983 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
984 LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
985 LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
986 if (pVoice->bEqSupport) {
987 LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
988 LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
989 LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
990 LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
991 LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
992 LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
993 LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
994 LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
995 LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
996 }
997 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
998
999 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
1000 if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
1001 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1002 }
1003
1004 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1005 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1006 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1007 }
1008
1009 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1010 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1011 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1012 }
1013
1014 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1015 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1016 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1017 }
1018
1019 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1020 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1021 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1022 }
1023
1024 if (pRegion->lfos[i].HasEq()) {
1025 if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1026 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1027 }
1028 }
1029
1030 if (!pVoice->bEqSupport) {
1031 bHasEq = false;
1032 } else {
1033 suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1034 suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1035 suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1036 suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1037 suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1038 suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1039 suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1040 suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1041 suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1042
1043 bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1044 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1045 eqEGs.size() > 0 || eqLFOs.size() > 0;
1046 }
1047
1048 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1049 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1050
1051 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1052 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1053
1054 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1055 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1056
1057 Units.clear();
1058
1059 EqUnitSupport::ImportUnits(this);
1060
1061 Units.add(&suVolOnCC);
1062 Units.add(&suPitchOnCC);
1063 Units.add(&suCutoffOnCC);
1064 Units.add(&suResOnCC);
1065
1066 Units.add(&suVolEG);
1067 Units.add(&suFilEG);
1068 Units.add(&suPitchEG);
1069
1070 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1071 Units.add(&suPitchLFO);
1072 Units.add(&suPitchLFO.suDepthOnCC);
1073 Units.add(&suPitchLFO.suFadeEG);
1074
1075 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1076 Units.add(&suAmpLFO.suDepthOnCC);
1077 Units.add(&suAmpLFO);
1078 Units.add(&suAmpLFO.suFadeEG);
1079
1080 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1081 Units.add(&suFilLFO.suDepthOnCC);
1082 Units.add(&suFilLFO);
1083 Units.add(&suFilLFO.suFadeEG);
1084
1085 for (int i = 0; i < EGs.size(); i++) {
1086 Units.add(EGs[i]);
1087 Units.add(&(EGs[i]->suAmpOnCC));
1088 Units.add(&(EGs[i]->suVolOnCC));
1089 Units.add(&(EGs[i]->suPitchOnCC));
1090 Units.add(&(EGs[i]->suCutoffOnCC));
1091 Units.add(&(EGs[i]->suResOnCC));
1092 Units.add(&(EGs[i]->suPanOnCC));
1093 EGs[i]->ImportUnits(this); // class EqUnitSupport
1094 }
1095
1096 for (int i = 0; i < LFOs.size(); i++) {
1097 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1098 Units.add(LFOs[i]);
1099 Units.add(&(LFOs[i]->suFadeEG));
1100 Units.add(&(LFOs[i]->suVolOnCC));
1101 Units.add(&(LFOs[i]->suPitchOnCC));
1102 Units.add(&(LFOs[i]->suPanOnCC));
1103 Units.add(&(LFOs[i]->suCutoffOnCC));
1104 Units.add(&(LFOs[i]->suResOnCC));
1105 LFOs[i]->ImportUnits(this); // class EqUnitSupport
1106 }
1107
1108 Units.add(&suEndpoint);
1109 Units.add(&suEndpoint.suXFInCC);
1110 Units.add(&suEndpoint.suXFOutCC);
1111 Units.add(&suEndpoint.suPanOnCC);
1112
1113 SignalUnitRack::Trigger();
1114 }
1115
1116 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1117 return &suEndpoint;
1118 }
1119
1120 void SfzSignalUnitRack::EnterFadeOutStage() {
1121 suVolEG.EG.enterFadeOutStage();
1122
1123 for (int i = 0; i < volEGs.size(); i++) {
1124 volEGs[i]->EG.enterFadeOutStage();
1125 }
1126 }
1127
1128 void SfzSignalUnitRack::Reset() {
1129 EqUnitSupport::ResetUnits();
1130
1131 suVolOnCC.RemoveAllCCs();
1132 suPitchOnCC.RemoveAllCCs();
1133 suCutoffOnCC.RemoveAllCCs();
1134 suResOnCC.RemoveAllCCs();
1135 suEndpoint.suXFInCC.RemoveAllCCs();
1136 suEndpoint.suXFOutCC.RemoveAllCCs();
1137 suEndpoint.suPanOnCC.RemoveAllCCs();
1138 suPitchLFO.suDepthOnCC.RemoveAllCCs();
1139 suPitchLFO.suFreqOnCC.RemoveAllCCs();
1140 suFilLFO.suDepthOnCC.RemoveAllCCs();
1141 suFilLFO.suFreqOnCC.RemoveAllCCs();
1142 suAmpLFO.suDepthOnCC.RemoveAllCCs();
1143 suAmpLFO.suFreqOnCC.RemoveAllCCs();
1144
1145 for (int i = 0; i < EGs.capacity(); i++) {
1146 EGs[i]->suAmpOnCC.RemoveAllCCs();
1147 EGs[i]->suVolOnCC.RemoveAllCCs();
1148 EGs[i]->suPitchOnCC.RemoveAllCCs();
1149 EGs[i]->suCutoffOnCC.RemoveAllCCs();
1150 EGs[i]->suResOnCC.RemoveAllCCs();
1151 EGs[i]->suPanOnCC.RemoveAllCCs();
1152 EGs[i]->ResetUnits(); // class EqUnitSupport
1153 }
1154
1155 for (int i = 0; i < LFOs.capacity(); i++) {
1156 LFOs[i]->suDepthOnCC.RemoveAllCCs();
1157 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1158 LFOs[i]->suVolOnCC.RemoveAllCCs();
1159 LFOs[i]->suPitchOnCC.RemoveAllCCs();
1160 LFOs[i]->suFreqOnCC.RemoveAllCCs();
1161 LFOs[i]->suPanOnCC.RemoveAllCCs();
1162 LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1163 LFOs[i]->suResOnCC.RemoveAllCCs();
1164 LFOs[i]->ResetUnits(); // class EqUnitSupport
1165 }
1166 }
1167
1168 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1169 if (!pEqSupport->HasSupport()) return;
1170 if (pEqSupport->GetBandCount() < 3) {
1171 std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1172 return;
1173 }
1174
1175 ::sfz::Region* const pRegion = pVoice->pRegion;
1176
1177 float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1178 float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1179 float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1180
1181 float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1182 float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1183 float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1184
1185 float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1186 float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1187 float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1188
1189 for (int i = 0; i < eqEGs.size(); i++) {
1190 EGv2Unit* eg = eqEGs[i];
1191 if (!eg->Active()) continue;
1192
1193 float l = eg->GetLevel();
1194 dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1195 dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1196 dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1197
1198 freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1199 freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1200 freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1201
1202 bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1203 bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1204 bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1205 }
1206
1207 for (int i = 0; i < eqLFOs.size(); i++) {
1208 LFOv2Unit* lfo = eqLFOs[i];
1209 if (!lfo->Active()) continue;
1210
1211 float l = lfo->GetLevel();
1212 dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1213 dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1214 dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1215
1216 freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1217 freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1218 freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1219
1220 bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1221 bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1222 bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1223 }
1224
1225 pEqSupport->SetGain(0, dB1);
1226 pEqSupport->SetGain(1, dB2);
1227 pEqSupport->SetGain(2, dB3);
1228
1229 pEqSupport->SetFreq(0, freq1);
1230 pEqSupport->SetFreq(1, freq2);
1231 pEqSupport->SetFreq(2, freq3);
1232
1233 pEqSupport->SetBandwidth(0, bw1);
1234 pEqSupport->SetBandwidth(1, bw2);
1235 pEqSupport->SetBandwidth(2, bw3);
1236 }
1237
1238 EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1239 : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1240 suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1241 suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1242 {
1243 SetVoice(pVoice);
1244 }
1245
1246 void EqUnitSupport::SetVoice(Voice* pVoice) {
1247 suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1248 suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1249 suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1250 }
1251
1252 void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1253 if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1254 if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1255 if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1256 if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1257 if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1258 if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1259 if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1260 if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1261 if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1262 }
1263
1264 void EqUnitSupport::ResetUnits() {
1265 suEq1GainOnCC.RemoveAllCCs();
1266 suEq2GainOnCC.RemoveAllCCs();
1267 suEq3GainOnCC.RemoveAllCCs();
1268 suEq1FreqOnCC.RemoveAllCCs();
1269 suEq2FreqOnCC.RemoveAllCCs();
1270 suEq3FreqOnCC.RemoveAllCCs();
1271 suEq1BwOnCC.RemoveAllCCs();
1272 suEq2BwOnCC.RemoveAllCCs();
1273 suEq3BwOnCC.RemoveAllCCs();
1274 }
1275
1276 void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1277 suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1278 suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1279 suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1280 suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1281 suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1282 suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1283 suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1284 suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1285 suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1286 }
1287
1288 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC