/[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 2227 by iliev, Wed Aug 3 17:11:40 2011 UTC revision 2296 by iliev, Thu Dec 8 20:03:47 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            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          EG.trigger(uint(pRegion->ampeg_start * 10),          if (Level != l) {
125                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),              Level = l;
126                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),              if (pListener != NULL) pListener->ValueChanged(this);
127                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          }
                    uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),  
                    GetSampleRate());  
128      }      }
129            
130            
131        EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132            : EGUnit< ::LinuxSampler::sfz::EG>(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          EG.trigger(uint(pRegion->pitcheg_start * 10),          float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
166                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
169                     GetSampleRate());          float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171            
172            float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173            sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174            
175            float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176            release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177            
178            EG.trigger (
179                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                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
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()
217            );
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          // 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->fileg_delay + pRegion->fileg_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          EG.trigger(uint(pRegion->fileg_start * 10),          float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
237                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
240                     GetSampleRate());          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)      LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257          : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),          : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258            suFadeEG(rack), suFreqOnCC(rack, this)            suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259      { }      { }
260            
261      LFOUnit::LFOUnit(const LFOUnit& Unit)      LFOUnit::LFOUnit(const LFOUnit& Unit)
262          : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),          : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263            suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)            suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265      {      {
266          Copy(Unit);          Copy(Unit);
267      }      }
# Line 125  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()) {          if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285              float f = pLfoInfo->fade;              float f = pLfoInfo->fade;
286              for (int i = 0; i < pLfoInfo->fade_oncc.size(); i++) {              f += GetInfluence(pLfoInfo->fade_oncc);
                 int val = pVoice->GetControllerValue(pLfoInfo->fade_oncc[i].Controller);  
                 f += (val / 127.0f) * pLfoInfo->fade_oncc[i].Influence;  
             }  
