/[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 2236 by iliev, Thu Aug 11 18:25:45 2011 UTC revision 2252 by iliev, Sat Aug 20 14:01:36 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 59  namespace LinuxSampler { namespace sfz { Line 65  namespace LinuxSampler { namespace sfz {
65      void XFInCCUnit::Calculate() {      void XFInCCUnit::Calculate() {
66          float l = 1;          float l = 1;
67                                    
68          for (int i = 0; i < Ctrls.size(); i++) {          RTList<CC>::Iterator ctrl = pCtrls->first();
69            RTList<CC>::Iterator end  = pCtrls->end();
70            for(; ctrl != end; ++ctrl) {
71              float c = 1;              float c = 1;
72              int influence = Ctrls[i].Influence;              int influence = (*ctrl).Influence;
73              int lo = influence & 0xff;              int lo = influence & 0xff;
74              int hi = influence >> 8;              int hi = influence >> 8;
75              if (Ctrls[i].Value <= lo) {              if ((*ctrl).Value <= lo) {
76                  c = 0;                  c = 0;
77              } else if (Ctrls[i].Value >= hi) {              } else if ((*ctrl).Value >= hi) {
78                  c = 1;                  c = 1;
79              } else {              } else {
80                  float xfVelSize = hi - lo;                  float xfVelSize = hi - lo;
81                  float velPos = Ctrls[i].Value - lo;                  float velPos = (*ctrl).Value - lo;
82                  c = velPos / xfVelSize;                  c = velPos / xfVelSize;
83                  if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {                  if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84                      c = sin(c * M_PI / 2.0);                      c = sin(c * M_PI / 2.0);
# Line 90  namespace LinuxSampler { namespace sfz { Line 98  namespace LinuxSampler { namespace sfz {
98      void XFOutCCUnit::Calculate() {      void XFOutCCUnit::Calculate() {
99          float l = 1;          float l = 1;
100                                    
101          for (int i = 0; i < Ctrls.size(); i++) {          RTList<CC>::Iterator ctrl = pCtrls->first();
102            RTList<CC>::Iterator end  = pCtrls->end();
103            for(; ctrl != end; ++ctrl) {
104              float c = 1;              float c = 1;
105              int influence = Ctrls[i].Influence;              int influence = (*ctrl).Influence;
106              int lo = influence & 0xff;              int lo = influence & 0xff;
107              int hi = influence >> 8;              int hi = influence >> 8;
108              if (Ctrls[i].Value >= hi) {              if ((*ctrl).Value >= hi) {
109                  c = 0;                  c = 0;
110              } else if (Ctrls[i].Value <= lo) {              } else if ((*ctrl).Value <= lo) {
111                  c = 1;                  c = 1;
112              } else {              } else {
113                  float xfVelSize = hi - lo;                  float xfVelSize = hi - lo;
114                  float velPos = Ctrls[i].Value - lo;                  float velPos = (*ctrl).Value - lo;
115                  c = 1.0f - velPos / xfVelSize;                  c = 1.0f - velPos / xfVelSize;
116                  if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {                  if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117                      c = sin(c * M_PI / 2.0);                      c = sin(c * M_PI / 2.0);
# Line 119  namespace LinuxSampler { namespace sfz { Line 129  namespace LinuxSampler { namespace sfz {
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 138  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          EG.trigger(uint(pRegion->pitcheg_start * 10),          float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
169                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
172                     GetSampleRate());          float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173            sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174            
175            float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176            release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177            
178            EG.trigger (
179                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181            );
182      }      }
183            
184            
185      void FilEGUnit::Trigger() {      void FilEGUnit::Trigger() {
186          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
187          depth = pRegion->fileg_depth;          depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188                    
189          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
190          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191    
192          // set the delay trigger          // set the delay trigger
193          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194            delay += GetInfluence(pRegion->fileg_delay_oncc);
195            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196            
197            float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198            
199            float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200            attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201            
202            float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203            hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204            
205            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(uint(pRegion->fileg_start * 10),          EG.trigger (
215                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          );
                    uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),  
                    GetSampleRate());  
218      }      }
219            
220            
# Line 251  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 300  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 334  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) (*ctrl).pSmoother->setValue((*ctrl).Value);
403          }          }
404          CCSignalUnit::Trigger();          CCSignalUnit::Trigger();
405      }      }
406            
407       void CCUnit::SetCCs(::sfz::Array<int>& cc) {      void CCUnit::SetCCs(::sfz::Array<int>& cc) {
408           RemoveAllCCs();          RemoveAllCCs();
409           for (int i = 0; i < 128; i++) {          for (int i = 0; i < 128; i++) {
410               if (cc[i] != 0) AddCC(i, cc[i]);              if (cc[i] != 0) AddCC(i, cc[i]);
411           }          }
412       }      }
413            
414       void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {      void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
415           RemoveAllCCs();          RemoveAllCCs();
416           for (int i = 0; i < cc.size(); i++) {          for (int i = 0; i < cc.size(); i++) {
417               if (cc[i].Influence != 0) {              if (cc[i].Influence != 0) {
418                   short int curve = cc[i].Curve;                  short int curve = cc[i].Curve;
419                   if (curve >= GetCurveCount()) curve = -1;                  if (curve >= GetCurveCount()) curve = -1;
420                   AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);                  AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
421               }              }
422           }          }
423       }      }
424            
425       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) {
426           AddCC(Controller, Influence, Curve);          AddCC(Controller, Influence, Curve);
427       }      }
428            
429       int CCUnit::GetCurveCount() {      int CCUnit::GetCurveCount() {
430           return pVoice->pRegion->GetInstrument()->curves.size();          return pVoice->pRegion->GetInstrument()->curves.size();
431       }      }
432            
433       ::sfz::Curve* CCUnit::GetCurve(int idx) {      ::sfz::Curve* CCUnit::GetCurve(int idx) {
434           return &pVoice->pRegion->GetInstrument()->curves[idx];          return &pVoice->pRegion->GetInstrument()->curves[idx];
435       }      }
436            
437       double CCUnit::GetSampleRate() {      double CCUnit::GetSampleRate() {
438          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
439      }      }
440        
441        
442        SmoothCCUnit::~SmoothCCUnit() {
443            if (pSmoothers != NULL) delete pSmoothers;
444        }
445            
446       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) {
447           if (Smooth > 0) {          if (Smooth > 0) {
448               Smoothers[Controller].trigger(Smooth / 1000.0f, GetSampleRate());              if (pSmoothers->poolIsEmpty()) {
449               AddCC(Controller, Influence, Curve, &Smoothers[Controller]);                  std::cerr << "Maximum number of smoothers reached" << std::endl;
450           } else {                  return;
451               AddCC(Controller, Influence, Curve);              }
452           }              Smoother* smoother = &(*(pSmoothers->allocAppend()));
453       }              smoother->trigger(Smooth / 1000.0f, GetSampleRate());
454                AddCC(Controller, Influence, Curve, smoother);
455            } else {
456                AddCC(Controller, Influence, Curve);
457            }
458        }
459        
460        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
461            if (pSmoothers != NULL) delete pSmoothers;
462            pSmoothers = new RTList<Smoother>(pSmootherPool);
463        }
464        
465        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
466            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
467            InitSmoothers(pSmootherPool);
468        }
469    
470    
471      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
472            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
473        {
474                    
475      }      }
476            
# Line 458  namespace LinuxSampler { namespace sfz { Line 543  namespace LinuxSampler { namespace sfz {
543                    
544          suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);          suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
545          suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);          suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
546            
547            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
548            
549            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
550      }      }
551            
552      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 487  namespace LinuxSampler { namespace sfz { Line 576  namespace LinuxSampler { namespace sfz {
576                            
577              if (dB >= -144) {              if (dB >= -144) {
578                  if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;                  if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
579                  amp *= ::sf2::ToRatio(dB * 10.0);                  amp *= ToRatio(dB * 10.0);
580              }              }
581                            
582              vol += amp * eg->GetLevel();              vol += amp * eg->GetLevel();
# Line 496  namespace LinuxSampler { namespace sfz { Line 585  namespace LinuxSampler { namespace sfz {
585          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
586          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
587          float f = u2->Active() ? u2->GetLevel() : 0;          float f = u2->Active() ? u2->GetLevel() : 0;
588          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;
589                    
590          vol *= ::sf2::ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
591                    
592          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
593              LFOv2Unit* lfo = GetRack()->volLFOs[i];              LFOv2Unit* lfo = GetRack()->volLFOs[i];
594              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
595                            
596              float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;              float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
597              vol *= ::sf2::ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);              vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
598          }          }
599                    
600          if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();          if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
# Line 514  namespace LinuxSampler { namespace sfz { Line 603  namespace LinuxSampler { namespace sfz {
603      }      }
604            
605      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
606          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
607                    
608          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
609          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
610          float f = u1->Active() ? u1->GetLevel() : 0;          float f = u1->Active() ? u1->GetLevel() : 0;
611          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;          val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
612                    
613          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
614          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
# Line 546  namespace LinuxSampler { namespace sfz { Line 635  namespace LinuxSampler { namespace sfz {
635      }      }
636            
637      float EndpointUnit::CalculateFilterCutoff(float cutoff) {      float EndpointUnit::CalculateFilterCutoff(float cutoff) {
638           cutoff *= GetFilterCutoff();          cutoff *= GetFilterCutoff();
639           float maxCutoff = 0.49 * pVoice->GetSampleRate();          float maxCutoff = 0.49 * pVoice->GetSampleRate();
640           return cutoff > maxCutoff ? maxCutoff : cutoff;          return cutoff > maxCutoff ? maxCutoff : cutoff;
641      }      }
642            
643      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
# Line 577  namespace LinuxSampler { namespace sfz { Line 666  namespace LinuxSampler { namespace sfz {
666              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
667          }          }
668                    
669          return p;          return p * pitchVeltrackRatio;
670      }      }
671            
672      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
673           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
674                    
675          for (int i = 0; i < GetRack()->resEGs.size(); i++) {          for (int i = 0; i < GetRack()->resEGs.size(); i++) {
676              EGv2Unit* eg = GetRack()->resEGs[i];              EGv2Unit* eg = GetRack()->resEGs[i];
# Line 603  namespace LinuxSampler { namespace sfz { Line 692  namespace LinuxSampler { namespace sfz {
692      }      }
693            
694      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
695          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
696            
697            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
698                EGv2Unit* eg = GetRack()->panEGs[i];
699                if (!eg->Active()) continue;
700                
701                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
702                
703                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
704                    uint8_t val = eg->GetLevel() * 127;
705                    if (val > 127) val = 127;
706                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
707                } else {
708                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
709                }
710            }
711                    
712          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
713              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
# Line 622  namespace LinuxSampler { namespace sfz { Line 726  namespace LinuxSampler { namespace sfz {
726            
727      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
728          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
729          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), suVolOnCC(this),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
730            suVolOnCC(this), suCutoffOnCC(this), suResOnCC(this),
731          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
732          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
733          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
734      {      {
735          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
736          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
737          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
738          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
739          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
740          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
# Line 642  namespace LinuxSampler { namespace sfz { Line 747  namespace LinuxSampler { namespace sfz {
747              EGs[i]->suPitchOnCC.pVoice = voice;              EGs[i]->suPitchOnCC.pVoice = voice;
748              EGs[i]->suCutoffOnCC.pVoice = voice;              EGs[i]->suCutoffOnCC.pVoice = voice;
749              EGs[i]->suResOnCC.pVoice = voice;              EGs[i]->suResOnCC.pVoice = voice;
750                EGs[i]->suPanOnCC.pVoice = voice;
751          }          }
752                    
753          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
754              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
755              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
756                LFOs[i]->suDepthOnCC.pVoice = voice;
757                LFOs[i]->suFreqOnCC.pVoice = voice;
758              LFOs[i]->suFadeEG.pVoice = voice;              LFOs[i]->suFadeEG.pVoice = voice;
759              LFOs[i]->suVolOnCC.pVoice = voice;              LFOs[i]->suVolOnCC.pVoice = voice;
760              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
# Line 667  namespace LinuxSampler { namespace sfz { Line 775  namespace LinuxSampler { namespace sfz {
775          }          }
776      }      }
777            
778        void SfzSignalUnitRack::InitRTLists() {
779            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
780            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
781            
782            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
783            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
784            suResOnCC.InitCCList(pCCPool, pSmootherPool);
785            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
786            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
787            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
788            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
789            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
790            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
791            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
792            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
793            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
794            
795            for (int i = 0; i < EGs.capacity(); i++) {
796                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
797                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
798                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
799                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
800                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
801                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
802            }
803            
804            for (int i = 0; i < LFOs.capacity(); i++) {
805                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
806                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
807                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
808                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
809                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
810                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
811                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
812                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
813            }
814        }
815        
816      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
817          EGs.clear();          EGs.clear();
818          volEGs.clear();          volEGs.clear();
819          pitchEGs.clear();          pitchEGs.clear();
820          filEGs.clear();          filEGs.clear();
821          resEGs.clear();          resEGs.clear();
822            panEGs.clear();
823                    
824          LFOs.clear();          LFOs.clear();
825          volLFOs.clear();          volLFOs.clear();
# Line 684  namespace LinuxSampler { namespace sfz { Line 831  namespace LinuxSampler { namespace sfz {
831          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
832                    
833          suVolOnCC.SetCCs(pRegion->volume_oncc);          suVolOnCC.SetCCs(pRegion->volume_oncc);
834            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
835            suResOnCC.SetCCs(pRegion->resonance_oncc);
836                    
837          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
838              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
# Line 697  namespace LinuxSampler { namespace sfz { Line 846  namespace LinuxSampler { namespace sfz {
846                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);                  EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
847                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
848                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
849                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
850              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
851                            
852              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 720  namespace LinuxSampler { namespace sfz { Line 870  namespace LinuxSampler { namespace sfz {
870                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);                  if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
871                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
872              }              }
873                
874                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
875                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
876                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
877                }
878          }          }
879                    
880          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 729  namespace LinuxSampler { namespace sfz { Line 884  namespace LinuxSampler { namespace sfz {
884                    
885          // LFO          // LFO
886          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
887              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
888                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
889                    else pRegion->lfos[i].freq = 0;
890                }
891                            
892              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
893                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
# Line 781  namespace LinuxSampler { namespace sfz { Line 939  namespace LinuxSampler { namespace sfz {
939          Units.clear();          Units.clear();
940                    
941          Units.add(&suVolOnCC);          Units.add(&suVolOnCC);
942            Units.add(&suCutoffOnCC);
943            Units.add(&suResOnCC);
944                    
945          Units.add(&suVolEG);          Units.add(&suVolEG);
946          Units.add(&suFilEG);          Units.add(&suFilEG);
# Line 808  namespace LinuxSampler { namespace sfz { Line 968  namespace LinuxSampler { namespace sfz {
968              Units.add(&(EGs[i]->suPitchOnCC));              Units.add(&(EGs[i]->suPitchOnCC));
969              Units.add(&(EGs[i]->suCutoffOnCC));              Units.add(&(EGs[i]->suCutoffOnCC));
970              Units.add(&(EGs[i]->suResOnCC));              Units.add(&(EGs[i]->suResOnCC));
971                Units.add(&(EGs[i]->suPanOnCC));
972          }          }
973                    
974          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
# Line 824  namespace LinuxSampler { namespace sfz { Line 985  namespace LinuxSampler { namespace sfz {
985          Units.add(&suEndpoint);          Units.add(&suEndpoint);
986          Units.add(&suEndpoint.suXFInCC);          Units.add(&suEndpoint.suXFInCC);
987          Units.add(&suEndpoint.suXFOutCC);          Units.add(&suEndpoint.suXFOutCC);
988            Units.add(&suEndpoint.suPanOnCC);
989                    
990          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
991      }      }
# Line 840  namespace LinuxSampler { namespace sfz { Line 1002  namespace LinuxSampler { namespace sfz {
1002          }          }
1003      }      }
1004            
1005        void SfzSignalUnitRack::Reset() {
1006            suVolOnCC.RemoveAllCCs();
1007            suCutoffOnCC.RemoveAllCCs();
1008            suResOnCC.RemoveAllCCs();
1009            suEndpoint.suXFInCC.RemoveAllCCs();
1010            suEndpoint.suXFOutCC.RemoveAllCCs();
1011            suEndpoint.suPanOnCC.RemoveAllCCs();
1012            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1013            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1014            suFilLFO.suDepthOnCC.RemoveAllCCs();
1015            suFilLFO.suFreqOnCC.RemoveAllCCs();
1016            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1017            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1018            
1019            for (int i = 0; i < EGs.capacity(); i++) {
1020                EGs[i]->suAmpOnCC.RemoveAllCCs();
1021                EGs[i]->suVolOnCC.RemoveAllCCs();
1022                EGs[i]->suPitchOnCC.RemoveAllCCs();
1023                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1024                EGs[i]->suResOnCC.RemoveAllCCs();
1025                EGs[i]->suPanOnCC.RemoveAllCCs();
1026            }
1027            
1028            for (int i = 0; i < LFOs.capacity(); i++) {
1029                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1030                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1031                LFOs[i]->suVolOnCC.RemoveAllCCs();
1032                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1033                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1034                LFOs[i]->suPanOnCC.RemoveAllCCs();
1035                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1036                LFOs[i]->suResOnCC.RemoveAllCCs();
1037            }
1038        }
1039        
1040  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2236  
changed lines
  Added in v.2252

  ViewVC Help
Powered by ViewVC