/[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 2225 by iliev, Tue Aug 2 13:44:57 2011 UTC revision 2296 by iliev, Thu Dec 8 20:03:47 2011 UTC
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "SfzSignalUnitRack.h"  #include "SfzSignalUnitRack.h"
24  #include "Voice.h"  #include "Engine.h"
25  #include <SF.h>  
26    #define _200TH_ROOT_OF_10 1.011579454259899
27    
28  namespace LinuxSampler { namespace sfz {  namespace LinuxSampler { namespace sfz {
29            
30        double ToRatio(int Centibels) {
31            if (Centibels == 0) return 1.0;
32            return pow(_200TH_ROOT_OF_10, Centibels);
33        }
34        
35      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36                    
37      }      }
# Line 34  namespace LinuxSampler { namespace sfz { Line 40  namespace LinuxSampler { namespace sfz {
40          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41      }      }
42            
43        float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44            float f = 0;
45            for (int i = 0; i < cc.size(); i++) {
46                int val = pVoice->GetControllerValue(cc[i].Controller);
47                f += (val / 127.0f) * cc[i].Influence;
48            }
49            return f;
50        }
51            
52      void 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), 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          EG.trigger(uint(pRegion->pitcheg_start * 10),          float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
178                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          EG.trigger (
179                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181                     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
190            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191    
192            // set the delay trigger
193            float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194            delay += GetInfluence(pRegion->fileg_delay_oncc);
195            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196            
197            float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198            
199            float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200            attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201            
202            float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203            hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204            
205            float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206            decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207            
208            float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209            sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210            
211            float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217            );
218        }
219        
220        
221        void AmpEGUnit::Trigger() {
222            ::sfz::Region* const pRegion = pVoice->pRegion;
223                    
224          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
225          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226    
227          // set the delay trigger          // set the delay trigger
228          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229            delay += GetInfluence(pRegion->ampeg_delaycc);
230            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231            
232            float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233            
234            float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235            attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236            
237            float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238            hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239            
240            float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242            
243            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(uint(pRegion->fileg_start * 10),          EG.trigger (
250                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          );
                    uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),  
                    GetSampleRate());  
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;
# Line 105  namespace LinuxSampler { namespace sfz { Line 272  namespace LinuxSampler { namespace sfz {
272          SignalUnit::Increment();          SignalUnit::Increment();
273                    
274          Level = pLFO->Render();          Level = pLFO->Render();
275            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276      }      }
277            
278      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 112  namespace LinuxSampler { namespace sfz { Line 280  namespace LinuxSampler { namespace sfz {
280          Level = 0;          Level = 0;
281                    
282          // set the delay trigger          // set the delay trigger
283          uiDelayTrigger = pLfoInfo->delay * GetSampleRate();          uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
284            if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285                float f = pLfoInfo->fade;
286                f += GetInfluence(pLfoInfo->fade_oncc);
287                
288                if (f != 0) {
289                    suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290                    suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
291                }
292            }
293        }
294        
295        void 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() {      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          );          );
# Line 130  namespace LinuxSampler { namespace sfz { Line 313  namespace LinuxSampler { namespace sfz {
313      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316            suPitchOnCC(rack)            suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317      {      {
318          lfos.add(&lfo0);          lfos.add(&lfo0);
319          lfos.add(&lfo1);          lfos.add(&lfo1);
# Line 149  namespace LinuxSampler { namespace sfz { Line 332  namespace LinuxSampler { namespace sfz {
332          else pLFO = lfos[pLfoInfo->wave];          else pLFO = lfos[pLfoInfo->wave];
333                    
334          pLFO->Trigger (          pLFO->Trigger (
335              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
336              start_level_mid,              start_level_mid,
337              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
338          );          );
339          pLFO->Update(0);          pLFO->Update(0);
340                    
341          float phase = pLfoInfo->phase;          float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
         for (int i = 0; i < pLfoInfo->phase_oncc.size(); i++) {  
             int val = pVoice->GetControllerValue(pLfoInfo->phase_oncc[i].Controller);  
             phase += (val / 127.0f) * pLfoInfo->phase_oncc[i].Influence;  
         }  
342          if (phase != 0) pLFO->SetPhase(phase);          if (phase != 0) pLFO->SetPhase(phase);
343      }      }
344            
345      void AmpLFOUnit::Trigger() {      void AmpLFOUnit::Trigger() {
346            bActive = true;
347          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
348          pLfoInfo->delay = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349          pLfoInfo->freq = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
350            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351          pLfoInfo->volume = pRegion->amplfo_depth;          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();          LFOv1Unit::Trigger();
359      }      }
360            
361      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
362            bActive = true;
363          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
364          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365          pLfoInfo->freq = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
366            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367          pLfoInfo->pitch = pRegion->pitchlfo_depth;          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();          LFOv1Unit::Trigger();
375      }      }
376            
377      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
378            bActive = true;
379          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
380          pLfoInfo->delay = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381          pLfoInfo->freq = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
382            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383          pLfoInfo->cutoff = pRegion->fillfo_depth;          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();          LFOv1Unit::Trigger();
391      }      }
392            
393      CCUnit::CCUnit(SfzSignalUnitRack* rack): CCSignalUnit(rack) { }      CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
394            pVoice = NULL;
395        }
396            
397      void CCUnit::Trigger() {      void CCUnit::Trigger() {
398          for (int i = 0; i < Ctrls.size(); i++) {          RTList<CC>::Iterator ctrl = pCtrls->first();
399              Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);          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();          CCSignalUnit::Trigger();
412      }      }
413            
414       void CCUnit::SetCCs(::sfz::Array<int>& cc) {      void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415           RemoveAllCCs();          RemoveAllCCs();
416           for (int i = 0; i < 128; i++) {          for (int i = 0; i < 128; i++) {
417               if (cc[i] != 0) AddCC(i, cc[i]);              if (cc[i] != 0) AddCC(i, cc[i]);
418           }          }
419       }      }
420            
421       void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {      void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422           RemoveAllCCs();          RemoveAllCCs();
423           for (int i = 0; i < cc.size(); i++) {          for (int i = 0; i < 128; i++) {
424               if (cc[i].Influence != 0) AddCC(cc[i].Controller, cc[i].Influence);              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            
# Line 223  namespace LinuxSampler { namespace sfz { Line 493  namespace LinuxSampler { namespace sfz {
493      }      }
494            
495      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
496            float xfInVelCoeff = 1;
497            
498            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
499                xfInVelCoeff = 0;
500            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
501                xfInVelCoeff = 1;
502            } else {
503                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
504                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
505                xfInVelCoeff = velPos / xfVelSize;
506                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
507                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
508                }
509            }
510                    
511            float xfOutVelCoeff = 1;
512            
513            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
514                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
515            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
516                xfOutVelCoeff = 1;
517            } else {
518                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
519                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
520                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
521                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
522                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
523                }
524            }
525            
526            float xfInKeyCoeff = 1;
527            
528            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
529                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
530            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
531                xfInKeyCoeff = 1;
532            } else {
533                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
534                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
535                xfInKeyCoeff = keyPos / xfKeySize;
536                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
537                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
538                }
539            }
540            
541            float xfOutKeyCoeff = 1;
542            
543            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
544                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
545            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
546                xfOutKeyCoeff = 1;
547            } else {
548                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
549                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
550                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
551                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
552                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
553                }
554            }
555            
556            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
557            
558            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
559            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
560            
561            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
562            
563            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
564      }      }
565            
566      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 243  namespace LinuxSampler { namespace sfz { Line 580  namespace LinuxSampler { namespace sfz {
580          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
581              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
582              if (!eg->Active()) continue;              if (!eg->Active()) continue;
583              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
584                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
585                if (dB < -144) dB = eg->pEGInfo->volume;
586                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
587                
588                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
589                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
590                
591                if (dB >= -144) {
592                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
593                    amp *= ToRatio(dB * 10.0);
594                }
595                
596                vol += amp * eg->GetLevel();
597          }          }
598                    
599          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
600          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
601            float f = u2->Active() ? u2->GetLevel() : 0;
602            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
603                    
604          return vol;          vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
605            
606            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
607                LFOv2Unit* lfo = GetRack()->volLFOs[i];
608                if (!lfo->Active()) continue;
609                
610                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
611                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
612            }
613            
614            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
615            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
616            return vol * xfCoeff;
617      }      }
618            
619      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
620          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
621                    
622          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
623          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
624            float f = u1->Active() ? u1->GetLevel() : 0;
625            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
626                    
627          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
628          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
629                    
630            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
631                EGv2Unit* eg = GetRack()->filEGs[i];
632                if (!eg->Active()) continue;
633                
634                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
635                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
636                val *= RTMath::CentsToFreqRatioUnlimited(f);
637            }
638            
639          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
640              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
641              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
642                            
643              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
644                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
645              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
646          }          }
647                    
648          return val;          return val;
649      }      }
650            
651        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
652            cutoff *= GetFilterCutoff();
653            float maxCutoff = 0.49 * pVoice->GetSampleRate();
654            return cutoff > maxCutoff ? maxCutoff : cutoff;
655        }
656        
657      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
658          double p;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
659            
660          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
661          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
662            
663            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
664                EGv2Unit* eg = GetRack()->pitchEGs[i];
665                if (!eg->Active()) continue;
666                
667                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
668                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
669            }
670                    
671          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
672          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
673          float f = u3->Active() ? u3->GetLevel() : 0;          float f = u3->Active() ? u3->GetLevel() : 0;
674          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
675                    
# Line 290  namespace LinuxSampler { namespace sfz { Line 681  namespace LinuxSampler { namespace sfz {
681              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));              p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
682          }          }
683                    
684          return p;          return p * pitchVeltrackRatio;
685      }      }
686            
687      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
688           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
689            
690            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
691                EGv2Unit* eg = GetRack()->resEGs[i];
692                if (!eg->Active()) continue;
693                
694                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
695                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
696            }
697                    
698          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
699              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
700              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
701                            
702              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
703                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
704          }          }
705                    
706          return val;          return val;
707      }      }
708            
709      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
710          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
711            
712            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
713                EGv2Unit* eg = GetRack()->panEGs[i];
714                if (!eg->Active()) continue;
715                
716                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
717                
718                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
719                    uint8_t val = eg->GetLevel() * 127;
720                    if (val > 127) val = 127;
721                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
722                } else {
723                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
724                }
725            }
726                    
727          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
728              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
729              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
730                            
731              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
732                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
733          }          }
734                    
735          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 325  namespace LinuxSampler { namespace sfz { Line 741  namespace LinuxSampler { namespace sfz {
741            
742      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
743          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
744          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
745            suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
746            suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
747            suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
748            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
749          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
750          LFOs(maxLfoCount), pitchLFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
751            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
752      {      {
753          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
754            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
755          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
756          suPitchLFO.suDepthCC.pVoice = voice;          
757            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
758            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
759            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
760            
761            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
762            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
763            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
764            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
765                    
766          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
767              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
768              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
769                EGs[i]->suAmpOnCC.pVoice = voice;
770                EGs[i]->suVolOnCC.pVoice = voice;
771                EGs[i]->suPitchOnCC.pVoice = voice;
772                EGs[i]->suCutoffOnCC.pVoice = voice;
773                EGs[i]->suResOnCC.pVoice = voice;
774                EGs[i]->suPanOnCC.pVoice = voice;
775          }          }
776                    
777          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
778              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
779              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
780                LFOs[i]->suDepthOnCC.pVoice = voice;
781                LFOs[i]->suFreqOnCC.pVoice = voice;
782                LFOs[i]->suFadeEG.pVoice = voice;
783                LFOs[i]->suVolOnCC.pVoice = voice;
784              LFOs[i]->suPitchOnCC.pVoice = voice;              LFOs[i]->suPitchOnCC.pVoice = voice;
785                LFOs[i]->suFreqOnCC.pVoice = voice;
786                LFOs[i]->suPanOnCC.pVoice = voice;
787                LFOs[i]->suCutoffOnCC.pVoice = voice;
788                LFOs[i]->suResOnCC.pVoice = voice;
789          }          }
790      }      }
791            
# Line 355  namespace LinuxSampler { namespace sfz { Line 799  namespace LinuxSampler { namespace sfz {
799          }          }
800      }      }
801            
802        void SfzSignalUnitRack::InitRTLists() {
803            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
804            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
805            
806            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
807            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
808            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
809            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
810            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
811            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
812            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
813            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
814            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
815            
816            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
817            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
818            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
819            suResOnCC.InitCCList(pCCPool, pSmootherPool);
820            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
821            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
822            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
823            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
824            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
825            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
826            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
827            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
828            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
829            
830            for (int i = 0; i < EGs.capacity(); i++) {
831                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
832                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
833                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
834                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
835                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
836                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
837            }
838            
839            for (int i = 0; i < LFOs.capacity(); i++) {
840                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
841                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
842                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
843                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
844                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
845                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
846                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
847                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
848            }
849        }
850        
851      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
852          EGs.clear();          EGs.clear();
853          volEGs.clear();          volEGs.clear();
854          pitchEGs.clear();          pitchEGs.clear();
855            filEGs.clear();
856            resEGs.clear();
857            panEGs.clear();
858                    
859          LFOs.clear();          LFOs.clear();
860            volLFOs.clear();
861          pitchLFOs.clear();          pitchLFOs.clear();
862          filLFOs.clear();          filLFOs.clear();
863          resLFOs.clear();          resLFOs.clear();
# Line 368  namespace LinuxSampler { namespace sfz { Line 865  namespace LinuxSampler { namespace sfz {
865                    
866          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
867                    
868            suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
869            suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
870            suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
871            suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
872            suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
873            suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
874            suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
875            suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
876            suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
877            
878            bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
879                     suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
880            
881            suVolOnCC.SetCCs(pRegion->volume_oncc);
882            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
883            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
884            suResOnCC.SetCCs(pRegion->resonance_oncc);
885            
886          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
887              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
888                            
# Line 375  namespace LinuxSampler { namespace sfz { Line 890  namespace LinuxSampler { namespace sfz {
890                  EGv2Unit eg(this);                  EGv2Unit eg(this);
891                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
892                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
893                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
894                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
895                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
896                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
897                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
898                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
899              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
900                            
901              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
902                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
903                ) {
904                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
905                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
906              }              }
907                
908                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
909                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
910                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
911                }
912                
913                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
914                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
915                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
916                }
917                
918                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
919                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
920                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
921                }
922                
923                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
924                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
925                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
926                }
927          }          }
928                    
929          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 390  namespace LinuxSampler { namespace sfz { Line 933  namespace LinuxSampler { namespace sfz {
933                    
934          // LFO          // LFO
935          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
936              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
937                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
938                    else pRegion->lfos[i].freq = 0;
939                }
940                            
941              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
942                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
943                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
944                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
945                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
946                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);                  LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
947                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
948                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
949                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
950                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
951              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
952                            
953                if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
954                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
955                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
956                }
957                
958              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {              if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
959                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);                  if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
960                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
961              }              }
962                            
963              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
964                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
965                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
966              }              }
967                            
968              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
969                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
970                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
971              }              }
972                            
973              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
974                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
975                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
976              }              }
977          }          }
978                    
979          suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
980            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
981            
982            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
983            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
984            
985            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
986            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
987                    
988          Units.clear();          Units.clear();
989                    
990            Units.add(&suEq1GainOnCC);
991            Units.add(&suEq2GainOnCC);
992            Units.add(&suEq3GainOnCC);
993            Units.add(&suEq1FreqOnCC);
994            Units.add(&suEq2FreqOnCC);
995            Units.add(&suEq3FreqOnCC);
996            Units.add(&suEq1BwOnCC);
997            Units.add(&suEq2BwOnCC);
998            Units.add(&suEq3BwOnCC);
999            
1000            Units.add(&suVolOnCC);
1001            Units.add(&suPitchOnCC);
1002            Units.add(&suCutoffOnCC);
1003            Units.add(&suResOnCC);
1004            
1005          Units.add(&suVolEG);          Units.add(&suVolEG);
1006          Units.add(&suFilEG);          Units.add(&suFilEG);
1007          Units.add(&suPitchEG);          Units.add(&suPitchEG);
1008            
1009            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1010          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
1011          Units.add(&suPitchLFO.suDepthCC);          Units.add(&suPitchLFO.suDepthOnCC);
1012            Units.add(&suPitchLFO.suFadeEG);
1013            
1014            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1015            Units.add(&suAmpLFO.suDepthOnCC);
1016          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
1017            Units.add(&suAmpLFO.suFadeEG);
1018            
1019            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1020            Units.add(&suFilLFO.suDepthOnCC);
1021          Units.add(&suFilLFO);          Units.add(&suFilLFO);
1022            Units.add(&suFilLFO.suFadeEG);
1023                    
1024          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1025              Units.add(EGs[i]);              Units.add(EGs[i]);
1026                Units.add(&(EGs[i]->suAmpOnCC));
1027                Units.add(&(EGs[i]->suVolOnCC));
1028                Units.add(&(EGs[i]->suPitchOnCC));
1029                Units.add(&(EGs[i]->suCutoffOnCC));
1030                Units.add(&(EGs[i]->suResOnCC));
1031                Units.add(&(EGs[i]->suPanOnCC));
1032          }          }
1033                    
1034          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1035                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1036              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1037                Units.add(&(LFOs[i]->suFadeEG));
1038                Units.add(&(LFOs[i]->suVolOnCC));
1039              Units.add(&(LFOs[i]->suPitchOnCC));              Units.add(&(LFOs[i]->suPitchOnCC));
1040                Units.add(&(LFOs[i]->suPanOnCC));
1041                Units.add(&(LFOs[i]->suCutoffOnCC));
1042                Units.add(&(LFOs[i]->suResOnCC));
1043          }          }
1044                    
1045          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1046            Units.add(&suEndpoint.suXFInCC);
1047            Units.add(&suEndpoint.suXFOutCC);
1048            Units.add(&suEndpoint.suPanOnCC);
1049                    
1050          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1051      }      }
# Line 458  namespace LinuxSampler { namespace sfz { Line 1062  namespace LinuxSampler { namespace sfz {
1062          }          }
1063      }      }
1064            
1065        void SfzSignalUnitRack::Reset() {
1066            suEq1GainOnCC.RemoveAllCCs();
1067            suEq2GainOnCC.RemoveAllCCs();
1068            suEq3GainOnCC.RemoveAllCCs();
1069            suEq1FreqOnCC.RemoveAllCCs();
1070            suEq2FreqOnCC.RemoveAllCCs();
1071            suEq3FreqOnCC.RemoveAllCCs();
1072            suEq1BwOnCC.RemoveAllCCs();
1073            suEq2BwOnCC.RemoveAllCCs();
1074            suEq3BwOnCC.RemoveAllCCs();
1075            
1076            suVolOnCC.RemoveAllCCs();
1077            suPitchOnCC.RemoveAllCCs();
1078            suCutoffOnCC.RemoveAllCCs();
1079            suResOnCC.RemoveAllCCs();
1080            suEndpoint.suXFInCC.RemoveAllCCs();
1081            suEndpoint.suXFOutCC.RemoveAllCCs();
1082            suEndpoint.suPanOnCC.RemoveAllCCs();
1083            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1084            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1085            suFilLFO.suDepthOnCC.RemoveAllCCs();
1086            suFilLFO.suFreqOnCC.RemoveAllCCs();
1087            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1088            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1089            
1090            for (int i = 0; i < EGs.capacity(); i++) {
1091                EGs[i]->suAmpOnCC.RemoveAllCCs();
1092                EGs[i]->suVolOnCC.RemoveAllCCs();
1093                EGs[i]->suPitchOnCC.RemoveAllCCs();
1094                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1095                EGs[i]->suResOnCC.RemoveAllCCs();
1096                EGs[i]->suPanOnCC.RemoveAllCCs();
1097            }
1098            
1099            for (int i = 0; i < LFOs.capacity(); i++) {
1100                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1101                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1102                LFOs[i]->suVolOnCC.RemoveAllCCs();
1103                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1104                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1105                LFOs[i]->suPanOnCC.RemoveAllCCs();
1106                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1107                LFOs[i]->suResOnCC.RemoveAllCCs();
1108            }
1109        }
1110        
1111        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1112            if (!pEqSupport->HasSupport()) return;
1113            if (pEqSupport->GetBandCount() < 3) {
1114                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1115                return;
1116            }
1117            
1118            ::sfz::Region* const pRegion = pVoice->pRegion;
1119            
1120            float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1121            pEqSupport->SetGain(0, dB);
1122            
1123            dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1124            pEqSupport->SetGain(1, dB);
1125            
1126            dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1127            pEqSupport->SetGain(2, dB);
1128            
1129            float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1130            pEqSupport->SetFreq(0, freq);
1131            
1132            freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1133            pEqSupport->SetFreq(1, freq);
1134            
1135            freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1136            pEqSupport->SetFreq(2, freq);
1137            
1138            float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1139            pEqSupport->SetBandwidth(0, bw);
1140            
1141            bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1142            pEqSupport->SetBandwidth(1, bw);
1143            
1144            bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1145            pEqSupport->SetBandwidth(2, bw);
1146        }
1147        
1148  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2225  
changed lines
  Added in v.2296

  ViewVC Help
Powered by ViewVC