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

Legend:
Removed from v.2220  
changed lines
  Added in v.2252

  ViewVC Help
Powered by ViewVC