/[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 2222 by iliev, Thu Jul 28 18:24:12 2011 UTC revision 3316 by schoenebeck, Thu Jul 20 12:05:53 2017 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  #include <SF.h>  
26    #define _200TH_ROOT_OF_10 1.011579454259899
27    
28  namespace LinuxSampler { namespace sfz {  namespace LinuxSampler { namespace sfz {
29            
30        double ToRatio(int Centibels) {
31            if (Centibels == 0) return 1.0;
32            return pow(_200TH_ROOT_OF_10, Centibels);
33        }
34        
35      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36                    
37      }      }
# Line 34  namespace LinuxSampler { namespace sfz { Line 40  namespace LinuxSampler { namespace sfz {
40          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41      }      }
42            
43        float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44            float f = 0;
45            for (int i = 0; i < cc.size(); i++) {
46                int val = pVoice->GetControllerValue(cc[i].Controller);
47                f += (val / 127.0f) * cc[i].Influence;
48            }
49            return f;
50        }
51            
52      void EGv1Unit::Trigger() {      void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53          ::sfz::Region* const pRegion = pVoice->pRegion;          RemoveAllCCs();
54                    
55          // the length of the decay and release curves are dependent on the velocity          for (int cc = 0; cc < 128; cc++) {
56          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);              if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57                int i = loCCs[cc];
58          // set the delay trigger              int j = hiCCs[cc];
59          uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate();              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          EG.trigger(uint(pRegion->ampeg_start * 10),          if (Level != l) {
92                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),              Level = l;
93                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),              if (pListener != NULL) pListener->ValueChanged(this);
94                     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());  
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 EGv2Unit::Trigger() {      void EGv2Unit::Trigger() {
137          EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);          egInfo = *pEGInfo;
138            for (int i = 0; i < egInfo.node.size(); i++) {
139                float f = GetInfluence(egInfo.node[i].level_oncc);
140                egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
141                
142                f = GetInfluence(egInfo.node[i].time_oncc);
143                egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144            }
145            EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity());
146      }      }
147            
148            
149      void PitchEGUnit::Trigger() {      void PitchEGUnit::Trigger() {
150          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
151          depth = pRegion->pitcheg_depth;          depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152                    
153          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
154          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
155    
156          // set the delay trigger          // set the delay trigger
157          uiDelayTrigger = (pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158            delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160            
161            float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162            
163            float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164            attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165            
166            float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167            hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168            
169            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171            
172            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->pitcheg_start * 10),          EG.trigger (
179                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
181                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          );
                    uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),  
                    GetSampleRate());  
