/[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 2382 by persson, Sun Dec 2 16:30:42 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 474  namespace LinuxSampler { namespace sfz { Line 771  namespace LinuxSampler { namespace sfz {
771              pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);              pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772          }          }
773                    
         if(pan < -100) return -100;  
         if(pan >  100) return  100;  
           
774          return pan;          return pan;
775      }      }
776            
777            
778      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
779          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice), pVoice(voice),
780          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), suVolOnCC(this),          suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
781            EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
782            resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
783            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
784          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
785          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
786          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount)
787      {      {
788          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
789          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
790            suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
791            
792            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
793          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
794          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
795          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 802  namespace LinuxSampler { namespace sfz {
802              EGs[i]->suPitchOnCC.pVoice = voice;              EGs[i]->suPitchOnCC.pVoice = voice;
803              EGs[i]->suCutoffOnCC.pVoice = voice;              EGs[i]->suCutoffOnCC.pVoice = voice;
804              EGs[i]->suResOnCC.pVoice = voice;              EGs[i]->suResOnCC.pVoice = voice;
805                EGs[i]->suPanOnCC.pVoice = voice;
806                EGs[i]->SetVoice(voice); // class EqUnitSupport
807          }          }
808                    
809          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
810              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
811              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
812                LFOs[i]->suDepthOnCC.pVoice = voice;
813                LFOs[i]->suFreqOnCC.pVoice = voice;
814              LFOs[i]->suFadeEG.pVoice = voice;              LFOs[i]->suFadeEG.pVoice = voice;
815              LFOs[i]->suVolOnCC.pVoice = voice;              LFOs[i]->suVolOnCC.pVoice = voice;
816              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
# Line 514  namespace LinuxSampler { namespace sfz { Line 818  namespace LinuxSampler { namespace sfz {
818              LFOs[i]->suPanOnCC.pVoice = voice;              LFOs[i]->suPanOnCC.pVoice = voice;
819              LFOs[i]->suCutoffOnCC.pVoice = voice;              LFOs[i]->suCutoffOnCC.pVoice = voice;
820              LFOs[i]->suResOnCC.pVoice = voice;              LFOs[i]->suResOnCC.pVoice = voice;
821                LFOs[i]->SetVoice(voice); // class EqUnitSupport
822          }          }
823      }      }
824            
# Line 527  namespace LinuxSampler { namespace sfz { Line 832  namespace LinuxSampler { namespace sfz {
832          }          }
833      }      }
834            
835        void SfzSignalUnitRack::InitRTLists() {
836            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
837            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
838            
839            EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
840            
841            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
842            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
843            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
844            suResOnCC.InitCCList(pCCPool, pSmootherPool);
845            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
846            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
847            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
848            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
849            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
850            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
851            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
852            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
853            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
854            
855            for (int i = 0; i < EGs.capacity(); i++) {
856                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
857                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
858                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
859                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
860                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
861                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
862                EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
863            }
864            
865            for (int i = 0; i < LFOs.capacity(); i++) {
866                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
867                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
868                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
869                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
870                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
871                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
872                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
873                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
874                LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
875            }
876        }
877        
878      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
879          EGs.clear();          EGs.clear();
880          volEGs.clear();          volEGs.clear();
881          pitchEGs.clear();          pitchEGs.clear();
882          filEGs.clear();          filEGs.clear();
883          resEGs.clear();          resEGs.clear();
884            panEGs.clear();
885            eqEGs.clear();
886                    
887          LFOs.clear();          LFOs.clear();
888          volLFOs.clear();          volLFOs.clear();
# Line 540  namespace LinuxSampler { namespace sfz { Line 890  namespace LinuxSampler { namespace sfz {
890          filLFOs.clear();          filLFOs.clear();
891          resLFOs.clear();          resLFOs.clear();
892          panLFOs.clear();          panLFOs.clear();
893            eqLFOs.clear();
894                    
895          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
896                    
897          suVolOnCC.SetCCs(pRegion->volume_oncc);          suVolOnCC.SetCCs(pRegion->volume_oncc);
898            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
899            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
900            suResOnCC.SetCCs(pRegion->resonance_oncc);
901                    
902          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
903              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
# Line 557  namespace LinuxSampler { namespace sfz { Line 911  namespace LinuxSampler { namespace sfz {
911                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
912                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
913                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
914                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
915                    if (pVoice->bEqSupport) {
916                        EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
917                        EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
918                        EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
919                        EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
920                        EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
921                        EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
922                        EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
923                        EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
924                        EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
925                    }
926              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
927                            
928              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 946  namespace LinuxSampler { namespace sfz {
946                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
947                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
948              }              }
949                
950                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
951                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
952                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
953                }
954                
955                if (pRegion->eg[i].HasEq()) {
956                    if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
957                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
958                }
959          }          }
960                    
961          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 589  namespace LinuxSampler { namespace sfz { Line 965  namespace LinuxSampler { namespace sfz {
965                    
966          // LFO          // LFO
967          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
968              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
969                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
970                    else pRegion->lfos[i].freq = 0;
971                }
972                            
973              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
974                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
# Line 601  namespace LinuxSampler { namespace sfz { Line 980  namespace LinuxSampler { namespace sfz {
980                  LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);                  LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
981                  LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);                  LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
982                  LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);                  LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
983                    if (pVoice->bEqSupport) {
984                        LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
985                        LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
986                        LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
987                        LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
988                        LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
989                        LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
990                        LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
991                        LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
992                        LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
993                    }
994              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
995                            
996              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 1017  namespace LinuxSampler { namespace sfz {
1017                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1018                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1019              }              }
1020                
1021                if (pRegion->lfos[i].HasEq()) {
1022                    if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1023                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1024                }
1025            }
1026            
1027            if (!pVoice->bEqSupport) {
1028                bHasEq = false;
1029            } else {
1030                suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1031                suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1032                suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1033                suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1034                suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1035                suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1036                suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1037                suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1038                suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1039            
1040                bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1041                         pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1042                         suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1043                         eqEGs.size() > 0 || eqLFOs.size() > 0;
1044          }          }
1045                    
1046          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
# Line 640  namespace LinuxSampler { namespace sfz { Line 1054  namespace LinuxSampler { namespace sfz {
1054                    
1055          Units.clear();          Units.clear();
1056                    
1057            EqUnitSupport::ImportUnits(this);
1058            
1059          Units.add(&suVolOnCC);          Units.add(&suVolOnCC);
1060            Units.add(&suPitchOnCC);
1061            Units.add(&suCutoffOnCC);
1062            Units.add(&suResOnCC);
1063                    
1064          Units.add(&suVolEG);          Units.add(&suVolEG);
1065          Units.add(&suFilEG);          Units.add(&suFilEG);
# Line 668  namespace LinuxSampler { namespace sfz { Line 1087  namespace LinuxSampler { namespace sfz {
1087              Units.add(&(EGs[i]->suPitchOnCC));              Units.add(&(EGs[i]->suPitchOnCC));
1088              Units.add(&(EGs[i]->suCutoffOnCC));              Units.add(&(EGs[i]->suCutoffOnCC));
1089              Units.add(&(EGs[i]->suResOnCC));              Units.add(&(EGs[i]->suResOnCC));
1090                Units.add(&(EGs[i]->suPanOnCC));
1091                EGs[i]->ImportUnits(this); // class EqUnitSupport
1092          }          }
1093                    
1094          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
# Line 679  namespace LinuxSampler { namespace sfz { Line 1100  namespace LinuxSampler { namespace sfz {
1100              Units.add(&(LFOs[i]->suPanOnCC));              Units.add(&(LFOs[i]->suPanOnCC));
1101              Units.add(&(LFOs[i]->suCutoffOnCC));              Units.add(&(LFOs[i]->suCutoffOnCC));
1102              Units.add(&(LFOs[i]->suResOnCC));              Units.add(&(LFOs[i]->suResOnCC));
1103                LFOs[i]->ImportUnits(this); // class EqUnitSupport
1104          }          }
1105                    
1106          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1107            Units.add(&suEndpoint.suXFInCC);
1108            Units.add(&suEndpoint.suXFOutCC);
1109            Units.add(&suEndpoint.suPanOnCC);
1110                    
1111          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1112      }      }
# Line 697  namespace LinuxSampler { namespace sfz { Line 1122  namespace LinuxSampler { namespace sfz {
1122              volEGs[i]->EG.enterFadeOutStage();              volEGs[i]->EG.enterFadeOutStage();
1123          }          }
1124      }      }
1125    
1126        void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1127            suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1128            for (int i = 0; i < volEGs.size(); i++) {
1129                volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1130            }
1131        }
1132    
1133        void SfzSignalUnitRack::Reset() {
1134            EqUnitSupport::ResetUnits();
1135            
1136            suVolOnCC.RemoveAllCCs();
1137            suPitchOnCC.RemoveAllCCs();
1138            suCutoffOnCC.RemoveAllCCs();
1139            suResOnCC.RemoveAllCCs();
1140            suEndpoint.suXFInCC.RemoveAllCCs();
1141            suEndpoint.suXFOutCC.RemoveAllCCs();
1142            suEndpoint.suPanOnCC.RemoveAllCCs();
1143            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1144            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1145            suFilLFO.suDepthOnCC.RemoveAllCCs();
1146            suFilLFO.suFreqOnCC.RemoveAllCCs();
1147            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1148            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1149            
1150            for (int i = 0; i < EGs.capacity(); i++) {
1151                EGs[i]->suAmpOnCC.RemoveAllCCs();
1152                EGs[i]->suVolOnCC.RemoveAllCCs();
1153                EGs[i]->suPitchOnCC.RemoveAllCCs();
1154                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1155                EGs[i]->suResOnCC.RemoveAllCCs();
1156                EGs[i]->suPanOnCC.RemoveAllCCs();
1157                EGs[i]->ResetUnits(); // class EqUnitSupport
1158            }
1159            
1160            for (int i = 0; i < LFOs.capacity(); i++) {
1161                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1162                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1163                LFOs[i]->suVolOnCC.RemoveAllCCs();
1164                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1165                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1166                LFOs[i]->suPanOnCC.RemoveAllCCs();
1167                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1168                LFOs[i]->suResOnCC.RemoveAllCCs();
1169                LFOs[i]->ResetUnits(); // class EqUnitSupport
1170            }
1171        }
1172    
1173        void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1174            suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1175            for (int i = 0; i < EGs.capacity(); i++) {
1176                EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1177            }
1178        }
1179        
1180        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1181            if (!pEqSupport->HasSupport()) return;
1182            if (pEqSupport->GetBandCount() < 3) {
1183                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1184                return;
1185            }
1186            
1187            ::sfz::Region* const pRegion = pVoice->pRegion;
1188            
1189            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1190            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1191            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1192            
1193            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1194            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1195            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1196            
1197            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1198            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1199            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1200            
1201            const float vel = pVoice->MIDIVelocity / 127.0f;
1202            
1203            dB1 += pRegion->eq1_vel2gain * vel;
1204            dB2 += pRegion->eq2_vel2gain * vel;
1205            dB3 += pRegion->eq3_vel2gain * vel;
1206            
1207            freq1 += pRegion->eq1_vel2freq * vel;
1208            freq2 += pRegion->eq2_vel2freq * vel;
1209            freq3 += pRegion->eq3_vel2freq * vel;
1210            
1211            for (int i = 0; i < eqEGs.size(); i++) {
1212                EGv2Unit* eg = eqEGs[i];
1213                if (!eg->Active()) continue;
1214                
1215                float l = eg->GetLevel();
1216                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1217                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1218                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1219                
1220                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1221                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1222                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1223                
1224                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1225                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1226                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1227            }
1228            
1229            for (int i = 0; i < eqLFOs.size(); i++) {
1230                LFOv2Unit* lfo = eqLFOs[i];
1231                if (!lfo->Active()) continue;
1232                
1233                float l = lfo->GetLevel();
1234                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1235                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1236                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1237                
1238                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1239                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1240                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1241                
1242                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1243                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1244                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1245            }
1246            
1247            pEqSupport->SetGain(0, dB1);
1248            pEqSupport->SetGain(1, dB2);
1249            pEqSupport->SetGain(2, dB3);
1250            
1251            pEqSupport->SetFreq(0, freq1);
1252            pEqSupport->SetFreq(1, freq2);
1253            pEqSupport->SetFreq(2, freq3);
1254            
1255            pEqSupport->SetBandwidth(0, bw1);
1256            pEqSupport->SetBandwidth(1, bw2);
1257            pEqSupport->SetBandwidth(2, bw3);
1258        }
1259        
1260        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1261            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1262              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1263              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1264        {
1265            SetVoice(pVoice);
1266        }
1267        
1268        void EqUnitSupport::SetVoice(Voice* pVoice) {
1269            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1270            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1271            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1272        }
1273        
1274        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1275            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1276            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1277            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1278            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1279            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1280            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1281            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1282            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1283            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1284        }
1285        
1286        void EqUnitSupport::ResetUnits() {
1287            suEq1GainOnCC.RemoveAllCCs();
1288            suEq2GainOnCC.RemoveAllCCs();
1289            suEq3GainOnCC.RemoveAllCCs();
1290            suEq1FreqOnCC.RemoveAllCCs();
1291            suEq2FreqOnCC.RemoveAllCCs();
1292            suEq3FreqOnCC.RemoveAllCCs();
1293            suEq1BwOnCC.RemoveAllCCs();
1294            suEq2BwOnCC.RemoveAllCCs();
1295            suEq3BwOnCC.RemoveAllCCs();
1296        }
1297        
1298        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1299            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1300            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1301            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1302            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1303            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1304            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1305            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1306            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1307            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1308        }
1309            
1310  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

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

  ViewVC Help
Powered by ViewVC