287                            
288              if (f != 0) {              if (f != 0) {
289                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
# Line 141  namespace LinuxSampler { namespace sfz { Line 293  namespace LinuxSampler { namespace sfz {
293      }      }
294            
295      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296          pLFO->SetFrequency(suFreqOnCC.GetLevel() + pLfoInfo->freq, GetSampleRate());          if (pLFO == NULL) return;
297            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298      }      }
299            
300            
# Line 160  namespace LinuxSampler { namespace sfz { Line 313  namespace LinuxSampler { namespace sfz {
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), 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            suPitchOnCC(rack)            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 185  namespace LinuxSampler { namespace sfz { Line 338  namespace LinuxSampler { namespace sfz {
338          );          );
339          pLFO->Update(0);          pLFO->Update(0);
340                    
341          float phase = pLfoInfo->phase;          float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
         for (int i = 0; i < pLfoInfo->phase_oncc.size(); i++) {  
             int val = pVoice->GetControllerValue(pLfoInfo->phase_oncc[i].Controller);  
             phase += (val / 127.0f) * pLfoInfo->phase_oncc[i].Influence;  
         }  
342          if (phase != 0) pLFO->SetPhase(phase);          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;          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;          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;          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            
# Line 228  namespace LinuxSampler { namespace sfz { Line 395  namespace LinuxSampler { namespace sfz {
395      }      }
396            
397      void CCUnit::Trigger() {      void CCUnit::Trigger() {
398          for (int i = 0; i < Ctrls.size(); i++) {          RTList<CC>::Iterator ctrl = pCtrls->first();
399              Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);          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();          CCSignalUnit::Trigger();
412      }      }
413            
414       void CCUnit::SetCCs(::sfz::Array<int>& cc) {      void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415           RemoveAllCCs();          RemoveAllCCs();
416           for (int i = 0; i < 128; i++) {          for (int i = 0; i < 128; i++) {
417               if (cc[i] != 0) AddCC(i, cc[i]);              if (cc[i] != 0) AddCC(i, cc[i]);
418           }          }
419       }      }
420            
421       void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {      void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422           RemoveAllCCs();          RemoveAllCCs();
423           for (int i = 0; i < cc.size(); i++) {          for (int i = 0; i < 128; i++) {
424               if (cc[i].Influence != 0) AddCC(cc[i].Controller, cc[i].Influence);              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            
# Line 258  namespace LinuxSampler { namespace sfz { Line 493  namespace LinuxSampler { namespace sfz {
493      }      }
494            
495      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
496            float xfInVelCoeff = 1;
497            
498            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
499                xfInVelCoeff = 0;
500            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
501                xfInVelCoeff = 1;
502            } else {
503                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
504                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
505                xfInVelCoeff = velPos / xfVelSize;
506                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
507                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
508                }
509            }
510            
511            float xfOutVelCoeff = 1;
512                    
513            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
514                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
515            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
516                xfOutVelCoeff = 1;
517            } else {
518                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
519                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
520                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
521                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
522                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
523                }
524            }
525            
526            float xfInKeyCoeff = 1;
527            
528            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
529                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
530            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
531                xfInKeyCoeff = 1;
532            } else {
533                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
534                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
535                xfInKeyCoeff = keyPos / xfKeySize;
536                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
537                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
538                }
539            }
540            
541            float xfOutKeyCoeff = 1;
542            
543            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
544                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
545            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
546                xfOutKeyCoeff = 1;
547            } else {
548                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
549                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
550                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
551                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
552                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
553                }
554            }
555            
556            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
557            
558            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
559            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
560            
561            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
562            
563            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
564      }      }
565            
566      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 278  namespace LinuxSampler { namespace sfz { Line 580  namespace LinuxSampler { namespace sfz {
580          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
581              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
582              if (!eg->Active()) continue;              if (!eg->Active()) continue;
583              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
584                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
585                if (dB < -144) dB = eg->pEGInfo->volume;
586                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
587                
588                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
589                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
590                
591                if (dB >= -144) {
592                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
593                    amp *= ToRatio(dB * 10.0);
594                }
595                
596                vol += amp * eg->GetLevel();
597          }          }
598                    
599          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
600          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
601            float f = u2->Active() ? u2->GetLevel() : 0;
602            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
603                    
604          return vol;          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
605            
606            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
607                LFOv2Unit* lfo = GetRack()->volLFOs[i];
608                if (!lfo->Active()) continue;
609                
610                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
611                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
612            }
613            
614            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
615            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
616            return vol * xfCoeff;
617      }      }
618            
619      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
620          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
621                    
622          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
623          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
624            float f = u1->Active() ? u1->GetLevel() : 0;
625            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
626                    
627          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
628          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
629                    
630            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
631                EGv2Unit* eg = GetRack()->filEGs[i];
632                if (!eg->Active()) continue;
633                
634                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
635                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
636                val *= RTMath::CentsToFreqRatioUnlimited(f);
637            }
638            
639          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
640              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
641              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
642                            
643              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
644                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
645              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
646          }          }
647                    
648          return val;          return val;
649      }      }
650            
651        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
652            cutoff *= GetFilterCutoff();
653            float maxCutoff = 0.49 * pVoice->GetSampleRate();
654            return cutoff > maxCutoff ? maxCutoff : cutoff;
655        }
656        
657      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
658          double p;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
659            
660          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
661          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
662            
663            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
664                EGv2Unit* eg = GetRack()->pitchEGs[i];
665                if (!eg->Active()) continue;
666                
667                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
668                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
669            }
670                    
671          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
672          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
673          float f = u3->Active() ? u3->GetLevel() : 0;          float f = u3->Active() ? u3->GetLevel() : 0;
674          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
675                    
# Line 325  namespace LinuxSampler { namespace sfz { Line 681  namespace LinuxSampler { namespace sfz {
681              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
682          }          }
683                    
684          return p;          return p * pitchVeltrackRatio;
685      }      }
686            
687      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
688           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
689            
690            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
691                EGv2Unit* eg = GetRack()->resEGs[i];
692                if (!eg->Active()) continue;
693                
694                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
695                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
696            }
697                    
698          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
699              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
700              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
701                            
702              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
703                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
704          }          }
705                    
706          return val;          return val;
707      }      }
708            
709      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
710          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
711            
712            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
713                EGv2Unit* eg = GetRack()->panEGs[i];
714                if (!eg->Active()) continue;
715                
716                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
717                
718                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
719                    uint8_t val = eg->GetLevel() * 127;
720                    if (val > 127) val = 127;
721                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
722                } else {
723                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
724                }
725            }
726                    
727          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
728              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
729              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
730                            
731              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
732                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
733          }          }
734                    
735          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 360  namespace LinuxSampler { namespace sfz { Line 741  namespace LinuxSampler { namespace sfz {
741            
742      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
743          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
744          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
745            suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
746            suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
747            suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
748            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
749          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
750          LFOs(maxLfoCount), pitchLFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
751            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
752      {      {
753          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
754            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
755          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
756          suPitchLFO.suDepthCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          
757          suFilLFO.suFadeEG.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
758          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
759            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
760            
761            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
762            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
763            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
764            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
765                    
766          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
767              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
768              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
769                EGs[i]->suAmpOnCC.pVoice = voice;
770                EGs[i]->suVolOnCC.pVoice = voice;
771                EGs[i]->suPitchOnCC.pVoice = voice;
772                EGs[i]->suCutoffOnCC.pVoice = voice;
773                EGs[i]->suResOnCC.pVoice = voice;
774                EGs[i]->suPanOnCC.pVoice = voice;
775          }          }
776                    
777          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
778              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
779              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
780                LFOs[i]->suDepthOnCC.pVoice = voice;
781                LFOs[i]->suFreqOnCC.pVoice = voice;
782              LFOs[i]->suFadeEG.pVoice = voice;              LFOs[i]->suFadeEG.pVoice = voice;
783                LFOs[i]->suVolOnCC.pVoice = voice;
784              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
785              LFOs[i]->suFreqOnCC.pVoice = voice;              LFOs[i]->suFreqOnCC.pVoice = voice;
786                LFOs[i]->suPanOnCC.pVoice = voice;
787                LFOs[i]->suCutoffOnCC.pVoice = voice;
788                LFOs[i]->suResOnCC.pVoice = voice;
789          }          }
790      }      }
791            
# Line 394  namespace LinuxSampler { namespace sfz { Line 799  namespace LinuxSampler { namespace sfz {
799          }          }
800      }      }
801            
802        void SfzSignalUnitRack::InitRTLists() {
803            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
804            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
805            
806            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
807            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
808            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
809            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
810            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
811            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
812            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
813            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
814            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
815            
816            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
817            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
818            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
819            suResOnCC.InitCCList(pCCPool, pSmootherPool);
820            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
821            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
822            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
823            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
824            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
825            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
826            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
827            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
828            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
829            
830            for (int i = 0; i < EGs.capacity(); i++) {
831                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
832                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
833                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
834                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
835                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
836                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
837            }
838            
839            for (int i = 0; i < LFOs.capacity(); i++) {
840                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
841                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
842                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
843                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
844                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
845                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
846                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
848            }
849        }
850        
851      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
852          EGs.clear();          EGs.clear();
853          volEGs.clear();          volEGs.clear();
854          pitchEGs.clear();          pitchEGs.clear();
855            filEGs.clear();
856            resEGs.clear();
857            panEGs.clear();
858                    
859          LFOs.clear();          LFOs.clear();
860            volLFOs.clear();
861          pitchLFOs.clear();          pitchLFOs.clear();
862          filLFOs.clear();          filLFOs.clear();
863          resLFOs.clear();          resLFOs.clear();
# Line 407  namespace LinuxSampler { namespace sfz { Line 865  namespace LinuxSampler { namespace sfz {
865                    
866          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
867                    
868            suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
869            suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
870            suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
871            suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
872            suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
873            suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
874            suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
875            suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
876            suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
877            
878            bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
879                     suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
880            
881            suVolOnCC.SetCCs(pRegion->volume_oncc);
882            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
883            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
884            suResOnCC.SetCCs(pRegion->resonance_oncc);
885            
886          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
887              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
888                            
# Line 414  namespace LinuxSampler { namespace sfz { Line 890  namespace LinuxSampler { namespace sfz {
890                  EGv2Unit eg(this);                  EGv2Unit eg(this);
891                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
892                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
893                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
894                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
895                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
896                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
897                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
898                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
899              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
900                            
901              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
902                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
903                ) {
904                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
905                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
906              }              }
907                
908                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
909                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
910                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
911                }
912                
913                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
914                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
915                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
916                }
917                
918                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
919                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
920                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
921                }
922                
923                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
924                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
925                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
926                }
927          }          }
928                    
929          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 429  namespace LinuxSampler { namespace sfz { Line 933  namespace LinuxSampler { namespace sfz {
933                    
934          // LFO          // LFO
935          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
936              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
937                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
938                    else pRegion->lfos[i].freq = 0;
939                }
940                            
941              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
942                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
943                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
944                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
945                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
946                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
947                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
948                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
949                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
950                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
951              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
952                            
953                if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
954                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
955                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
956                }
957                
958              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
959                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
960                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
961              }              }
962                            
963              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
964                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
965                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
966              }              }
967                            
968              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
969                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
970                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
971              }              }
972                            
973              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
974                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
975                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
976              }              }
977          }          }
978                    
979          suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
980          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
981                    
982            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
983          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
984                    
985            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
986          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
987                    
988          Units.clear();          Units.clear();
989                    
990            Units.add(&suEq1GainOnCC);
991            Units.add(&suEq2GainOnCC);
992            Units.add(&suEq3GainOnCC);
993            Units.add(&suEq1FreqOnCC);
994            Units.add(&suEq2FreqOnCC);
995            Units.add(&suEq3FreqOnCC);
996            Units.add(&suEq1BwOnCC);
997            Units.add(&suEq2BwOnCC);
998            Units.add(&suEq3BwOnCC);
999            
1000            Units.add(&suVolOnCC);
1001            Units.add(&suPitchOnCC);
1002            Units.add(&suCutoffOnCC);
1003            Units.add(&suResOnCC);
1004            
1005          Units.add(&suVolEG);          Units.add(&suVolEG);
1006          Units.add(&suFilEG);          Units.add(&suFilEG);
1007          Units.add(&suPitchEG);          Units.add(&suPitchEG);
1008                    
1009          Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)          Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1010          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
1011          Units.add(&suPitchLFO.suDepthCC);          Units.add(&suPitchLFO.suDepthOnCC);
1012          Units.add(&suPitchLFO.suFadeEG);          Units.add(&suPitchLFO.suFadeEG);
1013                    
1014          Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)          Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1015            Units.add(&suAmpLFO.suDepthOnCC);
1016          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
1017          Units.add(&suAmpLFO.suFadeEG);          Units.add(&suAmpLFO.suFadeEG);
1018                    
1019          Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)          Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1020            Units.add(&suFilLFO.suDepthOnCC);
1021          Units.add(&suFilLFO);          Units.add(&suFilLFO);
1022          Units.add(&suFilLFO.suFadeEG);          Units.add(&suFilLFO.suFadeEG);
1023                    
1024          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1025              Units.add(EGs[i]);              Units.add(EGs[i]);
1026                Units.add(&(EGs[i]->suAmpOnCC));
1027                Units.add(&(EGs[i]->suVolOnCC));
1028                Units.add(&(EGs[i]->suPitchOnCC));
1029                Units.add(&(EGs[i]->suCutoffOnCC));
1030                Units.add(&(EGs[i]->suResOnCC));
1031                Units.add(&(EGs[i]->suPanOnCC));
1032          }          }
1033                    
1034          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1035              Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)              Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1036              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1037              Units.add(&(LFOs[i]->suFadeEG));              Units.add(&(LFOs[i]->suFadeEG));
1038                Units.add(&(LFOs[i]->suVolOnCC));
1039              Units.add(&(LFOs[i]->suPitchOnCC));              Units.add(&(LFOs[i]->suPitchOnCC));
1040                Units.add(&(LFOs[i]->suPanOnCC));
1041                Units.add(&(LFOs[i]->suCutoffOnCC));
1042                Units.add(&(LFOs[i]->suResOnCC));
1043          }          }
1044                    
1045          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1046            Units.add(&suEndpoint.suXFInCC);
1047            Units.add(&suEndpoint.suXFOutCC);
1048            Units.add(&suEndpoint.suPanOnCC);
1049                    
1050          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1051      }      }
# Line 514  namespace LinuxSampler { namespace sfz { Line 1062  namespace LinuxSampler { namespace sfz {
1062          }          }
1063      }      }
1064            
1065        void SfzSignalUnitRack::Reset() {
1066            suEq1GainOnCC.RemoveAllCCs();
1067            suEq2GainOnCC.RemoveAllCCs();
1068            suEq3GainOnCC.RemoveAllCCs();
1069            suEq1FreqOnCC.RemoveAllCCs();
1070            suEq2FreqOnCC.RemoveAllCCs();
1071            suEq3FreqOnCC.RemoveAllCCs();
1072            suEq1BwOnCC.RemoveAllCCs();
1073            suEq2BwOnCC.RemoveAllCCs();
1074            suEq3BwOnCC.RemoveAllCCs();
1075            
1076            suVolOnCC.RemoveAllCCs();
1077            suPitchOnCC.RemoveAllCCs();
1078            suCutoffOnCC.RemoveAllCCs();
1079            suResOnCC.RemoveAllCCs();
1080            suEndpoint.suXFInCC.RemoveAllCCs();
1081            suEndpoint.suXFOutCC.RemoveAllCCs();
1082            suEndpoint.suPanOnCC.RemoveAllCCs();
1083            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1084            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1085            suFilLFO.suDepthOnCC.RemoveAllCCs();
1086            suFilLFO.suFreqOnCC.RemoveAllCCs();
1087            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1088            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1089            
1090            for (int i = 0; i < EGs.capacity(); i++) {
1091                EGs[i]->suAmpOnCC.RemoveAllCCs();
1092                EGs[i]->suVolOnCC.RemoveAllCCs();
1093                EGs[i]->suPitchOnCC.RemoveAllCCs();
1094                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1095                EGs[i]->suResOnCC.RemoveAllCCs();
1096                EGs[i]->suPanOnCC.RemoveAllCCs();
1097            }
1098            
1099            for (int i = 0; i < LFOs.capacity(); i++) {
1100                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1101                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1102                LFOs[i]->suVolOnCC.RemoveAllCCs();
1103                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1104                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1105                LFOs[i]->suPanOnCC.RemoveAllCCs();
1106                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1107                LFOs[i]->suResOnCC.RemoveAllCCs();
1108            }
1109        }
1110        
1111        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1112            if (!pEqSupport->HasSupport()) return;
1113            if (pEqSupport->GetBandCount() < 3) {
1114                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1115                return;
1116            }
1117            
1118            ::sfz::Region* const pRegion = pVoice->pRegion;
1119            
1120            float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1121            pEqSupport->SetGain(0, dB);
1122            
1123            dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1124            pEqSupport->SetGain(1, dB);
1125            
1126            dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1127            pEqSupport->SetGain(2, dB);
1128            
1129            float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1130            pEqSupport->SetFreq(0, freq);
1131            
1132            freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1133            pEqSupport->SetFreq(1, freq);
1134            
1135            freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1136            pEqSupport->SetFreq(2, freq);
1137            
1138            float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1139            pEqSupport->SetBandwidth(0, bw);
1140            
1141            bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1142            pEqSupport->SetBandwidth(1, bw);
1143            
1144            bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1145            pEqSupport->SetBandwidth(2, bw);
1146        }
1147        
1148  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2227  
changed lines
  Added in v.2296

  ViewVC Help
Powered by ViewVC