/[svn]/linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3561 - (hide annotations) (download)
Fri Aug 23 11:44:00 2019 UTC (4 years, 7 months ago) by schoenebeck
File size: 57147 byte(s)
NKSP: Added standard units support for numbers and final "!" operator:

* NKSP strictness: Variable names, function names and preprocessor condition
  names must start with a regular character (a-z or A-Z); starting them with
  a digit or underscore is no longer allowed.

* NKSP parser fix: equal comparison operator "=" and not equal comparison
  operator "#" must only accept integer operands.

* NKSP language: Implemented support for standard units like Hertz, seconds,
  Bel including support for metric unit prefixes; so one can now e.g.
  conveniently use numbers in scripts like "5us" meaning "5 microseconds",
  or e.g. "12kHz" meaning "12 kilo Hertz", or e.g. "-14mdB" meaning
  "minus 14 Millidecibel", or e.g. "28c" meaning "28 cents" (for tuning).

* NKSP language: Introduced "final" operator "!" which is specifically
  intended for synthesis parameter values to denote that the synthesis
  parameter value is intended to be the "final" value for that synthesis
  parameter that should explicitly be used by the engine and thus causing
  the sampler engine to ignore all other modulation sources for the same
  synthesis parameter (like e.g. LFO, EG); by simply prefixing a value,
  variable or formula with this new "!" operator the expression is marked as
  being "final".

* Bumped version (2.1.1.svn4).

