/[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 2230 by iliev, Fri Aug 5 17:59:10 2011 UTC revision 2249 by iliev, Fri Aug 19 18:29:29 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            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            float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200            attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201                    
202          EG.trigger(uint(pRegion->fileg_start * 10),          float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
205                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
208                     GetSampleRate());          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209            sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210            
211            float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
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 190  namespace LinuxSampler { namespace sfz { Line 312  namespace LinuxSampler { namespace sfz {
312      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
313          : 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),
314            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),
315            suPitchOnCC(rack)            suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
316      {      {
317          lfos.add(&lfo0);          lfos.add(&lfo0);
318          lfos.add(&lfo1);          lfos.add(&lfo1);
# Line 221  namespace LinuxSampler { namespace sfz { Line 343  namespace LinuxSampler { namespace sfz {
343            
344      void AmpLFOUnit::Trigger() {      void AmpLFOUnit::Trigger() {
345          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
346          pLfoInfo->delay  = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
347          pLfoInfo->freq   = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
348          pLfoInfo->fade   = pRegion->amplfo_fade;          pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
349          pLfoInfo->volume = pRegion->amplfo_depth;          pLfoInfo->volume = pRegion->amplfo_depth;
350                    
351          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 231  namespace LinuxSampler { namespace sfz { Line 353  namespace LinuxSampler { namespace sfz {
353            
354      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
355          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
356          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
357          pLfoInfo->freq  = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
358          pLfoInfo->fade  = pRegion->pitchlfo_fade;          pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
359          pLfoInfo->pitch = pRegion->pitchlfo_depth;          pLfoInfo->pitch = pRegion->pitchlfo_depth;
360                    
361          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 241  namespace LinuxSampler { namespace sfz { Line 363  namespace LinuxSampler { namespace sfz {
363            
364      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
365          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
366          pLfoInfo->delay  = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
367          pLfoInfo->freq   = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
368          pLfoInfo->fade   = pRegion->fillfo_fade;          pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
369          pLfoInfo->cutoff = pRegion->fillfo_depth;          pLfoInfo->cutoff = pRegion->fillfo_depth;
370                    
371          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 254  namespace LinuxSampler { namespace sfz { Line 376  namespace LinuxSampler { namespace sfz {
376      }      }
377            
378      void CCUnit::Trigger() {      void CCUnit::Trigger() {
379          for (int i = 0; i < Ctrls.size(); i++) {          RTList<CC>::Iterator ctrl = pCtrls->first();
380              Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);          RTList<CC>::Iterator end  = pCtrls->end();
381            for(; ctrl != end; ++ctrl) {
382                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
383                if ((*ctrl).pSmoother != NULL) (*ctrl).pSmoother->setValue((*ctrl).Value);
384          }          }
385          CCSignalUnit::Trigger();          CCSignalUnit::Trigger();
386      }      }
387            
388       void CCUnit::SetCCs(::sfz::Array<int>& cc) {      void CCUnit::SetCCs(::sfz::Array<int>& cc) {
389           RemoveAllCCs();          RemoveAllCCs();
390           for (int i = 0; i < 128; i++) {          for (int i = 0; i < 128; i++) {
391               if (cc[i] != 0) AddCC(i, cc[i]);              if (cc[i] != 0) AddCC(i, cc[i]);
392           }          }
393       }      }
394            
395       void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {      void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
396           RemoveAllCCs();          RemoveAllCCs();
397           for (int i = 0; i < cc.size(); i++) {          for (int i = 0; i < cc.size(); i++) {
398               if (cc[i].Influence != 0) {              if (cc[i].Influence != 0) {
399                   short int curve = cc[i].Curve;                  short int curve = cc[i].Curve;
400                   if (curve >= GetCurveCount()) curve = -1;                  if (curve >= GetCurveCount()) curve = -1;
401                   AddCC(cc[i].Controller, cc[i].Influence, curve);                  AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
402               }              }
403           }          }
404       }      }
405            
406       int CCUnit::GetCurveCount() {      void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
407           return pVoice->pRegion->GetInstrument()->curves.size();          AddCC(Controller, Influence, Curve);
408       }      }
409        
410        int CCUnit::GetCurveCount() {
411            return pVoice->pRegion->GetInstrument()->curves.size();
412        }
413            
414       ::sfz::Curve* CCUnit::GetCurve(int idx) {      ::sfz::Curve* CCUnit::GetCurve(int idx) {
415           return &pVoice->pRegion->GetInstrument()->curves[idx];          return &pVoice->pRegion->GetInstrument()->curves[idx];
416       }      }
417        
418        double CCUnit::GetSampleRate() {
419            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
420        }
421        
422        
423        SmoothCCUnit::~SmoothCCUnit() {
424            if (pSmoothers != NULL) delete pSmoothers;
425        }
426        
427        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
428            if (Smooth > 0) {
429                if (pSmoothers->poolIsEmpty()) {
430                    std::cerr << "Maximum number of smoothers reached" << std::endl;
431                    return;
432                }
433                Smoother* smoother = &(*(pSmoothers->allocAppend()));
434                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
435                AddCC(Controller, Influence, Curve, smoother);
436            } else {
437                AddCC(Controller, Influence, Curve);
438            }
439        }
440        
441        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
442            if (pSmoothers != NULL) delete pSmoothers;
443            pSmoothers = new RTList<Smoother>(pSmootherPool);
444        }
445        
446        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
447            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
448            InitSmoothers(pSmootherPool);
449        }
450    
451    
452      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
453            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
454        {
455                    
456      }      }
457            
# Line 296  namespace LinuxSampler { namespace sfz { Line 460  namespace LinuxSampler { namespace sfz {
460      }      }
461            
462      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
463            float xfInVelCoeff = 1;
464            
465            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
466                xfInVelCoeff = 0;
467            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
468                xfInVelCoeff = 1;
469            } else {
470                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
471                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
472                xfInVelCoeff = velPos / xfVelSize;
473                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
474                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
475                }
476            }
477                    
478            float xfOutVelCoeff = 1;
479            
480            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
481                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
482            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
483                xfOutVelCoeff = 1;
484            } else {
485                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
486                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
487                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
488                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
489                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
490                }
491            }
492            
493            float xfInKeyCoeff = 1;
494            
495            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
496                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
497            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
498                xfInKeyCoeff = 1;
499            } else {
500                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
501                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
502                xfInKeyCoeff = keyPos / xfKeySize;
503                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
504                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
505                }
506            }
507            
508            float xfOutKeyCoeff = 1;
509            
510            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
511                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
512            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
513                xfOutKeyCoeff = 1;
514            } else {
515                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
516                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
517                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
518                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
519                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
520                }
521            }
522            
523            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
524            
525            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
526            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
527            
528            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
529            
530            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
531      }      }
532            
533      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 316  namespace LinuxSampler { namespace sfz { Line 547  namespace LinuxSampler { namespace sfz {
547          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
548              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
549              if (!eg->Active()) continue;              if (!eg->Active()) continue;
             vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);  
550                            
551                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
552                if (dB < -144) dB = eg->pEGInfo->volume;
553                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
554                
555                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
556                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
557                
558                if (dB >= -144) {
559                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
560                    amp *= ToRatio(dB * 10.0);
561                }
562                
563                vol += amp * eg->GetLevel();
564          }          }
565                    
566          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
567          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
568            float f = u2->Active() ? u2->GetLevel() : 0;
569            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
570                    
571          vol *= ::sf2::ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
572                    
573          return vol;          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
574                LFOv2Unit* lfo = GetRack()->volLFOs[i];
575                if (!lfo->Active()) continue;
576                
577                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
578                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
579            }
580            
581            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
582            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
583            return vol * xfCoeff;
584      }      }
585            
586      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
587          float val;          float val;
588                    
589          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
590          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
591            float f = u1->Active() ? u1->GetLevel() : 0;
592            val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
593                    
594          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
595          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
596                    
597            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
598                EGv2Unit* eg = GetRack()->filEGs[i];
599                if (!eg->Active()) continue;
600                
601                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
602                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
603                val *= RTMath::CentsToFreqRatioUnlimited(f);
604            }
605            
606          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
607              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
608              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
609                            
610              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
611                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
612              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
613          }          }
614                    
615          return val;          return val;
616      }      }
617            
618        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
619             cutoff *= GetFilterCutoff();
620             float maxCutoff = 0.49 * pVoice->GetSampleRate();
621             return cutoff > maxCutoff ? maxCutoff : cutoff;
622        }
623        
624      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
625          double p;          double p;
626          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
627          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
628                    
629            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
630                EGv2Unit* eg = GetRack()->pitchEGs[i];
631                if (!eg->Active()) continue;
632                
633                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
634                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
635            }
636            
637          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
638          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
639          float f = u3->Active() ? u3->GetLevel() : 0;          float f = u3->Active() ? u3->GetLevel() : 0;
640          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
641                    
# Line 366  namespace LinuxSampler { namespace sfz { Line 647  namespace LinuxSampler { namespace sfz {
647              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
648          }          }
649                    
650          return p;          return p * pitchVeltrackRatio;
651      }      }
652            
653      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
654           float val = 0;           float val = 0;
655                    
656            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
657                EGv2Unit* eg = GetRack()->resEGs[i];
658                if (!eg->Active()) continue;
659                
660                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
661                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
662            }
663            
664          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
665              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
666              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
667                            
668              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
669                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
670          }          }
671                    
672          return val;          return val;
673      }      }
674            
675      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
676          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
677            
678            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
679                EGv2Unit* eg = GetRack()->panEGs[i];
680                if (!eg->Active()) continue;
681                
682                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
683                
684                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
685                    uint8_t val = eg->GetLevel() * 127;
686                    if (val > 127) val = 127;
687                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
688                } else {
689                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
690                }
691            }
692                    
693          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
694              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
695              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
696                            
697              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
698                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
699          }          }
700                    
701          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 401  namespace LinuxSampler { namespace sfz { Line 707  namespace LinuxSampler { namespace sfz {
707            
708      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
709          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
710          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), suVolOnCC(this),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
711          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
712          LFOs(maxLfoCount), pitchLFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
713            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
714      {      {
715          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
716            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
717          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
718          suPitchLFO.suDepthCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
719          suFilLFO.suFadeEG.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
720          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
721                    
722          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
723              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
724              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
725                EGs[i]->suAmpOnCC.pVoice = voice;
726                EGs[i]->suVolOnCC.pVoice = voice;
727                EGs[i]->suPitchOnCC.pVoice = voice;
728                EGs[i]->suCutoffOnCC.pVoice = voice;
729                EGs[i]->suResOnCC.pVoice = voice;
730                EGs[i]->suPanOnCC.pVoice = voice;
731          }          }
732                    
733          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
734              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
735              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
736                LFOs[i]->suDepthOnCC.pVoice = voice;
737                LFOs[i]->suFreqOnCC.pVoice = voice;
738              LFOs[i]->suFadeEG.pVoice = voice;              LFOs[i]->suFadeEG.pVoice = voice;
739                LFOs[i]->suVolOnCC.pVoice = voice;
740              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
741              LFOs[i]->suFreqOnCC.pVoice = voice;              LFOs[i]->suFreqOnCC.pVoice = voice;
742                LFOs[i]->suPanOnCC.pVoice = voice;
743                LFOs[i]->suCutoffOnCC.pVoice = voice;
744                LFOs[i]->suResOnCC.pVoice = voice;
745          }          }
746      }      }
747            
# Line 435  namespace LinuxSampler { namespace sfz { Line 755  namespace LinuxSampler { namespace sfz {
755          }          }
756      }      }
757            
758        void SfzSignalUnitRack::InitRTLists() {
759            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
760            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
761            
762            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
763            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
764            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
765            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
766            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
767            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
768            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
769            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
770            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
771            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
772            
773            for (int i = 0; i < EGs.capacity(); i++) {
774                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
775                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
776                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
777                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
778                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
779                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
780            }
781            
782            for (int i = 0; i < LFOs.capacity(); i++) {
783                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
784                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
785                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
786                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
787                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
788                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
789                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
790                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
791            }
792        }
793        
794      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
795          EGs.clear();          EGs.clear();
796          volEGs.clear();          volEGs.clear();
797          pitchEGs.clear();          pitchEGs.clear();
798            filEGs.clear();
799            resEGs.clear();
800            panEGs.clear();
801                    
802          LFOs.clear();          LFOs.clear();
803            volLFOs.clear();
804          pitchLFOs.clear();          pitchLFOs.clear();
805          filLFOs.clear();          filLFOs.clear();
806          resLFOs.clear();          resLFOs.clear();
# Line 457  namespace LinuxSampler { namespace sfz { Line 817  namespace LinuxSampler { namespace sfz {
817                  EGv2Unit eg(this);                  EGv2Unit eg(this);
818                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
819                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
820                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
821                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
822                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
823                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
824                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
825                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
826              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
827                            
828              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
829                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
830                ) {
831                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
832                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
833              }              }
834                
835                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
836                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
837                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
838                }
839                
840                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
841                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
842                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
843                }
844                
845                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
846                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
847                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
848                }
849                
850                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
851                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
852                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
853                }
854          }          }
855                    
856          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 478  namespace LinuxSampler { namespace sfz { Line 866  namespace LinuxSampler { namespace sfz {
866                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
867                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
868                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
869                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
870                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
871                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
872                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
873                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
874                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
875              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
876                            
877                if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
878                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
879                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
880                }
881                
882              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
883                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
884                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
885              }              }
886                            
887              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
888                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
889                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
890              }              }
891                            
892              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
893                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
894                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
895              }              }
896                            
897              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
898                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
899                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
900              }              }
901          }          }
902                    
903          suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
904          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
905                    
906            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
907          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
908                    
909            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
910          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
911                    
912          Units.clear();          Units.clear();
# Line 520  namespace LinuxSampler { namespace sfz { Line 919  namespace LinuxSampler { namespace sfz {
919                    
920          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)
921          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
922          Units.add(&suPitchLFO.suDepthCC);          Units.add(&suPitchLFO.suDepthOnCC);
923          Units.add(&suPitchLFO.suFadeEG);          Units.add(&suPitchLFO.suFadeEG);
924                    
925          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)
926            Units.add(&suAmpLFO.suDepthOnCC);
927          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
928          Units.add(&suAmpLFO.suFadeEG);          Units.add(&suAmpLFO.suFadeEG);
929                    
930          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)
931            Units.add(&suFilLFO.suDepthOnCC);
932          Units.add(&suFilLFO);          Units.add(&suFilLFO);
933          Units.add(&suFilLFO.suFadeEG);          Units.add(&suFilLFO.suFadeEG);
934                    
935          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
936              Units.add(EGs[i]);              Units.add(EGs[i]);
937                Units.add(&(EGs[i]->suAmpOnCC));
938                Units.add(&(EGs[i]->suVolOnCC));
939                Units.add(&(EGs[i]->suPitchOnCC));
940                Units.add(&(EGs[i]->suCutoffOnCC));
941                Units.add(&(EGs[i]->suResOnCC));
942                Units.add(&(EGs[i]->suPanOnCC));
943          }          }
944                    
945          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
946              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)
947              Units.add(LFOs[i]);              Units.add(LFOs[i]);
948              Units.add(&(LFOs[i]->suFadeEG));              Units.add(&(LFOs[i]->suFadeEG));
949                Units.add(&(LFOs[i]->suVolOnCC));
950              Units.add(&(LFOs[i]->suPitchOnCC));              Units.add(&(LFOs[i]->suPitchOnCC));
951                Units.add(&(LFOs[i]->suPanOnCC));
952                Units.add(&(LFOs[i]->suCutoffOnCC));
953                Units.add(&(LFOs[i]->suResOnCC));
954          }          }
955                    
956          Units.add(&suEndpoint);          Units.add(&suEndpoint);
957            Units.add(&suEndpoint.suXFInCC);
958            Units.add(&suEndpoint.suXFOutCC);
959            Units.add(&suEndpoint.suPanOnCC);
960                    
961          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
962      }      }
# Line 559  namespace LinuxSampler { namespace sfz { Line 973  namespace LinuxSampler { namespace sfz {
973          }          }
974      }      }
975            
976        void SfzSignalUnitRack::Reset() {
977            suVolOnCC.RemoveAllCCs();
978            suEndpoint.suXFInCC.RemoveAllCCs();
979            suEndpoint.suXFOutCC.RemoveAllCCs();
980            suEndpoint.suPanOnCC.RemoveAllCCs();
981            suPitchLFO.suDepthOnCC.RemoveAllCCs();
982            suPitchLFO.suFreqOnCC.RemoveAllCCs();
983            suFilLFO.suDepthOnCC.RemoveAllCCs();
984            suFilLFO.suFreqOnCC.RemoveAllCCs();
985            suAmpLFO.suDepthOnCC.RemoveAllCCs();
986            suAmpLFO.suFreqOnCC.RemoveAllCCs();
987            
988            for (int i = 0; i < EGs.capacity(); i++) {
989                EGs[i]->suAmpOnCC.RemoveAllCCs();
990                EGs[i]->suVolOnCC.RemoveAllCCs();
991                EGs[i]->suPitchOnCC.RemoveAllCCs();
992                EGs[i]->suCutoffOnCC.RemoveAllCCs();
993                EGs[i]->suResOnCC.RemoveAllCCs();
994                EGs[i]->suPanOnCC.RemoveAllCCs();
995            }
996            
997            for (int i = 0; i < LFOs.capacity(); i++) {
998                LFOs[i]->suDepthOnCC.RemoveAllCCs();
999                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1000                LFOs[i]->suVolOnCC.RemoveAllCCs();
1001                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1002                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1003                LFOs[i]->suPanOnCC.RemoveAllCCs();
1004                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1005                LFOs[i]->suResOnCC.RemoveAllCCs();
1006            }
1007        }
1008        
1009  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2230  
changed lines
  Added in v.2249

  ViewVC Help
Powered by ViewVC