/[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 2227 by iliev, Wed Aug 3 17:11:40 2011 UTC revision 2251 by iliev, Sat Aug 20 10:38:31 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 34  namespace LinuxSampler { namespace sfz { Line 40  namespace LinuxSampler { namespace sfz {
40          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41      }      }
42            
43        float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44            float f = 0;
45            for (int i = 0; i < cc.size(); i++) {
46                int val = pVoice->GetControllerValue(cc[i].Controller);
47                f += (val / 127.0f) * cc[i].Influence;
48            }
49            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 EGv1Unit::Trigger() {      void XFInCCUnit::Calculate() {
66          ::sfz::Region* const pRegion = pVoice->pRegion;          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          // the length of the decay and release curves are dependent on the velocity          if (Level != l) {
92          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);              Level = l;
93                if (pListener != NULL) pListener->ValueChanged(this);
94          // set the delay trigger          }
95          uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate();      }
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          EG.trigger(uint(pRegion->ampeg_start * 10),          if (Level != l) {
125                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),              Level = l;
126                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),              if (pListener != NULL) pListener->ValueChanged(this);
127                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          }
                    uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),  
                    GetSampleRate());  
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          EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);          egInfo = *pEGInfo;
138            for (int i = 0; i < egInfo.node.size(); i++) {
139                float f = GetInfluence(egInfo.node[i].level_oncc);
140                egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
141                
142                f = GetInfluence(egInfo.node[i].time_oncc);
143                egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144            }
145            EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity);
146      }      }
147            
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            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(uint(pRegion->pitcheg_start * 10),          EG.trigger (
179                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          );
                    uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),  
                    GetSampleRate());  
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          EG.trigger(uint(pRegion->fileg_start * 10),          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
211                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
214                     GetSampleRate());          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        
221        void AmpEGUnit::Trigger() {
222            ::sfz::Region* const pRegion = pVoice->pRegion;
223            
224            // the length of the decay and release curves are dependent on the velocity
225            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226    
227            // set the delay trigger
228            float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229            delay += GetInfluence(pRegion->ampeg_delaycc);
230            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231            
232            float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233            
234            float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235            attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236            
237            float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238            hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239            
240            float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242            
243            float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245            
246            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248            
249            EG.trigger (
250                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252            );
253      }      }
254            
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 125  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              for (int i = 0; i < pLfoInfo->fade_oncc.size(); i++) {              f += GetInfluence(pLfoInfo->fade_oncc);
                 int val = pVoice->GetControllerValue(pLfoInfo->fade_oncc[i].Controller);  
                 f += (val / 127.0f) * pLfoInfo->fade_oncc[i].Influence;  
             }  
287                            
288              if (f != 0) {              if (f != 0) {
289                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
# Line 141  namespace LinuxSampler { namespace sfz { Line 293  namespace LinuxSampler { namespace sfz {
293      }      }
294            
295      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296          pLFO->SetFrequency(suFreqOnCC.GetLevel() + pLfoInfo->freq, GetSampleRate());          if (pLFO == NULL) return;
297            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298      }      }
299            
300            
# Line 160  namespace LinuxSampler { namespace sfz { Line 313  namespace LinuxSampler { namespace sfz {
313      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316            suPitchOnCC(rack)            suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317      {      {
318          lfos.add(&lfo0);          lfos.add(&lfo0);
319          lfos.add(&lfo1);          lfos.add(&lfo1);
# Line 185  namespace LinuxSampler { namespace sfz { Line 338  namespace LinuxSampler { namespace sfz {
338          );          );
339          pLFO->Update(0);          pLFO->Update(0);
340                    
341          float phase = pLfoInfo->phase;          float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
         for (int i = 0; i < pLfoInfo->phase_oncc.size(); i++) {  
             int val = pVoice->GetControllerValue(pLfoInfo->phase_oncc[i].Controller);  
             phase += (val / 127.0f) * pLfoInfo->phase_oncc[i].Influence;  
         }  
