/[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 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)      EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132          : EGUnit< ::LinuxSampler::sfz::EG>(rack),          : EGUnit< ::LinuxSampler::sfz::EG>(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            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            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171                    
172          EG.trigger(uint(pRegion->pitcheg_start * 10),          float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
175                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
178                     GetSampleRate());          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          EG.trigger(uint(pRegion->fileg_start * 10),          float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
202                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
205                     GetSampleRate());          float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206            decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207            
208            float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209            sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210            
211            float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217            );
218      }      }
219            
220            
# Line 177  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 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) {      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 320  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 350  namespace LinuxSampler { namespace sfz { Line 590  namespace LinuxSampler { namespace sfz {
590                            
591              if (dB >= -144) {              if (dB >= -144) {
592                  if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;                  if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
593                  amp *= ::sf2::ToRatio(dB * 10.0);                  amp *= ToRatio(dB * 10.0);
594              }              }
595                            
596              vol += amp * eg->GetLevel();              vol += amp * eg->GetLevel();
# Line 359  namespace LinuxSampler { namespace sfz { Line 599  namespace LinuxSampler { namespace sfz {
599          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
600          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
601          float f = u2->Active() ? u2->GetLevel() : 0;          float f = u2->Active() ? u2->GetLevel() : 0;
602          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;
603                    
604          vol *= ::sf2::ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
605                    
606          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
607              LFOv2Unit* lfo = GetRack()->volLFOs[i];              LFOv2Unit* lfo = GetRack()->volLFOs[i];
608              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
609                            
610              float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;              float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
611              vol *= ::sf2::ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);              vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
612          }          }
613                    
614          return vol;          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          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
624          float f = u1->Active() ? u1->GetLevel() : 0;          float f = u1->Active() ? u1->GetLevel() : 0;
625          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;          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;
# Line 407  namespace LinuxSampler { namespace sfz { Line 649  namespace LinuxSampler { namespace sfz {
649      }      }
650            
651      float EndpointUnit::CalculateFilterCutoff(float cutoff) {      float EndpointUnit::CalculateFilterCutoff(float cutoff) {
652           cutoff *= GetFilterCutoff();          cutoff *= GetFilterCutoff();
653           float maxCutoff = 0.49 * pVoice->GetSampleRate();          float maxCutoff = 0.49 * pVoice->GetSampleRate();
654           return cutoff > maxCutoff ? maxCutoff : cutoff;          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++) {          for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
664              EGv2Unit* eg = GetRack()->pitchEGs[i];              EGv2Unit* eg = GetRack()->pitchEGs[i];
# Line 438  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++) {          for (int i = 0; i < GetRack()->resEGs.size(); i++) {
691              EGv2Unit* eg = GetRack()->resEGs[i];              EGv2Unit* eg = GetRack()->resEGs[i];
# Line 464  namespace LinuxSampler { namespace sfz { Line 707  namespace LinuxSampler { namespace sfz {
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];
# Line 483  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), filEGs(maxEgCount), resEGs(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), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
751          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          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            suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
756            
757            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;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
763          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
764          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 771  namespace LinuxSampler { namespace sfz {
771              EGs[i]->suPitchOnCC.pVoice = voice;              EGs[i]->suPitchOnCC.pVoice = voice;
772              EGs[i]->suCutoffOnCC.pVoice = voice;              EGs[i]->suCutoffOnCC.pVoice = voice;
773              EGs[i]->suResOnCC.pVoice = voice;              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;              LFOs[i]->suVolOnCC.pVoice = voice;
784              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
# Line 527  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();          filEGs.clear();
856          resEGs.clear();          resEGs.clear();
857            panEGs.clear();
858                    
859          LFOs.clear();          LFOs.clear();
860          volLFOs.clear();          volLFOs.clear();
# Line 543  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 557  namespace LinuxSampler { namespace sfz { Line 895  namespace LinuxSampler { namespace sfz {
895                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
896                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
897                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);                  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 || !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 919  namespace LinuxSampler { namespace sfz {
919                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
920                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  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 589  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);
# Line 640  namespace LinuxSampler { namespace sfz { Line 987  namespace LinuxSampler { namespace sfz {
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 668  namespace LinuxSampler { namespace sfz { Line 1028  namespace LinuxSampler { namespace sfz {
1028              Units.add(&(EGs[i]->suPitchOnCC));              Units.add(&(EGs[i]->suPitchOnCC));
1029              Units.add(&(EGs[i]->suCutoffOnCC));              Units.add(&(EGs[i]->suCutoffOnCC));
1030              Units.add(&(EGs[i]->suResOnCC));              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++) {
# Line 682  namespace LinuxSampler { namespace sfz { Line 1043  namespace LinuxSampler { namespace sfz {
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 698  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.2235  
changed lines
  Added in v.2296

  ViewVC Help
Powered by ViewVC