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

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

  ViewVC Help
Powered by ViewVC