/[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 2264 by iliev, Mon Aug 22 10:00:01 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 EGv1Unit::Trigger() {      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 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          EG.trigger(uint(pRegion->ampeg_start * 10),          float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),          decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),          
172                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173                     uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),          sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174                     std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),          
175                     GetSampleRate());          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()
181            );
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          EG.trigger(uint(pRegion->pitcheg_start * 10),          float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),          attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),          
237                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238                     uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),          hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239                     std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),          
240                     GetSampleRate());          float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242            
243            float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245            
246            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248            
249            EG.trigger (
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            if (pLFO == NULL) return;
297            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298        }
299        
300        
301        void LFOv1Unit::Trigger() {
302          LFOUnit::Trigger();          LFOUnit::Trigger();
303                    
304          lfo.trigger (          lfo.trigger (
305              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
306              start_level_mid,              start_level_mid,
307              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
308          );          );
309          lfo.update(0);          lfo.update(0);
310      }      }
311        
312        
313        LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314            : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315              lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316              suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317        {
318            lfos.add(&lfo0);
319            lfos.add(&lfo1);
320            lfos.add(&lfo2);
321            lfos.add(&lfo3);
322            lfos.add(&lfo4);
323            lfos.add(&lfo5);
324            lfos.add(&lfo6);
325            lfos.add(&lfo7);
326        }
327        
328        void LFOv2Unit::Trigger() {
329            LFOUnit::Trigger();
330            
331            if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332            else pLFO = lfos[pLfoInfo->wave];
333            
334            pLFO->Trigger (
335                pLfoInfo->freq + suFreqOnCC.GetLevel(),
336                start_level_mid,
337                1, 0, false, GetSampleRate()
338            );
339            pLFO->Update(0);
340            
341            float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
342            if (phase != 0) pLFO->SetPhase(phase);
343        }
344        
345        void AmpLFOUnit::Trigger() {
346            bActive = true;
347            ::sfz::Region* const pRegion = pVoice->pRegion;
348            pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349            pLfoInfo->freq   = pRegion->amplfo_freq;
350            pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351            pLfoInfo->volume = pRegion->amplfo_depth;
352            
353            if (pLfoInfo->freq <= 0) {
354                if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
355                else bActive = false;
356            }
357            
358            LFOv1Unit::Trigger();
359        }
360        
361        void PitchLFOUnit::Trigger() {
362            bActive = true;
363            ::sfz::Region* const pRegion = pVoice->pRegion;
364            pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365            pLfoInfo->freq  = pRegion->pitchlfo_freq;
366            pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367            pLfoInfo->pitch = pRegion->pitchlfo_depth;
368            
369            if (pLfoInfo->freq <= 0) {
370                if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
371                else bActive = false;
372            }
373            
374            LFOv1Unit::Trigger();
375        }
376        
377        void FilLFOUnit::Trigger() {
378            bActive = true;
379            ::sfz::Region* const pRegion = pVoice->pRegion;
380            pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381            pLfoInfo->freq   = pRegion->fillfo_freq;
382            pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383            pLfoInfo->cutoff = pRegion->fillfo_depth;
384            
385            if (pLfoInfo->freq <= 0) {
386                if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
387                else bActive = false;
388            }
389            
390            LFOv1Unit::Trigger();
391        }
392        
393        CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
394            pVoice = NULL;
395        }
396        
397        void CCUnit::Trigger() {
398            RTList<CC>::Iterator ctrl = pCtrls->first();
399            RTList<CC>::Iterator end  = pCtrls->end();
400            for(; ctrl != end; ++ctrl) {
401                (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402                if ((*ctrl).pSmoother != NULL) {
403                    if ((*ctrl).Step > 0) {
404                        float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405                        (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406                    } else {
407                        (*ctrl).pSmoother->setValue((*ctrl).Value);
408                    }
409                }
410            }
411            CCSignalUnit::Trigger();
412        }
413        
414        void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415            RemoveAllCCs();
416            for (int i = 0; i < 128; i++) {
417                if (cc[i] != 0) AddCC(i, cc[i]);
418            }
419        }
420        
421        void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
422            RemoveAllCCs();
423            for (int i = 0; i < cc.size(); i++) {
424                if (cc[i].Influence != 0) {
425                    short int curve = cc[i].Curve;
426                    if (curve >= GetCurveCount()) curve = -1;
427                    AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
428                }
429            }
430        }
431        
432        void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
433            AddCC(Controller, Influence, Curve, NULL, Step);
434        }
435        
436        int CCUnit::GetCurveCount() {
437            return pVoice->pRegion->GetInstrument()->curves.size();
438        }
439        
440        ::sfz::Curve* CCUnit::GetCurve(int idx) {
441            return &pVoice->pRegion->GetInstrument()->curves[idx];
442        }
443        
444        double CCUnit::GetSampleRate() {
445            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
446        }
447        
448        
449        SmoothCCUnit::~SmoothCCUnit() {
450            if (pSmoothers != NULL) delete pSmoothers;
451        }
452        
453        void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
454            if (Smooth > 0) {
455                if (pSmoothers->poolIsEmpty()) {
456                    std::cerr << "Maximum number of smoothers reached" << std::endl;
457                    return;
458                }
459                Smoother* smoother = &(*(pSmoothers->allocAppend()));
460                smoother->trigger(Smooth / 1000.0f, GetSampleRate());
461                AddCC(Controller, Influence, Curve, smoother, Step);
462            } else {
463                AddCC(Controller, Influence, Curve, NULL, Step);
464            }
465        }
466        
467        void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
468            if (pSmoothers != NULL) delete pSmoothers;
469            pSmoothers = new RTList<Smoother>(pSmootherPool);
470        }
471        
472        void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
473            CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
474            InitSmoothers(pSmootherPool);
475        }
476    
477    
478      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
479            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
480        {
481                    
482      }      }
483            
# Line 115  namespace LinuxSampler { namespace sfz { Line 486  namespace LinuxSampler { namespace sfz {
486      }      }
487            
488      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
489            float xfInVelCoeff = 1;
490            
491            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
492                xfInVelCoeff = 0;
493            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
494                xfInVelCoeff = 1;
495            } else {
496                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
497                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
498                xfInVelCoeff = velPos / xfVelSize;
499                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
500                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
501                }
502            }
503            
504            float xfOutVelCoeff = 1;
505            
506            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
507                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
508            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
509                xfOutVelCoeff = 1;
510            } else {
511                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
512                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
513                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
514                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
515                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
516                }
517            }
518            
519            float xfInKeyCoeff = 1;
520            
521            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
522                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
523            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
524                xfInKeyCoeff = 1;
525            } else {
526                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
527                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
528                xfInKeyCoeff = keyPos / xfKeySize;
529                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
530                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
531                }
532            }
533            
534            float xfOutKeyCoeff = 1;
535            
536            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
537                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
538            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
539                xfOutKeyCoeff = 1;
540            } else {
541                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
542                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
543                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
544                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
545                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
546                }
547            }
548                    
549            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
550            
551            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
552            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
553            
554            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
555            
556            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
557      }      }
558            
559      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 135  namespace LinuxSampler { namespace sfz { Line 573  namespace LinuxSampler { namespace sfz {
573          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
574              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
575              if (!eg->Active()) continue;              if (!eg->Active()) continue;
576              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
577                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
578                if (dB < -144) dB = eg->pEGInfo->volume;
579                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
580                
581                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
582                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
583                
584                if (dB >= -144) {
585                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
586                    amp *= ToRatio(dB * 10.0);
587                }
588                
589                vol += amp * eg->GetLevel();
590            }
591            
592            AmpLFOUnit* u = &(GetRack()->suAmpLFO);
593            CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
594            float f = u2->Active() ? u2->GetLevel() : 0;
595            vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
596            
597            vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
598            
599            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
600                LFOv2Unit* lfo = GetRack()->volLFOs[i];
601                if (!lfo->Active()) continue;
602                
603                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
604                vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
605          }          }
606                    
607          return vol;          if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
608            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
609            return vol * xfCoeff;
610      }      }
611            
612      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
613          float val = 1;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
614            
615            FilLFOUnit* u = &(GetRack()->suFilLFO);
616            CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
617            float f = u1->Active() ? u1->GetLevel() : 0;
618            val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
619            
620            FilEGUnit* u2 = &(GetRack()->suFilEG);
621            val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
622            
623            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
624                EGv2Unit* eg = GetRack()->filEGs[i];
625                if (!eg->Active()) continue;
626                
627                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
628                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
629                val *= RTMath::CentsToFreqRatioUnlimited(f);
630            }
631                    
632          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
633              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
634              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
635                            
636              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
637                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
638              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
639          }          }
640                    
641          return val;          return val;
642      }      }
643            
644        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
645            cutoff *= GetFilterCutoff();
646            float maxCutoff = 0.49 * pVoice->GetSampleRate();
647            return cutoff > maxCutoff ? maxCutoff : cutoff;
648        }
649        
650      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
651            double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
652            
653          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
654          double pitchEg = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
655          return pitchEg;          
656            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
657                EGv2Unit* eg = GetRack()->pitchEGs[i];
658                if (!eg->Active()) continue;
659                
660                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
661                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
662            }
663            
664            PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
665            CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
666            float f = u3->Active() ? u3->GetLevel() : 0;
667            p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
668            
669            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
670                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
671                if (!lfo->Active()) continue;
672                
673                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
674                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
675            }
676            
677            return p * pitchVeltrackRatio;
678      }      }
679            
680      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
681           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
682            
683            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
684                EGv2Unit* eg = GetRack()->resEGs[i];
685                if (!eg->Active()) continue;
686                
687                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
688                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
689            }
690                    
691          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
692              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
693              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
694                            
695              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
696                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
697          }          }
698                    
699          return val;          return val;
700      }      }
701            
702      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
703          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
704            
705            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
706                EGv2Unit* eg = GetRack()->panEGs[i];
707                if (!eg->Active()) continue;
708                
709                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
710                
711                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
712                    uint8_t val = eg->GetLevel() * 127;
713                    if (val > 127) val = 127;
714                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
715                } else {
716                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
717                }
718            }
719                    
720          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
721              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
722              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
723                            
724              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
725                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
726          }          }
727                    
728          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 192  namespace LinuxSampler { namespace sfz { Line 733  namespace LinuxSampler { namespace sfz {
733            
734            
735      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
736          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
737          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
738          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
739            suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
740            LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
741            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
742      {      {
743          suEndpoint.pVoice = suVolEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
744            suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
745            suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
746            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
747            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
748            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
749            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
750                    
751          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
752              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
753              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
754                EGs[i]->suAmpOnCC.pVoice = voice;
755                EGs[i]->suVolOnCC.pVoice = voice;
756                EGs[i]->suPitchOnCC.pVoice = voice;
757                EGs[i]->suCutoffOnCC.pVoice = voice;
758                EGs[i]->suResOnCC.pVoice = voice;
759                EGs[i]->suPanOnCC.pVoice = voice;
760          }          }
761                    
762          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
763              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
764              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
765                LFOs[i]->suDepthOnCC.pVoice = voice;
766                LFOs[i]->suFreqOnCC.pVoice = voice;
767                LFOs[i]->suFadeEG.pVoice = voice;
768                LFOs[i]->suVolOnCC.pVoice = voice;
769                LFOs[i]->suPitchOnCC.pVoice = voice;
770                LFOs[i]->suFreqOnCC.pVoice = voice;
771                LFOs[i]->suPanOnCC.pVoice = voice;
772                LFOs[i]->suCutoffOnCC.pVoice = voice;
773                LFOs[i]->suResOnCC.pVoice = voice;
774          }          }
775      }      }
776            
# Line 219  namespace LinuxSampler { namespace sfz { Line 784  namespace LinuxSampler { namespace sfz {
784          }          }
785      }      }
786            
787        void SfzSignalUnitRack::InitRTLists() {
788            Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
789            Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
790            
791            suVolOnCC.InitCCList(pCCPool, pSmootherPool);
792            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
793            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
794            suResOnCC.InitCCList(pCCPool, pSmootherPool);
795            suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
796            suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
797            suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
798            suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
799            suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
800            suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
801            suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
802            suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
803            suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
804            
805            for (int i = 0; i < EGs.capacity(); i++) {
806                EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
807                EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
808                EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
809                EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
810                EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
811                EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
812            }
813            
814            for (int i = 0; i < LFOs.capacity(); i++) {
815                LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
816                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
817                LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
818                LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
819                LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
820                LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
821                LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
822                LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
823            }
824        }
825        
826      void SfzSignalUnitRack::Trigger() {      void SfzSignalUnitRack::Trigger() {
827          EGs.clear();          EGs.clear();
828          volEGs.clear();          volEGs.clear();
829          pitchEGs.clear();          pitchEGs.clear();
830            filEGs.clear();
831            resEGs.clear();
832            panEGs.clear();
833                    
834          LFOs.clear();          LFOs.clear();
835            volLFOs.clear();
836            pitchLFOs.clear();
837          filLFOs.clear();          filLFOs.clear();
838          resLFOs.clear();          resLFOs.clear();
839          panLFOs.clear();          panLFOs.clear();
840                    
841          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
842                    
843            suVolOnCC.SetCCs(pRegion->volume_oncc);
844            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
845            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
846            suResOnCC.SetCCs(pRegion->resonance_oncc);
847            
848          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
849              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
850                            
# Line 238  namespace LinuxSampler { namespace sfz { Line 852  namespace LinuxSampler { namespace sfz {
852                  EGv2Unit eg(this);                  EGv2Unit eg(this);
853                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
854                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
855                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
856                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
857                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
858                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
859                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
860                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
861              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
862                            
863              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
864                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
865                ) {
866                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
867                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
868              }              }
869                
870                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
871                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
872                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
873                }
874                
875                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
876                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
877                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
878                }
879                
880                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
881                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
882                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
883                }
884                
885                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
886                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
887                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
888                }
889          }          }
890                    
891          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 253  namespace LinuxSampler { namespace sfz { Line 895  namespace LinuxSampler { namespace sfz {
895                    
896          // LFO          // LFO
897          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
898              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
899                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
900                    else pRegion->lfos[i].freq = 0;
901                }
902                            
903              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
904                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
905                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
906                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
907                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
908                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
909                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
910                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
911                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
912                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
913              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
914                            
915              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
916                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
917                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
918                }
919                
920                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
921                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
922                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
923                }
924                
925                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
926                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
927                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
928              }              }
929                            
930              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
931                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
932                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
933              }              }
934                            
935              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
936                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
937                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
938              }              }
939          }          }
940                    
941            suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
942            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
943            
944            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
945            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
946            
947            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
948            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
949            
950          Units.clear();          Units.clear();
951                    
952            Units.add(&suVolOnCC);
953            Units.add(&suPitchOnCC);
954            Units.add(&suCutoffOnCC);
955            Units.add(&suResOnCC);
956            
957          Units.add(&suVolEG);          Units.add(&suVolEG);
958            Units.add(&suFilEG);
959          Units.add(&suPitchEG);          Units.add(&suPitchEG);
960                    
961            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
962            Units.add(&suPitchLFO);
963            Units.add(&suPitchLFO.suDepthOnCC);
964            Units.add(&suPitchLFO.suFadeEG);
965            
966            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
967            Units.add(&suAmpLFO.suDepthOnCC);
968            Units.add(&suAmpLFO);
969            Units.add(&suAmpLFO.suFadeEG);
970            
971            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
972            Units.add(&suFilLFO.suDepthOnCC);
973            Units.add(&suFilLFO);
974            Units.add(&suFilLFO.suFadeEG);
975            
976          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
977              Units.add(EGs[i]);              Units.add(EGs[i]);
978                Units.add(&(EGs[i]->suAmpOnCC));
979                Units.add(&(EGs[i]->suVolOnCC));
980                Units.add(&(EGs[i]->suPitchOnCC));
981                Units.add(&(EGs[i]->suCutoffOnCC));
982                Units.add(&(EGs[i]->suResOnCC));
983                Units.add(&(EGs[i]->suPanOnCC));
984          }          }
985                    
986          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
987                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
988              Units.add(LFOs[i]);              Units.add(LFOs[i]);
989                Units.add(&(LFOs[i]->suFadeEG));
990                Units.add(&(LFOs[i]->suVolOnCC));
991                Units.add(&(LFOs[i]->suPitchOnCC));
992                Units.add(&(LFOs[i]->suPanOnCC));
993                Units.add(&(LFOs[i]->suCutoffOnCC));
994                Units.add(&(LFOs[i]->suResOnCC));
995          }          }
996                    
997          Units.add(&suEndpoint);          Units.add(&suEndpoint);
998            Units.add(&suEndpoint.suXFInCC);
999            Units.add(&suEndpoint.suXFOutCC);
1000            Units.add(&suEndpoint.suPanOnCC);
1001                    
1002          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
1003      }      }
# Line 307  namespace LinuxSampler { namespace sfz { Line 1014  namespace LinuxSampler { namespace sfz {
1014          }          }
1015      }      }
1016            
1017        void SfzSignalUnitRack::Reset() {
1018            suVolOnCC.RemoveAllCCs();
1019            suPitchOnCC.RemoveAllCCs();
1020            suCutoffOnCC.RemoveAllCCs();
1021            suResOnCC.RemoveAllCCs();
1022            suEndpoint.suXFInCC.RemoveAllCCs();
1023            suEndpoint.suXFOutCC.RemoveAllCCs();
1024            suEndpoint.suPanOnCC.RemoveAllCCs();
1025            suPitchLFO.suDepthOnCC.RemoveAllCCs();
1026            suPitchLFO.suFreqOnCC.RemoveAllCCs();
1027            suFilLFO.suDepthOnCC.RemoveAllCCs();
1028            suFilLFO.suFreqOnCC.RemoveAllCCs();
1029            suAmpLFO.suDepthOnCC.RemoveAllCCs();
1030            suAmpLFO.suFreqOnCC.RemoveAllCCs();
1031            
1032            for (int i = 0; i < EGs.capacity(); i++) {
1033                EGs[i]->suAmpOnCC.RemoveAllCCs();
1034                EGs[i]->suVolOnCC.RemoveAllCCs();
1035                EGs[i]->suPitchOnCC.RemoveAllCCs();
1036                EGs[i]->suCutoffOnCC.RemoveAllCCs();
1037                EGs[i]->suResOnCC.RemoveAllCCs();
1038                EGs[i]->suPanOnCC.RemoveAllCCs();
1039            }
1040            
1041            for (int i = 0; i < LFOs.capacity(); i++) {
1042                LFOs[i]->suDepthOnCC.RemoveAllCCs();
1043                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1044                LFOs[i]->suVolOnCC.RemoveAllCCs();
1045                LFOs[i]->suPitchOnCC.RemoveAllCCs();
1046                LFOs[i]->suFreqOnCC.RemoveAllCCs();
1047                LFOs[i]->suPanOnCC.RemoveAllCCs();
1048                LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1049                LFOs[i]->suResOnCC.RemoveAllCCs();
1050            }
1051        }
1052        
1053  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

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

  ViewVC Help
Powered by ViewVC