/[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 2235 by iliev, Wed Aug 10 19:40:39 2011 UTC revision 2327 by persson, Sat Mar 10 16:16:14 2012 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2011 Grigor Iliev                                       *   *   Copyright (C) 2011 - 2012 Grigor Iliev                                *
6   *                                                                         *   *                                                                         *
7   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
8   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "SfzSignalUnitRack.h"  #include "SfzSignalUnitRack.h"
24  #include "Voice.h"  #include "Engine.h"
25  #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)      EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132          : EGUnit< ::LinuxSampler::sfz::EG>(rack),          : EGUnit< ::LinuxSampler::sfz::EG>(rack), EqUnitSupport(rack), suAmpOnCC(rack), suVolOnCC(rack),
133            suAmpOnCC(rack), suVolOnCC(rack), suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)            suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134      { }      { }
135            
136      void EGv2Unit::Trigger() {      void EGv2Unit::Trigger() {
# Line 64  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          EG.trigger(uint(pRegion->pitcheg_start * 10),          float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          
163                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          
166                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167                     GetSampleRate());          hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168            
169            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171            
172            float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173            sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174            
175            float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176            release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177            
178            EG.trigger (
179                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
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          EG.trigger(uint(pRegion->fileg_start * 10),          float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
205                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
208                     GetSampleRate());          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209            sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210            
211            float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
217            );
218      }      }
219            
220            
# Line 132  namespace LinuxSampler { namespace sfz { Line 248  namespace LinuxSampler { namespace sfz {
248                    
249          EG.trigger (          EG.trigger (
250              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,              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()              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
252          );          );
253      }      }
254            
# Line 171  namespace LinuxSampler { namespace sfz { Line 287  namespace LinuxSampler { namespace sfz {
287                            
288              if (f != 0) {              if (f != 0) {
289                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290                  suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());                  suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
291              }              }
292          }          }
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 194  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 226  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 260  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, 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::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {      void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
475           if (Smooth > 0) {          if (pSmoothers != NULL) delete pSmoothers;
476               Smoothers[Controller].trigger(Smooth / 1000.0f, GetSampleRate());          pSmoothers = new RTList<Smoother>(pSmootherPool);
477               AddCC(Controller, Influence, Curve, &Smoothers[Controller]);      }
478           } else {      
479               AddCC(Controller, Influence, Curve);      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 350  namespace LinuxSampler { namespace sfz { Line 629  namespace LinuxSampler { namespace sfz {
629                            
630              if (dB >= -144) {              if (dB >= -144) {
631                  if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;                  if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
632                  amp *= ::sf2::ToRatio(dB * 10.0);                  amp *= ToRatio(dB * 10.0);
633              }              }
634                            
635              vol += amp * eg->GetLevel();              vol += amp * eg->GetLevel();
# Line 359  namespace LinuxSampler { namespace sfz { Line 638  namespace LinuxSampler { namespace sfz {
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;
# Line 407  namespace LinuxSampler { namespace sfz { Line 688  namespace LinuxSampler { namespace sfz {
688      }      }
689            
690      float EndpointUnit::CalculateFilterCutoff(float cutoff) {      float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691           cutoff *= GetFilterCutoff();          cutoff *= GetFilterCutoff();
692           float maxCutoff = 0.49 * pVoice->GetSampleRate();          float maxCutoff = 0.49 * pVoice->GetSampleRate();
693           return cutoff > maxCutoff ? maxCutoff : cutoff;          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++) {          for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
703              EGv2Unit* eg = GetRack()->pitchEGs[i];              EGv2Unit* eg = GetRack()->pitchEGs[i];
# Line 438  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++) {          for (int i = 0; i < GetRack()->resEGs.size(); i++) {
730              EGv2Unit* eg = GetRack()->resEGs[i];              EGv2Unit* eg = GetRack()->resEGs[i];
# Line 464  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 482  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), filEGs(maxEgCount), resEGs(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 502  namespace LinuxSampler { namespace sfz { Line 805  namespace LinuxSampler { namespace sfz {
805              EGs[i]->suPitchOnCC.pVoice = voice;              EGs[i]->suPitchOnCC.pVoice = voice;
806              EGs[i]->suCutoffOnCC.pVoice = voice;              EGs[i]->suCutoffOnCC.pVoice = voice;
807              EGs[i]->suResOnCC.pVoice = voice;              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 514  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 527  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();          filEGs.clear();
886          resEGs.clear();          resEGs.clear();
887            panEGs.clear();
888            eqEGs.clear();
889                    
890          LFOs.clear();          LFOs.clear();
891          volLFOs.clear();          volLFOs.clear();
# Line 540  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 557  namespace LinuxSampler { namespace sfz { Line 914  namespace LinuxSampler { namespace sfz {
914                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
915                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
916                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);                  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 || !pRegion->eg[i].amplitude_oncc.empty() ||              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
# Line 580  namespace LinuxSampler { namespace sfz { Line 949  namespace LinuxSampler { namespace sfz {
949                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
950                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  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 589  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 601  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 627  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 640  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 668  namespace LinuxSampler { namespace sfz { Line 1090  namespace LinuxSampler { namespace sfz {
1090              Units.add(&(EGs[i]->suPitchOnCC));              Units.add(&(EGs[i]->suPitchOnCC));
1091              Units.add(&(EGs[i]->suCutoffOnCC));              Units.add(&(EGs[i]->suCutoffOnCC));
1092              Units.add(&(EGs[i]->suResOnCC));              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 679  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 697  namespace LinuxSampler { namespace sfz { Line 1125  namespace LinuxSampler { namespace sfz {
1125              volEGs[i]->EG.enterFadeOutStage();              volEGs[i]->EG.enterFadeOutStage();
1126          }          }
1127      }      }
1128    
1129        void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1130            suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1131            for (int i = 0; i < volEGs.size(); i++) {
1132                volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1133            }
1134        }
1135    
1136        void SfzSignalUnitRack::Reset() {
1137            EqUnitSupport::ResetUnits();
1138            
1139            suVolOnCC.RemoveAllCCs();
1140            suPitchOnCC.RemoveAllCCs();
1141            suCutoffOnCC.RemoveAllCCs();
1142            suResOnCC.RemoveAllCCs();
1143            suEndpoint.suXFInCC.RemoveAllCCs();
1144            suEndpoint.suXFOutCC.RemoveAllCCs();
1145            suEndpoint.suPanOnCC.RemoveAllCCs();
1146            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1147            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1148            suFilLFO.suDepthOnCC.RemoveAllCCs();
1149            suFilLFO.suFreqOnCC.RemoveAllCCs();
1150            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1151            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1152            
1153            for (int i = 0; i < EGs.capacity(); i++) {
1154                EGs[i]->suAmpOnCC.RemoveAllCCs();
1155                EGs[i]->suVolOnCC.RemoveAllCCs();
1156                EGs[i]->suPitchOnCC.RemoveAllCCs();
1157                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1158                EGs[i]->suResOnCC.RemoveAllCCs();
1159                EGs[i]->suPanOnCC.RemoveAllCCs();
1160                EGs[i]->ResetUnits(); // class EqUnitSupport
1161            }
1162            
1163            for (int i = 0; i < LFOs.capacity(); i++) {
1164                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1165                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1166                LFOs[i]->suVolOnCC.RemoveAllCCs();
1167                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1168                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1169                LFOs[i]->suPanOnCC.RemoveAllCCs();
1170                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1171                LFOs[i]->suResOnCC.RemoveAllCCs();
1172                LFOs[i]->ResetUnits(); // class EqUnitSupport
1173            }
1174        }
1175    
1176        void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1177            suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1178            for (int i = 0; i < EGs.capacity(); i++) {
1179                EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1180            }
1181        }
1182        
1183        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1184            if (!pEqSupport->HasSupport()) return;
1185            if (pEqSupport->GetBandCount() < 3) {
1186                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1187                return;
1188            }
1189            
1190            ::sfz::Region* const pRegion = pVoice->pRegion;
1191            
1192            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1193            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1194            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1195            
1196            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1197            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1198            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1199            
1200            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1201            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1202            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1203            
1204            const float vel = pVoice->MIDIVelocity / 127.0f;
1205            
1206            dB1 += pRegion->eq1_vel2gain * vel;
1207            dB2 += pRegion->eq2_vel2gain * vel;
1208            dB3 += pRegion->eq3_vel2gain * vel;
1209            
1210            freq1 += pRegion->eq1_vel2freq * vel;
1211            freq2 += pRegion->eq2_vel2freq * vel;
1212            freq3 += pRegion->eq3_vel2freq * vel;
1213            
1214            for (int i = 0; i < eqEGs.size(); i++) {
1215                EGv2Unit* eg = eqEGs[i];
1216                if (!eg->Active()) continue;
1217                
1218                float l = eg->GetLevel();
1219                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1220                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1221                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1222                
1223                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1224                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1225                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1226                
1227                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1228                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1229                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1230            }
1231            
1232            for (int i = 0; i < eqLFOs.size(); i++) {
1233                LFOv2Unit* lfo = eqLFOs[i];
1234                if (!lfo->Active()) continue;
1235                
1236                float l = lfo->GetLevel();
1237                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1238                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1239                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1240                
1241                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1242                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1243                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1244                
1245                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1246                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1247                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1248            }
1249            
1250            pEqSupport->SetGain(0, dB1);
1251            pEqSupport->SetGain(1, dB2);
1252            pEqSupport->SetGain(2, dB3);
1253            
1254            pEqSupport->SetFreq(0, freq1);
1255            pEqSupport->SetFreq(1, freq2);
1256            pEqSupport->SetFreq(2, freq3);
1257            
1258            pEqSupport->SetBandwidth(0, bw1);
1259            pEqSupport->SetBandwidth(1, bw2);
1260            pEqSupport->SetBandwidth(2, bw3);
1261        }
1262        
1263        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1264            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1265              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1266              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1267        {
1268            SetVoice(pVoice);
1269        }
1270        
1271        void EqUnitSupport::SetVoice(Voice* pVoice) {
1272            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1273            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1274            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1275        }
1276        
1277        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1278            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1279            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1280            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1281            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1282            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1283            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1284            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1285            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1286            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1287        }
1288        
1289        void EqUnitSupport::ResetUnits() {
1290            suEq1GainOnCC.RemoveAllCCs();
1291            suEq2GainOnCC.RemoveAllCCs();
1292            suEq3GainOnCC.RemoveAllCCs();
1293            suEq1FreqOnCC.RemoveAllCCs();
1294            suEq2FreqOnCC.RemoveAllCCs();
1295            suEq3FreqOnCC.RemoveAllCCs();
1296            suEq1BwOnCC.RemoveAllCCs();
1297            suEq2BwOnCC.RemoveAllCCs();
1298            suEq3BwOnCC.RemoveAllCCs();
1299        }
1300        
1301        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1302            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1303            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1304            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1305            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1306            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1307            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1308            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1309            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1310            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1311        }
1312            
1313  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2235  
changed lines
  Added in v.2327

  ViewVC Help
Powered by ViewVC