/[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 2224 by iliev, Mon Aug 1 19:08:09 2011 UTC revision 2238 by iliev, Fri Aug 12 17:30:47 2011 UTC
# Line 34  namespace LinuxSampler { namespace sfz { Line 34  namespace LinuxSampler { namespace sfz {
34          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
35      }      }
36            
37        float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
38            float f = 0;
39            for (int i = 0; i < cc.size(); i++) {
40                int val = pVoice->GetControllerValue(cc[i].Controller);
41                f += (val / 127.0f) * cc[i].Influence;
42            }
43            return f;
44        }
45            
46      void EGv1Unit::Trigger() {      void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
47          ::sfz::Region* const pRegion = pVoice->pRegion;          RemoveAllCCs();
48                    
49          // the length of the decay and release curves are dependent on the velocity          for (int cc = 0; cc < 128; cc++) {
50          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);              if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
51                int i = loCCs[cc];
52          // set the delay trigger              int j = hiCCs[cc];
53          uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate();              if (j == 0) j = 127;
54                i += j << 8; // workaround to keep both values in the Influence parameter
55                AddCC(cc, i);
56            }
57        }
58        
59        void XFInCCUnit::Calculate() {
60            float l = 1;
61                    
62            for (int i = 0; i < Ctrls.size(); i++) {
63                float c = 1;
64                int influence = Ctrls[i].Influence;
65                int lo = influence & 0xff;
66                int hi = influence >> 8;
67                if (Ctrls[i].Value <= lo) {
68                    c = 0;
69                } else if (Ctrls[i].Value >= hi) {
70                    c = 1;
71                } else {
72                    float xfVelSize = hi - lo;
73                    float velPos = Ctrls[i].Value - lo;
74                    c = velPos / xfVelSize;
75                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
76                        c = sin(c * M_PI / 2.0);
77                    }
78                }
79                
80                l *= c;
81            }
82                    
83          EG.trigger(uint(pRegion->ampeg_start * 10),          if (Level != l) {
84                     std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),              Level = l;
85                     std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),              if (pListener != NULL) pListener->ValueChanged(this);
86                     std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),          }
                    uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),  
                    GetSampleRate());  
