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

Legend:
Removed from v.2218  
changed lines
  Added in v.3561

  ViewVC Help
Powered by ViewVC