/[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 2224 by iliev, Mon Aug 1 19:08: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            float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167            hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168            
169            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171                    
172          EG.trigger(uint(pRegion->pitcheg_start * 10),          float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
175                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
178                     GetSampleRate());          EG.trigger (
179                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181            );
182      }      }
183            
184            
185      void FilEGUnit::Trigger() {      void FilEGUnit::Trigger() {
186          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
187          depth = pRegion->fileg_depth;          depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188            
189            // the length of the decay and release curves are dependent on the velocity
190            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191    
192            // set the delay trigger
193            float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194            delay += GetInfluence(pRegion->fileg_delay_oncc);
195            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196            
197            float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198            
199            float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200            attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201            
202            float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203            hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204            
205            float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206            decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207            
208            float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209            sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210            
211            float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
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          // the length of the decay and release curves are dependent on the velocity
225          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226    
227          // set the delay trigger          // set the delay trigger
228          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          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          EG.trigger(uint(pRegion->fileg_start * 10),          float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
240                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
243                     GetSampleRate());          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);
267        }
268    
269      void LFOUnit::Increment() {      void LFOUnit::Increment() {
270          if (DelayStage()) return;          if (DelayStage()) return;
# Line 105  namespace LinuxSampler { namespace sfz { Line 272  namespace LinuxSampler { namespace sfz {
272          SignalUnit::Increment();          SignalUnit::Increment();
273                    
274          Level = pLFO->Render();          Level = pLFO->Render();
275            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276      }      }
277            
278      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 112  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()) {
285                float f = pLfoInfo->fade;
286                f += GetInfluence(pLfoInfo->fade_oncc);
287                
288                if (f != 0) {
289                    suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290                    suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
291                }
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 129  namespace LinuxSampler { namespace sfz { Line 311  namespace LinuxSampler { namespace sfz {
311            
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              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 148  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 + GetInfluence(pLfoInfo->phase_oncc);
341            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 + GetInfluence(pRegion->amplfo_fade_oncc);
349          pLfoInfo->volume = pRegion->amplfo_depth;          pLfoInfo->volume = pRegion->amplfo_depth;
350                    
351          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 166  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 + GetInfluence(pRegion->pitchlfo_fade_oncc);
359          pLfoInfo->pitch = pRegion->pitchlfo_depth;          pLfoInfo->pitch = pRegion->pitchlfo_depth;
360                    
361          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 175  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 + 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) {
396            RemoveAllCCs();
397            for (int i = 0; i < cc.size(); i++) {
398                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 208  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 228  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          return p;          
642            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
643                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
644                if (!lfo->Active()) continue;
645                
646                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
647                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
648            }
649            
650            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 301  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), 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 = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
718            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
719            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;
739                LFOs[i]->suVolOnCC.pVoice = voice;
740                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 330  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();
805          filLFOs.clear();          filLFOs.clear();
806          resLFOs.clear();          resLFOs.clear();
807          panLFOs.clear();          panLFOs.clear();
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 349  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 370  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);
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].cutoff != 0) {              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()) {
883                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
884                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
885                }
886                
887                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);
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);
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);
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));
949                Units.add(&(LFOs[i]->suVolOnCC));
950                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 425  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.2224  
changed lines
  Added in v.2249

  ViewVC Help
Powered by ViewVC