342          if (phase != 0) pLFO->SetPhase(phase);          if (phase != 0) pLFO->SetPhase(phase);
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 228  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            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) AddCC(cc[i].Controller, cc[i].Influence);              if (cc[i].Influence != 0) {
418           }                  short int curve = cc[i].Curve;
419       }                  if (curve >= GetCurveCount()) curve = -1;
420                    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) {
426            AddCC(Controller, Influence, Curve);
427        }
428        
429        int CCUnit::GetCurveCount() {
430            return pVoice->pRegion->GetInstrument()->curves.size();
431        }
432        
433        ::sfz::Curve* CCUnit::GetCurve(int idx) {
434            return &pVoice->pRegion->GetInstrument()->curves[idx];
435        }
436        
437        double CCUnit::GetSampleRate() {
438            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) {
447            if (Smooth > 0) {
448                if (pSmoothers->poolIsEmpty()) {
449                    std::cerr << "Maximum number of smoothers reached" << std::endl;
450                    return;
451                }
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) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
472            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
473        {
474                    
475      }      }
476            
# Line 258  namespace LinuxSampler { namespace sfz { Line 479  namespace LinuxSampler { namespace sfz {
479      }      }
480            
481      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
482            float xfInVelCoeff = 1;
483                    
484            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
485                xfInVelCoeff = 0;
486            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
487                xfInVelCoeff = 1;
488            } else {
489                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
490                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
491                xfInVelCoeff = velPos / xfVelSize;
492                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
493                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
494                }
495            }
496            
497            float xfOutVelCoeff = 1;
498            
499            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
500                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
501            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
502                xfOutVelCoeff = 1;
503            } else {
504                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
505                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
506                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
507                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
508                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
509                }
510            }
511            
512            float xfInKeyCoeff = 1;
513            
514            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
515                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
516            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
517                xfInKeyCoeff = 1;
518            } else {
519                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
520                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
521                xfInKeyCoeff = keyPos / xfKeySize;
522                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
523                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
524                }
525            }
526            
527            float xfOutKeyCoeff = 1;
528            
529            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
530                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
531            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
532                xfOutKeyCoeff = 1;
533            } else {
534                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
535                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
536                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
537                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
538                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
539                }
540            }
541            
542            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
543            
544            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
545            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 278  namespace LinuxSampler { namespace sfz { Line 566  namespace LinuxSampler { namespace sfz {
566          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
567              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
568              if (!eg->Active()) continue;              if (!eg->Active()) continue;
569              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
570                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
571                if (dB < -144) dB = eg->pEGInfo->volume;
572                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
573                
574                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
575                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
576                
577                if (dB >= -144) {
578                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
579                    amp *= ToRatio(dB * 10.0);
580                }
581                
582                vol += amp * eg->GetLevel();
583          }          }
584                    
585          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
586          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
587            float f = u2->Active() ? u2->GetLevel() : 0;
588            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
589            
590            vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
591                    
592          return vol;          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
593                LFOv2Unit* lfo = GetRack()->volLFOs[i];
594                if (!lfo->Active()) continue;
595                
596                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
597                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
598            }
599            
600            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
601            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
602            return vol * xfCoeff;
603      }      }
604            
605      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
606          float val;          float val;
607                    
608          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
609          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
610            float f = u1->Active() ? u1->GetLevel() : 0;
611            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;
615                    
616            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
617                EGv2Unit* eg = GetRack()->filEGs[i];
618                if (!eg->Active()) continue;
619                
620                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
621                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
622                val *= RTMath::CentsToFreqRatioUnlimited(f);
623            }
624            
625          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
626              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
627              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
628                            
629              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
630                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
631              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
632          }          }
633                    
634          return val;          return val;
635      }      }
636            
637        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
638             cutoff *= GetFilterCutoff();
639             float maxCutoff = 0.49 * pVoice->GetSampleRate();
640             return cutoff > maxCutoff ? maxCutoff : cutoff;
641        }
642        
643      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
644          double p;          double p;
645          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
646          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
647                    
648            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
649                EGv2Unit* eg = GetRack()->pitchEGs[i];
650                if (!eg->Active()) continue;
651                
652                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
653                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
654            }
655            
656          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
657          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
658          float f = u3->Active() ? u3->GetLevel() : 0;          float f = u3->Active() ? u3->GetLevel() : 0;
659          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
660                    
# Line 325  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 = 0;
674                    
675            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
676                EGv2Unit* eg = GetRack()->resEGs[i];
677                if (!eg->Active()) continue;
678                
679                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
680                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
681            }
682            
683          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
684              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
685              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
686                            
687              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
688                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
689          }          }
690                    
691          return val;          return val;
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];
714              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
715                            
716              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
717                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
718          }          }
719                    
720          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 360  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),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
730          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
731          LFOs(maxLfoCount), pitchLFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
732            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
733      {      {
734          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
735          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
736          suPitchLFO.suDepthCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
737          suFilLFO.suFadeEG.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
738          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
739            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
740                    
741          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
742              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
743              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
744                EGs[i]->suAmpOnCC.pVoice = voice;
745                EGs[i]->suVolOnCC.pVoice = voice;
746                EGs[i]->suPitchOnCC.pVoice = voice;
747                EGs[i]->suCutoffOnCC.pVoice = voice;
748                EGs[i]->suResOnCC.pVoice = voice;
749                EGs[i]->suPanOnCC.pVoice = voice;
750          }          }
751                    
752          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
753              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
754              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
755                LFOs[i]->suDepthOnCC.pVoice = voice;
756                LFOs[i]->suFreqOnCC.pVoice = voice;
757              LFOs[i]->suFadeEG.pVoice = voice;              LFOs[i]->suFadeEG.pVoice = voice;
758                LFOs[i]->suVolOnCC.pVoice = voice;
759              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
760              LFOs[i]->suFreqOnCC.pVoice = voice;              LFOs[i]->suFreqOnCC.pVoice = voice;
761                LFOs[i]->suPanOnCC.pVoice = voice;
762                LFOs[i]->suCutoffOnCC.pVoice = voice;
763                LFOs[i]->suResOnCC.pVoice = voice;
764          }          }
765      }      }
766            
# Line 394  namespace LinuxSampler { namespace sfz { Line 774  namespace LinuxSampler { namespace sfz {
774          }          }
775      }      }
776            
777        void SfzSignalUnitRack::InitRTLists() {
778            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
779            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
780            
781            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
782            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
783            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
784            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
785            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
786            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
787            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
788            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
789            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
790            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
791            
792            for (int i = 0; i < EGs.capacity(); i++) {
793                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
794                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
795                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
796                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
797                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
798                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
799            }
800            
801            for (int i = 0; i < LFOs.capacity(); i++) {
802                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
803                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
804                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
805                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
806                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
807                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
808                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
809                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
810            }
811        }
812        
813      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
814          EGs.clear();          EGs.clear();
815          volEGs.clear();          volEGs.clear();
816          pitchEGs.clear();          pitchEGs.clear();
817            filEGs.clear();
818            resEGs.clear();
819            panEGs.clear();
820                    
821          LFOs.clear();          LFOs.clear();
822            volLFOs.clear();
823          pitchLFOs.clear();          pitchLFOs.clear();
824          filLFOs.clear();          filLFOs.clear();
825          resLFOs.clear();          resLFOs.clear();
# Line 407  namespace LinuxSampler { namespace sfz { Line 827  namespace LinuxSampler { namespace sfz {
827                    
828          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
829                    
830            suVolOnCC.SetCCs(pRegion->volume_oncc);
831            
832          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
833              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
834                            
# Line 414  namespace LinuxSampler { namespace sfz { Line 836  namespace LinuxSampler { namespace sfz {
836                  EGv2Unit eg(this);                  EGv2Unit eg(this);
837                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
838                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
839                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
840                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
841                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
842                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
843                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
844                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
845              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
846                            
847              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
848                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
849                ) {
850                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
851                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
852              }              }
853                
854                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
855                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
856                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
857                }
858                
859                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
860                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
861                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
862                }
863                
864                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
865                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
866                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
867                }
868                
869                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
870                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
871                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
872                }
873          }          }
874                    
875          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 429  namespace LinuxSampler { namespace sfz { Line 879  namespace LinuxSampler { namespace sfz {
879                    
880          // LFO          // LFO
881          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
882              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
883                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
884                    else pRegion->lfos[i].freq = 0;
885                }
886                            
887              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
888                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
889                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
890                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
891                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
892                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
893                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);                  LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
894                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
895                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
896                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
897              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
898                            
899                if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
900                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
901                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
902                }
903                
904              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
905                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
906                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
907              }              }
908                            
909              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
910                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
911                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
912              }              }
913                            
914              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
915                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
916                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
917              }              }
918                            
919              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
920                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
921                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
922              }              }
923          }          }
924                    
925          suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
926          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);          suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
927                    
928            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
929          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);          suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
930                    
931            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
932          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);          suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
933                    
934          Units.clear();          Units.clear();
935                    
936            Units.add(&suVolOnCC);
937            
938          Units.add(&suVolEG);          Units.add(&suVolEG);
939          Units.add(&suFilEG);          Units.add(&suFilEG);
940          Units.add(&suPitchEG);          Units.add(&suPitchEG);
941                    
942          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)
943          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
944          Units.add(&suPitchLFO.suDepthCC);          Units.add(&suPitchLFO.suDepthOnCC);
945          Units.add(&suPitchLFO.suFadeEG);          Units.add(&suPitchLFO.suFadeEG);
946                    
947          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)
948            Units.add(&suAmpLFO.suDepthOnCC);
949          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
950          Units.add(&suAmpLFO.suFadeEG);          Units.add(&suAmpLFO.suFadeEG);
951                    
952          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)
953            Units.add(&suFilLFO.suDepthOnCC);
954          Units.add(&suFilLFO);          Units.add(&suFilLFO);
955          Units.add(&suFilLFO.suFadeEG);          Units.add(&suFilLFO.suFadeEG);
956                    
957          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
958              Units.add(EGs[i]);              Units.add(EGs[i]);
959                Units.add(&(EGs[i]->suAmpOnCC));
960                Units.add(&(EGs[i]->suVolOnCC));
961                Units.add(&(EGs[i]->suPitchOnCC));
962                Units.add(&(EGs[i]->suCutoffOnCC));
963                Units.add(&(EGs[i]->suResOnCC));
964                Units.add(&(EGs[i]->suPanOnCC));
965          }          }
966                    
967          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
968              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)
969              Units.add(LFOs[i]);              Units.add(LFOs[i]);
970              Units.add(&(LFOs[i]->suFadeEG));              Units.add(&(LFOs[i]->suFadeEG));
971                Units.add(&(LFOs[i]->suVolOnCC));
972              Units.add(&(LFOs[i]->suPitchOnCC));              Units.add(&(LFOs[i]->suPitchOnCC));
973                Units.add(&(LFOs[i]->suPanOnCC));
974                Units.add(&(LFOs[i]->suCutoffOnCC));
975                Units.add(&(LFOs[i]->suResOnCC));
976          }          }
977                    
978          Units.add(&suEndpoint);          Units.add(&suEndpoint);
979            Units.add(&suEndpoint.suXFInCC);
980            Units.add(&suEndpoint.suXFOutCC);
981            Units.add(&suEndpoint.suPanOnCC);
982                    
983          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
984      }      }
# Line 514  namespace LinuxSampler { namespace sfz { Line 995  namespace LinuxSampler { namespace sfz {
995          }          }
996      }      }
997            
998        void SfzSignalUnitRack::Reset() {
999            suVolOnCC.RemoveAllCCs();
1000            suEndpoint.suXFInCC.RemoveAllCCs();
1001            suEndpoint.suXFOutCC.RemoveAllCCs();
1002            suEndpoint.suPanOnCC.RemoveAllCCs();
1003            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1004            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1005            suFilLFO.suDepthOnCC.RemoveAllCCs();
1006            suFilLFO.suFreqOnCC.RemoveAllCCs();
1007            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1008            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1009            
1010            for (int i = 0; i < EGs.capacity(); i++) {
1011                EGs[i]->suAmpOnCC.RemoveAllCCs();
1012                EGs[i]->suVolOnCC.RemoveAllCCs();
1013                EGs[i]->suPitchOnCC.RemoveAllCCs();
1014                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1015                EGs[i]->suResOnCC.RemoveAllCCs();
1016                EGs[i]->suPanOnCC.RemoveAllCCs();
1017            }
1018            
1019            for (int i = 0; i < LFOs.capacity(); i++) {
1020                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1021                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1022                LFOs[i]->suVolOnCC.RemoveAllCCs();
1023                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1024                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1025                LFOs[i]->suPanOnCC.RemoveAllCCs();
1026                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1027                LFOs[i]->suResOnCC.RemoveAllCCs();
1028            }
1029        }
1030        
1031  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2227  
changed lines
  Added in v.2251

  ViewVC Help
Powered by ViewVC