/[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 2221 by iliev, Thu Jul 28 17:17:42 2011 UTC revision 2248 by iliev, Fri Aug 19 15:51:18 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            
# Line 78  namespace LinuxSampler { namespace sfz { Line 165  namespace LinuxSampler { namespace sfz {
165                     GetSampleRate());                     GetSampleRate());
166      }      }
167            
168        
169        void FilEGUnit::Trigger() {
170            ::sfz::Region* const pRegion = pVoice->pRegion;
171            depth = pRegion->fileg_depth;
172            
173            // the length of the decay and release curves are dependent on the velocity
174            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
175    
176            // set the delay trigger
177            uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();
178            
179            EG.trigger(uint(pRegion->fileg_start * 10),
180                       std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),
181                       std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),
182                       std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),
183                       uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),
184                       std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),
185                       GetSampleRate());
186        }
187        
188        
189        void AmpEGUnit::Trigger() {
190            ::sfz::Region* const pRegion = pVoice->pRegion;
191            
192            // the length of the decay and release curves are dependent on the velocity
193            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
194    
195            // set the delay trigger
196            float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
197            delay += GetInfluence(pRegion->ampeg_delaycc);
198            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
199            
200            float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
201            
202            float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
203            attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
204            
205            float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
206            hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
207            
208            float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
209            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
210            
211            float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
212            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
213            
214            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
215            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
216            
217            EG.trigger (
218                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
219                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
220            );
221        }
222        
223        
224        LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
225            : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
226              suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
227        { }
228        
229        LFOUnit::LFOUnit(const LFOUnit& Unit)
230            : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
231              suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
232              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
233        {
234            Copy(Unit);
235        }
236    
237      void LFOUnit::Increment() {      void LFOUnit::Increment() {
238          if (DelayStage()) return;          if (DelayStage()) return;
239                    
240          SignalUnit::Increment();          SignalUnit::Increment();
241                    
242          Level = lfo.render();          Level = pLFO->Render();
243            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
244      }      }
245            
246      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 92  namespace LinuxSampler { namespace sfz { Line 248  namespace LinuxSampler { namespace sfz {
248          Level = 0;          Level = 0;
249                    
250          // set the delay trigger          // set the delay trigger
251          uiDelayTrigger = pLfoInfo->delay * GetSampleRate();          uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
252            if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
253                float f = pLfoInfo->fade;
254                f += GetInfluence(pLfoInfo->fade_oncc);
255                
256                if (f != 0) {
257                    suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
258                    suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
259                }
260            }
261      }      }
262            
263        void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
264            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
265        }
266        
267        
268      void LFOv1Unit::Trigger() {      void LFOv1Unit::Trigger() {
269          LFOUnit::Trigger();          LFOUnit::Trigger();
270                    
271          lfo.trigger (          lfo.trigger (
272              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
273              start_level_mid,              start_level_mid,
274              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
275          );          );
276          lfo.update(0);          lfo.update(0);
277      }      }
278            
279        
280        LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
281            : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
282              lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
283              suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
284        {
285            lfos.add(&lfo0);
286            lfos.add(&lfo1);
287            lfos.add(&lfo2);
288            lfos.add(&lfo3);
289            lfos.add(&lfo4);
290            lfos.add(&lfo5);
291            lfos.add(&lfo6);
292            lfos.add(&lfo7);
293        }
294        
295      void LFOv2Unit::Trigger() {      void LFOv2Unit::Trigger() {
296          LFOUnit::Trigger();          LFOUnit::Trigger();
297                    
298          lfo.trigger (          if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
299              pLfoInfo->freq,          else pLFO = lfos[pLfoInfo->wave];
300            
301            pLFO->Trigger (
302                pLfoInfo->freq + suFreqOnCC.GetLevel(),
303              start_level_mid,              start_level_mid,
304              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
305          );          );
306          lfo.update(0);          pLFO->Update(0);
307            
308            float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
309            if (phase != 0) pLFO->SetPhase(phase);
310      }      }
311            
312      void AmpLFOUnit::Trigger() {      void AmpLFOUnit::Trigger() {
313          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
314          pLfoInfo->delay = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
315          pLfoInfo->freq = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
316            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
317          pLfoInfo->volume = pRegion->amplfo_depth;          pLfoInfo->volume = pRegion->amplfo_depth;
318                    
319          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 128  namespace LinuxSampler { namespace sfz { Line 321  namespace LinuxSampler { namespace sfz {
321            
322      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
323          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
324          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
325          pLfoInfo->freq = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
326            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
327          pLfoInfo->pitch = pRegion->pitchlfo_depth;          pLfoInfo->pitch = pRegion->pitchlfo_depth;
328                    
329          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 137  namespace LinuxSampler { namespace sfz { Line 331  namespace LinuxSampler { namespace sfz {
331            
332      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
333          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
334          pLfoInfo->delay = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
335          pLfoInfo->freq = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
336            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
337          pLfoInfo->cutoff = pRegion->fillfo_depth;          pLfoInfo->cutoff = pRegion->fillfo_depth;
338                    
339          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
340      }      }
341        
342        CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
343            pVoice = NULL;
344        }
345        
346        void CCUnit::Trigger() {
347            RTList<CC>::Iterator ctrl = pCtrls->first();
348            RTList<CC>::Iterator end  = pCtrls->end();
349            for(; ctrl != end; ++ctrl) {
350                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
351                if ((*ctrl).pSmoother != NULL) (*ctrl).pSmoother->setValue((*ctrl).Value);
352            }
353            CCSignalUnit::Trigger();
354        }
355        
356        void CCUnit::SetCCs(::sfz::Array<int>& cc) {
357            RemoveAllCCs();
358            for (int i = 0; i < 128; i++) {
359                if (cc[i] != 0) AddCC(i, cc[i]);
360            }
361        }
362        
363        void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
364            RemoveAllCCs();
365            for (int i = 0; i < cc.size(); i++) {
366                if (cc[i].Influence != 0) {
367                    short int curve = cc[i].Curve;
368                    if (curve >= GetCurveCount()) curve = -1;
369                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
370                }
371            }
372        }
373        
374        void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
375            AddCC(Controller, Influence, Curve);
376        }
377        
378        int CCUnit::GetCurveCount() {
379            return pVoice->pRegion->GetInstrument()->curves.size();
380        }
381        
382        ::sfz::Curve* CCUnit::GetCurve(int idx) {
383            return &pVoice->pRegion->GetInstrument()->curves[idx];
384        }
385        
386        double CCUnit::GetSampleRate() {
387            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
388        }
389        
390        
391        SmoothCCUnit::~SmoothCCUnit() {
392            if (pSmoothers != NULL) delete pSmoothers;
393        }
394        
395        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
396            if (Smooth > 0) {
397                if (pSmoothers->poolIsEmpty()) {
398                    std::cerr << "Maximum number of smoothers reached" << std::endl;
399                    return;
400                }
401                Smoother* smoother = &(*(pSmoothers->allocAppend()));
402                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
403                AddCC(Controller, Influence, Curve, smoother);
404            } else {
405                AddCC(Controller, Influence, Curve);
406            }
407        }
408        
409        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
410            if (pSmoothers != NULL) delete pSmoothers;
411            pSmoothers = new RTList<Smoother>(pSmootherPool);
412        }
413        
414        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
415            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
416            InitSmoothers(pSmootherPool);
417        }
418    
419    
420      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
421            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
422        {
423                    
424      }      }
425            
# Line 154  namespace LinuxSampler { namespace sfz { Line 428  namespace LinuxSampler { namespace sfz {
428      }      }
429            
430      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
431            float xfInVelCoeff = 1;
432            
433            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
434                xfInVelCoeff = 0;
435            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
436                xfInVelCoeff = 1;
437            } else {
438                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
439                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
440                xfInVelCoeff = velPos / xfVelSize;
441                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
442                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
443                }
444            }
445                    
446            float xfOutVelCoeff = 1;
447            
448            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
449                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
450            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
451                xfOutVelCoeff = 1;
452            } else {
453                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
454                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
455                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
456                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
457                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
458                }
459            }
460            
461            float xfInKeyCoeff = 1;
462            
463            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
464                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
465            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
466                xfInKeyCoeff = 1;
467            } else {
468                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
469                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
470                xfInKeyCoeff = keyPos / xfKeySize;
471                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
472                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
473                }
474            }
475            
476            float xfOutKeyCoeff = 1;
477            
478            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
479                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
480            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
481                xfOutKeyCoeff = 1;
482            } else {
483                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
484                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
485                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
486                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
487                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
488                }
489            }
490            
491            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
492            
493            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
494            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
495            
496            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
497            
498            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
499      }      }
500            
501      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 174  namespace LinuxSampler { namespace sfz { Line 515  namespace LinuxSampler { namespace sfz {
515          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
516              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
517              if (!eg->Active()) continue;              if (!eg->Active()) continue;
518              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
519                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
520                if (dB < -144) dB = eg->pEGInfo->volume;
521                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
522                
523                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
524                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
525                
526                if (dB >= -144) {
527                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
528                    amp *= ToRatio(dB * 10.0);
529                }
530                
531                vol += amp * eg->GetLevel();
532          }          }
533                    
534          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
535          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
536            float f = u2->Active() ? u2->GetLevel() : 0;
537            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
538            
539            vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
540                    
541          return vol;          for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
542                LFOv2Unit* lfo = GetRack()->volLFOs[i];
543                if (!lfo->Active()) continue;
544                
545                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
546                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
547            }
548            
549            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
550            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
551            return vol * xfCoeff;
552      }      }
553            
554      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
555          float val;          float val;
556                    
557          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
558          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
559            float f = u1->Active() ? u1->GetLevel() : 0;
560            val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
561            
562            FilEGUnit* u2 = &(GetRack()->suFilEG);
563            val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
564            
565            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
566                EGv2Unit* eg = GetRack()->filEGs[i];
567                if (!eg->Active()) continue;
568                
569                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
570                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
571                val *= RTMath::CentsToFreqRatioUnlimited(f);
572            }
573                    
574          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
575              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
576              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
577                            
578              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
579                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
580              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
581          }          }
582                    
583          return val;          return val;
584      }      }
585            
586        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
587             cutoff *= GetFilterCutoff();
588             float maxCutoff = 0.49 * pVoice->GetSampleRate();
589             return cutoff > maxCutoff ? maxCutoff : cutoff;
590        }
591        
592      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
593          double p;          double p;
594          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
595          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
596                    
597            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
598                EGv2Unit* eg = GetRack()->pitchEGs[i];
599                if (!eg->Active()) continue;
600                
601                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
602                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
603            }
604            
605          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
606          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->pLfoInfo->pitch) : 1;          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
607            float f = u3->Active() ? u3->GetLevel() : 0;
608            p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
609            
610            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
611                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
612                if (!lfo->Active()) continue;
613                
614                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
615                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
616            }
617                    
618          return p;          return p * pitchVeltrackRatio;
619      }      }
620            
621      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
622           float val = 0;           float val = 0;
623                    
624            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
625                EGv2Unit* eg = GetRack()->resEGs[i];
626                if (!eg->Active()) continue;
627                
628                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
629                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
630            }
631            
632          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
633              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
634              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
635                            
636              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
637                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
638          }          }
639                    
640          return val;          return val;
641      }      }
642            
643      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
644          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
645            
646            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
647                EGv2Unit* eg = GetRack()->panEGs[i];
648                if (!eg->Active()) continue;
649                
650                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
651                
652                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
653                    uint8_t val = eg->GetLevel() * 127;
654                    if (val > 127) val = 127;
655                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
656                } else {
657                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
658                }
659            }
660                    
661          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
662              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
663              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
664                            
665              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
666                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
667          }          }
668                    
669          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 242  namespace LinuxSampler { namespace sfz { Line 674  namespace LinuxSampler { namespace sfz {
674            
675            
676      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
677          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
678          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
679          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
680          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
681            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
682      {      {
683          suEndpoint.pVoice = suVolEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
684          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
685            suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
686            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
687            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
688            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
689                    
690          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
691              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
692              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
693                EGs[i]->suAmpOnCC.pVoice = voice;
694                EGs[i]->suVolOnCC.pVoice = voice;
695                EGs[i]->suPitchOnCC.pVoice = voice;
696                EGs[i]->suCutoffOnCC.pVoice = voice;
697                EGs[i]->suResOnCC.pVoice = voice;
698                EGs[i]->suPanOnCC.pVoice = voice;
699          }          }
700                    
701          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
702              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
703              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
704                LFOs[i]->suDepthOnCC.pVoice = voice;
705                LFOs[i]->suFreqOnCC.pVoice = voice;
706                LFOs[i]->suFadeEG.pVoice = voice;
707                LFOs[i]->suVolOnCC.pVoice = voice;
708                LFOs[i]->suPitchOnCC.pVoice = voice;
709                LFOs[i]->suFreqOnCC.pVoice = voice;
710                LFOs[i]->suPanOnCC.pVoice = voice;
711                LFOs[i]->suCutoffOnCC.pVoice = voice;
712                LFOs[i]->suResOnCC.pVoice = voice;
713          }          }
714      }      }
715            
# Line 271  namespace LinuxSampler { namespace sfz { Line 723  namespace LinuxSampler { namespace sfz {
723          }          }
724      }      }
725            
726        void SfzSignalUnitRack::InitRTLists() {
727            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
728            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
729            
730            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
731            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
732            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
733            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
734            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
735            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
736            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
737            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
738            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
739            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
740            
741            for (int i = 0; i < EGs.capacity(); i++) {
742                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
743                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
744                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
745                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
746                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
747                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
748            }
749            
750            for (int i = 0; i < LFOs.capacity(); i++) {
751                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
752                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
753                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
754                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
755                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
756                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
757                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
758                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
759            }
760        }
761        
762      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
763          EGs.clear();          EGs.clear();
764          volEGs.clear();          volEGs.clear();
765          pitchEGs.clear();          pitchEGs.clear();
766            filEGs.clear();
767            resEGs.clear();
768            panEGs.clear();
769                    
770          LFOs.clear();          LFOs.clear();
771            volLFOs.clear();
772            pitchLFOs.clear();
773          filLFOs.clear();          filLFOs.clear();
774          resLFOs.clear();          resLFOs.clear();
775          panLFOs.clear();          panLFOs.clear();
776                    
777          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
778                    
779            suVolOnCC.SetCCs(pRegion->volume_oncc);
780            
781          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
782              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
783                            
# Line 290  namespace LinuxSampler { namespace sfz { Line 785  namespace LinuxSampler { namespace sfz {
785                  EGv2Unit eg(this);                  EGv2Unit eg(this);
786                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
787                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
788                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
789                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
790                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
791                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
792                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
793                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
794              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
795                            
796              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
797                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
798                ) {
799                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
800                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
801              }              }
802                
803                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
804                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
805                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
806                }
807                
808                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
809                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
810                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
811                }
812                
813                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
814                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
815                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
816                }
817                
818                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
819                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
820                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
821                }
822          }          }
823                    
824          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 311  namespace LinuxSampler { namespace sfz { Line 834  namespace LinuxSampler { namespace sfz {
834                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
835                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
836                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
837                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
838                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
839                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
840                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
841                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
842                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
843              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
844                            
845              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
846                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
847                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
848                }
849                
850                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
851                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
852                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
853                }
854                
855                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
856                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
857                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
858              }              }
859                            
860              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
861                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
862                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
863              }              }
864                            
865              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
866                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
867                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
868              }              }
869          }          }
870                    
871            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
872            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
873            
874            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
875            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
876            
877            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
878            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
879            
880          Units.clear();          Units.clear();
881                    
882            Units.add(&suVolOnCC);
883            
884          Units.add(&suVolEG);          Units.add(&suVolEG);
885            Units.add(&suFilEG);
886          Units.add(&suPitchEG);          Units.add(&suPitchEG);
887            
888            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
889          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
890            Units.add(&suPitchLFO.suDepthOnCC);
891            Units.add(&suPitchLFO.suFadeEG);
892            
893            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
894            Units.add(&suAmpLFO.suDepthOnCC);
895          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
896            Units.add(&suAmpLFO.suFadeEG);
897            
898            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
899            Units.add(&suFilLFO.suDepthOnCC);
900          Units.add(&suFilLFO);          Units.add(&suFilLFO);
901            Units.add(&suFilLFO.suFadeEG);
902                    
903          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
904              Units.add(EGs[i]);              Units.add(EGs[i]);
905                Units.add(&(EGs[i]->suAmpOnCC));
906                Units.add(&(EGs[i]->suVolOnCC));
907                Units.add(&(EGs[i]->suPitchOnCC));
908                Units.add(&(EGs[i]->suCutoffOnCC));
909                Units.add(&(EGs[i]->suResOnCC));
910                Units.add(&(EGs[i]->suPanOnCC));
911          }          }
912                    
913          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
914                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
915              Units.add(LFOs[i]);              Units.add(LFOs[i]);
916                Units.add(&(LFOs[i]->suFadeEG));
917                Units.add(&(LFOs[i]->suVolOnCC));
918                Units.add(&(LFOs[i]->suPitchOnCC));
919                Units.add(&(LFOs[i]->suPanOnCC));
920                Units.add(&(LFOs[i]->suCutoffOnCC));
921                Units.add(&(LFOs[i]->suResOnCC));
922          }          }
923                    
924          Units.add(&suEndpoint);          Units.add(&suEndpoint);
925            Units.add(&suEndpoint.suXFInCC);
926            Units.add(&suEndpoint.suXFOutCC);
927            Units.add(&suEndpoint.suPanOnCC);
928                    
929          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
930      }      }
# Line 362  namespace LinuxSampler { namespace sfz { Line 941  namespace LinuxSampler { namespace sfz {
941          }          }
942      }      }
943            
944        void SfzSignalUnitRack::Reset() {
945            suVolOnCC.RemoveAllCCs();
946            suEndpoint.suXFInCC.RemoveAllCCs();
947            suEndpoint.suXFOutCC.RemoveAllCCs();
948            suEndpoint.suPanOnCC.RemoveAllCCs();
949            suPitchLFO.suDepthOnCC.RemoveAllCCs();
950            suPitchLFO.suFreqOnCC.RemoveAllCCs();
951            suFilLFO.suDepthOnCC.RemoveAllCCs();
952            suFilLFO.suFreqOnCC.RemoveAllCCs();
953            suAmpLFO.suDepthOnCC.RemoveAllCCs();
954            suAmpLFO.suFreqOnCC.RemoveAllCCs();
955            
956            for (int i = 0; i < EGs.capacity(); i++) {
957                EGs[i]->suAmpOnCC.RemoveAllCCs();
958                EGs[i]->suVolOnCC.RemoveAllCCs();
959                EGs[i]->suPitchOnCC.RemoveAllCCs();
960                EGs[i]->suCutoffOnCC.RemoveAllCCs();
961                EGs[i]->suResOnCC.RemoveAllCCs();
962                EGs[i]->suPanOnCC.RemoveAllCCs();
963            }
964            
965            for (int i = 0; i < LFOs.capacity(); i++) {
966                LFOs[i]->suDepthOnCC.RemoveAllCCs();
967                LFOs[i]->suFreqOnCC.RemoveAllCCs();
968                LFOs[i]->suVolOnCC.RemoveAllCCs();
969                LFOs[i]->suPitchOnCC.RemoveAllCCs();
970                LFOs[i]->suFreqOnCC.RemoveAllCCs();
971                LFOs[i]->suPanOnCC.RemoveAllCCs();
972                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
973                LFOs[i]->suResOnCC.RemoveAllCCs();
974            }
975        }
976        
977  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2221  
changed lines
  Added in v.2248

  ViewVC Help
Powered by ViewVC