/[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 2219 by iliev, Thu Jul 28 12:35:49 2011 UTC revision 2879 by schoenebeck, Tue Apr 19 14:07:53 2016 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2011 Grigor Iliev                                       *   *   Copyright (C) 2011 - 2012 Grigor Iliev                                *
6   *                                                                         *   *                                                                         *
7   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
8   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# 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), EqUnitSupport(rack), suAmpOnCC(rack), suVolOnCC(rack),
133              suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134        { }
135            
136      void EGv1Unit::Trigger() {      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 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          EG.trigger(uint(pRegion->ampeg_start * 10),          // set the delay trigger
157                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),          float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),          delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160                     uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),          
161                     std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),          float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162                     GetSampleRate());          
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 (
179                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
181            );
182      }      }
183            
184      void EGv2Unit::Trigger() {      
185          EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);      void FilEGUnit::Trigger() {
186            ::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(), true
217            );
218      }      }
219            
220        
221        void AmpEGUnit::Trigger() {
222            ::sfz::Region* const pRegion = pVoice->pRegion;
223            
224            // the length of the decay and release curves are dependent on the velocity
225            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
226    
227            // set the delay trigger
228            float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229            delay += GetInfluence(pRegion->ampeg_delaycc);
230            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231            
232            float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233            
234            float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235            attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236            
237            float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238            hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239            
240            float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242            
243            float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245            
246            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248            
249            EG.trigger (
250                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
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 66  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(), false);
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), EqUnitSupport(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) {
403                    if ((*ctrl).Step > 0) {
404                        float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405                        (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406                    } else {
407                        (*ctrl).pSmoother->setValue((*ctrl).Value);
408                    }
409                }
410            }
411            CCSignalUnit::Trigger();
412        }
413        
414        void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415            RemoveAllCCs();
416            for (int i = 0; i < 128; i++) {
417                if (cc[i] != 0) AddCC(i, cc[i]);
418            }
419        }
420        
421        void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422            RemoveAllCCs();
423            for (int i = 0; i < 128; i++) {
424                if (cc[i] != 0) AddCC(i, cc[i]);
425            }
426        }
427        
428        void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
429            RemoveAllCCs();
430            for (int i = 0; i < cc.size(); i++) {
431                if (cc[i].Influence != 0) {
432                    short int curve = cc[i].Curve;
433                    if (curve >= GetCurveCount()) curve = -1;
434                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435                }
436            }
437        }
438        
439        void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440            AddCC(Controller, Influence, Curve, NULL, Step);
441        }
442        
443        int CCUnit::GetCurveCount() {
444            return pVoice->pRegion->GetInstrument()->curves.size();
445        }
446        
447        ::sfz::Curve* CCUnit::GetCurve(int idx) {
448            return &pVoice->pRegion->GetInstrument()->curves[idx];
449        }
450        
451        double CCUnit::GetSampleRate() {
452            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
453        }
454        
455        
456        SmoothCCUnit::~SmoothCCUnit() {
457            if (pSmoothers != NULL) delete pSmoothers;
458        }
459        
460        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461            if (Smooth > 0) {
462                if (pSmoothers->poolIsEmpty()) {
463                    std::cerr << "Maximum number of smoothers reached" << std::endl;
464                    return;
465                }
466                Smoother* smoother = &(*(pSmoothers->allocAppend()));
467                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
468                AddCC(Controller, Influence, Curve, smoother, Step);
469            } else {
470                AddCC(Controller, Influence, Curve, NULL, Step);
471            }
472        }
473        
474        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
475            if (pSmoothers != NULL) delete pSmoothers;
476            pSmoothers = new RTList<Smoother>(pSmootherPool);
477        }
478        
479        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
480            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
481            InitSmoothers(pSmootherPool);
482        }
483    
484    
485      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
487        {
488                    
489      }      }
490            
491        float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<float> >& cc) {
492            float f = 0;
493            for (int i = 0; i < 128; i++) {
494                if (cc[i]) {
495                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
496                }
497            }
498            return f;
499        }
500        
501        float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<int> >& cc) {
502            float f = 0;
503            for (int i = 0; i < 128; i++) {
504                if (cc[i]) {
505                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
506                }
507            }
508            return f;
509        }
510        
511      SfzSignalUnitRack* const EndpointUnit::GetRack() {      SfzSignalUnitRack* const EndpointUnit::GetRack() {
512          return static_cast<SfzSignalUnitRack* const>(pRack);          return static_cast<SfzSignalUnitRack* const>(pRack);
513      }      }
514            
515      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
516            uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
517            if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
518                    
519            if (pVoice->pRegion->delay) {
520                /* here we use the device sample rate */
521                uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
522            }
523            
524            if (pVoice->pRegion->delay_random) {
525                float r = pVoice->GetEngine()->Random();
526                uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
527            }
528            
529            uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
530            
531            float xfInVelCoeff = 1;
532            
533            if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
534                xfInVelCoeff = 0;
535            } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
536                xfInVelCoeff = 1;
537            } else {
538                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
539                float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
540                xfInVelCoeff = velPos / xfVelSize;
541                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
542                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
543                }
544            }
545            
546            float xfOutVelCoeff = 1;
547            
548            if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
549                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
550            } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
551                xfOutVelCoeff = 1;
552            } else {
553                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
554                float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
555                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
556                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
557                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
558                }
559            }
560            
561            float xfInKeyCoeff = 1;
562            
563            if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
564                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
565            } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
566                xfInKeyCoeff = 1;
567            } else {
568                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
569                float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
570                xfInKeyCoeff = keyPos / xfKeySize;
571                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
572                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
573                }
574            }
575            
576            float xfOutKeyCoeff = 1;
577            
578            if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
579                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
580            } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
581                xfOutKeyCoeff = 1;
582            } else {
583                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
584                float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
585                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
586                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
587                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
588                }
589            }
590            
591            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
592            
593            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
594            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
595            
596            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
597            
598            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
599      }      }
600            
601      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
602            if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
603                return false; // The key was released before the delay end, so the voice won't play at all.
604            }
605            
606          if (GetRack()->suVolEG.Active()) return true;          if (GetRack()->suVolEG.Active()) return true;
607                    
608          bool b = false;          bool b = false;
# Line 110  namespace LinuxSampler { namespace sfz { Line 619  namespace LinuxSampler { namespace sfz {
619          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
620              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
621              if (!eg->Active()) continue;              if (!eg->Active()) continue;
622              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
623                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
624                if (dB < -144) dB = eg->pEGInfo->volume;
625                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
626                
627                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
628                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
629                
630                if (dB >= -144) {
631                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
632                    amp *= ToRatio(dB * 10.0);
633                }
634                
635                vol += amp * eg->GetLevel();
636          }          }
637                    
638          return vol;          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
639            CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
640            float f = u2->Active() ? u2->GetLevel() : 0;
641            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
642            
643            vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
644            
645            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
646                LFOv2Unit* lfo = GetRack()->volLFOs[i];
647                if (!lfo->Active()) continue;
648                
649                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
650                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
651            }
652            
653            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
654            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
655            return vol * xfCoeff;
656      }      }
657            
658      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
659          float val = 1;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660            
661            FilLFOUnit* u = &(GetRack()->suFilLFO);
662            CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663            float f = u1->Active() ? u1->GetLevel() : 0;
664            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
665            
666            FilEGUnit* u2 = &(GetRack()->suFilEG);
667            val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
668            
669            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
670                EGv2Unit* eg = GetRack()->filEGs[i];
671                if (!eg->Active()) continue;
672                
673                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
674                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
675                val *= RTMath::CentsToFreqRatioUnlimited(f);
676            }
677                    
678          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
679              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
680              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
681                            
682              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
683                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
684              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
685          }          }
686                    
687          return val;          return val;
688      }      }
689            
690        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691            cutoff *= GetFilterCutoff();
692            float maxCutoff = 0.49 * pVoice->GetSampleRate();
693            return cutoff > maxCutoff ? maxCutoff : cutoff;
694        }
695        
696      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
697          return 1;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698            
699            EGv1Unit* u = &(GetRack()->suPitchEG);
700            p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701            
702            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
703                EGv2Unit* eg = GetRack()->pitchEGs[i];
704                if (!eg->Active()) continue;
705                
706                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
707                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
708            }
709            
710            PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
711            CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
712            float f = u3->Active() ? u3->GetLevel() : 0;
713            p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
714            
715            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
716                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
717                if (!lfo->Active()) continue;
718                
719                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
720                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
721            }
722            
723            return p * pitchVeltrackRatio;
724      }      }
725            
726      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
727           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
728            
729            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
730                EGv2Unit* eg = GetRack()->resEGs[i];
731                if (!eg->Active()) continue;
732                
733                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
734                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
735            }
736                    
737          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
738              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
739              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
740                            
741              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
742                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
743          }          }
744                    
745          return val;          return val;
746      }      }
747            
748      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
749          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
750            
751            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
752                EGv2Unit* eg = GetRack()->panEGs[i];
753                if (!eg->Active()) continue;
754                
755                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
756                
757                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
758                    uint8_t val = eg->GetLevel() * 127;
759                    if (val > 127) val = 127;
760                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
761                } else {
762                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
763                }
764            }
765                    
766          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
767              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
768              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
769                            
770              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
771                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772          }          }
773                    
         if(pan < -100) return -100;  
         if(pan >  100) return  100;  
           