182      }      }
183            
184            
185      void FilEGUnit::Trigger() {      void FilEGUnit::Trigger() {
186          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
187          depth = pRegion->fileg_depth;          depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188                    
189          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
190          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
191    
192          // set the delay trigger          // set the delay trigger
193          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          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          EG.trigger(uint(pRegion->fileg_start * 10),          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
211                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
214                     GetSampleRate());          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            if (pVoice->pNote)
246                sustain *= pVoice->pNote->Override.Sustain;
247    
248            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
249            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
250            
251            EG.trigger (
252                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
253                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
254            );
255        }
256        
257        
258        LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
259            : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
260              suFadeEG(rack), suDepthOnCC(rack), suFreqOnCC(rack, this)
261        { }
262        
263        LFOUnit::LFOUnit(const LFOUnit& Unit)
264            : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
265              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
266              suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
267        {
268            Copy(Unit);
269        }
270    
271      void LFOUnit::Increment() {      void LFOUnit::Increment() {
272          if (DelayStage()) return;          if (DelayStage()) return;
273                    
274          SignalUnit::Increment();          SignalUnit::Increment();
275                    
276          Level = lfo.render();          Level = pLFO->Render();
277            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
278      }      }
279            
280      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 112  namespace LinuxSampler { namespace sfz { Line 282  namespace LinuxSampler { namespace sfz {
282          Level = 0;          Level = 0;
283                    
284          // set the delay trigger          // set the delay trigger
285          uiDelayTrigger = pLfoInfo->delay * GetSampleRate();          uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
286            if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
287                float f = pLfoInfo->fade;
288                f += GetInfluence(pLfoInfo->fade_oncc);
289                
290                if (f != 0) {
291                    suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
292                    suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
293                }
294            }
295        }
296        
297        void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
298            if (pLFO == NULL) return;
299            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
300      }      }
301            
302        
303      void LFOv1Unit::Trigger() {      void LFOv1Unit::Trigger() {
304          LFOUnit::Trigger();          LFOUnit::Trigger();
305                    
306          lfo.trigger (          lfo.trigger (
307              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
308              start_level_mid,              start_level_mid,
309              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
310          );          );
311          lfo.update(0);          lfo.updateByMIDICtrlValue(0);
312        }
313        
314        
315        LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
316            : LFOUnit(rack), EqUnitSupport(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
317              lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
318              suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
319        {
320            lfos.add(&lfo0);
321            lfos.add(&lfo1);
322            lfos.add(&lfo2);
323            lfos.add(&lfo3);
324            lfos.add(&lfo4);
325            lfos.add(&lfo5);
326            lfos.add(&lfo6);
327            lfos.add(&lfo7);
328      }      }
329            
330      void LFOv2Unit::Trigger() {      void LFOv2Unit::Trigger() {
331          LFOUnit::Trigger();          LFOUnit::Trigger();
332                    
333          lfo.trigger (          if (/*pLfoInfo->wave < 0 ||*/ pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
334              pLfoInfo->freq,          else pLFO = lfos[pLfoInfo->wave];
335            
336            pLFO->Trigger (
337                pLfoInfo->freq + suFreqOnCC.GetLevel(),
338              start_level_mid,              start_level_mid,
339              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
340          );          );
341          lfo.update(0);          pLFO->Update(0);
342            
343            float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
344            if (phase != 0) pLFO->SetPhase(phase);
345      }      }
346            
347      void AmpLFOUnit::Trigger() {      void AmpLFOUnit::Trigger() {
348            bActive = true;
349          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
350          pLfoInfo->delay = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
351          pLfoInfo->freq = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
352            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
353          pLfoInfo->volume = pRegion->amplfo_depth;          pLfoInfo->volume = pRegion->amplfo_depth;
354                    
355            if (pLfoInfo->freq <= 0) {
356                if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
357                else bActive = false;
358            }
359            
360          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
361      }      }
362            
363      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
364            bActive = true;
365          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
366          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
367          pLfoInfo->freq = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
368            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
369          pLfoInfo->pitch = pRegion->pitchlfo_depth;          pLfoInfo->pitch = pRegion->pitchlfo_depth;
370                    
371            if (pLfoInfo->freq <= 0) {
372                if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
373                else bActive = false;
374            }
375            
376          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
377      }      }
378            
379      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
380            bActive = true;
381          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
382          pLfoInfo->delay = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
383          pLfoInfo->freq = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
384            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
385          pLfoInfo->cutoff = pRegion->fillfo_depth;          pLfoInfo->cutoff = pRegion->fillfo_depth;
386                    
387            if (pLfoInfo->freq <= 0) {
388                if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
389                else bActive = false;
390            }
391            
392          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
393      }      }
394        
395        CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
396            pVoice = NULL;
397        }
398        
399        void CCUnit::Trigger() {
400            RTList<CC>::Iterator ctrl = pCtrls->first();
401            RTList<CC>::Iterator end  = pCtrls->end();
402            for(; ctrl != end; ++ctrl) {
403                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
404                if ((*ctrl).pSmoother != NULL) {
405                    if ((*ctrl).Step > 0) {
406                        float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
407                        (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
408                    } else {
409                        (*ctrl).pSmoother->setValue((*ctrl).Value);
410                    }
411                }
412            }
413            CCSignalUnit::Trigger();
414        }
415        
416        void CCUnit::SetCCs(::sfz::Array<int>& cc) {
417            RemoveAllCCs();
418            for (int i = 0; i < 128; i++) {
419                if (cc[i] != 0) AddCC(i, cc[i]);
420            }
421        }
422        
423        void CCUnit::SetCCs(::sfz::Array<float>& cc) {
424            RemoveAllCCs();
425            for (int i = 0; i < 128; i++) {
426                if (cc[i] != 0) AddCC(i, cc[i]);
427            }
428        }
429        
430        void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
431            RemoveAllCCs();
432            for (int i = 0; i < cc.size(); i++) {
433                if (cc[i].Influence != 0) {
434                    short int curve = cc[i].Curve;
435                    if (curve >= GetCurveCount()) curve = -1;
436                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
437                }
438            }
439        }
440        
441        void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
442            AddCC(Controller, Influence, Curve, NULL, Step);
443        }
444        
445        int CCUnit::GetCurveCount() {
446            return pVoice->pRegion->GetInstrument()->curves.size();
447        }
448        
449        ::sfz::Curve* CCUnit::GetCurve(int idx) {
450            return &pVoice->pRegion->GetInstrument()->curves[idx];
451        }
452        
453        double CCUnit::GetSampleRate() {
454            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
455        }
456        
457        
458        SmoothCCUnit::~SmoothCCUnit() {
459            if (pSmoothers != NULL) delete pSmoothers;
460        }
461        
462        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
463            if (Smooth > 0) {
464                if (pSmoothers->poolIsEmpty()) {
465                    std::cerr << "Maximum number of smoothers reached" << std::endl;
466                    return;
467                }
468                Smoother* smoother = &(*(pSmoothers->allocAppend()));
469                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
470                AddCC(Controller, Influence, Curve, smoother, Step);
471            } else {
472                AddCC(Controller, Influence, Curve, NULL, Step);
473            }
474        }
475        
476        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
477            if (pSmoothers != NULL) delete pSmoothers;
478            pSmoothers = new RTList<Smoother>(pSmootherPool);
479        }
480        
481        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
482            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
483            InitSmoothers(pSmootherPool);
484        }
485    
486    
487      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
488            : EndpointSignalUnit(rack), pitchVeltrackRatio(0), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack)
489        {
490                    
491      }      }
492            
493        float EndpointUnit::GetInfluence(::sfz::Array< optional<float> >& cc) {
494            float f = 0;
495            for (int i = 0; i < 128; i++) {
496                if (cc[i]) {
497                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
498                }
499            }
500            return f;
501        }
502        
503        float EndpointUnit::GetInfluence(::sfz::Array< optional<int> >& cc) {
504            float f = 0;
505            for (int i = 0; i < 128; i++) {
506                if (cc[i]) {
507                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
508                }
509            }
510            return f;
511        }
512        
513      SfzSignalUnitRack* const EndpointUnit::GetRack() {      SfzSignalUnitRack* const EndpointUnit::GetRack() {
514          return static_cast<SfzSignalUnitRack* const>(pRack);          return static_cast<SfzSignalUnitRack* const>(pRack);
515      }      }
516            
517      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
518            uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
519            if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
520                    
521            if (pVoice->pRegion->delay) {
522                /* here we use the device sample rate */
523                uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
524            }
525            
526            if (pVoice->pRegion->delay_random) {
527                float r = pVoice->GetEngine()->Random();
528                uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
529            }
530            
531            uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
532            
533            float xfInVelCoeff = 1;
534            
535            if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
536                xfInVelCoeff = 0;
537            } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
538                xfInVelCoeff = 1;
539            } else {
540                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
541                float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
542                xfInVelCoeff = velPos / xfVelSize;
543                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
544                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
545                }
546            }
547            
548            float xfOutVelCoeff = 1;
549            
550            if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
551                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
552            } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
553                xfOutVelCoeff = 1;
554            } else {
555                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
556                float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
557                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
558                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
559                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
560                }
561            }
562            
563            float xfInKeyCoeff = 1;
564            
565            if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
566                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
567            } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
568                xfInKeyCoeff = 1;
569            } else {
570                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
571                float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
572                xfInKeyCoeff = keyPos / xfKeySize;
573                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
574                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
575                }
576            }
577            
578            float xfOutKeyCoeff = 1;
579            
580            if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
581                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
582            } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
583                xfOutKeyCoeff = 1;
584            } else {
585                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
586                float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
587                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
588                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
589                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
590                }
591            }
592            
593            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
594            
595            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
596            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
597            
598            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
599            
600            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
601      }      }
602            
603      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
604            if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
605                return false; // The key was released before the delay end, so the voice won't play at all.
606            }
607            
608          if (GetRack()->suVolEG.Active()) return true;          if (GetRack()->suVolEG.Active()) return true;
609                    
610          bool b = false;          bool b = false;
# Line 194  namespace LinuxSampler { namespace sfz { Line 621  namespace LinuxSampler { namespace sfz {
621          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
622              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
623              if (!eg->Active()) continue;              if (!eg->Active()) continue;
624              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
625                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
626                if (dB < -144) dB = eg->pEGInfo->volume;
627                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
628                
629                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
630                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
631                
632                if (dB >= -144) {
633                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
634                    amp *= ToRatio(dB * 10.0);
635                }
636                
637                vol += amp * eg->GetLevel();
638          }          }
639                    
640          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
641          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
642            float f = u2->Active() ? u2->GetLevel() : 0;
643            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
644                    
645          return vol;          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
646            
647            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
648                LFOv2Unit* lfo = GetRack()->volLFOs[i];
649                if (!lfo->Active()) continue;
650                
651                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
652                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
653            }
654            
655            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
656            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
657            return vol * xfCoeff;
658      }      }
659            
660      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
661          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
662                    
663          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
664          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
665            float f = u1->Active() ? u1->GetLevel() : 0;
666            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
667                    
668          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
669          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
670                    
671            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
672                EGv2Unit* eg = GetRack()->filEGs[i];
673                if (!eg->Active()) continue;
674                
675                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
676                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
677                val *= RTMath::CentsToFreqRatioUnlimited(f);
678            }
679            
680          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
681              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
682              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
683                            
684              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
685                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
686              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
687          }          }
688                    
689          return val;          return val;
690      }      }
691            
692        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
693            cutoff *= GetFilterCutoff();
694            float maxCutoff = 0.49 * pVoice->GetSampleRate();
695            return cutoff > maxCutoff ? maxCutoff : cutoff;
696        }
697        
698      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
699          double p;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
700            
701          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
702          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
703            
704            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
705                EGv2Unit* eg = GetRack()->pitchEGs[i];
706                if (!eg->Active()) continue;
707                
708                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
709                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
710            }
711                    
712          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
713          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->pLfoInfo->pitch) : 1;          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
714            float f = u3->Active() ? u3->GetLevel() : 0;
715            p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
716            
717            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
718                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
719                if (!lfo->Active()) continue;
720                
721                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
722                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
723            }
724                    
725          return p;          return p * pitchVeltrackRatio;
726      }      }
727            
728      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
729           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
730            
731            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
732                EGv2Unit* eg = GetRack()->resEGs[i];
733                if (!eg->Active()) continue;
734                
735                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
736                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
737            }
738                    
739          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
740              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
741              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
742                            
743              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
744                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
745          }          }
746                    
747          return val;          return val;
748      }      }
749            
750      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
751          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
752            
753            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
754                EGv2Unit* eg = GetRack()->panEGs[i];
755                if (!eg->Active()) continue;
756                
757                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
758                
759                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
760                    uint8_t val = eg->GetLevel() * 127;
761                    if (val > 127) val = 127;
762                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
763                } else {
764                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
765                }
766            }
767                    
768          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
769              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
770              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
771                            
772              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
773                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
774          }          }
775                    
         if(pan < -100) return -100;  
         if(pan >  100) return  100;  
           
