/[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 2220 by iliev, Thu Jul 28 15:47:51 2011 UTC revision 2249 by iliev, Fri Aug 19 18:29:29 2011 UTC
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "SfzSignalUnitRack.h"  #include "SfzSignalUnitRack.h"
24  #include "Voice.h"  #include "Engine.h"
25    
26    #define _200TH_ROOT_OF_10 1.011579454259899
27    
28  namespace LinuxSampler { namespace sfz {  namespace LinuxSampler { namespace sfz {
29            
30        double ToRatio(int Centibels) {
31            if (Centibels == 0) return 1.0;
32            return pow(_200TH_ROOT_OF_10, Centibels);
33        }
34        
35      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {      SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36                    
37      }      }
# Line 33  namespace LinuxSampler { namespace sfz { Line 40  namespace LinuxSampler { namespace sfz {
40          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41      }      }
42            
43        float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44            float f = 0;
45            for (int i = 0; i < cc.size(); i++) {
46                int val = pVoice->GetControllerValue(cc[i].Controller);
47                f += (val / 127.0f) * cc[i].Influence;
48            }
49            return f;
50        }
51        
52        void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53            RemoveAllCCs();
54            
55            for (int cc = 0; cc < 128; cc++) {
56                if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57                int i = loCCs[cc];
58                int j = hiCCs[cc];
59                if (j == 0) j = 127;
60                i += j << 8; // workaround to keep both values in the Influence parameter
61                AddCC(cc, i);
62            }
63        }
64        
65        void XFInCCUnit::Calculate() {
66            float l = 1;
67                    
68            RTList<CC>::Iterator ctrl = pCtrls->first();
69            RTList<CC>::Iterator end  = pCtrls->end();
70            for(; ctrl != end; ++ctrl) {
71                float c = 1;
72                int influence = (*ctrl).Influence;
73                int lo = influence & 0xff;
74                int hi = influence >> 8;
75                if ((*ctrl).Value <= lo) {
76                    c = 0;
77                } else if ((*ctrl).Value >= hi) {
78                    c = 1;
79                } else {
80                    float xfVelSize = hi - lo;
81                    float velPos = (*ctrl).Value - lo;
82                    c = velPos / xfVelSize;
83                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84                        c = sin(c * M_PI / 2.0);
85                    }
86                }
87                
88                l *= c;
89            }
90            
91            if (Level != l) {
92                Level = l;
93                if (pListener != NULL) pListener->ValueChanged(this);
94            }
95        }
96        
97        
98        void XFOutCCUnit::Calculate() {
99            float l = 1;
100                    
101            RTList<CC>::Iterator ctrl = pCtrls->first();
102            RTList<CC>::Iterator end  = pCtrls->end();
103            for(; ctrl != end; ++ctrl) {
104                float c = 1;
105                int influence = (*ctrl).Influence;
106                int lo = influence & 0xff;
107                int hi = influence >> 8;
108                if ((*ctrl).Value >= hi) {
109                    c = 0;
110                } else if ((*ctrl).Value <= lo) {
111                    c = 1;
112                } else {
113                    float xfVelSize = hi - lo;
114                    float velPos = (*ctrl).Value - lo;
115                    c = 1.0f - velPos / xfVelSize;
116                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117                        c = sin(c * M_PI / 2.0);
118                    }
119                }
120                
121                l *= c;
122            }
123            
124            if (Level != l) {
125                Level = l;
126                if (pListener != NULL) pListener->ValueChanged(this);
127            }
128        }
129        
130        
131        EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132            : EGUnit< ::LinuxSampler::sfz::EG>(rack), 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 EGv1Unit::Trigger() {      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          EG.trigger(uint(pRegion->ampeg_start * 10),          float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),          release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),          
178                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          EG.trigger (
179                     uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                     std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181                     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          EG.trigger(uint(pRegion->pitcheg_start * 10),          float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
240                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
243                     GetSampleRate());          float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245            
246            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248            
249            EG.trigger (
250                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252            );
253      }      }
254            
255        
256        LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257            : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258              suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259        { }
260        
261        LFOUnit::LFOUnit(const LFOUnit& Unit)
262            : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263              suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265        {
266            Copy(Unit);
267        }
268    
269      void LFOUnit::Increment() {      void LFOUnit::Increment() {
270          if (DelayStage()) return;          if (DelayStage()) return;
271                    
272          SignalUnit::Increment();          SignalUnit::Increment();
273                    
274          Level = lfo.render();          Level = pLFO->Render();
275            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276      }      }
277            
278      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 91  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 LFOv2Unit::Trigger() {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
297        }
298        
299        
300        void LFOv1Unit::Trigger() {
301          LFOUnit::Trigger();          LFOUnit::Trigger();
302                    
303          lfo.trigger (          lfo.trigger (
304              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
305              start_level_mid,              start_level_mid,
306              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
307          );          );
308          lfo.update(0);          lfo.update(0);
309      }      }
310        
311        
312        LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
313            : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
314              lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
315              suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
316        {
317            lfos.add(&lfo0);
318            lfos.add(&lfo1);
319            lfos.add(&lfo2);
320            lfos.add(&lfo3);
321            lfos.add(&lfo4);
322            lfos.add(&lfo5);
323            lfos.add(&lfo6);
324            lfos.add(&lfo7);
325        }
326        
327        void LFOv2Unit::Trigger() {
328            LFOUnit::Trigger();
329            
330            if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
331            else pLFO = lfos[pLfoInfo->wave];
332            
333            pLFO->Trigger (
334                pLfoInfo->freq + suFreqOnCC.GetLevel(),
335                start_level_mid,
336                1, 0, false, GetSampleRate()
337            );
338            pLFO->Update(0);
339            
340            float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
341            if (phase != 0) pLFO->SetPhase(phase);
342        }
343        
344        void AmpLFOUnit::Trigger() {
345            ::sfz::Region* const pRegion = pVoice->pRegion;
346            pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
347            pLfoInfo->freq   = pRegion->amplfo_freq;
348            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
349            pLfoInfo->volume = pRegion->amplfo_depth;
350            
351            LFOv1Unit::Trigger();
352        }
353        
354        void PitchLFOUnit::Trigger() {
355            ::sfz::Region* const pRegion = pVoice->pRegion;
356            pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
357            pLfoInfo->freq  = pRegion->pitchlfo_freq;
358            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
359            pLfoInfo->pitch = pRegion->pitchlfo_depth;
360            
361            LFOv1Unit::Trigger();
362        }
363        
364        void FilLFOUnit::Trigger() {
365            ::sfz::Region* const pRegion = pVoice->pRegion;
366            pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
367            pLfoInfo->freq   = pRegion->fillfo_freq;
368            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
369            pLfoInfo->cutoff = pRegion->fillfo_depth;
370            
371            LFOv1Unit::Trigger();
372        }
373        
374        CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
375            pVoice = NULL;
376        }
377        
378        void CCUnit::Trigger() {
379            RTList<CC>::Iterator ctrl = pCtrls->first();
380            RTList<CC>::Iterator end  = pCtrls->end();
381            for(; ctrl != end; ++ctrl) {
382                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
383                if ((*ctrl).pSmoother != NULL) (*ctrl).pSmoother->setValue((*ctrl).Value);
384            }
385            CCSignalUnit::Trigger();
386        }
387        
388        void CCUnit::SetCCs(::sfz::Array<int>& cc) {
389            RemoveAllCCs();
390            for (int i = 0; i < 128; i++) {
391                if (cc[i] != 0) AddCC(i, cc[i]);
392            }
393        }
394        
395        void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
396            RemoveAllCCs();
397            for (int i = 0; i < cc.size(); i++) {
398                if (cc[i].Influence != 0) {
399                    short int curve = cc[i].Curve;
400                    if (curve >= GetCurveCount()) curve = -1;
401                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
402                }
403            }
404        }
405        
406        void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
407            AddCC(Controller, Influence, Curve);
408        }
409        
410        int CCUnit::GetCurveCount() {
411            return pVoice->pRegion->GetInstrument()->curves.size();
412        }
413        
414        ::sfz::Curve* CCUnit::GetCurve(int idx) {
415            return &pVoice->pRegion->GetInstrument()->curves[idx];
416        }
417        
418        double CCUnit::GetSampleRate() {
419            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
420        }
421        
422        
423        SmoothCCUnit::~SmoothCCUnit() {
424            if (pSmoothers != NULL) delete pSmoothers;
425        }
426        
427        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
428            if (Smooth > 0) {
429                if (pSmoothers->poolIsEmpty()) {
430                    std::cerr << "Maximum number of smoothers reached" << std::endl;
431                    return;
432                }
433                Smoother* smoother = &(*(pSmoothers->allocAppend()));
434                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
435                AddCC(Controller, Influence, Curve, smoother);
436            } else {
437                AddCC(Controller, Influence, Curve);
438            }
439        }
440        
441        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
442            if (pSmoothers != NULL) delete pSmoothers;
443            pSmoothers = new RTList<Smoother>(pSmootherPool);
444        }
445        
446        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
447            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
448            InitSmoothers(pSmootherPool);
449        }
450    
451    
452      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
453            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
454        {
455                    
456      }      }
457            
# Line 115  namespace LinuxSampler { namespace sfz { Line 460  namespace LinuxSampler { namespace sfz {
460      }      }
461            
462      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
463            float xfInVelCoeff = 1;
464            
465            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
466                xfInVelCoeff = 0;
467            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
468                xfInVelCoeff = 1;
469            } else {
470                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
471                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
472                xfInVelCoeff = velPos / xfVelSize;
473                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
474                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
475                }
476            }
477            
478            float xfOutVelCoeff = 1;
479            
480            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
481                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
482            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
483                xfOutVelCoeff = 1;
484            } else {
485                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
486                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
487                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
488                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
489                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
490                }
491            }
492            
493            float xfInKeyCoeff = 1;
494            
495            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
496                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
497            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
498                xfInKeyCoeff = 1;
499            } else {
500                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
501                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
502                xfInKeyCoeff = keyPos / xfKeySize;
503                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
504                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
505                }
506            }
507            
508            float xfOutKeyCoeff = 1;
509            
510            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
511                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
512            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
513                xfOutKeyCoeff = 1;
514            } else {
515                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
516                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
517                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
518                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
519                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
520                }
521            }
522            
523            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
524            
525            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
526            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
527            
528            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
529                    
530            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
531      }      }
532            
533      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 135  namespace LinuxSampler { namespace sfz { Line 547  namespace LinuxSampler { namespace sfz {
547          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
548              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
549              if (!eg->Active()) continue;              if (!eg->Active()) continue;
550              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
551                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
552                if (dB < -144) dB = eg->pEGInfo->volume;
553                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
554                
555                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
556                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
557                
558                if (dB >= -144) {
559                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
560                    amp *= ToRatio(dB * 10.0);
561                }
562                
563                vol += amp * eg->GetLevel();
564            }
565            
566            AmpLFOUnit* u = &(GetRack()->suAmpLFO);
567            CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
568            float f = u2->Active() ? u2->GetLevel() : 0;
569            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
570            
571            vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
572            
573            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
574                LFOv2Unit* lfo = GetRack()->volLFOs[i];
575                if (!lfo->Active()) continue;
576                
577                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
578                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
579          }          }
580                    
581          return vol;          if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
582            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
583            return vol * xfCoeff;
584      }      }
585            
586      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
587          float val = 1;          float val;
588            
589            FilLFOUnit* u = &(GetRack()->suFilLFO);
590            CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
591            float f = u1->Active() ? u1->GetLevel() : 0;
592            val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
593            
594            FilEGUnit* u2 = &(GetRack()->suFilEG);
595            val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
596            
597            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
598                EGv2Unit* eg = GetRack()->filEGs[i];
599                if (!eg->Active()) continue;
600                
601                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
602                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
603                val *= RTMath::CentsToFreqRatioUnlimited(f);
604            }
605                    
606          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
607              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
608              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
609                            
610              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
611                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
612              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
613          }          }
614                    
615          return val;          return val;
616      }      }
617            
618        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
619             cutoff *= GetFilterCutoff();
620             float maxCutoff = 0.49 * pVoice->GetSampleRate();
621             return cutoff > maxCutoff ? maxCutoff : cutoff;
622        }
623        
624      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
625            double p;
626          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
627          double pitchEg = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
628          return pitchEg;          
629            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
630                EGv2Unit* eg = GetRack()->pitchEGs[i];
631                if (!eg->Active()) continue;
632                
633                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
634                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
635            }
636            
637            PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
638            CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
639            float f = u3->Active() ? u3->GetLevel() : 0;
640            p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
641            
642            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
643                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
644                if (!lfo->Active()) continue;
645                
646                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
647                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
648            }
649            
650            return p * pitchVeltrackRatio;
651      }      }
652            
653      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
654           float val = 0;           float val = 0;
655                    
656            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
657                EGv2Unit* eg = GetRack()->resEGs[i];
658                if (!eg->Active()) continue;
659                
660                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
661                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
662            }
663            
664          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
665              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
666              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
667                            
668              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
669                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
670          }          }
671                    
672          return val;          return val;
673      }      }
674            
675      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
676          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
677            
678            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
679                EGv2Unit* eg = GetRack()->panEGs[i];
680                if (!eg->Active()) continue;
681                
682                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
683                
684                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
685                    uint8_t val = eg->GetLevel() * 127;
686                    if (val > 127) val = 127;
687                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
688                } else {
689                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
690                }
691            }
692                    
693          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
694              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
695              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
696                            
697              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
698                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
699          }          }
700                    
701          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 192  namespace LinuxSampler { namespace sfz { Line 706  namespace LinuxSampler { namespace sfz {
706            
707            
708      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
709          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
710          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
711          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
712            LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
713            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
714      {      {
715          suEndpoint.pVoice = suVolEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
716            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
717            suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
718            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
719            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
720            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
721                    
722          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
723              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
724              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
725                EGs[i]->suAmpOnCC.pVoice = voice;
726                EGs[i]->suVolOnCC.pVoice = voice;
727                EGs[i]->suPitchOnCC.pVoice = voice;
728                EGs[i]->suCutoffOnCC.pVoice = voice;
729                EGs[i]->suResOnCC.pVoice = voice;
730                EGs[i]->suPanOnCC.pVoice = voice;
731          }          }
732                    
733          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
734              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
735              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
736                LFOs[i]->suDepthOnCC.pVoice = voice;
737                LFOs[i]->suFreqOnCC.pVoice = voice;
738                LFOs[i]->suFadeEG.pVoice = voice;
739                LFOs[i]->suVolOnCC.pVoice = voice;
740                LFOs[i]->suPitchOnCC.pVoice = voice;
741                LFOs[i]->suFreqOnCC.pVoice = voice;
742                LFOs[i]->suPanOnCC.pVoice = voice;
743                LFOs[i]->suCutoffOnCC.pVoice = voice;
744                LFOs[i]->suResOnCC.pVoice = voice;
745          }          }
746      }      }
747            
# Line 219  namespace LinuxSampler { namespace sfz { Line 755  namespace LinuxSampler { namespace sfz {
755          }          }
756      }      }
757            
758        void SfzSignalUnitRack::InitRTLists() {
759            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
760            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
761            
762            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
763            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
764            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
765            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
766            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
767            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
768            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
769            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
770            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
771            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
772            
773            for (int i = 0; i < EGs.capacity(); i++) {
774                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
775                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
776                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
777                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
778                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
779                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
780            }
781            
782            for (int i = 0; i < LFOs.capacity(); i++) {
783                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
784                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
785                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
786                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
787                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
788                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
789                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
790                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
791            }
792        }
793        
794      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
795          EGs.clear();          EGs.clear();
796          volEGs.clear();          volEGs.clear();
797          pitchEGs.clear();          pitchEGs.clear();
798            filEGs.clear();
799            resEGs.clear();
800            panEGs.clear();
801                    
802          LFOs.clear();          LFOs.clear();
803            volLFOs.clear();
804            pitchLFOs.clear();
805          filLFOs.clear();          filLFOs.clear();
806          resLFOs.clear();          resLFOs.clear();
807          panLFOs.clear();          panLFOs.clear();
808                    
809          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
810                    
811            suVolOnCC.SetCCs(pRegion->volume_oncc);
812            
813          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
814              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
815                            
# Line 238  namespace LinuxSampler { namespace sfz { Line 817  namespace LinuxSampler { namespace sfz {
817                  EGv2Unit eg(this);                  EGv2Unit eg(this);
818                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
819                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
820                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
821                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
822                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
823                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
824                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
825                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
826              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
827                            
828              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
829                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
830                ) {
831                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
832                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
833              }              }
834                
835                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
836                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
837                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
838                }
839                
840                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
841                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
842                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
843                }
844                
845                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
846                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
847                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
848                }
849                
850                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
851                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
852                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
853                }
854          }          }
855                    
856          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 259  namespace LinuxSampler { namespace sfz { Line 866  namespace LinuxSampler { namespace sfz {
866                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
867                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
868                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
869                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
870                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
871                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
872                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
873                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
874                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
875              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
876                            
877              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
878                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
879                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
880                }
881                
882                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
883                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
884                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
885                }
886                
887                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
888                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
889                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
890              }              }
891                            
892              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
893                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
894                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
895              }              }
896                            
897              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
898                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
899                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
900              }              }
901          }          }
902                    
903            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
904            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
905            
906            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
907            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
908            
909            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
910            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
911            
912          Units.clear();          Units.clear();
913                    
914            Units.add(&suVolOnCC);
915            
916          Units.add(&suVolEG);          Units.add(&suVolEG);
917            Units.add(&suFilEG);
918          Units.add(&suPitchEG);          Units.add(&suPitchEG);
919                    
920            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
921            Units.add(&suPitchLFO);
922            Units.add(&suPitchLFO.suDepthOnCC);
923            Units.add(&suPitchLFO.suFadeEG);
924            
925            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
926            Units.add(&suAmpLFO.suDepthOnCC);
927            Units.add(&suAmpLFO);
928            Units.add(&suAmpLFO.suFadeEG);
929            
930            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
931            Units.add(&suFilLFO.suDepthOnCC);
932            Units.add(&suFilLFO);
933            Units.add(&suFilLFO.suFadeEG);
934            
935          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
936              Units.add(EGs[i]);              Units.add(EGs[i]);
937                Units.add(&(EGs[i]->suAmpOnCC));
938                Units.add(&(EGs[i]->suVolOnCC));
939                Units.add(&(EGs[i]->suPitchOnCC));
940                Units.add(&(EGs[i]->suCutoffOnCC));
941                Units.add(&(EGs[i]->suResOnCC));
942                Units.add(&(EGs[i]->suPanOnCC));
943          }          }
944                    
945          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
946                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
947              Units.add(LFOs[i]);              Units.add(LFOs[i]);
948                Units.add(&(LFOs[i]->suFadeEG));
949                Units.add(&(LFOs[i]->suVolOnCC));
950                Units.add(&(LFOs[i]->suPitchOnCC));
951                Units.add(&(LFOs[i]->suPanOnCC));
952                Units.add(&(LFOs[i]->suCutoffOnCC));
953                Units.add(&(LFOs[i]->suResOnCC));
954          }          }
955                    
956          Units.add(&suEndpoint);          Units.add(&suEndpoint);
957            Units.add(&suEndpoint.suXFInCC);
958            Units.add(&suEndpoint.suXFOutCC);
959            Units.add(&suEndpoint.suPanOnCC);
960                    
961          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
962      }      }
# Line 307  namespace LinuxSampler { namespace sfz { Line 973  namespace LinuxSampler { namespace sfz {
973          }          }
974      }      }
975            
976        void SfzSignalUnitRack::Reset() {
977            suVolOnCC.RemoveAllCCs();
978            suEndpoint.suXFInCC.RemoveAllCCs();
979            suEndpoint.suXFOutCC.RemoveAllCCs();
980            suEndpoint.suPanOnCC.RemoveAllCCs();
981            suPitchLFO.suDepthOnCC.RemoveAllCCs();
982            suPitchLFO.suFreqOnCC.RemoveAllCCs();
983            suFilLFO.suDepthOnCC.RemoveAllCCs();
984            suFilLFO.suFreqOnCC.RemoveAllCCs();
985            suAmpLFO.suDepthOnCC.RemoveAllCCs();
986            suAmpLFO.suFreqOnCC.RemoveAllCCs();
987            
988            for (int i = 0; i < EGs.capacity(); i++) {
989                EGs[i]->suAmpOnCC.RemoveAllCCs();
990                EGs[i]->suVolOnCC.RemoveAllCCs();
991                EGs[i]->suPitchOnCC.RemoveAllCCs();
992                EGs[i]->suCutoffOnCC.RemoveAllCCs();
993                EGs[i]->suResOnCC.RemoveAllCCs();
994                EGs[i]->suPanOnCC.RemoveAllCCs();
995            }
996            
997            for (int i = 0; i < LFOs.capacity(); i++) {
998                LFOs[i]->suDepthOnCC.RemoveAllCCs();
999                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1000                LFOs[i]->suVolOnCC.RemoveAllCCs();
1001                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1002                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1003                LFOs[i]->suPanOnCC.RemoveAllCCs();
1004                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1005                LFOs[i]->suResOnCC.RemoveAllCCs();
1006            }
1007        }
1008        
1009  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2220  
changed lines
  Added in v.2249

  ViewVC Help
Powered by ViewVC