87      }      }
88            
89            
90        void XFOutCCUnit::Calculate() {
91            float l = 1;
92                    
93            for (int i = 0; i < Ctrls.size(); i++) {
94                float c = 1;
95                int influence = Ctrls[i].Influence;
96                int lo = influence & 0xff;
97                int hi = influence >> 8;
98                if (Ctrls[i].Value >= hi) {
99                    c = 0;
100                } else if (Ctrls[i].Value <= lo) {
101                    c = 1;
102                } else {
103                    float xfVelSize = hi - lo;
104                    float velPos = Ctrls[i].Value - lo;
105                    c = 1.0f - velPos / xfVelSize;
106                    if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
107                        c = sin(c * M_PI / 2.0);
108                    }
109                }
110                
111                l *= c;
112            }
113            
114            if (Level != l) {
115                Level = l;
116                if (pListener != NULL) pListener->ValueChanged(this);
117            }
118        }
119        
120        
121        EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
122            : EGUnit< ::LinuxSampler::sfz::EG>(rack), suAmpOnCC(rack), suVolOnCC(rack),
123              suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
124        { }
125        
126      void EGv2Unit::Trigger() {      void EGv2Unit::Trigger() {
127          EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);          egInfo = *pEGInfo;
128            for (int i = 0; i < egInfo.node.size(); i++) {
129                float f = GetInfluence(egInfo.node[i].level_oncc);
130                egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
131                
132                f = GetInfluence(egInfo.node[i].time_oncc);
133                egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
134            }
135            EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity);
136      }      }
137            
138            
# Line 98  namespace LinuxSampler { namespace sfz { Line 175  namespace LinuxSampler { namespace sfz {
175                     GetSampleRate());                     GetSampleRate());
176      }      }
177            
178        
179        void AmpEGUnit::Trigger() {
180            ::sfz::Region* const pRegion = pVoice->pRegion;
181            
182            // the length of the decay and release curves are dependent on the velocity
183            const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
184    
185            // set the delay trigger
186            float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
187            delay += GetInfluence(pRegion->ampeg_delaycc);
188            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
189            
190            float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
191            
192            float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
193            attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
194            
195            float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
196            hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
197            
198            float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
199            decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
200            
201            float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
202            sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
203            
204            float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
205            release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
206            
207            EG.trigger (
208                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
209                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
210            );
211        }
212        
213        
214        LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
215            : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
216              suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
217        { }
218        
219        LFOUnit::LFOUnit(const LFOUnit& Unit)
220            : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
221              suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
222              suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
223        {
224            Copy(Unit);
225        }
226    
227      void LFOUnit::Increment() {      void LFOUnit::Increment() {
228          if (DelayStage()) return;          if (DelayStage()) return;
# Line 105  namespace LinuxSampler { namespace sfz { Line 230  namespace LinuxSampler { namespace sfz {
230          SignalUnit::Increment();          SignalUnit::Increment();
231                    
232          Level = pLFO->Render();          Level = pLFO->Render();
233            if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
234      }      }
235            
236      void LFOUnit::Trigger() {      void LFOUnit::Trigger() {
# Line 112  namespace LinuxSampler { namespace sfz { Line 238  namespace LinuxSampler { namespace sfz {
238          Level = 0;          Level = 0;
239                    
240          // set the delay trigger          // set the delay trigger
241          uiDelayTrigger = pLfoInfo->delay * GetSampleRate();          uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
242            if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
243                float f = pLfoInfo->fade;
244                f += GetInfluence(pLfoInfo->fade_oncc);
245                
246                if (f != 0) {
247                    suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
248                    suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
249                }
250            }
251      }      }
252            
253        void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
254            pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
255        }
256        
257        
258      void LFOv1Unit::Trigger() {      void LFOv1Unit::Trigger() {
259          LFOUnit::Trigger();          LFOUnit::Trigger();
260                    
261          lfo.trigger (          lfo.trigger (
262              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
263              start_level_mid,              start_level_mid,
264              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
265          );          );
# Line 129  namespace LinuxSampler { namespace sfz { Line 269  namespace LinuxSampler { namespace sfz {
269            
270      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
271          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
272            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f)            lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
273              suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
274      {      {
275          lfos.add(&lfo0);          lfos.add(&lfo0);
276          lfos.add(&lfo1);          lfos.add(&lfo1);
# Line 148  namespace LinuxSampler { namespace sfz { Line 289  namespace LinuxSampler { namespace sfz {
289          else pLFO = lfos[pLfoInfo->wave];          else pLFO = lfos[pLfoInfo->wave];
290                    
291          pLFO->Trigger (          pLFO->Trigger (
292              pLfoInfo->freq,              pLfoInfo->freq + suFreqOnCC.GetLevel(),
293              start_level_mid,              start_level_mid,
294              1, 0, false, GetSampleRate()              1, 0, false, GetSampleRate()
295          );          );
296          pLFO->Update(0);          pLFO->Update(0);
297            
298            float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
299            if (phase != 0) pLFO->SetPhase(phase);
300      }      }
301            
302      void AmpLFOUnit::Trigger() {      void AmpLFOUnit::Trigger() {
303          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
304          pLfoInfo->delay = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay;
305          pLfoInfo->freq = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
306            pLfoInfo->fade   = pRegion->amplfo_fade;
307          pLfoInfo->volume = pRegion->amplfo_depth;          pLfoInfo->volume = pRegion->amplfo_depth;
308                    
309          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 167  namespace LinuxSampler { namespace sfz { Line 312  namespace LinuxSampler { namespace sfz {
312      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
313          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
314          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay;
315          pLfoInfo->freq = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
316            pLfoInfo->fade  = pRegion->pitchlfo_fade;
317          pLfoInfo->pitch = pRegion->pitchlfo_depth;          pLfoInfo->pitch = pRegion->pitchlfo_depth;
318                    
319          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
# Line 175  namespace LinuxSampler { namespace sfz { Line 321  namespace LinuxSampler { namespace sfz {
321            
322      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
323          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
324          pLfoInfo->delay = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay;
325          pLfoInfo->freq = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
326            pLfoInfo->fade   = pRegion->fillfo_fade;
327          pLfoInfo->cutoff = pRegion->fillfo_depth;          pLfoInfo->cutoff = pRegion->fillfo_depth;
328                    
329          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
330      }      }
331            
332      CCUnit::CCUnit(SfzSignalUnitRack* rack): CCSignalUnit(rack) { }      CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
333            pVoice = NULL;
334        }
335            
336      void CCUnit::Trigger() {      void CCUnit::Trigger() {
337          for (int i = 0; i < Ctrls.size(); i++) {          for (int i = 0; i < Ctrls.size(); i++) {
338              Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);              Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);
339                if (Ctrls[i].pSmoother != NULL) Ctrls[i].pSmoother->setValue(Ctrls[i].Value);
340          }          }
341          CCSignalUnit::Trigger();          CCSignalUnit::Trigger();
342      }      }
# Line 197  namespace LinuxSampler { namespace sfz { Line 347  namespace LinuxSampler { namespace sfz {
347               if (cc[i] != 0) AddCC(i, cc[i]);               if (cc[i] != 0) AddCC(i, cc[i]);
348           }           }
349       }       }
350        
351         void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
352             RemoveAllCCs();
353             for (int i = 0; i < cc.size(); i++) {
354                 if (cc[i].Influence != 0) {
355                     short int curve = cc[i].Curve;
356                     if (curve >= GetCurveCount()) curve = -1;
357                     AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
358                 }
359             }
360         }
361        
362         void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
363             AddCC(Controller, Influence, Curve);
364         }
365        
366         int CCUnit::GetCurveCount() {
367             return pVoice->pRegion->GetInstrument()->curves.size();
368         }
369        
370         ::sfz::Curve* CCUnit::GetCurve(int idx) {
371             return &pVoice->pRegion->GetInstrument()->curves[idx];
372         }
373        
374         double CCUnit::GetSampleRate() {
375            return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
376        }
377        
378         void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
379             if (Smooth > 0) {
380                 if (Smoothers.size() >= Smoothers.capacity()) {
381                     std::cerr << "Maximum number of smoothers reached" << std::endl;
382                     return;
383                 }
384                
385                 Smoothers.increment().trigger(Smooth / 1000.0f, GetSampleRate());
386                 AddCC(Controller, Influence, Curve, &Smoothers[Smoothers.size() - 1]);
387             } else {
388                 AddCC(Controller, Influence, Curve);
389             }
390         }
391    
392    
393      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
394            : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
395        {
396                    
397      }      }
398            
# Line 208  namespace LinuxSampler { namespace sfz { Line 401  namespace LinuxSampler { namespace sfz {
401      }      }
402            
403      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
404            float xfInVelCoeff = 1;
405                    
406            if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
407                xfInVelCoeff = 0;
408            } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
409                xfInVelCoeff = 1;
410            } else {
411                float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
412                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
413                xfInVelCoeff = velPos / xfVelSize;
414                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
415                    xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
416                }
417            }
418            
419            float xfOutVelCoeff = 1;
420            
421            if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
422                if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
423            } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
424                xfOutVelCoeff = 1;
425            } else {
426                float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
427                float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
428                xfOutVelCoeff = 1.0f - velPos / xfVelSize;
429                if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
430                    xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
431                }
432            }
433            
434            float xfInKeyCoeff = 1;
435            
436            if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
437                if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
438            } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
439                xfInKeyCoeff = 1;
440            } else {
441                float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
442                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
443                xfInKeyCoeff = keyPos / xfKeySize;
444                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
445                    xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
446                }
447            }
448            
449            float xfOutKeyCoeff = 1;
450            
451            if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
452                if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
453            } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
454                xfOutKeyCoeff = 1;
455            } else {
456                float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
457                float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
458                xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
459                if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
460                    xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
461                }
462            }
463            
464            xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
465            
466            suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
467            suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
468            
469            suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
470            
471            pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
472      }      }
473            
474      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
# Line 228  namespace LinuxSampler { namespace sfz { Line 488  namespace LinuxSampler { namespace sfz {
488          for (int i = 0; i < GetRack()->volEGs.size(); i++) {          for (int i = 0; i < GetRack()->volEGs.size(); i++) {
489              EGv2Unit* eg = GetRack()->volEGs[i];              EGv2Unit* eg = GetRack()->volEGs[i];
490              if (!eg->Active()) continue;              if (!eg->Active()) continue;
491              vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);              
492                float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
493                if (dB < -144) dB = eg->pEGInfo->volume;
494                else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
495                
496                float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
497                amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
498                
499                if (dB >= -144) {
500                    if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
501                    amp *= ::sf2::ToRatio(dB * 10.0);
502                }
503                
504                vol += amp * eg->GetLevel();
505          }          }
506                    
507          AmpLFOUnit* u = &(GetRack()->suAmpLFO);          AmpLFOUnit* u = &(GetRack()->suAmpLFO);
508          vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;          CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
509            float f = u2->Active() ? u2->GetLevel() : 0;
510            vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
511                    
512          return vol;          vol *= ::sf2::ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
513            
514            for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
515                LFOv2Unit* lfo = GetRack()->volLFOs[i];
516                if (!lfo->Active()) continue;
517                
518                float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
519                vol *= ::sf2::ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
520            }
521            
522            if (suXFInCC.Active())  vol *= suXFInCC.GetLevel();
523            if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
524            return vol * xfCoeff;
525      }      }
526            
527      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
528          float val;          float val;
529                    
530          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
531          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
532            float f = u1->Active() ? u1->GetLevel() : 0;
533            val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
534                    
535          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
536          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
537                    
538            for (int i = 0; i < GetRack()->filEGs.size(); i++) {
539                EGv2Unit* eg = GetRack()->filEGs[i];
540                if (!eg->Active()) continue;
541                
542                float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
543                f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
544                val *= RTMath::CentsToFreqRatioUnlimited(f);
545            }
546            
547          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {          for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
548              LFOv2Unit* lfo = GetRack()->filLFOs[i];              LFOv2Unit* lfo = GetRack()->filLFOs[i];
549              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
550                            
551              float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;              float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
552                f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
553              val *= RTMath::CentsToFreqRatioUnlimited(f);              val *= RTMath::CentsToFreqRatioUnlimited(f);
554          }          }
555                    
556          return val;          return val;
557      }      }
558            
559        float EndpointUnit::CalculateFilterCutoff(float cutoff) {
560             cutoff *= GetFilterCutoff();
561             float maxCutoff = 0.49 * pVoice->GetSampleRate();
562             return cutoff > maxCutoff ? maxCutoff : cutoff;
563        }
564        
565      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
566          double p;          double p;
567          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
568          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
569                    
570            for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
571                EGv2Unit* eg = GetRack()->pitchEGs[i];
572                if (!eg->Active()) continue;
573                
574                float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
575                p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
576            }
577            
578          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);          PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
579          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);          CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
580          float f = u3->Active() ? u3->GetLevel() : 0;          float f = u3->Active() ? u3->GetLevel() : 0;
581          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;          p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
582          return p;          
583            for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
584                LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
585                if (!lfo->Active()) continue;
586                
587                float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
588                p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
589            }
590            
591            return p * pitchVeltrackRatio;
592      }      }
593            
594      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
595           float val = 0;           float val = 0;
596                    
597            for (int i = 0; i < GetRack()->resEGs.size(); i++) {
598                EGv2Unit* eg = GetRack()->resEGs[i];
599                if (!eg->Active()) continue;
600                
601                float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
602                val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
603            }
604            
605          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {          for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
606              LFOv2Unit* lfo = GetRack()->resLFOs[i];              LFOv2Unit* lfo = GetRack()->resLFOs[i];
607              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
608                            
609              val += lfo->GetLevel() * lfo->pLfoInfo->resonance;              float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
610                val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
611          }          }
612                    
613          return val;          return val;
614      }      }
615            
616      float EndpointUnit::GetPan() {      float EndpointUnit::GetPan() {
617          float pan = 0;          float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
618            
619            for (int i = 0; i < GetRack()->panEGs.size(); i++) {
620                EGv2Unit* eg = GetRack()->panEGs[i];
621                if (!eg->Active()) continue;
622                
623                float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
624                
625                if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
626                    uint8_t val = eg->GetLevel() * 127;
627                    if (val > 127) val = 127;
628                    pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] +  eg->GetLevel() * f;
629                } else {
630                    pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
631                }
632            }
633                    
634          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {          for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
635              LFOv2Unit* lfo = GetRack()->panLFOs[i];              LFOv2Unit* lfo = GetRack()->panLFOs[i];
636              if (!lfo->Active()) continue;              if (!lfo->Active()) continue;
637                            
638              pan += lfo->GetLevel() * lfo->pLfoInfo->pan;              float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
639                pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
640          }          }
641                    
642          if(pan < -100) return -100;          if(pan < -100) return -100;
# Line 301  namespace LinuxSampler { namespace sfz { Line 648  namespace LinuxSampler { namespace sfz {
648            
649      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
650          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
651          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
652          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
653          LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
654            filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
655      {      {
656          suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
657          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
658          suPitchLFO.suDepthCC.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
659            suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
660            suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
661            suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
662                    
663          for (int i = 0; i < EGs.capacity(); i++) {          for (int i = 0; i < EGs.capacity(); i++) {
664              EGs[i] = new EGv2Unit(this);              EGs[i] = new EGv2Unit(this);
665              EGs[i]->pVoice = voice;              EGs[i]->pVoice = voice;
666                EGs[i]->suAmpOnCC.pVoice = voice;
667                EGs[i]->suVolOnCC.pVoice = voice;
668                EGs[i]->suPitchOnCC.pVoice = voice;
669                EGs[i]->suCutoffOnCC.pVoice = voice;
670                EGs[i]->suResOnCC.pVoice = voice;
671                EGs[i]->suPanOnCC.pVoice = voice;
672          }          }
673                    
674          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
675              LFOs[i] = new LFOv2Unit(this);              LFOs[i] = new LFOv2Unit(this);
676              LFOs[i]->pVoice = voice;              LFOs[i]->pVoice = voice;
677                LFOs[i]->suFadeEG.pVoice = voice;
678                LFOs[i]->suVolOnCC.pVoice = voice;
679                LFOs[i]->suPitchOnCC.pVoice = voice;
680                LFOs[i]->suFreqOnCC.pVoice = voice;
681                LFOs[i]->suPanOnCC.pVoice = voice;
682                LFOs[i]->suCutoffOnCC.pVoice = voice;
683                LFOs[i]->suResOnCC.pVoice = voice;
684          }          }
685      }      }
686            
# Line 334  namespace LinuxSampler { namespace sfz { Line 698  namespace LinuxSampler { namespace sfz {
698          EGs.clear();          EGs.clear();
699          volEGs.clear();          volEGs.clear();
700          pitchEGs.clear();          pitchEGs.clear();
701            filEGs.clear();
702            resEGs.clear();
703            panEGs.clear();
704                    
705          LFOs.clear();          LFOs.clear();
706            volLFOs.clear();
707            pitchLFOs.clear();
708          filLFOs.clear();          filLFOs.clear();
709          resLFOs.clear();          resLFOs.clear();
710          panLFOs.clear();          panLFOs.clear();
711                    
712          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
713                    
714            suVolOnCC.SetCCs(pRegion->volume_oncc);
715            
716          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
717              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
718                            
# Line 349  namespace LinuxSampler { namespace sfz { Line 720  namespace LinuxSampler { namespace sfz {
720                  EGv2Unit eg(this);                  EGv2Unit eg(this);
721                  eg.pEGInfo = &(pRegion->eg[i]);                  eg.pEGInfo = &(pRegion->eg[i]);
722                  EGs.increment()->Copy(eg);                  EGs.increment()->Copy(eg);
723                    EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
724                    EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
725                    EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
726                    EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
727                    EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
728                    EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
729              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
730                            
731              if (pRegion->eg[i].amplitude > 0) {              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
732                     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
733                ) {
734                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);                  if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
735                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
736              }              }
737                
738                if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
739                    if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
740                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
741                }
742                
743                if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
744                    if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
745                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
746                }
747                
748                if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
749                    if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
750                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
751                }
752                
753                if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
754                    if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
755                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
756                }
757          }          }
758                    
759          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 370  namespace LinuxSampler { namespace sfz { Line 769  namespace LinuxSampler { namespace sfz {
769                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
770                  lfo.pLfoInfo = &(pRegion->lfos[i]);                  lfo.pLfoInfo = &(pRegion->lfos[i]);
771                  LFOs.increment()->Copy(lfo);                  LFOs.increment()->Copy(lfo);
772                    LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
773                    LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
774                    LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
775                    LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
776                    LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
777                    LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
778              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
779                            
780              if (pRegion->lfos[i].cutoff != 0) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
781                    if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
782                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
783                }
784                
785                if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
786                    if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
787                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
788                }
789                
790                if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
791                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);                  if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
792                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
793              }              }
794                            
795              if (pRegion->lfos[i].resonance != 0) {              if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
796                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);                  if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
797                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
798              }              }
799                            
800              if (pRegion->lfos[i].pan != 0) {              if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
801                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
802                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
803              }              }
804          }          }
805                    
806          suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
807            suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
808            
809            suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
810            suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
811            
812            suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
813            suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
814                    
815          Units.clear();          Units.clear();
816                    
817            Units.add(&suVolOnCC);
818            
819          Units.add(&suVolEG);          Units.add(&suVolEG);
820          Units.add(&suFilEG);          Units.add(&suFilEG);
821          Units.add(&suPitchEG);          Units.add(&suPitchEG);
822            
823            Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
824          Units.add(&suPitchLFO);          Units.add(&suPitchLFO);
825          Units.add(&suPitchLFO.suDepthCC);          Units.add(&suPitchLFO.suDepthOnCC);
826            Units.add(&suPitchLFO.suFadeEG);
827            
828            Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
829            Units.add(&suAmpLFO.suDepthOnCC);
830          Units.add(&suAmpLFO);          Units.add(&suAmpLFO);
831            Units.add(&suAmpLFO.suFadeEG);
832            
833            Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
834            Units.add(&suFilLFO.suDepthOnCC);
835          Units.add(&suFilLFO);          Units.add(&suFilLFO);
836            Units.add(&suFilLFO.suFadeEG);
837                    
838          for (int i = 0; i < EGs.size(); i++) {          for (int i = 0; i < EGs.size(); i++) {
839              Units.add(EGs[i]);              Units.add(EGs[i]);
840                Units.add(&(EGs[i]->suAmpOnCC));
841                Units.add(&(EGs[i]->suVolOnCC));
842                Units.add(&(EGs[i]->suPitchOnCC));
843                Units.add(&(EGs[i]->suCutoffOnCC));
844                Units.add(&(EGs[i]->suResOnCC));
845                Units.add(&(EGs[i]->suPanOnCC));
846          }          }
847                    
848          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
849                Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
850              Units.add(LFOs[i]);              Units.add(LFOs[i]);
851                Units.add(&(LFOs[i]->suFadeEG));
852                Units.add(&(LFOs[i]->suVolOnCC));
853                Units.add(&(LFOs[i]->suPitchOnCC));
854                Units.add(&(LFOs[i]->suPanOnCC));
855                Units.add(&(LFOs[i]->suCutoffOnCC));
856                Units.add(&(LFOs[i]->suResOnCC));
857          }          }
858                    
859          Units.add(&suEndpoint);          Units.add(&suEndpoint);
860            Units.add(&suEndpoint.suXFInCC);
861            Units.add(&suEndpoint.suXFOutCC);
862            Units.add(&suEndpoint.suPanOnCC);
863                    
864          SignalUnitRack::Trigger();          SignalUnitRack::Trigger();
865      }      }

Legend:
Removed from v.2224  
changed lines
  Added in v.2238

  ViewVC Help
Powered by ViewVC