776          return pan;          return pan;
777      }      }
778            
779            
780      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
781          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice),
782          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
783          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
784          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
785            EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
786            resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
787            LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
788            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount),
789            pVoice(voice)
790      {      {
791          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
792            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
793          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
794                    
795            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
796            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
797            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
798            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
799            
800          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
801              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
802              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
803                EGs[i]->suAmpOnCC.pVoice = voice;
804                EGs[i]->suVolOnCC.pVoice = voice;
805                EGs[i]->suPitchOnCC.pVoice = voice;
806                EGs[i]->suCutoffOnCC.pVoice = voice;
807                EGs[i]->suResOnCC.pVoice = voice;
808                EGs[i]->suPanOnCC.pVoice = voice;
809                EGs[i]->SetVoice(voice); // class EqUnitSupport
810          }          }
811                    
812          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
813              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
814              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
815                LFOs[i]->suDepthOnCC.pVoice = voice;
816                LFOs[i]->suFreqOnCC.pVoice = voice;
817                LFOs[i]->suFadeEG.pVoice = voice;
818                LFOs[i]->suVolOnCC.pVoice = voice;
819                LFOs[i]->suPitchOnCC.pVoice = voice;
820                LFOs[i]->suFreqOnCC.pVoice = voice;
821                LFOs[i]->suPanOnCC.pVoice = voice;
822                LFOs[i]->suCutoffOnCC.pVoice = voice;
823                LFOs[i]->suResOnCC.pVoice = voice;
824                LFOs[i]->SetVoice(voice); // class EqUnitSupport
825          }          }
826      }      }
827            
# Line 294  namespace LinuxSampler { namespace sfz { Line 835  namespace LinuxSampler { namespace sfz {
835          }          }
836      }      }
837            
838        void SfzSignalUnitRack::InitRTLists() {
839            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
840            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
841            
842            EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
843            
844            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
845            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
846            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847            suResOnCC.InitCCList(pCCPool, pSmootherPool);
848            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
849            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
850            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
851            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
852            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
853            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
854            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
855            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
856            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
857            
858            for (int i = 0; i < EGs.capacity(); i++) {
859                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
860                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
861                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
862                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
863                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
864                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
865                EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
866            }
867            
868            for (int i = 0; i < LFOs.capacity(); i++) {
869                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
870                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
871                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
874                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
875                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
876                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
877                LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
878            }
879        }
880        
881      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
882          EGs.clear();          EGs.clear();
883          volEGs.clear();          volEGs.clear();
884          pitchEGs.clear();          pitchEGs.clear();
885            filEGs.clear();
886            resEGs.clear();
887            panEGs.clear();
888            eqEGs.clear();
889                    
890          LFOs.clear();          LFOs.clear();
891            volLFOs.clear();
892            pitchLFOs.clear();
893          filLFOs.clear();          filLFOs.clear();
894          resLFOs.clear();          resLFOs.clear();
895          panLFOs.clear();          panLFOs.clear();
896            eqLFOs.clear();
897                    
898          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
899                    
900            suVolOnCC.SetCCs(pRegion->volume_oncc);
901            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
902            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
903            suResOnCC.SetCCs(pRegion->resonance_oncc);
904            
905          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
906              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
907                            
# Line 313  namespace LinuxSampler { namespace sfz { Line 909  namespace LinuxSampler { namespace sfz {
909                  EGv2Unit eg(this);                  EGv2Unit eg(this);
910                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
911                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
912                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
913                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
914                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
915                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
916                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
917                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
918                    if (pVoice->bEqSupport) {
919                        EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
920                        EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
921                        EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
922                        EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
923                        EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
924                        EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
925                        EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
926                        EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
927                        EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
928                    }
929              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
930                            
931              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
932                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
933                ) {
934                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
935                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
936              }              }
937                
938                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
939                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
940                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
941                }
942                
943                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
944                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
945                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
946                }
947                
948                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
949                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
950                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
951                }
952                
953                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
954                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
955                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
956                }
957                
958                if (pRegion->eg[i].HasEq()) {
959                    if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
960                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
961                }
962          }          }
963                    
964          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 328  namespace LinuxSampler { namespace sfz { Line 968  namespace LinuxSampler { namespace sfz {
968                    
969          // LFO          // LFO
970          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
971              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
972                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
973                    else pRegion->lfos[i].freq = 0;
974                }
975                            
976              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
977                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
978                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
979                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
980                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
981                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
982                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
983                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
984                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
985                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
986                    if (pVoice->bEqSupport) {
987                        LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
988                        LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
989                        LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
990                        LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
991                        LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
992                        LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
993                        LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
994                        LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
995                        LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
996                    }
997              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
998                            
999              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
1000                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
1001                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1002                }
1003                
1004                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
1005                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
1006                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1007                }
1008                
1009                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1010                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1011                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1012              }              }
1013                            
1014              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1015                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1016                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1017              }              }
1018                            
1019              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1020                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1021                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1022              }              }
1023                
1024                if (pRegion->lfos[i].HasEq()) {
1025                    if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1026                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1027                }
1028          }          }
1029                    
1030            if (!pVoice->bEqSupport) {
1031                bHasEq = false;
1032            } else {
1033                suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1034                suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1035                suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1036                suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1037                suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1038                suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1039                suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1040                suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1041                suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1042            
1043                bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1044                         pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1045                         suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1046                         eqEGs.size() > 0 || eqLFOs.size() > 0;
1047            }
1048            
1049            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1050            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1051            
1052            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1053            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1054            
1055            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1056            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1057            
1058          Units.clear();          Units.clear();
1059                    
1060            EqUnitSupport::ImportUnits(this);
1061            
1062            Units.add(&suVolOnCC);
1063            Units.add(&suPitchOnCC);
1064            Units.add(&suCutoffOnCC);
1065            Units.add(&suResOnCC);
1066            
1067          Units.add(&suVolEG);          Units.add(&suVolEG);
1068          Units.add(&suFilEG);          Units.add(&suFilEG);
1069          Units.add(&suPitchEG);          Units.add(&suPitchEG);
1070            
1071            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1072          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
1073            Units.add(&suPitchLFO.suDepthOnCC);
1074            Units.add(&suPitchLFO.suFadeEG);
1075            
1076            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1077            Units.add(&suAmpLFO.suDepthOnCC);
1078          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
1079            Units.add(&suAmpLFO.suFadeEG);
1080            
1081            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1082            Units.add(&suFilLFO.suDepthOnCC);
1083          Units.add(&suFilLFO);          Units.add(&suFilLFO);
1084            Units.add(&suFilLFO.suFadeEG);
1085                    
1086          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1087              Units.add(EGs[i]);              Units.add(EGs[i]);
1088                Units.add(&(EGs[i]->suAmpOnCC));
1089                Units.add(&(EGs[i]->suVolOnCC));
1090                Units.add(&(EGs[i]->suPitchOnCC));
1091                Units.add(&(EGs[i]->suCutoffOnCC));
1092                Units.add(&(EGs[i]->suResOnCC));
1093                Units.add(&(EGs[i]->suPanOnCC));
1094                EGs[i]->ImportUnits(this); // class EqUnitSupport
1095          }          }
1096                    
1097          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1098                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1099              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1100                Units.add(&(LFOs[i]->suFadeEG));
1101                Units.add(&(LFOs[i]->suVolOnCC));
1102                Units.add(&(LFOs[i]->suPitchOnCC));
1103                Units.add(&(LFOs[i]->suPanOnCC));
1104                Units.add(&(LFOs[i]->suCutoffOnCC));
1105                Units.add(&(LFOs[i]->suResOnCC));
1106                LFOs[i]->ImportUnits(this); // class EqUnitSupport
1107          }          }
1108                    
1109          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1110            Units.add(&suEndpoint.suXFInCC);
1111            Units.add(&suEndpoint.suXFOutCC);
1112            Units.add(&suEndpoint.suPanOnCC);
1113                    
1114          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1115      }      }
# Line 385  namespace LinuxSampler { namespace sfz { Line 1125  namespace LinuxSampler { namespace sfz {
1125              volEGs[i]->EG.enterFadeOutStage();              volEGs[i]->EG.enterFadeOutStage();
1126          }          }
1127      }      }
1128    
1129        void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1130            suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1131            for (int i = 0; i < volEGs.size(); i++) {
1132                volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1133            }
1134        }
1135    
1136        void SfzSignalUnitRack::Reset() {
1137            EqUnitSupport::ResetUnits();
1138            
1139            suVolOnCC.RemoveAllCCs();
1140            suPitchOnCC.RemoveAllCCs();
1141            suCutoffOnCC.RemoveAllCCs();
1142            suResOnCC.RemoveAllCCs();
1143            suEndpoint.suXFInCC.RemoveAllCCs();
1144            suEndpoint.suXFOutCC.RemoveAllCCs();
1145            suEndpoint.suPanOnCC.RemoveAllCCs();
1146            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1147            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1148            suFilLFO.suDepthOnCC.RemoveAllCCs();
1149            suFilLFO.suFreqOnCC.RemoveAllCCs();
1150            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1151            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1152            
1153            for (int i = 0; i < EGs.capacity(); i++) {
1154                EGs[i]->suAmpOnCC.RemoveAllCCs();
1155                EGs[i]->suVolOnCC.RemoveAllCCs();
1156                EGs[i]->suPitchOnCC.RemoveAllCCs();
1157                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1158                EGs[i]->suResOnCC.RemoveAllCCs();
1159                EGs[i]->suPanOnCC.RemoveAllCCs();
1160                EGs[i]->ResetUnits(); // class EqUnitSupport
1161            }
1162            
1163            for (int i = 0; i < LFOs.capacity(); i++) {
1164                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1165                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1166                LFOs[i]->suVolOnCC.RemoveAllCCs();
1167                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1168                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1169                LFOs[i]->suPanOnCC.RemoveAllCCs();
1170                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1171                LFOs[i]->suResOnCC.RemoveAllCCs();
1172                LFOs[i]->ResetUnits(); // class EqUnitSupport
1173            }
1174        }
1175    
1176        void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1177            suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1178            for (int i = 0; i < EGs.capacity(); i++) {
1179                EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1180            }
1181        }
1182        
1183        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1184            if (!pEqSupport->HasSupport()) return;
1185            if (pEqSupport->GetBandCount() < 3) {
1186                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1187                return;
1188            }
1189            
1190            ::sfz::Region* const pRegion = pVoice->pRegion;
1191            
1192            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1193            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1194            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1195            
1196            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1197            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1198            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1199            
1200            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1201            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1202            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1203            
1204            const float vel = pVoice->MIDIVelocity() / 127.0f;
1205            
1206            dB1 += pRegion->eq1_vel2gain * vel;
1207            dB2 += pRegion->eq2_vel2gain * vel;
1208            dB3 += pRegion->eq3_vel2gain * vel;
1209            
1210            freq1 += pRegion->eq1_vel2freq * vel;
1211            freq2 += pRegion->eq2_vel2freq * vel;
1212            freq3 += pRegion->eq3_vel2freq * vel;
1213            
1214            for (int i = 0; i < eqEGs.size(); i++) {
1215                EGv2Unit* eg = eqEGs[i];
1216                if (!eg->Active()) continue;
1217                
1218                float l = eg->GetLevel();
1219                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1220                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1221                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1222                
1223                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1224                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1225                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1226                
1227                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1228                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1229                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1230            }
1231            
1232            for (int i = 0; i < eqLFOs.size(); i++) {
1233                LFOv2Unit* lfo = eqLFOs[i];
1234                if (!lfo->Active()) continue;
1235                
1236                float l = lfo->GetLevel();
1237                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1238                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1239                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1240                
1241                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1242                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1243                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1244                
1245                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1246                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1247                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1248            }
1249            
1250            pEqSupport->SetGain(0, dB1);
1251            pEqSupport->SetGain(1, dB2);
1252            pEqSupport->SetGain(2, dB3);
1253            
1254            pEqSupport->SetFreq(0, freq1);
1255            pEqSupport->SetFreq(1, freq2);
1256            pEqSupport->SetFreq(2, freq3);
1257            
1258            pEqSupport->SetBandwidth(0, bw1);
1259            pEqSupport->SetBandwidth(1, bw2);
1260            pEqSupport->SetBandwidth(2, bw3);
1261        }
1262        
1263        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1264            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1265              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1266              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1267        {
1268            SetVoice(pVoice);
1269        }
1270        
1271        void EqUnitSupport::SetVoice(Voice* pVoice) {
1272            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1273            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1274            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1275        }
1276        
1277        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1278            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1279            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1280            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1281            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1282            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1283            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1284            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1285            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1286            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1287        }
1288        
1289        void EqUnitSupport::ResetUnits() {
1290            suEq1GainOnCC.RemoveAllCCs();
1291            suEq2GainOnCC.RemoveAllCCs();
1292            suEq3GainOnCC.RemoveAllCCs();
1293            suEq1FreqOnCC.RemoveAllCCs();
1294            suEq2FreqOnCC.RemoveAllCCs();
1295            suEq3FreqOnCC.RemoveAllCCs();
1296            suEq1BwOnCC.RemoveAllCCs();
1297            suEq2BwOnCC.RemoveAllCCs();
1298            suEq3BwOnCC.RemoveAllCCs();
1299        }
1300        
1301        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1302            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1303            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1304            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1305            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1306            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1307            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1308            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1309            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1310            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1311        }
1312            
1313  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2222  
changed lines
  Added in v.3316

  ViewVC Help
Powered by ViewVC