/[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 2232 by iliev, Mon Aug 8 13:40:04 2011 UTC revision 2296 by iliev, Thu Dec 8 20:03:47 2011 UTC
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "SfzSignalUnitRack.h"  #include "SfzSignalUnitRack.h"
24  #include "Voice.h"  #include "Engine.h"
25  #include <SF.h>  
26    #define _200TH_ROOT_OF_10 1.011579454259899
27    
28  namespace LinuxSampler { namespace sfz {  namespace LinuxSampler { namespace sfz {
29            
30        double ToRatio(int Centibels) {
31            if (Centibels == 0) return 1.0;
32            return pow(_200TH_ROOT_OF_10, Centibels);
33        }
34        
35      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36                    
37      }      }
# Line 43  namespace LinuxSampler { namespace sfz { Line 49  namespace LinuxSampler { namespace sfz {
49          return f;          return f;
50      }      }
51            
52        void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53            RemoveAllCCs();
54            
55            for (int cc = 0; cc < 128; cc++) {
56                if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57                int i = loCCs[cc];
58                int j = hiCCs[cc];
59                if (j == 0) j = 127;
60                i += j << 8; // workaround to keep both values in the Influence parameter
61                AddCC(cc, i);
62            }
63        }
64        
65        void XFInCCUnit::Calculate() {
66            float l = 1;
67                    
68            RTList<CC>::Iterator ctrl = pCtrls->first();
69            RTList<CC>::Iterator end  = pCtrls->end();
70            for(; ctrl != end; ++ctrl) {
71                float c = 1;
72                int influence = (*ctrl).Influence;
73                int lo = influence & 0xff;
74                int hi = influence >> 8;
75                if ((*ctrl).Value <= lo) {
76                    c = 0;
77                } else if ((*ctrl).Value >= hi) {
78                    c = 1;
79                } else {
80                    float xfVelSize = hi - lo;
81                    float velPos = (*ctrl).Value - lo;
82                    c = velPos / xfVelSize;
83                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84                        c = sin(c * M_PI / 2.0);
85                    }
86                }
87                
88                l *= c;
89            }
90            
91            if (Level != l) {
92                Level = l;
93                if (pListener != NULL) pListener->ValueChanged(this);
94            }
95        }
96        
97        
98        void XFOutCCUnit::Calculate() {
99            float l = 1;
100                    
101            RTList<CC>::Iterator ctrl = pCtrls->first();
102            RTList<CC>::Iterator end  = pCtrls->end();
103            for(; ctrl != end; ++ctrl) {
104                float c = 1;
105                int influence = (*ctrl).Influence;
106                int lo = influence & 0xff;
107                int hi = influence >> 8;
108                if ((*ctrl).Value >= hi) {
109                    c = 0;
110                } else if ((*ctrl).Value <= lo) {
111                    c = 1;
112                } else {
113                    float xfVelSize = hi - lo;
114                    float velPos = (*ctrl).Value - lo;
115                    c = 1.0f - velPos / xfVelSize;
116                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117                        c = sin(c * M_PI / 2.0);
118                    }
119                }
120                
121                l *= c;
122            }
123            
124            if (Level != l) {
125                Level = l;
126                if (pListener != NULL) pListener->ValueChanged(this);
127            }
128        }
129        
130        
131        EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132            : EGUnit< ::LinuxSampler::sfz::EG>(rack), suAmpOnCC(rack), suVolOnCC(rack),
133              suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134        { }
135            
136      void EGv2Unit::Trigger() {      void EGv2Unit::Trigger() {
137          egInfo = *pEGInfo;          egInfo = *pEGInfo;
# Line 59  namespace LinuxSampler { namespace sfz { Line 148  namespace LinuxSampler { namespace sfz {
148            
149      void PitchEGUnit::Trigger() {      void PitchEGUnit::Trigger() {
150          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
151          depth = pRegion->pitcheg_depth;          depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152                    
153          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
154          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
155    
156          // set the delay trigger          // set the delay trigger
157          uiDelayTrigger = (pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158            delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160            
161            float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162            
163            float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164            attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165            
166            float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167            hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168                    
169          EG.trigger(uint(pRegion->pitcheg_start * 10),          float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
172                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
175                     GetSampleRate());          float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176            release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177            
178            EG.trigger (
179                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181            );
182      }      }
183            
184            
185      void FilEGUnit::Trigger() {      void FilEGUnit::Trigger() {
186          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
187          depth = pRegion->fileg_depth;          depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188                    
189          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
190          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191    
192          // set the delay trigger          // set the delay trigger
193          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194            delay += GetInfluence(pRegion->fileg_delay_oncc);
195            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196            
197            float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198            
199            float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200            attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201            
202            float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203            hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204                    
205          EG.trigger(uint(pRegion->fileg_start * 10),          float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
208                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
211                     GetSampleRate());          float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217            );
218      }      }
219            
220            
# Line 134  namespace LinuxSampler { namespace sfz { Line 255  namespace LinuxSampler { namespace sfz {
255            
256      LFOUnit::LFOUnit(SfzSignalUnitRack* rack)      LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257          : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),          : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258            suFadeEG(rack), suFreqOnCC(rack, this)            suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259      { }      { }
260            
261      LFOUnit::LFOUnit(const LFOUnit& Unit)      LFOUnit::LFOUnit(const LFOUnit& Unit)
262          : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),          : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263            suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)            suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265      {      {
266          Copy(Unit);          Copy(Unit);
267      }      }
# Line 158  namespace LinuxSampler { namespace sfz { Line 280  namespace LinuxSampler { namespace sfz {
280          Level = 0;          Level = 0;
281                    
282          // set the delay trigger          // set the delay trigger
283          uiDelayTrigger = pLfoInfo->delay * GetSampleRate();          uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
284          if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {          if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285              float f = pLfoInfo->fade;              float f = pLfoInfo->fade;
286              f += GetInfluence(pLfoInfo->fade_oncc);              f += GetInfluence(pLfoInfo->fade_oncc);
# Line 171  namespace LinuxSampler { namespace sfz { Line 293  namespace LinuxSampler { namespace sfz {
293      }      }
294            
295      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296            if (pLFO == NULL) return;
297          pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());          pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298      }      }
299            
# Line 190  namespace LinuxSampler { namespace sfz { Line 313  namespace LinuxSampler { namespace sfz {
313      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316            suPitchOnCC(rack)            suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317      {      {
318          lfos.add(&lfo0);          lfos.add(&lfo0);
319          lfos.add(&lfo1);          lfos.add(&lfo1);
# Line 220  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 254  namespace LinuxSampler { namespace sfz { Line 395  namespace LinuxSampler { namespace sfz {
395      }      }
396            
397      void CCUnit::Trigger() {      void CCUnit::Trigger() {
398          for (int i = 0; i < Ctrls.size(); i++) {          RTList<CC>::Iterator ctrl = pCtrls->first();
399              Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);          RTList<CC>::Iterator end  = pCtrls->end();
400              if (Ctrls[i].pSmoother != NULL) Ctrls[i].pSmoother->setValue(Ctrls[i].Value);          for(; ctrl != end; ++ctrl) {
401                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402                if ((*ctrl).pSmoother != NULL) {
403                    if ((*ctrl).Step > 0) {
404                        float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405                        (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406                    } else {
407                        (*ctrl).pSmoother->setValue((*ctrl).Value);
408                    }
409                }
410          }          }
411          CCSignalUnit::Trigger();          CCSignalUnit::Trigger();
412      }      }
413            
414       void CCUnit::SetCCs(::sfz::Array<int>& cc) {      void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415           RemoveAllCCs();          RemoveAllCCs();
416           for (int i = 0; i < 128; i++) {          for (int i = 0; i < 128; i++) {
417               if (cc[i] != 0) AddCC(i, cc[i]);              if (cc[i] != 0) AddCC(i, cc[i]);
418           }          }
419       }      }
420            
421       void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {      void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422           RemoveAllCCs();          RemoveAllCCs();
423           for (int i = 0; i < cc.size(); i++) {          for (int i = 0; i < 128; i++) {
424               if (cc[i].Influence != 0) {              if (cc[i] != 0) AddCC(i, cc[i]);
425                   short int curve = cc[i].Curve;          }
426                   if (curve >= GetCurveCount()) curve = -1;      }
427                   AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);      
428               }      void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
429           }          RemoveAllCCs();
430       }          for (int i = 0; i < cc.size(); i++) {
431                if (cc[i].Influence != 0) {
432                    short int curve = cc[i].Curve;
433                    if (curve >= GetCurveCount()) curve = -1;
434                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435                }
436            }
437        }
438            
439       void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {      void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440           AddCC(Controller, Influence, Curve);          AddCC(Controller, Influence, Curve, NULL, Step);
441       }      }
442            
443       int CCUnit::GetCurveCount() {      int CCUnit::GetCurveCount() {
444           return pVoice->pRegion->GetInstrument()->curves.size();          return pVoice->pRegion->GetInstrument()->curves.size();
445       }      }
446            
447       ::sfz::Curve* CCUnit::GetCurve(int idx) {      ::sfz::Curve* CCUnit::GetCurve(int idx) {
448           return &pVoice->pRegion->GetInstrument()->curves[idx];          return &pVoice->pRegion->GetInstrument()->curves[idx];
449       }      }
450            
451       double CCUnit::GetSampleRate() {      double CCUnit::GetSampleRate() {
452          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
453      }      }
454        
455        
456        SmoothCCUnit::~SmoothCCUnit() {
457            if (pSmoothers != NULL) delete pSmoothers;
458        }
459            
460       void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {      void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461           if (Smooth > 0) {          if (Smooth > 0) {
462               Smoothers[Controller].trigger(Smooth / 1000.0f, GetSampleRate());              if (pSmoothers->poolIsEmpty()) {
463               AddCC(Controller, Influence, Curve, &Smoothers[Controller]);                  std::cerr << "Maximum number of smoothers reached" << std::endl;
464           } else {                  return;
465               AddCC(Controller, Influence, Curve);              }
466           }              Smoother* smoother = &(*(pSmoothers->allocAppend()));
467       }              smoother->trigger(Smooth / 1000.0f, GetSampleRate());
468                AddCC(Controller, Influence, Curve, smoother, Step);
469            } else {
470                AddCC(Controller, Influence, Curve, NULL, Step);
471            }
472        }
473        
474        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
475            if (pSmoothers != NULL) delete pSmoothers;
476            pSmoothers = new RTList<Smoother>(pSmootherPool);
477        }
478        
479        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
480            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
481            InitSmoothers(pSmootherPool);
482        }
483    
484    
485      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
487        {
488                    
489      }      }
490            
# Line 314  namespace LinuxSampler { namespace sfz { Line 493  namespace LinuxSampler { namespace sfz {
493      }      }
494            
495      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
496            float xfInVelCoeff = 1;
497            
498            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
499                xfInVelCoeff = 0;
500            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
501                xfInVelCoeff = 1;
502            } else {
503                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
504                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
505                xfInVelCoeff = velPos / xfVelSize;
506                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
507                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
508                }
509            }
510            
511            float xfOutVelCoeff = 1;
512            
513            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
514                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
515            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
516                xfOutVelCoeff = 1;
517            } else {
518                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
519                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
520                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
521                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
522                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
523                }
524            }
525            
526            float xfInKeyCoeff = 1;
527            
528            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
529                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
530            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
531                xfInKeyCoeff = 1;
532            } else {
533                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
534                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
535                xfInKeyCoeff = keyPos / xfKeySize;
536                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
537                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
538                }
539            }
540                    
541            float xfOutKeyCoeff = 1;
542            
543            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
544                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
545            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
546                xfOutKeyCoeff = 1;
547            } else {
548                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
549                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
550                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
551                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
552                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
553                }
554            }
555            
556            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
557            
558            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
559            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
560            
561            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
562            
563            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
564      }      }
565            
566      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 334  namespace LinuxSampler { namespace sfz { Line 580  namespace LinuxSampler { namespace sfz {
580          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
581              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
582              if (!eg->Active()) continue;              if (!eg->Active()) continue;
             vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);  
583                            
584                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
585                if (dB < -144) dB = eg->pEGInfo->volume;
586                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
587                
588                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
589                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
590                
591                if (dB >= -144) {
592                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
593                    amp *= ToRatio(dB * 10.0);
594                }
595                
596                vol += amp * eg->GetLevel();
597          }          }
598                    
599          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
600          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
601            float f = u2->Active() ? u2->GetLevel() : 0;
602            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
603                    
604          vol *= ::sf2::ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
605                    
606          return vol;          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
607                LFOv2Unit* lfo = GetRack()->volLFOs[i];
608                if (!lfo->Active()) continue;
609                
610                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
611                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
612            }
613            
614            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
615            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
616            return vol * xfCoeff;
617      }      }
618            
619      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
620          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
621                    
622          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
623          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
624            float f = u1->Active() ? u1->GetLevel() : 0;
625            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
626                    
627          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
628          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
629                    
630            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
631                EGv2Unit* eg = GetRack()->filEGs[i];
632                if (!eg->Active()) continue;
633                
634                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
635                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
636                val *= RTMath::CentsToFreqRatioUnlimited(f);
637            }
638            
639          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
640              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
641              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
642                            
643              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
644                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
645              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
646          }          }
647                    
648          return val;          return val;
649      }      }
650            
651        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
652            cutoff *= GetFilterCutoff();
653            float maxCutoff = 0.49 * pVoice->GetSampleRate();
654            return cutoff > maxCutoff ? maxCutoff : cutoff;
655        }
656        
657      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
658          double p;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
659            
660          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
661          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
662            
663            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
664                EGv2Unit* eg = GetRack()->pitchEGs[i];
665                if (!eg->Active()) continue;
666                
667                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
668                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
669            }
670                    
671          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
672          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
673          float f = u3->Active() ? u3->GetLevel() : 0;          float f = u3->Active() ? u3->GetLevel() : 0;
674          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
675                    
# Line 384  namespace LinuxSampler { namespace sfz { Line 681  namespace LinuxSampler { namespace sfz {
681              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
682          }          }
683                    
684          return p;          return p * pitchVeltrackRatio;
685      }      }
686            
687      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
688           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
689            
690            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
691                EGv2Unit* eg = GetRack()->resEGs[i];
692                if (!eg->Active()) continue;
693                
694                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
695                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
696            }
697                    
698          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
699              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
700              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
701                            
702              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
703                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
704          }          }
705                    
706          return val;          return val;
707      }      }
708            
709      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
710          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
711            
712            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
713                EGv2Unit* eg = GetRack()->panEGs[i];
714                if (!eg->Active()) continue;
715                
716                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
717                
718                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
719                    uint8_t val = eg->GetLevel() * 127;
720                    if (val > 127) val = 127;
721                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
722                } else {
723                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
724                }
725            }
726                    
727          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
728              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
729              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
730                            
731              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
732                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
733          }          }
734                    
735          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 419  namespace LinuxSampler { namespace sfz { Line 741  namespace LinuxSampler { namespace sfz {
741            
742      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
743          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
744          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), suVolOnCC(this),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
745            suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
746            suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
747            suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
748            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
749          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
750          LFOs(maxLfoCount), pitchLFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
751            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
752      {      {
753          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
754          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
755          suPitchLFO.suDepthCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
756          suFilLFO.suFadeEG.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          
757          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
758            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
759            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
760            
761            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
762            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
763            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
764            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
765                    
766          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
767              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
768              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
769                EGs[i]->suAmpOnCC.pVoice = voice;
770                EGs[i]->suVolOnCC.pVoice = voice;
771                EGs[i]->suPitchOnCC.pVoice = voice;
772                EGs[i]->suCutoffOnCC.pVoice = voice;
773                EGs[i]->suResOnCC.pVoice = voice;
774                EGs[i]->suPanOnCC.pVoice = voice;
775          }          }
776                    
777          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
778              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
779              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
780                LFOs[i]->suDepthOnCC.pVoice = voice;
781                LFOs[i]->suFreqOnCC.pVoice = voice;
782              LFOs[i]->suFadeEG.pVoice = voice;              LFOs[i]->suFadeEG.pVoice = voice;
783                LFOs[i]->suVolOnCC.pVoice = voice;
784              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
785              LFOs[i]->suFreqOnCC.pVoice = voice;              LFOs[i]->suFreqOnCC.pVoice = voice;
786                LFOs[i]->suPanOnCC.pVoice = voice;
787                LFOs[i]->suCutoffOnCC.pVoice = voice;
788                LFOs[i]->suResOnCC.pVoice = voice;
789          }          }
790      }      }
791            
# Line 453  namespace LinuxSampler { namespace sfz { Line 799  namespace LinuxSampler { namespace sfz {
799          }          }
800      }      }
801            
802        void SfzSignalUnitRack::InitRTLists() {
803            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
804            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
805            
806            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
807            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
808            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
809            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
810            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
811            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
812            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
813            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
814            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
815            
816            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
817            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
818            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
819            suResOnCC.InitCCList(pCCPool, pSmootherPool);
820            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
821            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
822            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
823            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
824            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
825            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
826            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
827            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
828            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
829            
830            for (int i = 0; i < EGs.capacity(); i++) {
831                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
832                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
833                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
834                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
835                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
836                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
837            }
838            
839            for (int i = 0; i < LFOs.capacity(); i++) {
840                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
841                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
842                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
843                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
844                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
845                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
846                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
848            }
849        }
850        
851      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
852          EGs.clear();          EGs.clear();
853          volEGs.clear();          volEGs.clear();
854          pitchEGs.clear();          pitchEGs.clear();
855            filEGs.clear();
856            resEGs.clear();
857            panEGs.clear();
858                    
859          LFOs.clear();          LFOs.clear();
860            volLFOs.clear();
861          pitchLFOs.clear();          pitchLFOs.clear();
862          filLFOs.clear();          filLFOs.clear();
863          resLFOs.clear();          resLFOs.clear();
# Line 466  namespace LinuxSampler { namespace sfz { Line 865  namespace LinuxSampler { namespace sfz {
865                    
866          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
867                    
868            suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
869            suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
870            suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
871            suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
872            suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
873            suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
874            suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
875            suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
876            suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
877            
878            bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
879                     suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
880            
881          suVolOnCC.SetCCs(pRegion->volume_oncc);          suVolOnCC.SetCCs(pRegion->volume_oncc);
882            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
883            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
884            suResOnCC.SetCCs(pRegion->resonance_oncc);
885                    
886          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
887              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
# Line 475  namespace LinuxSampler { namespace sfz { Line 890  namespace LinuxSampler { namespace sfz {
890                  EGv2Unit eg(this);                  EGv2Unit eg(this);
891                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
892                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
893                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
894                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
895                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
896                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
897                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
898                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
899              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
900                            
901              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
902                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
903                ) {
904                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
905                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
906              }              }
907                
908                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
909                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
910                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
911                }
912                
913                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
914                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
915                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
916                }
917                
918                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
919                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
920                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
921                }
922                
923                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
924                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
925                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
926                }
927          }          }
928                    
929          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 490  namespace LinuxSampler { namespace sfz { Line 933  namespace LinuxSampler { namespace sfz {
933                    
934          // LFO          // LFO
935          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
936              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
937                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
938                    else pRegion->lfos[i].freq = 0;
939                }
940                            
941              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
942                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
943                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
944                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
945                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
946                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
947                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
948                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
949                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
950                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
951              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
952                            
953                if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
954                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
955                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
956                }
957                
958              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
959                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
960                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
961              }              }
962                            
963              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
964                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
965                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
966              }              }
967                            
968              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
969                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
970                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
971              }              }
972                            
973              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
974                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
975                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
976              }              }
977          }          }
978                    
979          suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
980          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
981                    
982            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
983          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
984                    
985            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
986          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
987                    
988          Units.clear();          Units.clear();
989                    
990            Units.add(&suEq1GainOnCC);
991            Units.add(&suEq2GainOnCC);
992            Units.add(&suEq3GainOnCC);
993            Units.add(&suEq1FreqOnCC);
994            Units.add(&suEq2FreqOnCC);
995            Units.add(&suEq3FreqOnCC);
996            Units.add(&suEq1BwOnCC);
997            Units.add(&suEq2BwOnCC);
998            Units.add(&suEq3BwOnCC);
999            
1000          Units.add(&suVolOnCC);          Units.add(&suVolOnCC);
1001            Units.add(&suPitchOnCC);
1002            Units.add(&suCutoffOnCC);
1003            Units.add(&suResOnCC);
1004                    
1005          Units.add(&suVolEG);          Units.add(&suVolEG);
1006          Units.add(&suFilEG);          Units.add(&suFilEG);
# Line 538  namespace LinuxSampler { namespace sfz { Line 1008  namespace LinuxSampler { namespace sfz {
1008                    
1009          Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)          Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1010          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
1011          Units.add(&suPitchLFO.suDepthCC);          Units.add(&suPitchLFO.suDepthOnCC);
1012          Units.add(&suPitchLFO.suFadeEG);          Units.add(&suPitchLFO.suFadeEG);
1013                    
1014          Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)          Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1015            Units.add(&suAmpLFO.suDepthOnCC);
1016          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
1017          Units.add(&suAmpLFO.suFadeEG);          Units.add(&suAmpLFO.suFadeEG);
1018                    
1019          Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)          Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1020            Units.add(&suFilLFO.suDepthOnCC);
1021          Units.add(&suFilLFO);          Units.add(&suFilLFO);
1022          Units.add(&suFilLFO.suFadeEG);          Units.add(&suFilLFO.suFadeEG);
1023                    
1024          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1025              Units.add(EGs[i]);              Units.add(EGs[i]);
1026                Units.add(&(EGs[i]->suAmpOnCC));
1027                Units.add(&(EGs[i]->suVolOnCC));
1028                Units.add(&(EGs[i]->suPitchOnCC));
1029                Units.add(&(EGs[i]->suCutoffOnCC));
1030                Units.add(&(EGs[i]->suResOnCC));
1031                Units.add(&(EGs[i]->suPanOnCC));
1032          }          }
1033                    
1034          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1035              Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)              Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1036              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1037              Units.add(&(LFOs[i]->suFadeEG));              Units.add(&(LFOs[i]->suFadeEG));
1038                Units.add(&(LFOs[i]->suVolOnCC));
1039              Units.add(&(LFOs[i]->suPitchOnCC));              Units.add(&(LFOs[i]->suPitchOnCC));
1040                Units.add(&(LFOs[i]->suPanOnCC));
1041                Units.add(&(LFOs[i]->suCutoffOnCC));
1042                Units.add(&(LFOs[i]->suResOnCC));
1043          }          }
1044                    
1045          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1046            Units.add(&suEndpoint.suXFInCC);
1047            Units.add(&suEndpoint.suXFOutCC);
1048            Units.add(&suEndpoint.suPanOnCC);
1049                    
1050          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1051      }      }
# Line 577  namespace LinuxSampler { namespace sfz { Line 1062  namespace LinuxSampler { namespace sfz {
1062          }          }
1063      }      }
1064            
1065        void SfzSignalUnitRack::Reset() {
1066            suEq1GainOnCC.RemoveAllCCs();
1067            suEq2GainOnCC.RemoveAllCCs();
1068            suEq3GainOnCC.RemoveAllCCs();
1069            suEq1FreqOnCC.RemoveAllCCs();
1070            suEq2FreqOnCC.RemoveAllCCs();
1071            suEq3FreqOnCC.RemoveAllCCs();
1072            suEq1BwOnCC.RemoveAllCCs();
1073            suEq2BwOnCC.RemoveAllCCs();
1074            suEq3BwOnCC.RemoveAllCCs();
1075            
1076            suVolOnCC.RemoveAllCCs();
1077            suPitchOnCC.RemoveAllCCs();
1078            suCutoffOnCC.RemoveAllCCs();
1079            suResOnCC.RemoveAllCCs();
1080            suEndpoint.suXFInCC.RemoveAllCCs();
1081            suEndpoint.suXFOutCC.RemoveAllCCs();
1082            suEndpoint.suPanOnCC.RemoveAllCCs();
1083            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1084            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1085            suFilLFO.suDepthOnCC.RemoveAllCCs();
1086            suFilLFO.suFreqOnCC.RemoveAllCCs();
1087            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1088            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1089            
1090            for (int i = 0; i < EGs.capacity(); i++) {
1091                EGs[i]->suAmpOnCC.RemoveAllCCs();
1092                EGs[i]->suVolOnCC.RemoveAllCCs();
1093                EGs[i]->suPitchOnCC.RemoveAllCCs();
1094                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1095                EGs[i]->suResOnCC.RemoveAllCCs();
1096                EGs[i]->suPanOnCC.RemoveAllCCs();
1097            }
1098            
1099            for (int i = 0; i < LFOs.capacity(); i++) {
1100                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1101                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1102                LFOs[i]->suVolOnCC.RemoveAllCCs();
1103                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1104                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1105                LFOs[i]->suPanOnCC.RemoveAllCCs();
1106                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1107                LFOs[i]->suResOnCC.RemoveAllCCs();
1108            }
1109        }
1110        
1111        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1112            if (!pEqSupport->HasSupport()) return;
1113            if (pEqSupport->GetBandCount() < 3) {
1114                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1115                return;
1116            }
1117            
1118            ::sfz::Region* const pRegion = pVoice->pRegion;
1119            
1120            float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1121            pEqSupport->SetGain(0, dB);
1122            
1123            dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1124            pEqSupport->SetGain(1, dB);
1125            
1126            dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1127            pEqSupport->SetGain(2, dB);
1128            
1129            float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1130            pEqSupport->SetFreq(0, freq);
1131            
1132            freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1133            pEqSupport->SetFreq(1, freq);
1134            
1135            freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1136            pEqSupport->SetFreq(2, freq);
1137            
1138            float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1139            pEqSupport->SetBandwidth(0, bw);
1140            
1141            bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1142            pEqSupport->SetBandwidth(1, bw);
1143            
1144            bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1145            pEqSupport->SetBandwidth(2, bw);
1146        }
1147        
1148  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

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

  ViewVC Help
Powered by ViewVC