774          return pan;          return pan;
775      }      }
776            
777            
778      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
779          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this),          : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice), pVoice(voice),
780          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
781          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
782            resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
783            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
784            suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
785            LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
786            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount)
787      {      {
788          suEndpoint.pVoice = suVolEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
789            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
790            suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
791            
792            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
793            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
794            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
795            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
796                    
797          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
798              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
799              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
800                EGs[i]->suAmpOnCC.pVoice = voice;
801                EGs[i]->suVolOnCC.pVoice = voice;
802                EGs[i]->suPitchOnCC.pVoice = voice;
803                EGs[i]->suCutoffOnCC.pVoice = voice;
804                EGs[i]->suResOnCC.pVoice = voice;
805                EGs[i]->suPanOnCC.pVoice = voice;
806                EGs[i]->SetVoice(voice); // class EqUnitSupport
807          }          }
808                    
809          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
810              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
811              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
812                LFOs[i]->suDepthOnCC.pVoice = voice;
813                LFOs[i]->suFreqOnCC.pVoice = voice;
814                LFOs[i]->suFadeEG.pVoice = voice;
815                LFOs[i]->suVolOnCC.pVoice = voice;
816                LFOs[i]->suPitchOnCC.pVoice = voice;
817                LFOs[i]->suFreqOnCC.pVoice = voice;
818                LFOs[i]->suPanOnCC.pVoice = voice;
819                LFOs[i]->suCutoffOnCC.pVoice = voice;
820                LFOs[i]->suResOnCC.pVoice = voice;
821                LFOs[i]->SetVoice(voice); // class EqUnitSupport
822          }          }
823      }      }
824            
# Line 192  namespace LinuxSampler { namespace sfz { Line 832  namespace LinuxSampler { namespace sfz {
832          }          }
833      }      }
834            
835        void SfzSignalUnitRack::InitRTLists() {
836            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
837            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
838            
839            EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
840            
841            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
842            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
843            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
844            suResOnCC.InitCCList(pCCPool, pSmootherPool);
845            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
846            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
847            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
848            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
849            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
850            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
851            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
852            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
853            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
854            
855            for (int i = 0; i < EGs.capacity(); i++) {
856                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
857                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
858                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
859                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
860                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
861                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
862                EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
863            }
864            
865            for (int i = 0; i < LFOs.capacity(); i++) {
866                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
867                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
868                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
869                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
870                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
871                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
872                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
873                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
874                LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
875            }
876        }
877        
878      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
879          EGs.clear();          EGs.clear();
880          volEGs.clear();          volEGs.clear();
881          pitchEGs.clear();          pitchEGs.clear();
882            filEGs.clear();
883            resEGs.clear();
884            panEGs.clear();
885            eqEGs.clear();
886                    
887          LFOs.clear();          LFOs.clear();
888            volLFOs.clear();
889            pitchLFOs.clear();
890          filLFOs.clear();          filLFOs.clear();
891          resLFOs.clear();          resLFOs.clear();
892          panLFOs.clear();          panLFOs.clear();
893            eqLFOs.clear();
894                    
895          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
896                    
897            suVolOnCC.SetCCs(pRegion->volume_oncc);
898            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
899            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
900            suResOnCC.SetCCs(pRegion->resonance_oncc);
901            
902          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
903              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
904                            
# Line 211  namespace LinuxSampler { namespace sfz { Line 906  namespace LinuxSampler { namespace sfz {
906                  EGv2Unit eg(this);                  EGv2Unit eg(this);
907                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
908                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
909                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
910                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
911                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
912                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
913                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
914                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
915                    if (pVoice->bEqSupport) {
916                        EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
917                        EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
918                        EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
919                        EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
920                        EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
921                        EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
922                        EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
923                        EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
924                        EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
925                    }
926              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
927                            
928              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
929                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
930                ) {
931                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
932                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
933              }              }
934                
935                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
936                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
937                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
938                }
939                
940                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
941                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
942                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
943                }
944                
945                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
946                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
947                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
948                }
949                
950                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
951                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
952                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
953                }
954                
955                if (pRegion->eg[i].HasEq()) {
956                    if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
957                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
958                }
959          }          }
960                    
961          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 226  namespace LinuxSampler { namespace sfz { Line 965  namespace LinuxSampler { namespace sfz {
965                    
966          // LFO          // LFO
967          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
968              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
969                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
970                    else pRegion->lfos[i].freq = 0;
971                }
972                            
973              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
974                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
975                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
976                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
977                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
978                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
979                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
980                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
981                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
982                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
983                    if (pVoice->bEqSupport) {
984                        LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
985                        LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
986                        LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
987                        LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
988                        LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
989                        LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
990                        LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
991                        LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
992                        LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
993                    }
994              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
995                            
996              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
997                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
998                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
999                }
1000                
1001                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1002                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1003                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1004                }
1005                
1006                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1007                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1008                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1009              }              }
1010                            
1011              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1012                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1013                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1014              }              }
1015                            
1016              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1017                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1018                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1019              }              }
1020                
1021                if (pRegion->lfos[i].HasEq()) {
1022                    if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1023                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1024                }
1025            }
1026            
1027            if (!pVoice->bEqSupport) {
1028                bHasEq = false;
1029            } else {
1030                suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1031                suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1032                suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1033                suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1034                suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1035                suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1036                suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1037                suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1038                suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1039            
1040                bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1041                         pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1042                         suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1043                         eqEGs.size() > 0 || eqLFOs.size() > 0;
1044          }          }
1045                    
1046            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1047            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1048            
1049            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1050            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1051            
1052            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1053            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1054            
1055          Units.clear();          Units.clear();
1056                    
1057            EqUnitSupport::ImportUnits(this);
1058            
1059            Units.add(&suVolOnCC);
1060            Units.add(&suPitchOnCC);
1061            Units.add(&suCutoffOnCC);
1062            Units.add(&suResOnCC);
1063            
1064          Units.add(&suVolEG);          Units.add(&suVolEG);
1065            Units.add(&suFilEG);
1066            Units.add(&suPitchEG);
1067            
1068            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1069            Units.add(&suPitchLFO);
1070            Units.add(&suPitchLFO.suDepthOnCC);
1071            Units.add(&suPitchLFO.suFadeEG);
1072            
1073            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1074            Units.add(&suAmpLFO.suDepthOnCC);
1075            Units.add(&suAmpLFO);
1076            Units.add(&suAmpLFO.suFadeEG);
1077            
1078            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1079            Units.add(&suFilLFO.suDepthOnCC);
1080            Units.add(&suFilLFO);
1081            Units.add(&suFilLFO.suFadeEG);
1082                    
1083          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1084              Units.add(EGs[i]);              Units.add(EGs[i]);
1085                Units.add(&(EGs[i]->suAmpOnCC));
1086                Units.add(&(EGs[i]->suVolOnCC));
1087                Units.add(&(EGs[i]->suPitchOnCC));
1088                Units.add(&(EGs[i]->suCutoffOnCC));
1089                Units.add(&(EGs[i]->suResOnCC));
1090                Units.add(&(EGs[i]->suPanOnCC));
1091                EGs[i]->ImportUnits(this); // class EqUnitSupport
1092          }          }
1093                    
1094          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1095                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1096              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1097                Units.add(&(LFOs[i]->suFadeEG));
1098                Units.add(&(LFOs[i]->suVolOnCC));
1099                Units.add(&(LFOs[i]->suPitchOnCC));
1100                Units.add(&(LFOs[i]->suPanOnCC));
1101                Units.add(&(LFOs[i]->suCutoffOnCC));
1102                Units.add(&(LFOs[i]->suResOnCC));
1103                LFOs[i]->ImportUnits(this); // class EqUnitSupport
1104          }          }
1105                    
1106          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1107            Units.add(&suEndpoint.suXFInCC);
1108            Units.add(&suEndpoint.suXFOutCC);
1109            Units.add(&suEndpoint.suPanOnCC);
1110                    
1111          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1112      }      }
# Line 278  namespace LinuxSampler { namespace sfz { Line 1122  namespace LinuxSampler { namespace sfz {
1122              volEGs[i]->EG.enterFadeOutStage();              volEGs[i]->EG.enterFadeOutStage();
1123          }          }
1124      }      }
1125    
1126        void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1127            suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1128            for (int i = 0; i < volEGs.size(); i++) {
1129                volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1130            }
1131        }
1132    
1133        void SfzSignalUnitRack::Reset() {
1134            EqUnitSupport::ResetUnits();
1135            
1136            suVolOnCC.RemoveAllCCs();
1137            suPitchOnCC.RemoveAllCCs();
1138            suCutoffOnCC.RemoveAllCCs();
1139            suResOnCC.RemoveAllCCs();
1140            suEndpoint.suXFInCC.RemoveAllCCs();
1141            suEndpoint.suXFOutCC.RemoveAllCCs();
1142            suEndpoint.suPanOnCC.RemoveAllCCs();
1143            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1144            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1145            suFilLFO.suDepthOnCC.RemoveAllCCs();
1146            suFilLFO.suFreqOnCC.RemoveAllCCs();
1147            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1148            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1149            
1150            for (int i = 0; i < EGs.capacity(); i++) {
1151                EGs[i]->suAmpOnCC.RemoveAllCCs();
1152                EGs[i]->suVolOnCC.RemoveAllCCs();
1153                EGs[i]->suPitchOnCC.RemoveAllCCs();
1154                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1155                EGs[i]->suResOnCC.RemoveAllCCs();
1156                EGs[i]->suPanOnCC.RemoveAllCCs();
1157                EGs[i]->ResetUnits(); // class EqUnitSupport
1158            }
1159            
1160            for (int i = 0; i < LFOs.capacity(); i++) {
1161                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1162                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1163                LFOs[i]->suVolOnCC.RemoveAllCCs();
1164                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1165                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1166                LFOs[i]->suPanOnCC.RemoveAllCCs();
1167                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1168                LFOs[i]->suResOnCC.RemoveAllCCs();
1169                LFOs[i]->ResetUnits(); // class EqUnitSupport
1170            }
1171        }
1172    
1173        void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1174            suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1175            for (int i = 0; i < EGs.capacity(); i++) {
1176                EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1177            }
1178        }
1179        
1180        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1181            if (!pEqSupport->HasSupport()) return;
1182            if (pEqSupport->GetBandCount() < 3) {
1183                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1184                return;
1185            }
1186            
1187            ::sfz::Region* const pRegion = pVoice->pRegion;
1188            
1189            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1190            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1191            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1192            
1193            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1194            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1195            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1196            
1197            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1198            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1199            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1200            
1201            const float vel = pVoice->MIDIVelocity() / 127.0f;
1202            
1203            dB1 += pRegion->eq1_vel2gain * vel;
1204            dB2 += pRegion->eq2_vel2gain * vel;
1205            dB3 += pRegion->eq3_vel2gain * vel;
1206            
1207            freq1 += pRegion->eq1_vel2freq * vel;
1208            freq2 += pRegion->eq2_vel2freq * vel;
1209            freq3 += pRegion->eq3_vel2freq * vel;
1210            
1211            for (int i = 0; i < eqEGs.size(); i++) {
1212                EGv2Unit* eg = eqEGs[i];
1213                if (!eg->Active()) continue;
1214                
1215                float l = eg->GetLevel();
1216                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1217                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1218                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1219                
1220                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1221                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1222                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1223                
1224                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1225                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1226                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1227            }
1228            
1229            for (int i = 0; i < eqLFOs.size(); i++) {
1230                LFOv2Unit* lfo = eqLFOs[i];
1231                if (!lfo->Active()) continue;
1232                
1233                float l = lfo->GetLevel();
1234                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1235                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1236                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1237                
1238                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1239                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1240                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1241                
1242                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1243                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1244                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1245            }
1246            
1247            pEqSupport->SetGain(0, dB1);
1248            pEqSupport->SetGain(1, dB2);
1249            pEqSupport->SetGain(2, dB3);
1250            
1251            pEqSupport->SetFreq(0, freq1);
1252            pEqSupport->SetFreq(1, freq2);
1253            pEqSupport->SetFreq(2, freq3);
1254            
1255            pEqSupport->SetBandwidth(0, bw1);
1256            pEqSupport->SetBandwidth(1, bw2);
1257            pEqSupport->SetBandwidth(2, bw3);
1258        }
1259        
1260        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1261            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1262              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1263              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1264        {
1265            SetVoice(pVoice);
1266        }
1267        
1268        void EqUnitSupport::SetVoice(Voice* pVoice) {
1269            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1270            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1271            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1272        }
1273        
1274        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1275            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1276            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1277            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1278            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1279            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1280            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1281            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1282            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1283            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1284        }
1285        
1286        void EqUnitSupport::ResetUnits() {
1287            suEq1GainOnCC.RemoveAllCCs();
1288            suEq2GainOnCC.RemoveAllCCs();
1289            suEq3GainOnCC.RemoveAllCCs();
1290            suEq1FreqOnCC.RemoveAllCCs();
1291            suEq2FreqOnCC.RemoveAllCCs();
1292            suEq3FreqOnCC.RemoveAllCCs();
1293            suEq1BwOnCC.RemoveAllCCs();
1294            suEq2BwOnCC.RemoveAllCCs();
1295            suEq3BwOnCC.RemoveAllCCs();
1296        }
1297        
1298        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1299            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1300            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1301            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1302            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1303            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1304            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1305            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1306            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1307            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1308        }
1309            
1310  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2219  
changed lines
  Added in v.2879

  ViewVC Help
Powered by ViewVC