/[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 2223 by iliev, Fri Jul 29 13:39:58 2011 UTC revision 2299 by iliev, Sun Dec 11 20:50:31 2011 UTC
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "SfzSignalUnitRack.h"  #include "SfzSignalUnitRack.h"
24  #include "Voice.h"  #include "Engine.h"
25  #include <SF.h>  
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 34  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 EGv1Unit::Trigger() {      void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53          ::sfz::Region* const pRegion = pVoice->pRegion;          RemoveAllCCs();
54                    
55          // the length of the decay and release curves are dependent on the velocity          for (int cc = 0; cc < 128; cc++) {
56          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);              if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57                int i = loCCs[cc];
58          // set the delay trigger              int j = hiCCs[cc];
59          uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate();              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          EG.trigger(uint(pRegion->ampeg_start * 10),          if (Level != l) {
92                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),              Level = l;
93                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),              if (pListener != NULL) pListener->ValueChanged(this);
94                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          }
95                     uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),      }
96                     std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),      
97                     GetSampleRate());      
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() {      void EGv2Unit::Trigger() {
137          EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);          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 PitchEGUnit::Trigger() {      void PitchEGUnit::Trigger() {
150          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
151          depth = pRegion->pitcheg_depth;          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->pitcheg_delay + pRegion->pitcheg_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            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171                    
172          EG.trigger(uint(pRegion->pitcheg_start * 10),          float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
175                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176                     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->pitcheg_release_oncc));
177                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
178                     GetSampleRate());          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()
181            );
182      }      }
183            
184            
185      void FilEGUnit::Trigger() {      void FilEGUnit::Trigger() {
186          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
187          depth = pRegion->fileg_depth;          depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188                    
189          // 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
190          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191    
192          // set the delay trigger          // set the delay trigger
193          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          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          EG.trigger(uint(pRegion->fileg_start * 10),          float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
214                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          EG.trigger (
215                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217                     GetSampleRate());          );
218      }      }
219            
220        
221        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            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226    
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                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252            );
253        }
254        
255        
256        LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257            : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258              suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259        { }
260        
261        LFOUnit::LFOUnit(const LFOUnit& Unit)
262            : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263              suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265        {
266            Copy(Unit);
267        }
268    
269      void LFOUnit::Increment() {      void LFOUnit::Increment() {
270          if (DelayStage()) return;          if (DelayStage()) return;
# Line 105  namespace LinuxSampler { namespace sfz { Line 272  namespace LinuxSampler { namespace sfz {
272          SignalUnit::Increment();          SignalUnit::Increment();
273                    
274          Level = pLFO->Render();          Level = pLFO->Render();
275            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276      }      }
277            
278      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 112  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());
291                }
292            }
293        }
294        
295        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() {      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          );          );
# Line 128  namespace LinuxSampler { namespace sfz { Line 311  namespace LinuxSampler { namespace sfz {
311            
312            
313      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),          : 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)            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);          lfos.add(&lfo0);
319          lfos.add(&lfo1);          lfos.add(&lfo1);
# Line 148  namespace LinuxSampler { namespace sfz { Line 332  namespace LinuxSampler { namespace sfz {
332          else pLFO = lfos[pLfoInfo->wave];          else pLFO = lfos[pLfoInfo->wave];
333                    
334          pLFO->Trigger (          pLFO->Trigger (
335              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
336              start_level_mid,              start_level_mid,
337              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
338          );          );
339          pLFO->Update(0);          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() {      void AmpLFOUnit::Trigger() {
346            bActive = true;
347          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
348          pLfoInfo->delay = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349          pLfoInfo->freq = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
350            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351          pLfoInfo->volume = pRegion->amplfo_depth;          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();          LFOv1Unit::Trigger();
359      }      }
360            
361      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
362            bActive = true;
363          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
364          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365          pLfoInfo->freq = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
366            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367          pLfoInfo->pitch = pRegion->pitchlfo_depth;          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();          LFOv1Unit::Trigger();
375      }      }
376            
377      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
378            bActive = true;
379          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
380          pLfoInfo->delay = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381          pLfoInfo->freq = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
382            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383          pLfoInfo->cutoff = pRegion->fillfo_depth;          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();          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), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
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 212  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);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
639          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          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;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660                    
661          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
662          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          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);          FilEGUnit* u2 = &(GetRack()->suFilEG);
667          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          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;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698            
699          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
700          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701            
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);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
711          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->pLfoInfo->pitch) : 1;          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;          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                    
774          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 283  namespace LinuxSampler { namespace sfz { Line 779  namespace LinuxSampler { namespace sfz {
779            
780            
781      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
782          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice), pVoice(voice),
783          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
784            EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
785            resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
786            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
787          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
788          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
789            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount)
790      {      {
791          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
792            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
793          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
794                    
795            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
796            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
797            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
798            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
799            
800          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
801              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
802              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
803                EGs[i]->suAmpOnCC.pVoice = voice;
804                EGs[i]->suVolOnCC.pVoice = voice;
805                EGs[i]->suPitchOnCC.pVoice = voice;
806                EGs[i]->suCutoffOnCC.pVoice = voice;
807                EGs[i]->suResOnCC.pVoice = voice;
808                EGs[i]->suPanOnCC.pVoice = voice;
809                EGs[i]->SetVoice(voice); // class EqUnitSupport
810          }          }
811                    
812          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
813              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
814              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
815                LFOs[i]->suDepthOnCC.pVoice = voice;
816                LFOs[i]->suFreqOnCC.pVoice = voice;
817                LFOs[i]->suFadeEG.pVoice = voice;
818                LFOs[i]->suVolOnCC.pVoice = voice;
819                LFOs[i]->suPitchOnCC.pVoice = voice;
820                LFOs[i]->suFreqOnCC.pVoice = voice;
821                LFOs[i]->suPanOnCC.pVoice = voice;
822                LFOs[i]->suCutoffOnCC.pVoice = voice;
823                LFOs[i]->suResOnCC.pVoice = voice;
824                LFOs[i]->SetVoice(voice); // class EqUnitSupport
825          }          }
826      }      }
827            
# Line 312  namespace LinuxSampler { namespace sfz { Line 835  namespace LinuxSampler { namespace sfz {
835          }          }
836      }      }
837            
838        void SfzSignalUnitRack::InitRTLists() {
839            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
840            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
841            
842            EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
843            
844            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
845            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
846            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847            suResOnCC.InitCCList(pCCPool, pSmootherPool);
848            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
849            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
850            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
851            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
852            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
853            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
854            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
855            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
856            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
857            
858            for (int i = 0; i < EGs.capacity(); i++) {
859                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
860                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
861                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
862                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
863                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
864                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
865                EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
866            }
867            
868            for (int i = 0; i < LFOs.capacity(); i++) {
869                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
870                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
871                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
874                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
875                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
876                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
877                LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
878            }
879        }
880        
881      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
882          EGs.clear();          EGs.clear();
883          volEGs.clear();          volEGs.clear();
884          pitchEGs.clear();          pitchEGs.clear();
885            filEGs.clear();
886            resEGs.clear();
887            panEGs.clear();
888            eqEGs.clear();
889                    
890          LFOs.clear();          LFOs.clear();
891            volLFOs.clear();
892            pitchLFOs.clear();
893          filLFOs.clear();          filLFOs.clear();
894          resLFOs.clear();          resLFOs.clear();
895          panLFOs.clear();          panLFOs.clear();
896            eqLFOs.clear();
897                    
898          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
899                    
900            suVolOnCC.SetCCs(pRegion->volume_oncc);
901            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
902            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
903            suResOnCC.SetCCs(pRegion->resonance_oncc);
904            
905          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
906              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
907                            
# Line 331  namespace LinuxSampler { namespace sfz { Line 909  namespace LinuxSampler { namespace sfz {
909                  EGv2Unit eg(this);                  EGv2Unit eg(this);
910                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
911                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
912                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
913                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
914                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
915                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
916                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
917                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
918                    if (pVoice->bEqSupport) {
919                        EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
920                        EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
921                        EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
922                        EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
923                        EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
924                        EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
925                        EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
926                        EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
927                        EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
928                    }
929              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
930                            
931              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
932                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
933                ) {
934                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
935                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
936              }              }
937                
938                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
939                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
940                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
941                }
942                
943                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
944                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
945                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
946                }
947                
948                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
949                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
950                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
951                }
952                
953                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
954                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
955                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
956                }
957                
958                if (pRegion->eg[i].HasEq()) {
959                    if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
960                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
961                }
962          }          }
963                    
964          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 346  namespace LinuxSampler { namespace sfz { Line 968  namespace LinuxSampler { namespace sfz {
968                    
969          // LFO          // LFO
970          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
971              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
972                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
973                    else pRegion->lfos[i].freq = 0;
974                }
975                            
976              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
977                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
978                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
979                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
980                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
981                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
982                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
983                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
984                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
985                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
986                    if (pVoice->bEqSupport) {
987                        LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
988                        LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
989                        LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
990                        LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
991                        LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
992                        LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
993                        LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
994                        LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
995                        LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
996                    }
997              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
998                            
999              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
1000                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
1001                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1002                }
1003                
1004                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1005                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1006                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1007                }
1008                
1009                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1010                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1011                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1012              }              }
1013                            
1014              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1015                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1016                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1017              }              }
1018                            
1019              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1020                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1021                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1022              }              }
1023                
1024                if (pRegion->lfos[i].HasEq()) {
1025                    if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1026                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1027                }
1028            }
1029            
1030            if (!pVoice->bEqSupport) {
1031                bHasEq = false;
1032            } else {
1033                suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1034                suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1035                suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1036                suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1037                suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1038                suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1039                suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1040                suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1041                suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1042            
1043                bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1044                         suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1045                         eqEGs.size() > 0 || eqLFOs.size() > 0;
1046          }          }
1047                    
1048            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1049            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1050            
1051            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1052            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1053            
1054            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1055            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1056            
1057          Units.clear();          Units.clear();
1058                    
1059            EqUnitSupport::ImportUnits(this);
1060            
1061            Units.add(&suVolOnCC);
1062            Units.add(&suPitchOnCC);
1063            Units.add(&suCutoffOnCC);
1064            Units.add(&suResOnCC);
1065            
1066          Units.add(&suVolEG);          Units.add(&suVolEG);
1067          Units.add(&suFilEG);          Units.add(&suFilEG);
1068          Units.add(&suPitchEG);          Units.add(&suPitchEG);
1069            
1070            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1071          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
1072            Units.add(&suPitchLFO.suDepthOnCC);
1073            Units.add(&suPitchLFO.suFadeEG);
1074            
1075            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1076            Units.add(&suAmpLFO.suDepthOnCC);
1077          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
1078            Units.add(&suAmpLFO.suFadeEG);
1079            
1080            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1081            Units.add(&suFilLFO.suDepthOnCC);
1082          Units.add(&suFilLFO);          Units.add(&suFilLFO);
1083            Units.add(&suFilLFO.suFadeEG);
1084                    
1085          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1086              Units.add(EGs[i]);              Units.add(EGs[i]);
1087                Units.add(&(EGs[i]->suAmpOnCC));
1088                Units.add(&(EGs[i]->suVolOnCC));
1089                Units.add(&(EGs[i]->suPitchOnCC));
1090                Units.add(&(EGs[i]->suCutoffOnCC));
1091                Units.add(&(EGs[i]->suResOnCC));
1092                Units.add(&(EGs[i]->suPanOnCC));
1093                EGs[i]->ImportUnits(this); // class EqUnitSupport
1094          }          }
1095                    
1096          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1097                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1098              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1099                Units.add(&(LFOs[i]->suFadeEG));
1100                Units.add(&(LFOs[i]->suVolOnCC));
1101                Units.add(&(LFOs[i]->suPitchOnCC));
1102                Units.add(&(LFOs[i]->suPanOnCC));
1103                Units.add(&(LFOs[i]->suCutoffOnCC));
1104                Units.add(&(LFOs[i]->suResOnCC));
1105                LFOs[i]->ImportUnits(this); // class EqUnitSupport
1106          }          }
1107                    
1108          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1109            Units.add(&suEndpoint.suXFInCC);
1110            Units.add(&suEndpoint.suXFOutCC);
1111            Units.add(&suEndpoint.suPanOnCC);
1112                    
1113          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1114      }      }
# Line 404  namespace LinuxSampler { namespace sfz { Line 1125  namespace LinuxSampler { namespace sfz {
1125          }          }
1126      }      }
1127            
1128        void SfzSignalUnitRack::Reset() {
1129            EqUnitSupport::ResetUnits();
1130            
1131            suVolOnCC.RemoveAllCCs();
1132            suPitchOnCC.RemoveAllCCs();
1133            suCutoffOnCC.RemoveAllCCs();
1134            suResOnCC.RemoveAllCCs();
1135            suEndpoint.suXFInCC.RemoveAllCCs();
1136            suEndpoint.suXFOutCC.RemoveAllCCs();
1137            suEndpoint.suPanOnCC.RemoveAllCCs();
1138            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1139            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1140            suFilLFO.suDepthOnCC.RemoveAllCCs();
1141            suFilLFO.suFreqOnCC.RemoveAllCCs();
1142            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1143            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1144            
1145            for (int i = 0; i < EGs.capacity(); i++) {
1146                EGs[i]->suAmpOnCC.RemoveAllCCs();
1147                EGs[i]->suVolOnCC.RemoveAllCCs();
1148                EGs[i]->suPitchOnCC.RemoveAllCCs();
1149                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1150                EGs[i]->suResOnCC.RemoveAllCCs();
1151                EGs[i]->suPanOnCC.RemoveAllCCs();
1152                EGs[i]->ResetUnits(); // class EqUnitSupport
1153            }
1154            
1155            for (int i = 0; i < LFOs.capacity(); i++) {
1156                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1157                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1158                LFOs[i]->suVolOnCC.RemoveAllCCs();
1159                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1160                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1161                LFOs[i]->suPanOnCC.RemoveAllCCs();
1162                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1163                LFOs[i]->suResOnCC.RemoveAllCCs();
1164                LFOs[i]->ResetUnits(); // class EqUnitSupport
1165            }
1166        }
1167        
1168        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1169            if (!pEqSupport->HasSupport()) return;
1170            if (pEqSupport->GetBandCount() < 3) {
1171                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1172                return;
1173            }
1174            
1175            ::sfz::Region* const pRegion = pVoice->pRegion;
1176            
1177            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1178            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1179            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1180            
1181            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1182            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1183            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1184            
1185            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1186            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1187            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1188            
1189            for (int i = 0; i < eqEGs.size(); i++) {
1190                EGv2Unit* eg = eqEGs[i];
1191                if (!eg->Active()) continue;
1192                
1193                float l = eg->GetLevel();
1194                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1195                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1196                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1197                
1198                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1199                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1200                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1201                
1202                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1203                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1204                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1205            }
1206            
1207            for (int i = 0; i < eqLFOs.size(); i++) {
1208                LFOv2Unit* lfo = eqLFOs[i];
1209                if (!lfo->Active()) continue;
1210                
1211                float l = lfo->GetLevel();
1212                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1213                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1214                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1215                
1216                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1217                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1218                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1219                
1220                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1221                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1222                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1223            }
1224            
1225            pEqSupport->SetGain(0, dB1);
1226            pEqSupport->SetGain(1, dB2);
1227            pEqSupport->SetGain(2, dB3);
1228            
1229            pEqSupport->SetFreq(0, freq1);
1230            pEqSupport->SetFreq(1, freq2);
1231            pEqSupport->SetFreq(2, freq3);
1232            
1233            pEqSupport->SetBandwidth(0, bw1);
1234            pEqSupport->SetBandwidth(1, bw2);
1235            pEqSupport->SetBandwidth(2, bw3);
1236        }
1237        
1238        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1239            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1240              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1241              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1242        {
1243            SetVoice(pVoice);
1244        }
1245        
1246        void EqUnitSupport::SetVoice(Voice* pVoice) {
1247            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1248            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1249            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1250        }
1251        
1252        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1253            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1254            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1255            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1256            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1257            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1258            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1259            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1260            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1261            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1262        }
1263        
1264        void EqUnitSupport::ResetUnits() {
1265            suEq1GainOnCC.RemoveAllCCs();
1266            suEq2GainOnCC.RemoveAllCCs();
1267            suEq3GainOnCC.RemoveAllCCs();
1268            suEq1FreqOnCC.RemoveAllCCs();
1269            suEq2FreqOnCC.RemoveAllCCs();
1270            suEq3FreqOnCC.RemoveAllCCs();
1271            suEq1BwOnCC.RemoveAllCCs();
1272            suEq2BwOnCC.RemoveAllCCs();
1273            suEq3BwOnCC.RemoveAllCCs();
1274        }
1275        
1276        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1277            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1278            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1279            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1280            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1281            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1282            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1283            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1284            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1285            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1286        }
1287        
1288  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2223  
changed lines
  Added in v.2299

  ViewVC Help
Powered by ViewVC