/[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 3316 - (hide annotations) (download)
Thu Jul 20 12:05:53 2017 UTC (6 years, 9 months ago) by schoenebeck
File size: 57129 byte(s)
* NKSP: Implemented built-in script function "change_sustain()".
* Bumped version (2.0.0.svn72).

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

  ViewVC Help
Powered by ViewVC