/[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 3118 - (hide annotations) (download)
Fri Apr 21 13:33:03 2017 UTC (7 years ago) by schoenebeck
File size: 57054 byte(s)
* NKSP: Fixed crash when using built-in script array variable "%ALL_EVENTS".
* NKSP: Added built-in function "change_amp_lfo_depth()".
* NKSP: Added built-in function "change_amp_lfo_freq()".
* NKSP: Added built-in function "change_pitch_lfo_depth()".
* NKSP: Added built-in function "change_pitch_lfo_freq()".
* Bumped version (2.0.0.svn44).

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    
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 persson 2311 uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
252 iliev 2229 );
253     }
254    
255    
256 iliev 2227 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257     : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258 schoenebeck 3034 suFadeEG(rack), suDepthOnCC(rack), suFreqOnCC(rack, this)
259 iliev 2227 { }
260    
261     LFOUnit::LFOUnit(const LFOUnit& Unit)
262     : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263 schoenebeck 3034 suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
264     suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
265 iliev 2227 {
266 iliev 2226 Copy(Unit);
267     }
268 iliev 2222
269 iliev 2219 void LFOUnit::Increment() {
270     if (DelayStage()) return;
271    
272     SignalUnit::Increment();
273    
274 iliev 2223 Level = pLFO->Render();
275 iliev 2226 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276 iliev 2219 }
277    
278     void LFOUnit::Trigger() {
279     //reset
280     Level = 0;
281    
282     // set the delay trigger
283 iliev 2233 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
284 iliev 2226 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285     float f = pLfoInfo->fade;
286 iliev 2229 f += GetInfluence(pLfoInfo->fade_oncc);
287 iliev 2226
288     if (f != 0) {
289     suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290 persson 2311 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
291 iliev 2226 }
292     }
293 iliev 2219 }
294    
295 iliev 2227 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296 iliev 2251 if (pLFO == NULL) return;
297 iliev 2229 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298 iliev 2227 }
299    
300    
301 iliev 2221 void LFOv1Unit::Trigger() {
302     LFOUnit::Trigger();
303    
304     lfo.trigger (
305 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
306 iliev 2221 start_level_mid,
307     1, 0, false, GetSampleRate()
308     );
309 schoenebeck 3118 lfo.updateByMIDICtrlValue(0);
310 iliev 2221 }
311    
312 iliev 2223
313     LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314 iliev 2299 : LFOUnit(rack), EqUnitSupport(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315 iliev 2225 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316 iliev 2233 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317 iliev 2223 {
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 iliev 2219 void LFOv2Unit::Trigger() {
329     LFOUnit::Trigger();
330    
331 schoenebeck 3054 if (/*pLfoInfo->wave < 0 ||*/ pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332 iliev 2223 else pLFO = lfos[pLfoInfo->wave];
333    
334     pLFO->Trigger (
335 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
336 iliev 2219 start_level_mid,
337     1, 0, false, GetSampleRate()
338     );
339 iliev 2223 pLFO->Update(0);
340 iliev 2225
341 iliev 2229 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
342 iliev 2225 if (phase != 0) pLFO->SetPhase(phase);
343 iliev 2219 }
344 iliev 2221
345     void AmpLFOUnit::Trigger() {
346 iliev 2251 bActive = true;
347 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
348 iliev 2248 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349 iliev 2226 pLfoInfo->freq = pRegion->amplfo_freq;
350 iliev 2248 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351 iliev 2221 pLfoInfo->volume = pRegion->amplfo_depth;
352    
353 iliev 2251 if (pLfoInfo->freq <= 0) {
354     if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
355     else bActive = false;
356     }
357    
358 iliev 2221 LFOv1Unit::Trigger();
359     }
360    
361     void PitchLFOUnit::Trigger() {
362 iliev 2251 bActive = true;
363 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
364 iliev 2248 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365 iliev 2226 pLfoInfo->freq = pRegion->pitchlfo_freq;
366 iliev 2248 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367 iliev 2221 pLfoInfo->pitch = pRegion->pitchlfo_depth;
368    
369 iliev 2251 if (pLfoInfo->freq <= 0) {
370     if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
371     else bActive = false;
372     }
373    
374 iliev 2221 LFOv1Unit::Trigger();
375     }
376    
377     void FilLFOUnit::Trigger() {
378 iliev 2251 bActive = true;
379 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
380 iliev 2248 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381 iliev 2226 pLfoInfo->freq = pRegion->fillfo_freq;
382 iliev 2248 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383 iliev 2221 pLfoInfo->cutoff = pRegion->fillfo_depth;
384    
385 iliev 2251 if (pLfoInfo->freq <= 0) {
386     if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
387     else bActive = false;
388     }
389    
390 iliev 2221 LFOv1Unit::Trigger();
391     }
392 iliev 2224
393 iliev 2227 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
394     pVoice = NULL;
395     }
396 iliev 2224
397     void CCUnit::Trigger() {
398 iliev 2244 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 iliev 2264 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 iliev 2224 }
411     CCSignalUnit::Trigger();
412     }
413    
414 iliev 2244 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 iliev 2225
421 iliev 2296 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 iliev 2244 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 iliev 2264 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435 iliev 2244 }
436     }
437     }
438 iliev 2230
439 iliev 2264 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440     AddCC(Controller, Influence, Curve, NULL, Step);
441 iliev 2244 }
442 iliev 2232
443 iliev 2244 int CCUnit::GetCurveCount() {
444     return pVoice->pRegion->GetInstrument()->curves.size();
445     }
446 iliev 2230
447 iliev 2244 ::sfz::Curve* CCUnit::GetCurve(int idx) {
448     return &pVoice->pRegion->GetInstrument()->curves[idx];
449     }
450 iliev 2232
451 iliev 2244 double CCUnit::GetSampleRate() {
452 iliev 2232 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
453     }
454 iliev 2244
455    
456     SmoothCCUnit::~SmoothCCUnit() {
457     if (pSmoothers != NULL) delete pSmoothers;
458     }
459 iliev 2232
460 iliev 2264 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461 iliev 2244 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 iliev 2264 AddCC(Controller, Influence, Curve, smoother, Step);
469 iliev 2244 } else {
470 iliev 2264 AddCC(Controller, Influence, Curve, NULL, Step);
471 iliev 2244 }
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 iliev 2218
484 iliev 2219
485 iliev 2237 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486 schoenebeck 3034 : EndpointSignalUnit(rack), pitchVeltrackRatio(0), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack)
487 iliev 2237 {
488 iliev 2218
489     }
490    
491 schoenebeck 3082 float EndpointUnit::GetInfluence(::sfz::Array< optional<float> >& cc) {
492 iliev 2297 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 schoenebeck 3082 float EndpointUnit::GetInfluence(::sfz::Array< optional<int> >& cc) {
502 iliev 2297 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 iliev 2218 SfzSignalUnitRack* const EndpointUnit::GetRack() {
512     return static_cast<SfzSignalUnitRack* const>(pRack);
513     }
514    
515     void EndpointUnit::Trigger() {
516 iliev 2297 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 iliev 2236 float xfInVelCoeff = 1;
532 iliev 2218
533 schoenebeck 2879 if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
534 iliev 2236 xfInVelCoeff = 0;
535 schoenebeck 2879 } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
536 iliev 2236 xfInVelCoeff = 1;
537     } else {
538     float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
539 schoenebeck 2879 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
540 iliev 2236 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 schoenebeck 2879 if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
549 iliev 2236 if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
550 schoenebeck 2879 } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
551 iliev 2236 xfOutVelCoeff = 1;
552     } else {
553     float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
554 schoenebeck 2879 float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
555 iliev 2236 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 schoenebeck 2879 if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
564 iliev 2236 if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
565 schoenebeck 2879 } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
566 iliev 2236 xfInKeyCoeff = 1;
567     } else {
568     float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
569 schoenebeck 2879 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
570 iliev 2236 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 schoenebeck 2879 if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
579 iliev 2236 if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
580 schoenebeck 2879 } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
581 iliev 2236 xfOutKeyCoeff = 1;
582     } else {
583     float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
584 schoenebeck 2879 float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
585 iliev 2236 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 iliev 2237
596     suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
597    
598 schoenebeck 2879 pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
599 iliev 2218 }
600    
601     bool EndpointUnit::Active() {
602 iliev 2297 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 iliev 2218 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 iliev 2229
623 iliev 2235 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 iliev 2244 amp *= ToRatio(dB * 10.0);
633 iliev 2235 }
634    
635     vol += amp * eg->GetLevel();
636 iliev 2218 }
637    
638 iliev 2221 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
639 iliev 2233 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
640     float f = u2->Active() ? u2->GetLevel() : 0;
641 iliev 2244 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
642 iliev 2221
643 iliev 2244 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
644 iliev 2230
645 iliev 2233 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 iliev 2244 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
651 iliev 2233 }
652    
653 iliev 2236 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
654     if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
655     return vol * xfCoeff;
656 iliev 2218 }
657    
658     float EndpointUnit::GetFilterCutoff() {
659 iliev 2252 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660 iliev 2219
661 iliev 2221 FilLFOUnit* u = &(GetRack()->suFilLFO);
662 iliev 2233 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663     float f = u1->Active() ? u1->GetLevel() : 0;
664 iliev 2252 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
665 iliev 2221
666 iliev 2222 FilEGUnit* u2 = &(GetRack()->suFilEG);
667     val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
668    
669 iliev 2235 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 iliev 2219 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
679     LFOv2Unit* lfo = GetRack()->filLFOs[i];
680     if (!lfo->Active()) continue;
681    
682 iliev 2233 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
683     f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
684 iliev 2219 val *= RTMath::CentsToFreqRatioUnlimited(f);
685     }
686    
687     return val;
688 iliev 2218 }
689    
690 iliev 2235 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691 iliev 2252 cutoff *= GetFilterCutoff();
692     float maxCutoff = 0.49 * pVoice->GetSampleRate();
693     return cutoff > maxCutoff ? maxCutoff : cutoff;
694 iliev 2235 }
695    
696 iliev 2218 float EndpointUnit::GetPitch() {
697 iliev 2264 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698    
699 iliev 2220 EGv1Unit* u = &(GetRack()->suPitchEG);
700 iliev 2264 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701 iliev 2221
702 iliev 2235 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 iliev 2221 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
711 iliev 2233 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
712 iliev 2224 float f = u3->Active() ? u3->GetLevel() : 0;
713     p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
714 iliev 2225
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 iliev 2237 return p * pitchVeltrackRatio;
724 iliev 2218 }
725    
726     float EndpointUnit::GetResonance() {
727 iliev 2252 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
728 iliev 2219
729 iliev 2235 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 iliev 2219 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
738     LFOv2Unit* lfo = GetRack()->resLFOs[i];
739     if (!lfo->Active()) continue;
740    
741 iliev 2233 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
742     val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
743 iliev 2219 }
744    
745     return val;
746 iliev 2218 }
747    
748 iliev 2219 float EndpointUnit::GetPan() {
749 iliev 2237 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
750 iliev 2219
751 iliev 2237 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 iliev 2219 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
767     LFOv2Unit* lfo = GetRack()->panLFOs[i];
768     if (!lfo->Active()) continue;
769    
770 iliev 2233 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
771     pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772 iliev 2219 }
773    
774     return pan;
775     }
776 iliev 2218
777 iliev 2219
778 iliev 2218 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
779 schoenebeck 3034 : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice),
780 iliev 2299 suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
781 schoenebeck 3034 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
782     suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
783 iliev 2299 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
784     resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
785 iliev 2233 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
786 schoenebeck 3034 filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount),
787     pVoice(voice)
788 iliev 2218 {
789 iliev 2237 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
790 iliev 2236 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
791 iliev 2264 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
792 iliev 2296
793 iliev 2264 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
794 iliev 2233 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
795     suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
796     suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
797 iliev 2218
798     for (int i = 0; i < EGs.capacity(); i++) {
799     EGs[i] = new EGv2Unit(this);
800     EGs[i]->pVoice = voice;
801 iliev 2235 EGs[i]->suAmpOnCC.pVoice = voice;
802     EGs[i]->suVolOnCC.pVoice = voice;
803     EGs[i]->suPitchOnCC.pVoice = voice;
804     EGs[i]->suCutoffOnCC.pVoice = voice;
805     EGs[i]->suResOnCC.pVoice = voice;
806 iliev 2237 EGs[i]->suPanOnCC.pVoice = voice;
807 iliev 2299 EGs[i]->SetVoice(voice); // class EqUnitSupport
808 iliev 2218 }
809 iliev 2219
810     for (int i = 0; i < LFOs.capacity(); i++) {
811     LFOs[i] = new LFOv2Unit(this);
812     LFOs[i]->pVoice = voice;
813 iliev 2244 LFOs[i]->suDepthOnCC.pVoice = voice;
814     LFOs[i]->suFreqOnCC.pVoice = voice;
815 iliev 2226 LFOs[i]->suFadeEG.pVoice = voice;
816 iliev 2233 LFOs[i]->suVolOnCC.pVoice = voice;
817 iliev 2225 LFOs[i]->suPitchOnCC.pVoice = voice;
818 iliev 2227 LFOs[i]->suFreqOnCC.pVoice = voice;
819 iliev 2233 LFOs[i]->suPanOnCC.pVoice = voice;
820     LFOs[i]->suCutoffOnCC.pVoice = voice;
821     LFOs[i]->suResOnCC.pVoice = voice;
822 iliev 2299 LFOs[i]->SetVoice(voice); // class EqUnitSupport
823 iliev 2219 }
824 iliev 2218 }
825    
826     SfzSignalUnitRack::~SfzSignalUnitRack() {
827 iliev 2219 for (int i = 0; i < EGs.capacity(); i++) {
828 iliev 2218 delete EGs[i]; EGs[i] = NULL;
829     }
830 iliev 2219
831     for (int i = 0; i < LFOs.capacity(); i++) {
832     delete LFOs[i]; LFOs[i] = NULL;
833     }
834 iliev 2218 }
835    
836 iliev 2244 void SfzSignalUnitRack::InitRTLists() {
837     Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
838     Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
839    
840 iliev 2299 EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
841 iliev 2296
842 iliev 2244 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
843 iliev 2264 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
844 iliev 2252 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
845     suResOnCC.InitCCList(pCCPool, pSmootherPool);
846 iliev 2244 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
847     suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
848     suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
849     suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
850     suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
851     suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
852     suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
853     suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
854     suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
855    
856     for (int i = 0; i < EGs.capacity(); i++) {
857     EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
858     EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
859     EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
860     EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
861     EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
862     EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
863 iliev 2299 EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
864 iliev 2244 }
865    
866     for (int i = 0; i < LFOs.capacity(); i++) {
867     LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
868     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
869     LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
870     LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
871     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
872     LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
873     LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
874     LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
875 iliev 2299 LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
876 iliev 2244 }
877     }
878    
879 iliev 2218 void SfzSignalUnitRack::Trigger() {
880     EGs.clear();
881     volEGs.clear();
882     pitchEGs.clear();
883 iliev 2235 filEGs.clear();
884     resEGs.clear();
885 iliev 2237 panEGs.clear();
886 iliev 2299 eqEGs.clear();
887 iliev 2218
888 iliev 2219 LFOs.clear();
889 iliev 2233 volLFOs.clear();
890 iliev 2225 pitchLFOs.clear();
891 iliev 2219 filLFOs.clear();
892     resLFOs.clear();
893     panLFOs.clear();
894 iliev 2299 eqLFOs.clear();
895 iliev 2219
896 iliev 2218 ::sfz::Region* const pRegion = pVoice->pRegion;
897    
898 iliev 2230 suVolOnCC.SetCCs(pRegion->volume_oncc);
899 iliev 2264 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
900 iliev 2252 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
901     suResOnCC.SetCCs(pRegion->resonance_oncc);
902 iliev 2230
903 iliev 2219 for (int i = 0; i < pRegion->eg.size(); i++) {
904 iliev 2218 if (pRegion->eg[i].node.size() == 0) continue;
905    
906     if(EGs.size() < EGs.capacity()) {
907     EGv2Unit eg(this);
908     eg.pEGInfo = &(pRegion->eg[i]);
909     EGs.increment()->Copy(eg);
910 iliev 2235 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
911     EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
912     EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
913     EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
914     EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
915 iliev 2237 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
916 iliev 2299 if (pVoice->bEqSupport) {
917     EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
918     EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
919     EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
920     EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
921     EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
922     EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
923     EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
924     EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
925     EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
926     }
927 iliev 2218 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
928    
929 iliev 2235 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
930     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
931     ) {
932 iliev 2218 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
933     else std::cerr << "Maximum number of EGs reached!" << std::endl;
934     }
935 iliev 2235
936     if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
937     if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
938     else std::cerr << "Maximum number of EGs reached!" << std::endl;
939     }
940    
941     if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
942     if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
943     else std::cerr << "Maximum number of EGs reached!" << std::endl;
944     }
945    
946     if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
947     if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
948     else std::cerr << "Maximum number of EGs reached!" << std::endl;
949     }
950 iliev 2237
951     if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
952     if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
953     else std::cerr << "Maximum number of EGs reached!" << std::endl;
954     }
955 iliev 2299
956     if (pRegion->eg[i].HasEq()) {
957     if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
958     else std::cerr << "Maximum number of EGs reached!" << std::endl;
959     }
960 iliev 2218 }
961    
962     if (pRegion->ampeg_sustain == -1) {
963     if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
964     else pRegion->ampeg_sustain = 100;
965     }
966    
967 iliev 2219 // LFO
968     for (int i = 0; i < pRegion->lfos.size(); i++) {
969 iliev 2251 if (pRegion->lfos[i].freq <= 0) {
970     if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
971     else pRegion->lfos[i].freq = 0;
972     }
973 iliev 2219
974     if(LFOs.size() < LFOs.capacity()) {
975     LFOv2Unit lfo(this);
976     lfo.pLfoInfo = &(pRegion->lfos[i]);
977     LFOs.increment()->Copy(lfo);
978 iliev 2233 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
979 iliev 2225 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
980 iliev 2227 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
981 iliev 2233 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
982     LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
983     LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
984 iliev 2299 if (pVoice->bEqSupport) {
985     LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
986     LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
987     LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
988     LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
989     LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
990     LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
991     LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
992     LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
993     LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
994     }
995 iliev 2219 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
996    
997 iliev 2233 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
998     if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
999     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1000     }
1001    
1002 iliev 2225 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1003     if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1004     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1005     }
1006    
1007 iliev 2233 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1008 iliev 2219 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1009     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1010     }
1011    
1012 iliev 2233 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1013 iliev 2219 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1014     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1015     }
1016    
1017 iliev 2233 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1018 iliev 2219 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1019     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1020     }
1021 iliev 2299
1022     if (pRegion->lfos[i].HasEq()) {
1023     if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1024     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1025     }
1026 iliev 2219 }
1027    
1028 iliev 2299 if (!pVoice->bEqSupport) {
1029     bHasEq = false;
1030     } else {
1031     suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1032     suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1033     suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1034     suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1035     suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1036     suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1037     suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1038     suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1039     suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1040    
1041     bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1042 iliev 2300 pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1043 iliev 2299 suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1044     eqEGs.size() > 0 || eqLFOs.size() > 0;
1045     }
1046    
1047 iliev 2233 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1048 iliev 2227 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1049 iliev 2224
1050 iliev 2233 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1051 iliev 2227 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1052    
1053 iliev 2233 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1054 iliev 2227 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1055    
1056 iliev 2218 Units.clear();
1057    
1058 iliev 2299 EqUnitSupport::ImportUnits(this);
1059 iliev 2296
1060 iliev 2230 Units.add(&suVolOnCC);
1061 iliev 2264 Units.add(&suPitchOnCC);
1062 iliev 2252 Units.add(&suCutoffOnCC);
1063     Units.add(&suResOnCC);
1064 iliev 2230
1065 iliev 2218 Units.add(&suVolEG);
1066 iliev 2222 Units.add(&suFilEG);
1067 iliev 2220 Units.add(&suPitchEG);
1068 iliev 2227
1069     Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1070 iliev 2221 Units.add(&suPitchLFO);
1071 iliev 2233 Units.add(&suPitchLFO.suDepthOnCC);
1072 iliev 2226 Units.add(&suPitchLFO.suFadeEG);
1073 iliev 2227
1074     Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1075 iliev 2233 Units.add(&suAmpLFO.suDepthOnCC);
1076 iliev 2221 Units.add(&suAmpLFO);
1077 iliev 2226 Units.add(&suAmpLFO.suFadeEG);
1078 iliev 2227
1079     Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1080 iliev 2233 Units.add(&suFilLFO.suDepthOnCC);
1081 iliev 2221 Units.add(&suFilLFO);
1082 iliev 2226 Units.add(&suFilLFO.suFadeEG);
1083 iliev 2218
1084 iliev 2219 for (int i = 0; i < EGs.size(); i++) {
1085 iliev 2218 Units.add(EGs[i]);
1086 iliev 2235 Units.add(&(EGs[i]->suAmpOnCC));
1087     Units.add(&(EGs[i]->suVolOnCC));
1088     Units.add(&(EGs[i]->suPitchOnCC));
1089     Units.add(&(EGs[i]->suCutoffOnCC));
1090     Units.add(&(EGs[i]->suResOnCC));
1091 iliev 2237 Units.add(&(EGs[i]->suPanOnCC));
1092 iliev 2299 EGs[i]->ImportUnits(this); // class EqUnitSupport
1093 iliev 2218 }
1094    
1095 iliev 2219 for (int i = 0; i < LFOs.size(); i++) {
1096 iliev 2227 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1097 iliev 2219 Units.add(LFOs[i]);
1098 iliev 2226 Units.add(&(LFOs[i]->suFadeEG));
1099 iliev 2233 Units.add(&(LFOs[i]->suVolOnCC));
1100 iliev 2225 Units.add(&(LFOs[i]->suPitchOnCC));
1101 iliev 2233 Units.add(&(LFOs[i]->suPanOnCC));
1102     Units.add(&(LFOs[i]->suCutoffOnCC));
1103     Units.add(&(LFOs[i]->suResOnCC));
1104 iliev 2299 LFOs[i]->ImportUnits(this); // class EqUnitSupport
1105 iliev 2219 }
1106    
1107 iliev 2218 Units.add(&suEndpoint);
1108 iliev 2236 Units.add(&suEndpoint.suXFInCC);
1109     Units.add(&suEndpoint.suXFOutCC);
1110 iliev 2237 Units.add(&suEndpoint.suPanOnCC);
1111 iliev 2218
1112     SignalUnitRack::Trigger();
1113     }
1114    
1115     EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1116     return &suEndpoint;
1117     }
1118    
1119     void SfzSignalUnitRack::EnterFadeOutStage() {
1120     suVolEG.EG.enterFadeOutStage();
1121    
1122     for (int i = 0; i < volEGs.size(); i++) {
1123     volEGs[i]->EG.enterFadeOutStage();
1124     }
1125     }
1126 persson 2327
1127     void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1128     suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1129     for (int i = 0; i < volEGs.size(); i++) {
1130     volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1131     }
1132     }
1133    
1134 iliev 2244 void SfzSignalUnitRack::Reset() {
1135 iliev 2299 EqUnitSupport::ResetUnits();
1136 iliev 2296
1137 iliev 2244 suVolOnCC.RemoveAllCCs();
1138 iliev 2264 suPitchOnCC.RemoveAllCCs();
1139 iliev 2252 suCutoffOnCC.RemoveAllCCs();
1140     suResOnCC.RemoveAllCCs();
1141 iliev 2244 suEndpoint.suXFInCC.RemoveAllCCs();
1142     suEndpoint.suXFOutCC.RemoveAllCCs();
1143     suEndpoint.suPanOnCC.RemoveAllCCs();
1144     suPitchLFO.suDepthOnCC.RemoveAllCCs();
1145     suPitchLFO.suFreqOnCC.RemoveAllCCs();
1146     suFilLFO.suDepthOnCC.RemoveAllCCs();
1147     suFilLFO.suFreqOnCC.RemoveAllCCs();
1148     suAmpLFO.suDepthOnCC.RemoveAllCCs();
1149     suAmpLFO.suFreqOnCC.RemoveAllCCs();
1150    
1151     for (int i = 0; i < EGs.capacity(); i++) {
1152     EGs[i]->suAmpOnCC.RemoveAllCCs();
1153     EGs[i]->suVolOnCC.RemoveAllCCs();
1154     EGs[i]->suPitchOnCC.RemoveAllCCs();
1155     EGs[i]->suCutoffOnCC.RemoveAllCCs();
1156     EGs[i]->suResOnCC.RemoveAllCCs();
1157     EGs[i]->suPanOnCC.RemoveAllCCs();
1158 iliev 2299 EGs[i]->ResetUnits(); // class EqUnitSupport
1159 iliev 2244 }
1160    
1161     for (int i = 0; i < LFOs.capacity(); i++) {
1162     LFOs[i]->suDepthOnCC.RemoveAllCCs();
1163     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1164     LFOs[i]->suVolOnCC.RemoveAllCCs();
1165     LFOs[i]->suPitchOnCC.RemoveAllCCs();
1166     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1167     LFOs[i]->suPanOnCC.RemoveAllCCs();
1168     LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1169     LFOs[i]->suResOnCC.RemoveAllCCs();
1170 iliev 2299 LFOs[i]->ResetUnits(); // class EqUnitSupport
1171 iliev 2244 }
1172     }
1173 persson 2327
1174     void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1175     suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1176     for (int i = 0; i < EGs.capacity(); i++) {
1177     EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1178     }
1179     }
1180 iliev 2244
1181 iliev 2296 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1182     if (!pEqSupport->HasSupport()) return;
1183     if (pEqSupport->GetBandCount() < 3) {
1184     std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1185     return;
1186     }
1187    
1188     ::sfz::Region* const pRegion = pVoice->pRegion;
1189    
1190 iliev 2299 float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1191     float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1192     float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1193 iliev 2296
1194 iliev 2299 float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1195     float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1196     float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1197 iliev 2296
1198 iliev 2299 float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1199     float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1200     float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1201 iliev 2296
1202 schoenebeck 2879 const float vel = pVoice->MIDIVelocity() / 127.0f;
1203 iliev 2300
1204     dB1 += pRegion->eq1_vel2gain * vel;
1205     dB2 += pRegion->eq2_vel2gain * vel;
1206     dB3 += pRegion->eq3_vel2gain * vel;
1207    
1208     freq1 += pRegion->eq1_vel2freq * vel;
1209     freq2 += pRegion->eq2_vel2freq * vel;
1210     freq3 += pRegion->eq3_vel2freq * vel;
1211    
1212 iliev 2299 for (int i = 0; i < eqEGs.size(); i++) {
1213     EGv2Unit* eg = eqEGs[i];
1214     if (!eg->Active()) continue;
1215    
1216     float l = eg->GetLevel();
1217     dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1218     dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1219     dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1220    
1221     freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1222     freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1223     freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1224    
1225     bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1226     bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1227     bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1228     }
1229 iliev 2296
1230 iliev 2299 for (int i = 0; i < eqLFOs.size(); i++) {
1231     LFOv2Unit* lfo = eqLFOs[i];
1232     if (!lfo->Active()) continue;
1233    
1234     float l = lfo->GetLevel();
1235     dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1236     dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1237     dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1238    
1239     freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1240     freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1241     freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1242    
1243     bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1244     bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1245     bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1246     }
1247 iliev 2296
1248 iliev 2299 pEqSupport->SetGain(0, dB1);
1249     pEqSupport->SetGain(1, dB2);
1250     pEqSupport->SetGain(2, dB3);
1251 iliev 2296
1252 iliev 2299 pEqSupport->SetFreq(0, freq1);
1253     pEqSupport->SetFreq(1, freq2);
1254     pEqSupport->SetFreq(2, freq3);
1255 iliev 2296
1256 iliev 2299 pEqSupport->SetBandwidth(0, bw1);
1257     pEqSupport->SetBandwidth(1, bw2);
1258     pEqSupport->SetBandwidth(2, bw3);
1259 iliev 2296 }
1260    
1261 iliev 2299 EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1262     : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1263     suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1264     suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1265     {
1266     SetVoice(pVoice);
1267     }
1268    
1269     void EqUnitSupport::SetVoice(Voice* pVoice) {
1270     suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1271     suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1272     suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1273     }
1274    
1275     void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1276     if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1277     if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1278     if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1279     if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1280     if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1281     if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1282     if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1283     if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1284     if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1285     }
1286    
1287     void EqUnitSupport::ResetUnits() {
1288     suEq1GainOnCC.RemoveAllCCs();
1289     suEq2GainOnCC.RemoveAllCCs();
1290     suEq3GainOnCC.RemoveAllCCs();
1291     suEq1FreqOnCC.RemoveAllCCs();
1292     suEq2FreqOnCC.RemoveAllCCs();
1293     suEq3FreqOnCC.RemoveAllCCs();
1294     suEq1BwOnCC.RemoveAllCCs();
1295     suEq2BwOnCC.RemoveAllCCs();
1296     suEq3BwOnCC.RemoveAllCCs();
1297     }
1298    
1299     void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1300     suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1301     suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1302     suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1303     suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1304     suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1305     suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1306     suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1307     suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1308     suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1309     }
1310    
1311 iliev 2218 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC