/[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 2221 by iliev, Thu Jul 28 17:17:42 2011 UTC revision 2297 by iliev, Fri Dec 9 15:04:55 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 XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53            RemoveAllCCs();
54            
55            for (int cc = 0; cc < 128; cc++) {
56                if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57                int i = loCCs[cc];
58                int j = hiCCs[cc];
59                if (j == 0) j = 127;
60                i += j << 8; // workaround to keep both values in the Influence parameter
61                AddCC(cc, i);
62            }
63        }
64        
65        void XFInCCUnit::Calculate() {
66            float l = 1;
67                    
68            RTList<CC>::Iterator ctrl = pCtrls->first();
69            RTList<CC>::Iterator end  = pCtrls->end();
70            for(; ctrl != end; ++ctrl) {
71                float c = 1;
72                int influence = (*ctrl).Influence;
73                int lo = influence & 0xff;
74                int hi = influence >> 8;
75                if ((*ctrl).Value <= lo) {
76                    c = 0;
77                } else if ((*ctrl).Value >= hi) {
78                    c = 1;
79                } else {
80                    float xfVelSize = hi - lo;
81                    float velPos = (*ctrl).Value - lo;
82                    c = velPos / xfVelSize;
83                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84                        c = sin(c * M_PI / 2.0);
85                    }
86                }
87                
88                l *= c;
89            }
90            
91            if (Level != l) {
92                Level = l;
93                if (pListener != NULL) pListener->ValueChanged(this);
94            }
95        }
96        
97        
98        void XFOutCCUnit::Calculate() {
99            float l = 1;
100                    
101            RTList<CC>::Iterator ctrl = pCtrls->first();
102            RTList<CC>::Iterator end  = pCtrls->end();
103            for(; ctrl != end; ++ctrl) {
104                float c = 1;
105                int influence = (*ctrl).Influence;
106                int lo = influence & 0xff;
107                int hi = influence >> 8;
108                if ((*ctrl).Value >= hi) {
109                    c = 0;
110                } else if ((*ctrl).Value <= lo) {
111                    c = 1;
112                } else {
113                    float xfVelSize = hi - lo;
114                    float velPos = (*ctrl).Value - lo;
115                    c = 1.0f - velPos / xfVelSize;
116                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117                        c = sin(c * M_PI / 2.0);
118                    }
119                }
120                
121                l *= c;
122            }
123            
124            if (Level != l) {
125                Level = l;
126                if (pListener != NULL) pListener->ValueChanged(this);
127            }
128        }
129        
130        
131        EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132            : EGUnit< ::LinuxSampler::sfz::EG>(rack), suAmpOnCC(rack), suVolOnCC(rack),
133              suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134        { }
135        
136        void EGv2Unit::Trigger() {
137            egInfo = *pEGInfo;
138            for (int i = 0; i < egInfo.node.size(); i++) {
139                float f = GetInfluence(egInfo.node[i].level_oncc);
140                egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
141                
142                f = GetInfluence(egInfo.node[i].time_oncc);
143                egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144            }
145            EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity);
146        }
147            
148      void EGv1Unit::Trigger() {      
149        void PitchEGUnit::Trigger() {
150          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
151            depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152                    
153          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
154          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
155    
156          // set the delay trigger          // set the delay trigger
157          uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158            delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160            
161            float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162            
163            float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164            attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165            
166            float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167            hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168            
169            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171            
172            float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173            sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174            
175            float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176            release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177                    
178          EG.trigger(uint(pRegion->ampeg_start * 10),          EG.trigger (
179                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          );
                    uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),  
                    GetSampleRate());  
182      }      }
183            
184            
185      void EGv2Unit::Trigger() {      void FilEGUnit::Trigger() {
186          EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);          ::sfz::Region* const pRegion = pVoice->pRegion;
187            depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188            
189            // the length of the decay and release curves are dependent on the velocity
190            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191    
192            // set the delay trigger
193            float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194            delay += GetInfluence(pRegion->fileg_delay_oncc);
195            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196            
197            float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198            
199            float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200            attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201            
202            float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203            hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204            
205            float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206            decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207            
208            float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209            sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210            
211            float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217            );
218      }      }
219            
220            
221      void PitchEGUnit::Trigger() {      void AmpEGUnit::Trigger() {
222          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
         depth = pRegion->pitcheg_depth;  
223                    
224          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
225          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226    
227          // set the delay trigger          // set the delay trigger
228          uiDelayTrigger = (pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229            delay += GetInfluence(pRegion->ampeg_delaycc);
230            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231            
232            float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233            
234            float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235            attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236            
237            float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238            hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239            
240            float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242            
243            float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245                    
246          EG.trigger(uint(pRegion->pitcheg_start * 10),          float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
249                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          EG.trigger (
250                     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,
251                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252                     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;
271                    
272          SignalUnit::Increment();          SignalUnit::Increment();
273                    
274          Level = lfo.render();          Level = pLFO->Render();
275            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276      }      }
277            
278      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 92  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          );          );
309          lfo.update(0);          lfo.update(0);
310      }      }
311            
312        
313        LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314            : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315              lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316              suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317        {
318            lfos.add(&lfo0);
319            lfos.add(&lfo1);
320            lfos.add(&lfo2);
321            lfos.add(&lfo3);
322            lfos.add(&lfo4);
323            lfos.add(&lfo5);
324            lfos.add(&lfo6);
325            lfos.add(&lfo7);
326        }
327        
328      void LFOv2Unit::Trigger() {      void LFOv2Unit::Trigger() {
329          LFOUnit::Trigger();          LFOUnit::Trigger();
330                    
331          lfo.trigger (          if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332              pLfoInfo->freq,          else pLFO = lfos[pLfoInfo->wave];
333            
334            pLFO->Trigger (
335                pLfoInfo->freq + suFreqOnCC.GetLevel(),
336              start_level_mid,              start_level_mid,
337              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
338          );          );
339          lfo.update(0);          pLFO->Update(0);
340            
341            float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
342            if (phase != 0) pLFO->SetPhase(phase);
343      }      }
344            
345      void AmpLFOUnit::Trigger() {      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, Listener* l): CCSignalUnit(rack, l) {
394            pVoice = NULL;
395        }
396        
397        void CCUnit::Trigger() {
398            RTList<CC>::Iterator ctrl = pCtrls->first();
399            RTList<CC>::Iterator end  = pCtrls->end();
400            for(; ctrl != end; ++ctrl) {
401                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402                if ((*ctrl).pSmoother != NULL) {
403                    if ((*ctrl).Step > 0) {
404                        float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405                        (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406                    } else {
407                        (*ctrl).pSmoother->setValue((*ctrl).Value);
408                    }
409                }
410            }
411            CCSignalUnit::Trigger();
412        }
413        
414        void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415            RemoveAllCCs();
416            for (int i = 0; i < 128; i++) {
417                if (cc[i] != 0) AddCC(i, cc[i]);
418            }
419        }
420        
421        void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422            RemoveAllCCs();
423            for (int i = 0; i < 128; i++) {
424                if (cc[i] != 0) AddCC(i, cc[i]);
425            }
426        }
427        
428        void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
429            RemoveAllCCs();
430            for (int i = 0; i < cc.size(); i++) {
431                if (cc[i].Influence != 0) {
432                    short int curve = cc[i].Curve;
433                    if (curve >= GetCurveCount()) curve = -1;
434                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435                }
436            }
437        }
438        
439        void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440            AddCC(Controller, Influence, Curve, NULL, Step);
441        }
442        
443        int CCUnit::GetCurveCount() {
444            return pVoice->pRegion->GetInstrument()->curves.size();
445        }
446        
447        ::sfz::Curve* CCUnit::GetCurve(int idx) {
448            return &pVoice->pRegion->GetInstrument()->curves[idx];
449        }
450        
451        double CCUnit::GetSampleRate() {
452            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
453        }
454        
455        
456        SmoothCCUnit::~SmoothCCUnit() {
457            if (pSmoothers != NULL) delete pSmoothers;
458        }
459        
460        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461            if (Smooth > 0) {
462                if (pSmoothers->poolIsEmpty()) {
463                    std::cerr << "Maximum number of smoothers reached" << std::endl;
464                    return;
465                }
466                Smoother* smoother = &(*(pSmoothers->allocAppend()));
467                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
468                AddCC(Controller, Influence, Curve, smoother, Step);
469            } else {
470                AddCC(Controller, Influence, Curve, NULL, Step);
471            }
472        }
473        
474        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
475            if (pSmoothers != NULL) delete pSmoothers;
476            pSmoothers = new RTList<Smoother>(pSmootherPool);
477        }
478        
479        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
480            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
481            InitSmoothers(pSmootherPool);
482        }
483    
484    
485      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
487        {
488                    
489      }      }
490            
491        float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<float> >& cc) {
492            float f = 0;
493            for (int i = 0; i < 128; i++) {
494                if (cc[i]) {
495                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
496                }
497            }
498            return f;
499        }
500        
501        float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<int> >& cc) {
502            float f = 0;
503            for (int i = 0; i < 128; i++) {
504                if (cc[i]) {
505                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
506                }
507            }
508            return f;
509        }
510        
511      SfzSignalUnitRack* const EndpointUnit::GetRack() {      SfzSignalUnitRack* const EndpointUnit::GetRack() {
512          return static_cast<SfzSignalUnitRack* const>(pRack);          return static_cast<SfzSignalUnitRack* const>(pRack);
513      }      }
514            
515      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
516            uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
517            if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
518            
519            if (pVoice->pRegion->delay) {
520                /* here we use the device sample rate */
521                uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
522            }
523            
524            if (pVoice->pRegion->delay_random) {
525                float r = pVoice->GetEngine()->Random();
526                uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
527            }
528            
529            uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
530            
531            float xfInVelCoeff = 1;
532            
533            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
534                xfInVelCoeff = 0;
535            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
536                xfInVelCoeff = 1;
537            } else {
538                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
539                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
540                xfInVelCoeff = velPos / xfVelSize;
541                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
542                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
543                }
544            }
545            
546            float xfOutVelCoeff = 1;
547            
548            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
549                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
550            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
551                xfOutVelCoeff = 1;
552            } else {
553                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
554                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
555                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
556                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
557                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
558                }
559            }
560                    
561            float xfInKeyCoeff = 1;
562            
563            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
564                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
565            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
566                xfInKeyCoeff = 1;
567            } else {
568                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
569                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
570                xfInKeyCoeff = keyPos / xfKeySize;
571                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
572                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
573                }
574            }
575            
576            float xfOutKeyCoeff = 1;
577            
578            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
579                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
580            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
581                xfOutKeyCoeff = 1;
582            } else {
583                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
584                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
585                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
586                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
587                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
588                }
589            }
590            
591            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
592            
593            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
594            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
595            
596            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
597            
598            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
599      }      }
600            
601      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
602            if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
603                return false; // The key was released before the delay end, so the voice won't play at all.
604            }
605            
606          if (GetRack()->suVolEG.Active()) return true;          if (GetRack()->suVolEG.Active()) return true;
607                    
608          bool b = false;          bool b = false;
# Line 174  namespace LinuxSampler { namespace sfz { Line 619  namespace LinuxSampler { namespace sfz {
619          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
620              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
621              if (!eg->Active()) continue;              if (!eg->Active()) continue;
622              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
623                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
624                if (dB < -144) dB = eg->pEGInfo->volume;
625                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
626                
627                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
628                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
629                
630                if (dB >= -144) {
631                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
632                    amp *= ToRatio(dB * 10.0);
633                }
634                
635                vol += amp * eg->GetLevel();
636          }          }
637                    
638          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
639          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
640            float f = u2->Active() ? u2->GetLevel() : 0;
641            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
642            
643            vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
644            
645            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
646                LFOv2Unit* lfo = GetRack()->volLFOs[i];
647                if (!lfo->Active()) continue;
648                
649                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
650                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
651            }
652                    
653          return vol;          if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
654            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
655            return vol * xfCoeff;
656      }      }
657            
658      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
659          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660                    
661          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
662          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663            float f = u1->Active() ? u1->GetLevel() : 0;
664            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
665            
666            FilEGUnit* u2 = &(GetRack()->suFilEG);
667            val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
668            
669            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
670                EGv2Unit* eg = GetRack()->filEGs[i];
671                if (!eg->Active()) continue;
672                
673                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
674                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
675                val *= RTMath::CentsToFreqRatioUnlimited(f);
676            }
677                    
678          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
679              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
680              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
681                            
682              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
683                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
684              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
685          }          }
686                    
687          return val;          return val;
688      }      }
689            
690        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691            cutoff *= GetFilterCutoff();
692            float maxCutoff = 0.49 * pVoice->GetSampleRate();
693            return cutoff > maxCutoff ? maxCutoff : cutoff;
694        }
695        
696      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
697          double p;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698            
699          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
700          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701            
702            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
703                EGv2Unit* eg = GetRack()->pitchEGs[i];
704                if (!eg->Active()) continue;
705                
706                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
707                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
708            }
709                    
710          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
711          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->pLfoInfo->pitch) : 1;          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
712            float f = u3->Active() ? u3->GetLevel() : 0;
713            p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
714            
715            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
716                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
717                if (!lfo->Active()) continue;
718                
719                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
720                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
721            }
722                    
723          return p;          return p * pitchVeltrackRatio;
724      }      }
725            
726      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
727           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
728            
729            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
730                EGv2Unit* eg = GetRack()->resEGs[i];
731                if (!eg->Active()) continue;
732                
733                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
734                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
735            }
736                    
737          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
738              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
739              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
740                            
741              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
742                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
743          }          }
744                    
745          return val;          return val;
746      }      }
747            
748      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
749          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
750            
751            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
752                EGv2Unit* eg = GetRack()->panEGs[i];
753                if (!eg->Active()) continue;
754                
755                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
756                
757                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
758                    uint8_t val = eg->GetLevel() * 127;
759                    if (val > 127) val = 127;
760                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
761                } else {
762                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
763                }
764            }
765                    
766          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
767              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
768              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
769                            
770              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
771                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772          }          }
773                    
774          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 242  namespace LinuxSampler { namespace sfz { Line 779  namespace LinuxSampler { namespace sfz {
779            
780            
781      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
782          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
783          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
784            suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
785            suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
786            suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
787            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
788          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
789          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
790            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
791      {      {
792          suEndpoint.pVoice = suVolEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
793            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
794          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
795                    
796            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
797            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
798            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
799            
800            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
801            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
802            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
803            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
804            
805          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
806              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
807              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
808                EGs[i]->suAmpOnCC.pVoice = voice;
809                EGs[i]->suVolOnCC.pVoice = voice;
810                EGs[i]->suPitchOnCC.pVoice = voice;
811                EGs[i]->suCutoffOnCC.pVoice = voice;
812                EGs[i]->suResOnCC.pVoice = voice;
813                EGs[i]->suPanOnCC.pVoice = voice;
814          }          }
815                    
816          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
817              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
818              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
819                LFOs[i]->suDepthOnCC.pVoice = voice;
820                LFOs[i]->suFreqOnCC.pVoice = voice;
821                LFOs[i]->suFadeEG.pVoice = voice;
822                LFOs[i]->suVolOnCC.pVoice = voice;
823                LFOs[i]->suPitchOnCC.pVoice = voice;
824                LFOs[i]->suFreqOnCC.pVoice = voice;
825                LFOs[i]->suPanOnCC.pVoice = voice;
826                LFOs[i]->suCutoffOnCC.pVoice = voice;
827                LFOs[i]->suResOnCC.pVoice = voice;
828          }          }
829      }      }
830            
# Line 271  namespace LinuxSampler { namespace sfz { Line 838  namespace LinuxSampler { namespace sfz {
838          }          }
839      }      }
840            
841        void SfzSignalUnitRack::InitRTLists() {
842            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
843            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
844            
845            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
846            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
847            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
848            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
849            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
850            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
851            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
852            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
853            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
854            
855            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
856            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
857            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
858            suResOnCC.InitCCList(pCCPool, pSmootherPool);
859            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
860            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
861            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
862            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
863            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
864            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
865            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
866            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
867            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
868            
869            for (int i = 0; i < EGs.capacity(); i++) {
870                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
871                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
874                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
875                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
876            }
877            
878            for (int i = 0; i < LFOs.capacity(); i++) {
879                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
880                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
881                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
882                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
883                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
884                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
885                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
886                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
887            }
888        }
889        
890      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
891          EGs.clear();          EGs.clear();
892          volEGs.clear();          volEGs.clear();
893          pitchEGs.clear();          pitchEGs.clear();
894            filEGs.clear();
895            resEGs.clear();
896            panEGs.clear();
897                    
898          LFOs.clear();          LFOs.clear();
899            volLFOs.clear();
900            pitchLFOs.clear();
901          filLFOs.clear();          filLFOs.clear();
902          resLFOs.clear();          resLFOs.clear();
903          panLFOs.clear();          panLFOs.clear();
904                    
905          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
906                    
907            suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
908            suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
909            suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
910            suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
911            suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
912            suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
913            suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
914            suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
915            suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
916            
917            bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
918                     suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
919            
920            suVolOnCC.SetCCs(pRegion->volume_oncc);
921            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
922            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
923            suResOnCC.SetCCs(pRegion->resonance_oncc);
924            
925          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
926              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
927                            
# Line 290  namespace LinuxSampler { namespace sfz { Line 929  namespace LinuxSampler { namespace sfz {
929                  EGv2Unit eg(this);                  EGv2Unit eg(this);
930                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
931                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
932                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
933                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
934                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
935                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
936                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
937                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
938              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
939                            
940              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
941                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
942                ) {
943                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
944                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
945              }              }
946                
947                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
948                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
949                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
950                }
951                
952                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
953                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
954                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
955                }
956                
957                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
958                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
959                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
960                }
961                
962                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
963                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
964                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
965                }
966          }          }
967                    
968          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 305  namespace LinuxSampler { namespace sfz { Line 972  namespace LinuxSampler { namespace sfz {
972                    
973          // LFO          // LFO
974          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
975              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
976                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
977                    else pRegion->lfos[i].freq = 0;
978                }
979                            
980              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
981                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
982                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
983                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
984                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
985                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
986                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
987                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
988                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
989                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
990              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
991                            
992              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
993                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
994                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
995                }
996                
997                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
998                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
999                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1000                }
1001                
1002                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1003                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1004                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1005              }              }
1006                            
1007              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1008                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1009                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1010              }              }
1011                            
1012              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1013                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1014                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1015              }              }
1016          }          }
1017                    
1018            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1019            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1020            
1021            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1022            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1023            
1024            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1025            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1026            
1027          Units.clear();          Units.clear();
1028                    
1029            Units.add(&suEq1GainOnCC);
1030            Units.add(&suEq2GainOnCC);
1031            Units.add(&suEq3GainOnCC);
1032            Units.add(&suEq1FreqOnCC);
1033            Units.add(&suEq2FreqOnCC);
1034            Units.add(&suEq3FreqOnCC);
1035            Units.add(&suEq1BwOnCC);
1036            Units.add(&suEq2BwOnCC);
1037            Units.add(&suEq3BwOnCC);
1038            
1039            Units.add(&suVolOnCC);
1040            Units.add(&suPitchOnCC);
1041            Units.add(&suCutoffOnCC);
1042            Units.add(&suResOnCC);
1043            
1044          Units.add(&suVolEG);          Units.add(&suVolEG);
1045            Units.add(&suFilEG);
1046          Units.add(&suPitchEG);          Units.add(&suPitchEG);
1047            
1048            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1049          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
1050            Units.add(&suPitchLFO.suDepthOnCC);
1051            Units.add(&suPitchLFO.suFadeEG);
1052            
1053            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1054            Units.add(&suAmpLFO.suDepthOnCC);
1055          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
1056            Units.add(&suAmpLFO.suFadeEG);
1057            
1058            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1059            Units.add(&suFilLFO.suDepthOnCC);
1060          Units.add(&suFilLFO);          Units.add(&suFilLFO);
1061            Units.add(&suFilLFO.suFadeEG);
1062                    
1063          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
1064              Units.add(EGs[i]);              Units.add(EGs[i]);
1065                Units.add(&(EGs[i]->suAmpOnCC));
1066                Units.add(&(EGs[i]->suVolOnCC));
1067                Units.add(&(EGs[i]->suPitchOnCC));
1068                Units.add(&(EGs[i]->suCutoffOnCC));
1069                Units.add(&(EGs[i]->suResOnCC));
1070                Units.add(&(EGs[i]->suPanOnCC));
1071          }          }
1072                    
1073          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
1074                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1075              Units.add(LFOs[i]);              Units.add(LFOs[i]);
1076                Units.add(&(LFOs[i]->suFadeEG));
1077                Units.add(&(LFOs[i]->suVolOnCC));
1078                Units.add(&(LFOs[i]->suPitchOnCC));
1079                Units.add(&(LFOs[i]->suPanOnCC));
1080                Units.add(&(LFOs[i]->suCutoffOnCC));
1081                Units.add(&(LFOs[i]->suResOnCC));
1082          }          }
1083                    
1084          Units.add(&suEndpoint);          Units.add(&suEndpoint);
1085            Units.add(&suEndpoint.suXFInCC);
1086            Units.add(&suEndpoint.suXFOutCC);
1087            Units.add(&suEndpoint.suPanOnCC);
1088                    
1089          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1090      }      }
# Line 362  namespace LinuxSampler { namespace sfz { Line 1101  namespace LinuxSampler { namespace sfz {
1101          }          }
1102      }      }
1103            
1104        void SfzSignalUnitRack::Reset() {
1105            suEq1GainOnCC.RemoveAllCCs();
1106            suEq2GainOnCC.RemoveAllCCs();
1107            suEq3GainOnCC.RemoveAllCCs();
1108            suEq1FreqOnCC.RemoveAllCCs();
1109            suEq2FreqOnCC.RemoveAllCCs();
1110            suEq3FreqOnCC.RemoveAllCCs();
1111            suEq1BwOnCC.RemoveAllCCs();
1112            suEq2BwOnCC.RemoveAllCCs();
1113            suEq3BwOnCC.RemoveAllCCs();
1114            
1115            suVolOnCC.RemoveAllCCs();
1116            suPitchOnCC.RemoveAllCCs();
1117            suCutoffOnCC.RemoveAllCCs();
1118            suResOnCC.RemoveAllCCs();
1119            suEndpoint.suXFInCC.RemoveAllCCs();
1120            suEndpoint.suXFOutCC.RemoveAllCCs();
1121            suEndpoint.suPanOnCC.RemoveAllCCs();
1122            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1123            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1124            suFilLFO.suDepthOnCC.RemoveAllCCs();
1125            suFilLFO.suFreqOnCC.RemoveAllCCs();
1126            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1127            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1128            
1129            for (int i = 0; i < EGs.capacity(); i++) {
1130                EGs[i]->suAmpOnCC.RemoveAllCCs();
1131                EGs[i]->suVolOnCC.RemoveAllCCs();
1132                EGs[i]->suPitchOnCC.RemoveAllCCs();
1133                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1134                EGs[i]->suResOnCC.RemoveAllCCs();
1135                EGs[i]->suPanOnCC.RemoveAllCCs();
1136            }
1137            
1138            for (int i = 0; i < LFOs.capacity(); i++) {
1139                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1140                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1141                LFOs[i]->suVolOnCC.RemoveAllCCs();
1142                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1143                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1144                LFOs[i]->suPanOnCC.RemoveAllCCs();
1145                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1146                LFOs[i]->suResOnCC.RemoveAllCCs();
1147            }
1148        }
1149        
1150        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1151            if (!pEqSupport->HasSupport()) return;
1152            if (pEqSupport->GetBandCount() < 3) {
1153                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1154                return;
1155            }
1156            
1157            ::sfz::Region* const pRegion = pVoice->pRegion;
1158            
1159            float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1160            pEqSupport->SetGain(0, dB);
1161            
1162            dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1163            pEqSupport->SetGain(1, dB);
1164            
1165            dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1166            pEqSupport->SetGain(2, dB);
1167            
1168            float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1169            pEqSupport->SetFreq(0, freq);
1170            
1171            freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1172            pEqSupport->SetFreq(1, freq);
1173            
1174            freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1175            pEqSupport->SetFreq(2, freq);
1176            
1177            float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1178            pEqSupport->SetBandwidth(0, bw);
1179            
1180            bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1181            pEqSupport->SetBandwidth(1, bw);
1182            
1183            bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1184            pEqSupport->SetBandwidth(2, bw);
1185        }
1186        
1187  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2221  
changed lines
  Added in v.2297

  ViewVC Help
Powered by ViewVC