/[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 2233 by iliev, Mon Aug 8 18:46:19 2011 UTC revision 2300 by iliev, Mon Dec 12 09:20:00 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 43  namespace LinuxSampler { namespace sfz { Line 49  namespace LinuxSampler { namespace sfz {
49          return f;          return f;
50      }      }
51            
52        void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53            RemoveAllCCs();
54            
55            for (int cc = 0; cc < 128; cc++) {
56                if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57                int i = loCCs[cc];
58                int j = hiCCs[cc];
59                if (j == 0) j = 127;
60                i += j << 8; // workaround to keep both values in the Influence parameter
61                AddCC(cc, i);
62            }
63        }
64        
65        void XFInCCUnit::Calculate() {
66            float l = 1;
67                    
68            RTList<CC>::Iterator ctrl = pCtrls->first();
69            RTList<CC>::Iterator end  = pCtrls->end();
70            for(; ctrl != end; ++ctrl) {
71                float c = 1;
72                int influence = (*ctrl).Influence;
73                int lo = influence & 0xff;
74                int hi = influence >> 8;
75                if ((*ctrl).Value <= lo) {
76                    c = 0;
77                } else if ((*ctrl).Value >= hi) {
78                    c = 1;
79                } else {
80                    float xfVelSize = hi - lo;
81                    float velPos = (*ctrl).Value - lo;
82                    c = velPos / xfVelSize;
83                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84                        c = sin(c * M_PI / 2.0);
85                    }
86                }
87                
88                l *= c;
89            }
90            
91            if (Level != l) {
92                Level = l;
93                if (pListener != NULL) pListener->ValueChanged(this);
94            }
95        }
96        
97        
98        void XFOutCCUnit::Calculate() {
99            float l = 1;
100                    
101            RTList<CC>::Iterator ctrl = pCtrls->first();
102            RTList<CC>::Iterator end  = pCtrls->end();
103            for(; ctrl != end; ++ctrl) {
104                float c = 1;
105                int influence = (*ctrl).Influence;
106                int lo = influence & 0xff;
107                int hi = influence >> 8;
108                if ((*ctrl).Value >= hi) {
109                    c = 0;
110                } else if ((*ctrl).Value <= lo) {
111                    c = 1;
112                } else {
113                    float xfVelSize = hi - lo;
114                    float velPos = (*ctrl).Value - lo;
115                    c = 1.0f - velPos / xfVelSize;
116                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117                        c = sin(c * M_PI / 2.0);
118                    }
119                }
120                
121                l *= c;
122            }
123            
124            if (Level != l) {
125                Level = l;
126                if (pListener != NULL) pListener->ValueChanged(this);
127            }
128        }
129        
130        
131        EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132            : EGUnit< ::LinuxSampler::sfz::EG>(rack), EqUnitSupport(rack), suAmpOnCC(rack), suVolOnCC(rack),
133              suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134        { }
135            
136      void EGv2Unit::Trigger() {      void EGv2Unit::Trigger() {
137          egInfo = *pEGInfo;          egInfo = *pEGInfo;
# Line 59  namespace LinuxSampler { namespace sfz { Line 148  namespace LinuxSampler { namespace sfz {
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          // 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          EG.trigger(uint(pRegion->fileg_start * 10),          float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
208                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
211                     GetSampleRate());          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            
# Line 172  namespace LinuxSampler { namespace sfz { Line 293  namespace LinuxSampler { namespace sfz {
293      }      }
294            
295      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296            if (pLFO == NULL) return;
297          pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());          pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298      }      }
299            
# Line 189  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)            suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317      {      {
# Line 221  namespace LinuxSampler { namespace sfz { Line 343  namespace LinuxSampler { namespace sfz {
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 255  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              if (Ctrls[i].pSmoother != NULL) Ctrls[i].pSmoother->setValue(Ctrls[i].Value);          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) {              if (cc[i] != 0) AddCC(i, cc[i]);
425                   short int curve = cc[i].Curve;          }
426                   if (curve >= GetCurveCount()) curve = -1;      }
427                   AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);      
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) {      void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440           AddCC(Controller, Influence, Curve);          AddCC(Controller, Influence, Curve, NULL, Step);
441       }      }
442            
443       int CCUnit::GetCurveCount() {      int CCUnit::GetCurveCount() {
444           return pVoice->pRegion->GetInstrument()->curves.size();          return pVoice->pRegion->GetInstrument()->curves.size();
445       }      }
446            
447       ::sfz::Curve* CCUnit::GetCurve(int idx) {      ::sfz::Curve* CCUnit::GetCurve(int idx) {
448           return &pVoice->pRegion->GetInstrument()->curves[idx];          return &pVoice->pRegion->GetInstrument()->curves[idx];
449       }      }
450            
451       double CCUnit::GetSampleRate() {      double CCUnit::GetSampleRate() {
452          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          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) {      void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461           if (Smooth > 0) {          if (Smooth > 0) {
462               Smoothers[Controller].trigger(Smooth / 1000.0f, GetSampleRate());              if (pSmoothers->poolIsEmpty()) {
463               AddCC(Controller, Influence, Curve, &Smoothers[Controller]);                  std::cerr << "Maximum number of smoothers reached" << std::endl;
464           } else {                  return;
465               AddCC(Controller, Influence, Curve);              }
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 335  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;
             vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);  
622                            
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          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
640          float f = u2->Active() ? u2->GetLevel() : 0;          float f = u2->Active() ? u2->GetLevel() : 0;
641          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;          vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
642                    
643          vol *= ::sf2::ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
644                    
645          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
646              LFOv2Unit* lfo = GetRack()->volLFOs[i];              LFOv2Unit* lfo = GetRack()->volLFOs[i];
647              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
648                            
649              float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;              float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
650              vol *= ::sf2::ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);              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          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663          float f = u1->Active() ? u1->GetLevel() : 0;          float f = u1->Active() ? u1->GetLevel() : 0;
664          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;          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;
# Line 380  namespace LinuxSampler { namespace sfz { Line 687  namespace LinuxSampler { namespace sfz {
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          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
# Line 398  namespace LinuxSampler { namespace sfz { Line 720  namespace LinuxSampler { namespace sfz {
720              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));              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];
# Line 416  namespace LinuxSampler { namespace sfz { Line 746  namespace LinuxSampler { namespace sfz {
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];
# Line 434  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), suVolOnCC(this),          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), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
789          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          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          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
793            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;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
797          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
798          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
# Line 449  namespace LinuxSampler { namespace sfz { Line 800  namespace LinuxSampler { namespace sfz {
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;              LFOs[i]->suFadeEG.pVoice = voice;
818              LFOs[i]->suVolOnCC.pVoice = voice;              LFOs[i]->suVolOnCC.pVoice = voice;
819              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
# Line 461  namespace LinuxSampler { namespace sfz { Line 821  namespace LinuxSampler { namespace sfz {
821              LFOs[i]->suPanOnCC.pVoice = voice;              LFOs[i]->suPanOnCC.pVoice = voice;
822              LFOs[i]->suCutoffOnCC.pVoice = voice;              LFOs[i]->suCutoffOnCC.pVoice = voice;
823              LFOs[i]->suResOnCC.pVoice = voice;              LFOs[i]->suResOnCC.pVoice = voice;
824                LFOs[i]->SetVoice(voice); // class EqUnitSupport
825          }          }
826      }      }
827            
# Line 474  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();          volLFOs.clear();
# Line 485  namespace LinuxSampler { namespace sfz { Line 893  namespace LinuxSampler { namespace sfz {
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);          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;
# Line 497  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 512  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);
# Line 524  namespace LinuxSampler { namespace sfz { Line 983  namespace LinuxSampler { namespace sfz {
983                  LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);                  LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
984                  LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);                  LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
985                  LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);                  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].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
# Line 550  namespace LinuxSampler { namespace sfz { Line 1020  namespace LinuxSampler { namespace sfz {
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                         pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1045                         suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1046                         eqEGs.size() > 0 || eqLFOs.size() > 0;
1047          }          }
1048                    
1049          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
# Line 563  namespace LinuxSampler { namespace sfz { Line 1057  namespace LinuxSampler { namespace sfz {
1057                    
1058          Units.clear();          Units.clear();
1059                    
1060            EqUnitSupport::ImportUnits(this);
1061            
1062          Units.add(&suVolOnCC);          Units.add(&suVolOnCC);
1063            Units.add(&suPitchOnCC);
1064            Units.add(&suCutoffOnCC);
1065            Units.add(&suResOnCC);
1066                    
1067          Units.add(&suVolEG);          Units.add(&suVolEG);
1068          Units.add(&suFilEG);          Units.add(&suFilEG);
# Line 586  namespace LinuxSampler { namespace sfz { Line 1085  namespace LinuxSampler { namespace sfz {
1085                    
1086          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1087              Units.add(EGs[i]);              Units.add(EGs[i]);
1088                Units.add(&(EGs[i]->suAmpOnCC));
1089                Units.add(&(EGs[i]->suVolOnCC));
1090                Units.add(&(EGs[i]->suPitchOnCC));
1091                Units.add(&(EGs[i]->suCutoffOnCC));
1092                Units.add(&(EGs[i]->suResOnCC));
1093                Units.add(&(EGs[i]->suPanOnCC));
1094                EGs[i]->ImportUnits(this); // class EqUnitSupport
1095          }          }
1096                    
1097          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
# Line 597  namespace LinuxSampler { namespace sfz { Line 1103  namespace LinuxSampler { namespace sfz {
1103              Units.add(&(LFOs[i]->suPanOnCC));              Units.add(&(LFOs[i]->suPanOnCC));
1104              Units.add(&(LFOs[i]->suCutoffOnCC));              Units.add(&(LFOs[i]->suCutoffOnCC));
1105              Units.add(&(LFOs[i]->suResOnCC));              Units.add(&(LFOs[i]->suResOnCC));
1106                LFOs[i]->ImportUnits(this); // class EqUnitSupport
1107          }          }
1108                    
1109          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1110            Units.add(&suEndpoint.suXFInCC);
1111            Units.add(&suEndpoint.suXFOutCC);
1112            Units.add(&suEndpoint.suPanOnCC);
1113                    
1114          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1115      }      }
# Line 616  namespace LinuxSampler { namespace sfz { Line 1126  namespace LinuxSampler { namespace sfz {
1126          }          }
1127      }      }
1128            
1129        void SfzSignalUnitRack::Reset() {
1130            EqUnitSupport::ResetUnits();
1131            
1132            suVolOnCC.RemoveAllCCs();
1133            suPitchOnCC.RemoveAllCCs();
1134            suCutoffOnCC.RemoveAllCCs();
1135            suResOnCC.RemoveAllCCs();
1136            suEndpoint.suXFInCC.RemoveAllCCs();
1137            suEndpoint.suXFOutCC.RemoveAllCCs();
1138            suEndpoint.suPanOnCC.RemoveAllCCs();
1139            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1140            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1141            suFilLFO.suDepthOnCC.RemoveAllCCs();
1142            suFilLFO.suFreqOnCC.RemoveAllCCs();
1143            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1144            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1145            
1146            for (int i = 0; i < EGs.capacity(); i++) {
1147                EGs[i]->suAmpOnCC.RemoveAllCCs();
1148                EGs[i]->suVolOnCC.RemoveAllCCs();
1149                EGs[i]->suPitchOnCC.RemoveAllCCs();
1150                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1151                EGs[i]->suResOnCC.RemoveAllCCs();
1152                EGs[i]->suPanOnCC.RemoveAllCCs();
1153                EGs[i]->ResetUnits(); // class EqUnitSupport
1154            }
1155            
1156            for (int i = 0; i < LFOs.capacity(); i++) {
1157                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1158                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1159                LFOs[i]->suVolOnCC.RemoveAllCCs();
1160                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1161                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1162                LFOs[i]->suPanOnCC.RemoveAllCCs();
1163                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1164                LFOs[i]->suResOnCC.RemoveAllCCs();
1165                LFOs[i]->ResetUnits(); // class EqUnitSupport
1166            }
1167        }
1168        
1169        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1170            if (!pEqSupport->HasSupport()) return;
1171            if (pEqSupport->GetBandCount() < 3) {
1172                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1173                return;
1174            }
1175            
1176            ::sfz::Region* const pRegion = pVoice->pRegion;
1177            
1178            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1179            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1180            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1181            
1182            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1183            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1184            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1185            
1186            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1187            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1188            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1189            
1190            const float vel = pVoice->MIDIVelocity / 127.0f;
1191            
1192            dB1 += pRegion->eq1_vel2gain * vel;
1193            dB2 += pRegion->eq2_vel2gain * vel;
1194            dB3 += pRegion->eq3_vel2gain * vel;
1195            
1196            freq1 += pRegion->eq1_vel2freq * vel;
1197            freq2 += pRegion->eq2_vel2freq * vel;
1198            freq3 += pRegion->eq3_vel2freq * vel;
1199            
1200            for (int i = 0; i < eqEGs.size(); i++) {
1201                EGv2Unit* eg = eqEGs[i];
1202                if (!eg->Active()) continue;
1203                
1204                float l = eg->GetLevel();
1205                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1206                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1207                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1208                
1209                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1210                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1211                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1212                
1213                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1214                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1215                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1216            }
1217            
1218            for (int i = 0; i < eqLFOs.size(); i++) {
1219                LFOv2Unit* lfo = eqLFOs[i];
1220                if (!lfo->Active()) continue;
1221                
1222                float l = lfo->GetLevel();
1223                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1224                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1225                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1226                
1227                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1228                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1229                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1230                
1231                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1232                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1233                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1234            }
1235            
1236            pEqSupport->SetGain(0, dB1);
1237            pEqSupport->SetGain(1, dB2);
1238            pEqSupport->SetGain(2, dB3);
1239            
1240            pEqSupport->SetFreq(0, freq1);
1241            pEqSupport->SetFreq(1, freq2);
1242            pEqSupport->SetFreq(2, freq3);
1243            
1244            pEqSupport->SetBandwidth(0, bw1);
1245            pEqSupport->SetBandwidth(1, bw2);
1246            pEqSupport->SetBandwidth(2, bw3);
1247        }
1248        
1249        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1250            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1251              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1252              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1253        {
1254            SetVoice(pVoice);
1255        }
1256        
1257        void EqUnitSupport::SetVoice(Voice* pVoice) {
1258            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1259            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1260            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1261        }
1262        
1263        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1264            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1265            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1266            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1267            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1268            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1269            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1270            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1271            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1272            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1273        }
1274        
1275        void EqUnitSupport::ResetUnits() {
1276            suEq1GainOnCC.RemoveAllCCs();
1277            suEq2GainOnCC.RemoveAllCCs();
1278            suEq3GainOnCC.RemoveAllCCs();
1279            suEq1FreqOnCC.RemoveAllCCs();
1280            suEq2FreqOnCC.RemoveAllCCs();
1281            suEq3FreqOnCC.RemoveAllCCs();
1282            suEq1BwOnCC.RemoveAllCCs();
1283            suEq2BwOnCC.RemoveAllCCs();
1284            suEq3BwOnCC.RemoveAllCCs();
1285        }
1286        
1287        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1288            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1289            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1290            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1291            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1292            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1293            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1294            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1295            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1296            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1297        }
1298        
1299  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2233  
changed lines
  Added in v.2300

  ViewVC Help
Powered by ViewVC