/[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 2220 by iliev, Thu Jul 28 15:47:51 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    
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 33  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 77  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 91  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 LFOv2Unit::Trigger() {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
264            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
265        }
266        
267        
268        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() {
296            LFOUnit::Trigger();
297            
298            if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
299            else pLFO = lfos[pLfoInfo->wave];
300            
301            pLFO->Trigger (
302                pLfoInfo->freq + suFreqOnCC.GetLevel(),
303                start_level_mid,
304                1, 0, false, GetSampleRate()
305            );
306            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() {
313            ::sfz::Region* const pRegion = pVoice->pRegion;
314            pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
315            pLfoInfo->freq   = pRegion->amplfo_freq;
316            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
317            pLfoInfo->volume = pRegion->amplfo_depth;
318            
319            LFOv1Unit::Trigger();
320        }
321        
322        void PitchLFOUnit::Trigger() {
323            ::sfz::Region* const pRegion = pVoice->pRegion;
324            pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
325            pLfoInfo->freq  = pRegion->pitchlfo_freq;
326            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
327            pLfoInfo->pitch = pRegion->pitchlfo_depth;
328            
329            LFOv1Unit::Trigger();
330        }
331        
332        void FilLFOUnit::Trigger() {
333            ::sfz::Region* const pRegion = pVoice->pRegion;
334            pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
335            pLfoInfo->freq   = pRegion->fillfo_freq;
336            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
337            pLfoInfo->cutoff = pRegion->fillfo_depth;
338            
339            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 115  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 135  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          return vol;          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
535            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            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 = 1;          float val;
556            
557            FilLFOUnit* u = &(GetRack()->suFilLFO);
558            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;
594          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
595          double pitchEg = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
596          return pitchEg;          
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);
606            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 * 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 192  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          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
680            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            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 219  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 238  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 259  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);
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);
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);
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 307  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.2220  
changed lines
  Added in v.2248

  ViewVC Help
Powered by ViewVC