/[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 2879 - (hide annotations) (download)
Tue Apr 19 14:07:53 2016 UTC (8 years ago) by schoenebeck
File size: 57041 byte(s)
* All engines: Active voices are now internally grouped to "Note" objects,
  instead of being directly assigned to a keyboard key. This allows more
  fine graded processing of voices, which is i.e. required for certain
  instrument script features.
* Built-in script function "play_note()": Added support for passing
  special value -1 for "duration-us" argument, which will cause the
  triggered note to be released once the original note was released.
* Bumped version (2.0.0.svn3).

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

  ViewVC Help
Powered by ViewVC