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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.2220  
changed lines
  Added in v.3054

  ViewVC Help
Powered by ViewVC