1 iliev 2218 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 persson 2311 * Copyright (C) 2011 - 2012 Grigor Iliev *
6 iliev 2218 * *
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 iliev 2244 #include "Engine.h"
25 iliev 2218
26 iliev 2244 #define _200TH_ROOT_OF_10 1.011579454259899
27    
28 iliev 2218 namespace LinuxSampler { namespace sfz {
29    
30 iliev 2244 double ToRatio(int Centibels) {
31     if (Centibels == 0) return 1.0;
32     return pow(_200TH_ROOT_OF_10, Centibels);
33     }
34    
35 iliev 2218 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 iliev 2229 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 iliev 2218 }
51    
52 iliev 2236 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 iliev 2220
65 iliev 2236 void XFInCCUnit::Calculate() {
66     float l = 1;
67    
68 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
69     RTList<CC>::Iterator end = pCtrls->end();
70     for(; ctrl != end; ++ctrl) {
71 iliev 2236 float c = 1;
72 iliev 2244 int influence = (*ctrl).Influence;
73 iliev 2236 int lo = influence & 0xff;
74     int hi = influence >> 8;
75 iliev 2244 if ((*ctrl).Value <= lo) {
76 iliev 2236 c = 0;
77 iliev 2244 } else if ((*ctrl).Value >= hi) {
78 iliev 2236 c = 1;
79     } else {
80     float xfVelSize = hi - lo;
81 iliev 2244 float velPos = (*ctrl).Value - lo;
82 iliev 2236 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 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
102     RTList<CC>::Iterator end = pCtrls->end();
103     for(; ctrl != end; ++ctrl) {
104 iliev 2236 float c = 1;
105 iliev 2244 int influence = (*ctrl).Influence;
106 iliev 2236 int lo = influence & 0xff;
107     int hi = influence >> 8;
108 iliev 2244 if ((*ctrl).Value >= hi) {
109 iliev 2236 c = 0;
110 iliev 2244 } else if ((*ctrl).Value <= lo) {
111 iliev 2236 c = 1;
112     } else {
113     float xfVelSize = hi - lo;
114 iliev 2244 float velPos = (*ctrl).Value - lo;
115 iliev 2236 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 iliev 2235 EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132 iliev 2299 : EGUnit< ::LinuxSampler::sfz::EG>(rack), EqUnitSupport(rack), suAmpOnCC(rack), suVolOnCC(rack),
133 iliev 2237 suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134 iliev 2235 { }
135    
136 iliev 2218 void EGv2Unit::Trigger() {
137 iliev 2229 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 schoenebeck 2879 EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity());
146 iliev 2218 }
147 iliev 2219
148 iliev 2220
149     void PitchEGUnit::Trigger() {
150     ::sfz::Region* const pRegion = pVoice->pRegion;
151 iliev 2249 depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152 iliev 2220
153     // the length of the decay and release curves are dependent on the velocity
154 schoenebeck 2879 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
155 iliev 2218
156 iliev 2220 // set the delay trigger
157 iliev 2249 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 iliev 2220
161 iliev 2249 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 persson 2311 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
181 iliev 2249 );
182 iliev 2220 }
183    
184 iliev 2222
185     void FilEGUnit::Trigger() {
186     ::sfz::Region* const pRegion = pVoice->pRegion;
187 iliev 2249 depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188 iliev 2222
189     // the length of the decay and release curves are dependent on the velocity
190 schoenebeck 2879 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
191 iliev 2220
192 iliev 2222 // set the delay trigger
193 iliev 2249 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 iliev 2222
197 iliev 2249 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 persson 2311 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
217 iliev 2249 );
218 iliev 2222 }
219    
220 iliev 2226
221 iliev 2229 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 schoenebeck 2879 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
226 iliev 2229
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 schoenebeck 3561 if (pVoice->pNote) {
246     pVoice->pNote->Override.Sustain.applyTo(sustain);
247     }
248 schoenebeck 3316
249 iliev 2229 float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
250     release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
251    
252     EG.trigger (
253     uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
254 persson 2311 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
255 iliev 2229 );
256     }
257    
258    
259 iliev 2227 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
260     : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
261 schoenebeck 3034 suFadeEG(rack), suDepthOnCC(rack), suFreqOnCC(rack, this)
262 iliev 2227 { }
263    
264     LFOUnit::LFOUnit(const LFOUnit& Unit)
265     : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
266 schoenebeck 3034 suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
267     suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
268 iliev 2227 {
269 iliev 2226 Copy(Unit);
270     }
271 iliev 2222
272 iliev 2219 void LFOUnit::Increment() {
273     if (DelayStage()) return;
274    
275     SignalUnit::Increment();
276    
277 iliev 2223 Level = pLFO->Render();
278 iliev 2226 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
279 iliev 2219 }
280    
281     void LFOUnit::Trigger() {
282     //reset
283     Level = 0;
284    
285     // set the delay trigger
286 iliev 2233 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
287 iliev 2226 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
288     float f = pLfoInfo->fade;
289 iliev 2229 f += GetInfluence(pLfoInfo->fade_oncc);
290 iliev 2226
291     if (f != 0) {
292     suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
293 persson 2311 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
294 iliev 2226 }
295     }
296 iliev 2219 }
297    
298 iliev 2227 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
299 iliev 2251 if (pLFO == NULL) return;
300 iliev 2229 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
301 iliev 2227 }
302    
303    
304 iliev 2221 void LFOv1Unit::Trigger() {
305     LFOUnit::Trigger();
306    
307     lfo.trigger (
308 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
309 iliev 2221 start_level_mid,
310     1, 0, false, GetSampleRate()
311     );
312 schoenebeck 3118 lfo.updateByMIDICtrlValue(0);
313 iliev 2221 }
314    
315 iliev 2223
316     LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
317 iliev 2299 : LFOUnit(rack), EqUnitSupport(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
318 iliev 2225 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
319 iliev 2233 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
320 iliev 2223 {
321     lfos.add(&lfo0);
322     lfos.add(&lfo1);
323     lfos.add(&lfo2);
324     lfos.add(&lfo3);
325     lfos.add(&lfo4);
326     lfos.add(&lfo5);
327     lfos.add(&lfo6);
328     lfos.add(&lfo7);
329     }
330    
331 iliev 2219 void LFOv2Unit::Trigger() {
332     LFOUnit::Trigger();
333    
334 schoenebeck 3054 if (/*pLfoInfo->wave < 0 ||*/ pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
335 iliev 2223 else pLFO = lfos[pLfoInfo->wave];
336    
337     pLFO->Trigger (
338 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
339 iliev 2219 start_level_mid,
340     1, 0, false, GetSampleRate()
341     );
342 iliev 2223 pLFO->Update(0);
343 iliev 2225
344 iliev 2229 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
345 iliev 2225 if (phase != 0) pLFO->SetPhase(phase);
346 iliev 2219 }
347 iliev 2221
348     void AmpLFOUnit::Trigger() {
349 iliev 2251 bActive = true;
350 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
351 iliev 2248 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
352 iliev 2226 pLfoInfo->freq = pRegion->amplfo_freq;
353 iliev 2248 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
354 iliev 2221 pLfoInfo->volume = pRegion->amplfo_depth;
355    
356 iliev 2251 if (pLfoInfo->freq <= 0) {
357     if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
358     else bActive = false;
359     }
360    
361 iliev 2221 LFOv1Unit::Trigger();
362     }
363    
364     void PitchLFOUnit::Trigger() {
365 iliev 2251 bActive = true;
366 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
367 iliev 2248 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
368 iliev 2226 pLfoInfo->freq = pRegion->pitchlfo_freq;
369 iliev 2248 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
370 iliev 2221 pLfoInfo->pitch = pRegion->pitchlfo_depth;
371    
372 iliev 2251 if (pLfoInfo->freq <= 0) {
373     if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
374     else bActive = false;
375     }
376    
377 iliev 2221 LFOv1Unit::Trigger();
378     }
379    
380     void FilLFOUnit::Trigger() {
381 iliev 2251 bActive = true;
382 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
383 iliev 2248 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
384 iliev 2226 pLfoInfo->freq = pRegion->fillfo_freq;
385 iliev 2248 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
386 iliev 2221 pLfoInfo->cutoff = pRegion->fillfo_depth;
387    
388 iliev 2251 if (pLfoInfo->freq <= 0) {
389     if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
390     else bActive = false;
391     }
392    
393 iliev 2221 LFOv1Unit::Trigger();
394     }
395 iliev 2224
396 iliev 2227 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
397     pVoice = NULL;
398     }
399 iliev 2224
400     void CCUnit::Trigger() {
401 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
402     RTList<CC>::Iterator end = pCtrls->end();
403     for(; ctrl != end; ++ctrl) {
404     (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
405 iliev 2264 if ((*ctrl).pSmoother != NULL) {
406     if ((*ctrl).Step > 0) {
407     float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
408     (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
409     } else {
410     (*ctrl).pSmoother->setValue((*ctrl).Value);
411     }
412     }
413 iliev 2224 }
414     CCSignalUnit::Trigger();
415     }
416    
417 iliev 2244 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
418     RemoveAllCCs();
419     for (int i = 0; i < 128; i++) {
420     if (cc[i] != 0) AddCC(i, cc[i]);
421     }
422     }
423 iliev 2225
424 iliev 2296 void CCUnit::SetCCs(::sfz::Array<float>& cc) {
425     RemoveAllCCs();
426     for (int i = 0; i < 128; i++) {
427     if (cc[i] != 0) AddCC(i, cc[i]);
428     }
429     }
430    
431 iliev 2244 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
432     RemoveAllCCs();
433     for (int i = 0; i < cc.size(); i++) {
434     if (cc[i].Influence != 0) {
435     short int curve = cc[i].Curve;
436     if (curve >= GetCurveCount()) curve = -1;
437 iliev 2264 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
438 iliev 2244 }
439     }
440     }
441 iliev 2230
442 iliev 2264 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
443     AddCC(Controller, Influence, Curve, NULL, Step);
444 iliev 2244 }
445 iliev 2232
446 iliev 2244 int CCUnit::GetCurveCount() {
447     return pVoice->pRegion->GetInstrument()->curves.size();
448     }
449 iliev 2230
450 iliev 2244 ::sfz::Curve* CCUnit::GetCurve(int idx) {
451     return &pVoice->pRegion->GetInstrument()->curves[idx];
452     }
453 iliev 2232
454 iliev 2244 double CCUnit::GetSampleRate() {
455 iliev 2232 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
456     }
457 iliev 2244
458    
459     SmoothCCUnit::~SmoothCCUnit() {
460     if (pSmoothers != NULL) delete pSmoothers;
461     }
462 iliev 2232
463 iliev 2264 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
464 iliev 2244 if (Smooth > 0) {
465     if (pSmoothers->poolIsEmpty()) {
466     std::cerr << "Maximum number of smoothers reached" << std::endl;
467     return;
468     }
469     Smoother* smoother = &(*(pSmoothers->allocAppend()));
470     smoother->trigger(Smooth / 1000.0f, GetSampleRate());
471 iliev 2264 AddCC(Controller, Influence, Curve, smoother, Step);
472 iliev 2244 } else {
473 iliev 2264 AddCC(Controller, Influence, Curve, NULL, Step);
474 iliev 2244 }
475     }
476    
477     void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
478     if (pSmoothers != NULL) delete pSmoothers;
479     pSmoothers = new RTList<Smoother>(pSmootherPool);
480     }
481    
482     void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
483     CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
484     InitSmoothers(pSmootherPool);
485     }
486 iliev 2218
487 iliev 2219
488 iliev 2237 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
489 schoenebeck 3034 : EndpointSignalUnit(rack), pitchVeltrackRatio(0), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack)
490 iliev 2237 {
491 iliev 2218
492     }
493    
494 schoenebeck 3082 float EndpointUnit::GetInfluence(::sfz::Array< optional<float> >& cc) {
495 iliev 2297 float f = 0;
496     for (int i = 0; i < 128; i++) {
497     if (cc[i]) {
498     f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
499     }
500     }
501     return f;
502     }
503    
504 schoenebeck 3082 float EndpointUnit::GetInfluence(::sfz::Array< optional<int> >& cc) {
505 iliev 2297 float f = 0;
506     for (int i = 0; i < 128; i++) {
507     if (cc[i]) {
508     f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
509     }
510     }
511     return f;
512     }
513    
514 iliev 2218 SfzSignalUnitRack* const EndpointUnit::GetRack() {
515     return static_cast<SfzSignalUnitRack* const>(pRack);
516     }
517    
518     void EndpointUnit::Trigger() {
519 iliev 2297 uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
520     if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
521    
522     if (pVoice->pRegion->delay) {
523     /* here we use the device sample rate */
524     uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
525     }
526    
527     if (pVoice->pRegion->delay_random) {
528     float r = pVoice->GetEngine()->Random();
529     uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
530     }
531    
532     uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
533    
534 iliev 2236 float xfInVelCoeff = 1;
535 iliev 2218
536 schoenebeck 2879 if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
537 iliev 2236 xfInVelCoeff = 0;
538 schoenebeck 2879 } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
539 iliev 2236 xfInVelCoeff = 1;
540     } else {
541     float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
542 schoenebeck 2879 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
543 iliev 2236 xfInVelCoeff = velPos / xfVelSize;
544     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
545     xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
546     }
547     }
548    
549     float xfOutVelCoeff = 1;
550    
551 schoenebeck 2879 if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
552 iliev 2236 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
553 schoenebeck 2879 } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
554 iliev 2236 xfOutVelCoeff = 1;
555     } else {
556     float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
557 schoenebeck 2879 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
558 iliev 2236 xfOutVelCoeff = 1.0f - velPos / xfVelSize;
559     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
560     xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
561     }
562     }
563    
564     float xfInKeyCoeff = 1;
565    
566 schoenebeck 2879 if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
567 iliev 2236 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
568 schoenebeck 2879 } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
569 iliev 2236 xfInKeyCoeff = 1;
570     } else {
571     float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
572 schoenebeck 2879 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
573 iliev 2236 xfInKeyCoeff = keyPos / xfKeySize;
574     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
575     xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
576     }
577     }
578    
579     float xfOutKeyCoeff = 1;
580    
581 schoenebeck 2879 if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
582 iliev 2236 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
583 schoenebeck 2879 } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
584 iliev 2236 xfOutKeyCoeff = 1;
585     } else {
586     float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
587 schoenebeck 2879 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
588 iliev 2236 xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
589     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
590     xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
591     }
592     }
593    
594     xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
595    
596     suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
597     suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
598 iliev 2237
599     suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
600    
601 schoenebeck 2879 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
602 iliev 2218 }
603    
604     bool EndpointUnit::Active() {
605 iliev 2297 if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
606     return false; // The key was released before the delay end, so the voice won't play at all.
607     }
608    
609 iliev 2218 if (GetRack()->suVolEG.Active()) return true;
610    
611     bool b = false;
612     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
613     if (GetRack()->volEGs[i]->Active()) { b = true; break; }
614     }
615    
616     return b;
617     }
618    
619     float EndpointUnit::GetVolume() {
620     float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
621    
622     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
623     EGv2Unit* eg = GetRack()->volEGs[i];
624     if (!eg->Active()) continue;
625 iliev 2229
626 iliev 2235 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
627     if (dB < -144) dB = eg->pEGInfo->volume;
628     else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
629    
630     float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
631     amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
632    
633     if (dB >= -144) {
634     if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
635 iliev 2244 amp *= ToRatio(dB * 10.0);
636 iliev 2235 }
637    
638     vol += amp * eg->GetLevel();
639 iliev 2218 }
640    
641 iliev 2221 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
642 iliev 2233 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
643     float f = u2->Active() ? u2->GetLevel() : 0;
644 iliev 2244 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
645 iliev 2221
646 iliev 2244 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
647 iliev 2230
648 iliev 2233 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
649     LFOv2Unit* lfo = GetRack()->volLFOs[i];
650     if (!lfo->Active()) continue;
651    
652     float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
653 iliev 2244 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
654 iliev 2233 }
655    
656 iliev 2236 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
657     if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
658     return vol * xfCoeff;
659 iliev 2218 }
660    
661     float EndpointUnit::GetFilterCutoff() {
662 iliev 2252 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
663 iliev 2219
664 iliev 2221 FilLFOUnit* u = &(GetRack()->suFilLFO);
665 iliev 2233 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
666     float f = u1->Active() ? u1->GetLevel() : 0;
667 iliev 2252 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
668 iliev 2221
669 iliev 2222 FilEGUnit* u2 = &(GetRack()->suFilEG);
670     val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
671    
672 iliev 2235 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
673     EGv2Unit* eg = GetRack()->filEGs[i];
674     if (!eg->Active()) continue;
675    
676     float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
677     f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
678     val *= RTMath::CentsToFreqRatioUnlimited(f);
679     }
680    
681 iliev 2219 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
682     LFOv2Unit* lfo = GetRack()->filLFOs[i];
683     if (!lfo->Active()) continue;
684    
685 iliev 2233 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
686     f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
687 iliev 2219 val *= RTMath::CentsToFreqRatioUnlimited(f);
688     }
689    
690     return val;
691 iliev 2218 }
692    
693 iliev 2235 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
694 iliev 2252 cutoff *= GetFilterCutoff();
695     float maxCutoff = 0.49 * pVoice->GetSampleRate();
696     return cutoff > maxCutoff ? maxCutoff : cutoff;
697 iliev 2235 }
698    
699 iliev 2218 float EndpointUnit::GetPitch() {
700 iliev 2264 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
701    
702 iliev 2220 EGv1Unit* u = &(GetRack()->suPitchEG);
703 iliev 2264 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
704 iliev 2221
705 iliev 2235 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
706     EGv2Unit* eg = GetRack()->pitchEGs[i];
707     if (!eg->Active()) continue;
708    
709     float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
710     p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
711     }
712    
713 iliev 2221 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
714 iliev 2233 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
715 iliev 2224 float f = u3->Active() ? u3->GetLevel() : 0;
716     p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
717 iliev 2225
718     for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
719     LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
720     if (!lfo->Active()) continue;
721    
722     float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
723     p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
724     }
725    
726 iliev 2237 return p * pitchVeltrackRatio;
727 iliev 2218 }
728    
729     float EndpointUnit::GetResonance() {
730 iliev 2252 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
731 iliev 2219
732 iliev 2235 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
733     EGv2Unit* eg = GetRack()->resEGs[i];
734     if (!eg->Active()) continue;
735    
736     float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
737     val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
738     }
739    
740 iliev 2219 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
741     LFOv2Unit* lfo = GetRack()->resLFOs[i];
742     if (!lfo->Active()) continue;
743    
744 iliev 2233 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
745     val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
746 iliev 2219 }
747    
748     return val;
749 iliev 2218 }
750    
751 iliev 2219 float EndpointUnit::GetPan() {
752 iliev 2237 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
753 iliev 2219
754 iliev 2237 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
755     EGv2Unit* eg = GetRack()->panEGs[i];
756     if (!eg->Active()) continue;
757    
758     float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
759    
760     if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
761     uint8_t val = eg->GetLevel() * 127;
762     if (val > 127) val = 127;
763     pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
764     } else {
765     pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
766     }
767     }
768    
769 iliev 2219 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
770     LFOv2Unit* lfo = GetRack()->panLFOs[i];
771     if (!lfo->Active()) continue;
772    
773 iliev 2233 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
774     pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
775 iliev 2219 }
776    
777     return pan;
778     }
779 iliev 2218
780 iliev 2219
781 iliev 2218 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
782 schoenebeck 3034 : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice),
783 iliev 2299 suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
784 schoenebeck 3034 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
785     suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
786 iliev 2299 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
787     resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
788 iliev 2233 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
789 schoenebeck 3034 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount),
790     pVoice(voice)
791 iliev 2218 {
792 iliev 2237 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
793 iliev 2236 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
794 iliev 2264 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
795 iliev 2296
796 iliev 2264 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
797 iliev 2233 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
798     suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
799     suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
800 iliev 2218
801     for (int i = 0; i < EGs.capacity(); i++) {
802     EGs[i] = new EGv2Unit(this);
803     EGs[i]->pVoice = voice;
804 iliev 2235 EGs[i]->suAmpOnCC.pVoice = voice;
805     EGs[i]->suVolOnCC.pVoice = voice;
806     EGs[i]->suPitchOnCC.pVoice = voice;
807     EGs[i]->suCutoffOnCC.pVoice = voice;
808     EGs[i]->suResOnCC.pVoice = voice;
809 iliev 2237 EGs[i]->suPanOnCC.pVoice = voice;
810 iliev 2299 EGs[i]->SetVoice(voice); // class EqUnitSupport
811 iliev 2218 }
812 iliev 2219
813     for (int i = 0; i < LFOs.capacity(); i++) {
814     LFOs[i] = new LFOv2Unit(this);
815     LFOs[i]->pVoice = voice;
816 iliev 2244 LFOs[i]->suDepthOnCC.pVoice = voice;
817     LFOs[i]->suFreqOnCC.pVoice = voice;
818 iliev 2226 LFOs[i]->suFadeEG.pVoice = voice;
819 iliev 2233 LFOs[i]->suVolOnCC.pVoice = voice;
820 iliev 2225 LFOs[i]->suPitchOnCC.pVoice = voice;
821 iliev 2227 LFOs[i]->suFreqOnCC.pVoice = voice;
822 iliev 2233 LFOs[i]->suPanOnCC.pVoice = voice;
823     LFOs[i]->suCutoffOnCC.pVoice = voice;
824     LFOs[i]->suResOnCC.pVoice = voice;
825 iliev 2299 LFOs[i]->SetVoice(voice); // class EqUnitSupport
826 iliev 2219 }
827 iliev 2218 }
828    
829     SfzSignalUnitRack::~SfzSignalUnitRack() {
830 iliev 2219 for (int i = 0; i < EGs.capacity(); i++) {
831 iliev 2218 delete EGs[i]; EGs[i] = NULL;
832     }
833 iliev 2219
834     for (int i = 0; i < LFOs.capacity(); i++) {
835     delete LFOs[i]; LFOs[i] = NULL;
836     }
837 iliev 2218 }
838    
839 iliev 2244 void SfzSignalUnitRack::InitRTLists() {
840     Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
841     Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
842    
843 iliev 2299 EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
844 iliev 2296
845 iliev 2244 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
846 iliev 2264 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
847 iliev 2252 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
848     suResOnCC.InitCCList(pCCPool, pSmootherPool);
849 iliev 2244 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
850     suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
851     suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
852     suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
853     suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
854     suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
855     suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
856     suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
857     suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
858    
859     for (int i = 0; i < EGs.capacity(); i++) {
860     EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
861     EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
862     EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
863     EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
864     EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
865     EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
866 iliev 2299 EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
867 iliev 2244 }
868    
869     for (int i = 0; i < LFOs.capacity(); i++) {
870     LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
871     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
872     LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
873     LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
874     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
875     LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
876     LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
877     LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
878 iliev 2299 LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
879 iliev 2244 }
880     }
881    
882 iliev 2218 void SfzSignalUnitRack::Trigger() {
883     EGs.clear();
884     volEGs.clear();
885     pitchEGs.clear();
886 iliev 2235 filEGs.clear();
887     resEGs.clear();
888 iliev 2237 panEGs.clear();
889 iliev 2299 eqEGs.clear();
890 iliev 2218
891 iliev 2219 LFOs.clear();
892 iliev 2233 volLFOs.clear();
893 iliev 2225 pitchLFOs.clear();
894 iliev 2219 filLFOs.clear();
895     resLFOs.clear();
896     panLFOs.clear();
897 iliev 2299 eqLFOs.clear();
898 iliev 2219
899 iliev 2218 ::sfz::Region* const pRegion = pVoice->pRegion;
900    
901 iliev 2230 suVolOnCC.SetCCs(pRegion->volume_oncc);
902 iliev 2264 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
903 iliev 2252 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
904     suResOnCC.SetCCs(pRegion->resonance_oncc);
905 iliev 2230
906 iliev 2219 for (int i = 0; i < pRegion->eg.size(); i++) {
907 iliev 2218 if (pRegion->eg[i].node.size() == 0) continue;
908    
909     if(EGs.size() < EGs.capacity()) {
910     EGv2Unit eg(this);
911     eg.pEGInfo = &(pRegion->eg[i]);
912     EGs.increment()->Copy(eg);
913 iliev 2235 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
914     EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
915     EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
916     EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
917     EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
918 iliev 2237 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
919 iliev 2299 if (pVoice->bEqSupport) {
920     EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
921     EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
922     EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
923     EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
924     EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
925     EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
926     EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
927     EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
928     EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
929     }
930 iliev 2218 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
931    
932 iliev 2235 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
933     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
934     ) {
935 iliev 2218 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
936     else std::cerr << "Maximum number of EGs reached!" << std::endl;
937     }
938 iliev 2235
939     if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
940     if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
941     else std::cerr << "Maximum number of EGs reached!" << std::endl;
942     }
943    
944     if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
945     if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
946     else std::cerr << "Maximum number of EGs reached!" << std::endl;
947     }
948    
949     if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
950     if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
951     else std::cerr << "Maximum number of EGs reached!" << std::endl;
952     }
953 iliev 2237
954     if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
955     if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
956     else std::cerr << "Maximum number of EGs reached!" << std::endl;
957     }
958 iliev 2299
959     if (pRegion->eg[i].HasEq()) {
960     if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
961     else std::cerr << "Maximum number of EGs reached!" << std::endl;
962     }
963 iliev 2218 }
964    
965     if (pRegion->ampeg_sustain == -1) {
966     if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
967     else pRegion->ampeg_sustain = 100;
968     }
969    
970 iliev 2219 // LFO
971     for (int i = 0; i < pRegion->lfos.size(); i++) {
972 iliev 2251 if (pRegion->lfos[i].freq <= 0) {
973     if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
974     else pRegion->lfos[i].freq = 0;
975     }
976 iliev 2219
977     if(LFOs.size() < LFOs.capacity()) {
978     LFOv2Unit lfo(this);
979     lfo.pLfoInfo = &(pRegion->lfos[i]);
980     LFOs.increment()->Copy(lfo);
981 iliev 2233 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
982 iliev 2225 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
983 iliev 2227 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
984 iliev 2233 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
985     LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
986     LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
987 iliev 2299 if (pVoice->bEqSupport) {
988     LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
989     LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
990     LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
991     LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
992     LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
993     LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
994     LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
995     LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
996     LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
997     }
998 iliev 2219 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
999    
1000 iliev 2233 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
1001     if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
1002     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1003     }
1004    
1005 iliev 2225 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1006     if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1007     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1008     }
1009    
1010 iliev 2233 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1011 iliev 2219 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1012     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1013     }
1014    
1015 iliev 2233 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1016 iliev 2219 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1017     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1018     }
1019    
1020 iliev 2233 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1021 iliev 2219 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1022     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1023     }
1024 iliev 2299
1025     if (pRegion->lfos[i].HasEq()) {
1026     if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1027     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1028     }
1029 iliev 2219 }
1030    
1031 iliev 2299 if (!pVoice->bEqSupport) {
1032     bHasEq = false;
1033     } else {
1034     suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1035     suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1036     suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1037     suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1038     suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1039     suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1040     suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1041     suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1042     suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1043    
1044     bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1045 iliev 2300 pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1046 iliev 2299 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1047     eqEGs.size() > 0 || eqLFOs.size() > 0;
1048     }
1049    
1050 iliev 2233 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1051 iliev 2227 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1052 iliev 2224
1053 iliev 2233 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1054 iliev 2227 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1055    
1056 iliev 2233 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1057 iliev 2227 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1058    
1059 iliev 2218 Units.clear();
1060    
1061 iliev 2299 EqUnitSupport::ImportUnits(this);
1062 iliev 2296
1063 iliev 2230 Units.add(&suVolOnCC);
1064 iliev 2264 Units.add(&suPitchOnCC);
1065 iliev 2252 Units.add(&suCutoffOnCC);
1066     Units.add(&suResOnCC);
1067 iliev 2230
1068 iliev 2218 Units.add(&suVolEG);
1069 iliev 2222 Units.add(&suFilEG);
1070 iliev 2220 Units.add(&suPitchEG);
1071 iliev 2227
1072     Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1073 iliev 2221 Units.add(&suPitchLFO);
1074 iliev 2233 Units.add(&suPitchLFO.suDepthOnCC);
1075 iliev 2226 Units.add(&suPitchLFO.suFadeEG);
1076 iliev 2227
1077     Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1078 iliev 2233 Units.add(&suAmpLFO.suDepthOnCC);
1079 iliev 2221 Units.add(&suAmpLFO);
1080 iliev 2226 Units.add(&suAmpLFO.suFadeEG);
1081 iliev 2227
1082     Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1083 iliev 2233 Units.add(&suFilLFO.suDepthOnCC);
1084 iliev 2221 Units.add(&suFilLFO);
1085 iliev 2226 Units.add(&suFilLFO.suFadeEG);
1086 iliev 2218
1087 iliev 2219 for (int i = 0; i < EGs.size(); i++) {
1088 iliev 2218 Units.add(EGs[i]);
1089 iliev 2235 Units.add(&(EGs[i]->suAmpOnCC));
1090     Units.add(&(EGs[i]->suVolOnCC));
1091     Units.add(&(EGs[i]->suPitchOnCC));
1092     Units.add(&(EGs[i]->suCutoffOnCC));
1093     Units.add(&(EGs[i]->suResOnCC));
1094 iliev 2237 Units.add(&(EGs[i]->suPanOnCC));
1095 iliev 2299 EGs[i]->ImportUnits(this); // class EqUnitSupport
1096 iliev 2218 }
1097    
1098 iliev 2219 for (int i = 0; i < LFOs.size(); i++) {
1099 iliev 2227 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1100 iliev 2219 Units.add(LFOs[i]);
1101 iliev 2226 Units.add(&(LFOs[i]->suFadeEG));
1102 iliev 2233 Units.add(&(LFOs[i]->suVolOnCC));
1103 iliev 2225 Units.add(&(LFOs[i]->suPitchOnCC));
1104 iliev 2233 Units.add(&(LFOs[i]->suPanOnCC));
1105     Units.add(&(LFOs[i]->suCutoffOnCC));
1106     Units.add(&(LFOs[i]->suResOnCC));
1107 iliev 2299 LFOs[i]->ImportUnits(this); // class EqUnitSupport
1108 iliev 2219 }
1109    
1110 iliev 2218 Units.add(&suEndpoint);
1111 iliev 2236 Units.add(&suEndpoint.suXFInCC);
1112     Units.add(&suEndpoint.suXFOutCC);
1113 iliev 2237 Units.add(&suEndpoint.suPanOnCC);
1114 iliev 2218
1115     SignalUnitRack::Trigger();
1116     }
1117    
1118     EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1119     return &suEndpoint;
1120     }
1121    
1122     void SfzSignalUnitRack::EnterFadeOutStage() {
1123     suVolEG.EG.enterFadeOutStage();
1124    
1125     for (int i = 0; i < volEGs.size(); i++) {
1126     volEGs[i]->EG.enterFadeOutStage();
1127     }
1128     }
1129 persson 2327
1130     void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1131     suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1132     for (int i = 0; i < volEGs.size(); i++) {
1133     volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1134     }
1135     }
1136    
1137 iliev 2244 void SfzSignalUnitRack::Reset() {
1138 iliev 2299 EqUnitSupport::ResetUnits();
1139 iliev 2296
1140 iliev 2244 suVolOnCC.RemoveAllCCs();
1141 iliev 2264 suPitchOnCC.RemoveAllCCs();
1142 iliev 2252 suCutoffOnCC.RemoveAllCCs();
1143     suResOnCC.RemoveAllCCs();
1144 iliev 2244 suEndpoint.suXFInCC.RemoveAllCCs();
1145     suEndpoint.suXFOutCC.RemoveAllCCs();
1146     suEndpoint.suPanOnCC.RemoveAllCCs();
1147     suPitchLFO.suDepthOnCC.RemoveAllCCs();
1148     suPitchLFO.suFreqOnCC.RemoveAllCCs();
1149     suFilLFO.suDepthOnCC.RemoveAllCCs();
1150     suFilLFO.suFreqOnCC.RemoveAllCCs();
1151     suAmpLFO.suDepthOnCC.RemoveAllCCs();
1152     suAmpLFO.suFreqOnCC.RemoveAllCCs();
1153    
1154     for (int i = 0; i < EGs.capacity(); i++) {
1155     EGs[i]->suAmpOnCC.RemoveAllCCs();
1156     EGs[i]->suVolOnCC.RemoveAllCCs();
1157     EGs[i]->suPitchOnCC.RemoveAllCCs();
1158     EGs[i]->suCutoffOnCC.RemoveAllCCs();
1159     EGs[i]->suResOnCC.RemoveAllCCs();
1160     EGs[i]->suPanOnCC.RemoveAllCCs();
1161 iliev 2299 EGs[i]->ResetUnits(); // class EqUnitSupport
1162 iliev 2244 }
1163    
1164     for (int i = 0; i < LFOs.capacity(); i++) {
1165     LFOs[i]->suDepthOnCC.RemoveAllCCs();
1166     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1167     LFOs[i]->suVolOnCC.RemoveAllCCs();
1168     LFOs[i]->suPitchOnCC.RemoveAllCCs();
1169     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1170     LFOs[i]->suPanOnCC.RemoveAllCCs();
1171     LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1172     LFOs[i]->suResOnCC.RemoveAllCCs();
1173 iliev 2299 LFOs[i]->ResetUnits(); // class EqUnitSupport
1174 iliev 2244 }
1175     }
1176 persson 2327
1177     void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1178     suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1179     for (int i = 0; i < EGs.capacity(); i++) {
1180     EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1181     }
1182     }
1183 iliev 2244
1184 iliev 2296 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1185     if (!pEqSupport->HasSupport()) return;
1186     if (pEqSupport->GetBandCount() < 3) {
1187     std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1188     return;
1189     }
1190    
1191     ::sfz::Region* const pRegion = pVoice->pRegion;
1192    
1193 iliev 2299 float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1194     float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1195     float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1196 iliev 2296
1197 iliev 2299 float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1198     float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1199     float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1200 iliev 2296
1201 iliev 2299 float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1202     float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1203     float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1204 iliev 2296
1205 schoenebeck 2879 const float vel = pVoice->MIDIVelocity() / 127.0f;
1206 iliev 2300
1207     dB1 += pRegion->eq1_vel2gain * vel;
1208     dB2 += pRegion->eq2_vel2gain * vel;
1209     dB3 += pRegion->eq3_vel2gain * vel;
1210    
1211     freq1 += pRegion->eq1_vel2freq * vel;
1212     freq2 += pRegion->eq2_vel2freq * vel;
1213     freq3 += pRegion->eq3_vel2freq * vel;
1214    
1215 iliev 2299 for (int i = 0; i < eqEGs.size(); i++) {
1216     EGv2Unit* eg = eqEGs[i];
1217     if (!eg->Active()) continue;
1218    
1219     float l = eg->GetLevel();
1220     dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1221     dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1222     dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1223    
1224     freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1225     freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1226     freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1227    
1228     bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1229     bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1230     bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1231     }
1232 iliev 2296
1233 iliev 2299 for (int i = 0; i < eqLFOs.size(); i++) {
1234     LFOv2Unit* lfo = eqLFOs[i];
1235     if (!lfo->Active()) continue;
1236    
1237     float l = lfo->GetLevel();
1238     dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1239     dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1240     dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1241    
1242     freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1243     freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1244     freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1245    
1246     bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1247     bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1248     bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1249     }
1250 iliev 2296
1251 iliev 2299 pEqSupport->SetGain(0, dB1);
1252     pEqSupport->SetGain(1, dB2);
1253     pEqSupport->SetGain(2, dB3);
1254 iliev 2296
1255 iliev 2299 pEqSupport->SetFreq(0, freq1);
1256     pEqSupport->SetFreq(1, freq2);
1257     pEqSupport->SetFreq(2, freq3);
1258 iliev 2296
1259 iliev 2299 pEqSupport->SetBandwidth(0, bw1);
1260     pEqSupport->SetBandwidth(1, bw2);
1261     pEqSupport->SetBandwidth(2, bw3);
1262 iliev 2296 }
1263    
1264 iliev 2299 EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1265     : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1266     suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1267     suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1268     {
1269     SetVoice(pVoice);
1270     }
1271    
1272     void EqUnitSupport::SetVoice(Voice* pVoice) {
1273     suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1274     suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1275     suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1276     }
1277    
1278     void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1279     if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1280     if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1281     if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1282     if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1283     if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1284     if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1285     if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1286     if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1287     if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1288     }
1289    
1290     void EqUnitSupport::ResetUnits() {
1291     suEq1GainOnCC.RemoveAllCCs();
1292     suEq2GainOnCC.RemoveAllCCs();
1293     suEq3GainOnCC.RemoveAllCCs();
1294     suEq1FreqOnCC.RemoveAllCCs();
1295     suEq2FreqOnCC.RemoveAllCCs();
1296     suEq3FreqOnCC.RemoveAllCCs();
1297     suEq1BwOnCC.RemoveAllCCs();
1298     suEq2BwOnCC.RemoveAllCCs();
1299     suEq3BwOnCC.RemoveAllCCs();
1300     }
1301    
1302     void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1303     suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1304     suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1305     suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1306     suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1307     suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1308     suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1309     suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1310     suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1311     suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1312     }
1313    
1314 iliev 2218 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC