/[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 2244 by iliev, Thu Aug 18 11:32:33 2011 UTC revision 3054 by schoenebeck, Thu Dec 15 12:47:45 2016 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2011 Grigor Iliev                                       *   *   Copyright (C) 2011 - 2012 Grigor Iliev                                *
6   *                                                                         *   *                                                                         *
7   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
8   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 129  namespace LinuxSampler { namespace sfz { Line 129  namespace LinuxSampler { namespace sfz {
129            
130            
131      EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)      EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132          : EGUnit< ::LinuxSampler::sfz::EG>(rack), suAmpOnCC(rack), suVolOnCC(rack),          : EGUnit< ::LinuxSampler::sfz::EG>(rack), EqUnitSupport(rack), suAmpOnCC(rack), suVolOnCC(rack),
133            suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)            suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134      { }      { }
135            
# Line 142  namespace LinuxSampler { namespace sfz { Line 142  namespace LinuxSampler { namespace sfz {
142              f = GetInfluence(egInfo.node[i].time_oncc);              f = GetInfluence(egInfo.node[i].time_oncc);
143              egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);              egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144          }          }
145          EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity);          EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity());
146      }      }
147            
148            
149      void PitchEGUnit::Trigger() {      void PitchEGUnit::Trigger() {
150          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
151          depth = pRegion->pitcheg_depth;          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->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease) * GetSampleRate();          float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158            delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159            uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160            
161            float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162            
163            float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164            attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165            
166            float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167            hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168            
169            float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170            decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171            
172            float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173            sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174            
175            float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176            release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177                    
178          EG.trigger(uint(pRegion->pitcheg_start * 10),          EG.trigger (
179                     std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180                     std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
181                     std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),          );
                    uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),  
                    std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),  
                    GetSampleRate());  
182      }      }
183            
184            
185      void FilEGUnit::Trigger() {      void FilEGUnit::Trigger() {
186          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
187          depth = pRegion->fileg_depth;          depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188                    
189          // 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
190          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);          const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity());
191    
192          // set the delay trigger          // set the delay trigger
193          uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();          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          EG.trigger(uint(pRegion->fileg_start * 10),          float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206                     std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),          decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207                     std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),          
208                     std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),          float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209                     uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),          sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210                     std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),          
211                     GetSampleRate());          float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212            release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213            
214            EG.trigger (
215                uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216                uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), true
217            );
218      }      }
219            
220            
# Line 190  namespace LinuxSampler { namespace sfz { Line 222  namespace LinuxSampler { namespace sfz {
222          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
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          float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;          float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
# Line 216  namespace LinuxSampler { namespace sfz { Line 248  namespace LinuxSampler { namespace sfz {
248                    
249          EG.trigger (          EG.trigger (
250              uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,              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()              uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate(), false
252          );          );
253      }      }
254            
255            
256      LFOUnit::LFOUnit(SfzSignalUnitRack* rack)      LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257          : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),          : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258            suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)            suFadeEG(rack), suDepthOnCC(rack), suFreqOnCC(rack, this)
259      { }      { }
260            
261      LFOUnit::LFOUnit(const LFOUnit& Unit)      LFOUnit::LFOUnit(const LFOUnit& Unit)
262          : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),          : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263            suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),            suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
264            suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))            suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
265      {      {
266          Copy(Unit);          Copy(Unit);
267      }      }
# Line 255  namespace LinuxSampler { namespace sfz { Line 287  namespace LinuxSampler { namespace sfz {
287                            
288              if (f != 0) {              if (f != 0) {
289                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();                  suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290                  suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());                  suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate(), false);
291              }              }
292          }          }
293      }      }
294            
295      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {      void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296            if (pLFO == NULL) return;
297          pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());          pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298      }      }
299            
# Line 278  namespace LinuxSampler { namespace sfz { Line 311  namespace LinuxSampler { namespace sfz {
311            
312            
313      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)      LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314          : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),          : LFOUnit(rack), EqUnitSupport(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),            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)            suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317      {      {
# Line 295  namespace LinuxSampler { namespace sfz { Line 328  namespace LinuxSampler { namespace sfz {
328      void LFOv2Unit::Trigger() {      void LFOv2Unit::Trigger() {
329          LFOUnit::Trigger();          LFOUnit::Trigger();
330                    
331          if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;          if (/*pLfoInfo->wave < 0 ||*/ pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332          else pLFO = lfos[pLfoInfo->wave];          else pLFO = lfos[pLfoInfo->wave];
333                    
334          pLFO->Trigger (          pLFO->Trigger (
# Line 310  namespace LinuxSampler { namespace sfz { Line 343  namespace LinuxSampler { namespace sfz {
343      }      }
344            
345      void AmpLFOUnit::Trigger() {      void AmpLFOUnit::Trigger() {
346            bActive = true;
347          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
348          pLfoInfo->delay  = pRegion->amplfo_delay;          pLfoInfo->delay  = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349          pLfoInfo->freq   = pRegion->amplfo_freq;          pLfoInfo->freq   = pRegion->amplfo_freq;
350          pLfoInfo->fade   = pRegion->amplfo_fade;          pLfoInfo->fade   = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351          pLfoInfo->volume = pRegion->amplfo_depth;          pLfoInfo->volume = pRegion->amplfo_depth;
352                    
353            if (pLfoInfo->freq <= 0) {
354                if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
355                else bActive = false;
356            }
357            
358          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
359      }      }
360            
361      void PitchLFOUnit::Trigger() {      void PitchLFOUnit::Trigger() {
362            bActive = true;
363          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
364          pLfoInfo->delay = pRegion->pitchlfo_delay;          pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365          pLfoInfo->freq  = pRegion->pitchlfo_freq;          pLfoInfo->freq  = pRegion->pitchlfo_freq;
366          pLfoInfo->fade  = pRegion->pitchlfo_fade;          pLfoInfo->fade  = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367          pLfoInfo->pitch = pRegion->pitchlfo_depth;          pLfoInfo->pitch = pRegion->pitchlfo_depth;
368                    
369            if (pLfoInfo->freq <= 0) {
370                if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
371                else bActive = false;
372            }
373            
374          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
375      }      }
376            
377      void FilLFOUnit::Trigger() {      void FilLFOUnit::Trigger() {
378            bActive = true;
379          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
380          pLfoInfo->delay  = pRegion->fillfo_delay;          pLfoInfo->delay  = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381          pLfoInfo->freq   = pRegion->fillfo_freq;          pLfoInfo->freq   = pRegion->fillfo_freq;
382          pLfoInfo->fade   = pRegion->fillfo_fade;          pLfoInfo->fade   = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383          pLfoInfo->cutoff = pRegion->fillfo_depth;          pLfoInfo->cutoff = pRegion->fillfo_depth;
384                    
385            if (pLfoInfo->freq <= 0) {
386                if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
387                else bActive = false;
388            }
389            
390          LFOv1Unit::Trigger();          LFOv1Unit::Trigger();
391      }      }
392            
# Line 348  namespace LinuxSampler { namespace sfz { Line 399  namespace LinuxSampler { namespace sfz {
399          RTList<CC>::Iterator end  = pCtrls->end();          RTList<CC>::Iterator end  = pCtrls->end();
400          for(; ctrl != end; ++ctrl) {          for(; ctrl != end; ++ctrl) {
401              (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);              (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402              if ((*ctrl).pSmoother != NULL) (*ctrl).pSmoother->setValue((*ctrl).Value);              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();          CCSignalUnit::Trigger();
412      }      }
# Line 360  namespace LinuxSampler { namespace sfz { Line 418  namespace LinuxSampler { namespace sfz {
418          }          }
419      }      }
420            
421        void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422            RemoveAllCCs();
423            for (int i = 0; i < 128; i++) {
424                if (cc[i] != 0) AddCC(i, cc[i]);
425            }
426        }
427        
428      void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {      void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
429          RemoveAllCCs();          RemoveAllCCs();
430          for (int i = 0; i < cc.size(); i++) {          for (int i = 0; i < cc.size(); i++) {
431              if (cc[i].Influence != 0) {              if (cc[i].Influence != 0) {
432                  short int curve = cc[i].Curve;                  short int curve = cc[i].Curve;
433                  if (curve >= GetCurveCount()) curve = -1;                  if (curve >= GetCurveCount()) curve = -1;
434                  AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);                  AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435              }              }
436          }          }
437      }      }
438            
439      void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {      void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440          AddCC(Controller, Influence, Curve);          AddCC(Controller, Influence, Curve, NULL, Step);
441      }      }
442            
443      int CCUnit::GetCurveCount() {      int CCUnit::GetCurveCount() {
# Line 392  namespace LinuxSampler { namespace sfz { Line 457  namespace LinuxSampler { namespace sfz {
457          if (pSmoothers != NULL) delete pSmoothers;          if (pSmoothers != NULL) delete pSmoothers;
458      }      }
459            
460      void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {      void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461          if (Smooth > 0) {          if (Smooth > 0) {
462              if (pSmoothers->poolIsEmpty()) {              if (pSmoothers->poolIsEmpty()) {
463                  std::cerr << "Maximum number of smoothers reached" << std::endl;                  std::cerr << "Maximum number of smoothers reached" << std::endl;
# Line 400  namespace LinuxSampler { namespace sfz { Line 465  namespace LinuxSampler { namespace sfz {
465              }              }
466              Smoother* smoother = &(*(pSmoothers->allocAppend()));              Smoother* smoother = &(*(pSmoothers->allocAppend()));
467              smoother->trigger(Smooth / 1000.0f, GetSampleRate());              smoother->trigger(Smooth / 1000.0f, GetSampleRate());
468              AddCC(Controller, Influence, Curve, smoother);              AddCC(Controller, Influence, Curve, smoother, Step);
469          } else {          } else {
470              AddCC(Controller, Influence, Curve);              AddCC(Controller, Influence, Curve, NULL, Step);
471          }          }
472      }      }
473            
# Line 418  namespace LinuxSampler { namespace sfz { Line 483  namespace LinuxSampler { namespace sfz {
483    
484    
485      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)      EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486          : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)          : EndpointSignalUnit(rack), pitchVeltrackRatio(0), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack)
487      {      {
488                    
489      }      }
490            
491        float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<float> >& cc) {
492            float f = 0;
493            for (int i = 0; i < 128; i++) {
494                if (cc[i]) {
495                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
496                }
497            }
498            return f;
499        }
500        
501        float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<int> >& cc) {
502            float f = 0;
503            for (int i = 0; i < 128; i++) {
504                if (cc[i]) {
505                    f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
506                }
507            }
508            return f;
509        }
510        
511      SfzSignalUnitRack* const EndpointUnit::GetRack() {      SfzSignalUnitRack* const EndpointUnit::GetRack() {
512          return static_cast<SfzSignalUnitRack* const>(pRack);          return static_cast<SfzSignalUnitRack* const>(pRack);
513      }      }
514            
515      void EndpointUnit::Trigger() {      void EndpointUnit::Trigger() {
516            uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
517            if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
518            
519            if (pVoice->pRegion->delay) {
520                /* here we use the device sample rate */
521                uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
522            }
523            
524            if (pVoice->pRegion->delay_random) {
525                float r = pVoice->GetEngine()->Random();
526                uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
527            }
528            
529            uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
530            
531          float xfInVelCoeff = 1;          float xfInVelCoeff = 1;
532                    
533          if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {          if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfin_lovel) {
534              xfInVelCoeff = 0;              xfInVelCoeff = 0;
535          } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {          } else if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfin_hivel) {
536              xfInVelCoeff = 1;              xfInVelCoeff = 1;
537          } else {          } else {
538              float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;              float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
539              float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;              float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfin_lovel;
540              xfInVelCoeff = velPos / xfVelSize;              xfInVelCoeff = velPos / xfVelSize;
541              if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {              if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
542                  xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);                  xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
# Line 445  namespace LinuxSampler { namespace sfz { Line 545  namespace LinuxSampler { namespace sfz {
545                    
546          float xfOutVelCoeff = 1;          float xfOutVelCoeff = 1;
547                    
548          if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {          if (pVoice->MIDIVelocity() >= pVoice->pRegion->xfout_hivel) {
549              if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;              if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
550          } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {          } else if (pVoice->MIDIVelocity() <= pVoice->pRegion->xfout_lovel) {
551              xfOutVelCoeff = 1;              xfOutVelCoeff = 1;
552          } else {          } else {
553              float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;              float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
554              float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;              float velPos = pVoice->MIDIVelocity() - pVoice->pRegion->xfout_lovel;
555              xfOutVelCoeff = 1.0f - velPos / xfVelSize;              xfOutVelCoeff = 1.0f - velPos / xfVelSize;
556              if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {              if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
557                  xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);                  xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
# Line 460  namespace LinuxSampler { namespace sfz { Line 560  namespace LinuxSampler { namespace sfz {
560                    
561          float xfInKeyCoeff = 1;          float xfInKeyCoeff = 1;
562                    
563          if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {          if (pVoice->MIDIKey() <= pVoice->pRegion->xfin_lokey) {
564              if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;              if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
565          } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {          } else if (pVoice->MIDIKey() >= pVoice->pRegion->xfin_hikey) {
566              xfInKeyCoeff = 1;              xfInKeyCoeff = 1;
567          } else {          } else {
568              float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;              float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
569              float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;              float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfin_lokey;
570              xfInKeyCoeff = keyPos / xfKeySize;              xfInKeyCoeff = keyPos / xfKeySize;
571              if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {              if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
572                  xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);                  xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
# Line 475  namespace LinuxSampler { namespace sfz { Line 575  namespace LinuxSampler { namespace sfz {
575                    
576          float xfOutKeyCoeff = 1;          float xfOutKeyCoeff = 1;
577                    
578          if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {          if (pVoice->MIDIKey() >= pVoice->pRegion->xfout_hikey) {
579              if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;              if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
580          } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {          } else if (pVoice->MIDIKey() <= pVoice->pRegion->xfout_lokey) {
581              xfOutKeyCoeff = 1;              xfOutKeyCoeff = 1;
582          } else {          } else {
583              float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;              float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
584              float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;              float keyPos = pVoice->MIDIKey() - pVoice->pRegion->xfout_lokey;
585              xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;              xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
586              if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {              if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
587                  xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);                  xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
# Line 495  namespace LinuxSampler { namespace sfz { Line 595  namespace LinuxSampler { namespace sfz {
595                    
596          suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);          suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
597                    
598          pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);          pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity() / 127.0f) * pVoice->pRegion->pitch_veltrack);
599      }      }
600            
601      bool EndpointUnit::Active() {      bool EndpointUnit::Active() {
602            if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
603                return false; // The key was released before the delay end, so the voice won't play at all.
604            }
605            
606          if (GetRack()->suVolEG.Active()) return true;          if (GetRack()->suVolEG.Active()) return true;
607                    
608          bool b = false;          bool b = false;
# Line 552  namespace LinuxSampler { namespace sfz { Line 656  namespace LinuxSampler { namespace sfz {
656      }      }
657            
658      float EndpointUnit::GetFilterCutoff() {      float EndpointUnit::GetFilterCutoff() {
659          float val;          float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660                    
661          FilLFOUnit* u = &(GetRack()->suFilLFO);          FilLFOUnit* u = &(GetRack()->suFilLFO);
662          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);          CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663          float f = u1->Active() ? u1->GetLevel() : 0;          float f = u1->Active() ? u1->GetLevel() : 0;
664          val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;          val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
665                    
666          FilEGUnit* u2 = &(GetRack()->suFilEG);          FilEGUnit* u2 = &(GetRack()->suFilEG);
667          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;          val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
# Line 584  namespace LinuxSampler { namespace sfz { Line 688  namespace LinuxSampler { namespace sfz {
688      }      }
689            
690      float EndpointUnit::CalculateFilterCutoff(float cutoff) {      float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691           cutoff *= GetFilterCutoff();          cutoff *= GetFilterCutoff();
692           float maxCutoff = 0.49 * pVoice->GetSampleRate();          float maxCutoff = 0.49 * pVoice->GetSampleRate();
693           return cutoff > maxCutoff ? maxCutoff : cutoff;          return cutoff > maxCutoff ? maxCutoff : cutoff;
694      }      }
695            
696      float EndpointUnit::GetPitch() {      float EndpointUnit::GetPitch() {
697          double p;          double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698            
699          EGv1Unit* u = &(GetRack()->suPitchEG);          EGv1Unit* u = &(GetRack()->suPitchEG);
700          p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;          p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701                    
702          for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {          for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
703              EGv2Unit* eg = GetRack()->pitchEGs[i];              EGv2Unit* eg = GetRack()->pitchEGs[i];
# Line 619  namespace LinuxSampler { namespace sfz { Line 724  namespace LinuxSampler { namespace sfz {
724      }      }
725            
726      float EndpointUnit::GetResonance() {      float EndpointUnit::GetResonance() {
727           float val = 0;           float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
728                    
729          for (int i = 0; i < GetRack()->resEGs.size(); i++) {          for (int i = 0; i < GetRack()->resEGs.size(); i++) {
730              EGv2Unit* eg = GetRack()->resEGs[i];              EGv2Unit* eg = GetRack()->resEGs[i];
# Line 666  namespace LinuxSampler { namespace sfz { Line 771  namespace LinuxSampler { namespace sfz {
771              pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);              pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772          }          }
773                    
         if(pan < -100) return -100;  
         if(pan >  100) return  100;  
           
774          return pan;          return pan;
775      }      }
776            
777            
778      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)      SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
779          : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),          : SignalUnitRack(MaxUnitCount), EqUnitSupport(this, voice),
780          EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),          suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
781          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),          suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
782            suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
783            EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount),
784            resEGs(maxEgCount), panEGs(maxEgCount), eqEGs(maxEgCount),
785          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),          LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
786          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)          filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount), eqLFOs(maxLfoCount),
787            pVoice(voice)
788      {      {
789          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;          suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
790          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;          suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
791          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;          suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
792            
793            suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
794          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;          suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
795          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;          suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
796          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;          suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
# Line 696  namespace LinuxSampler { namespace sfz { Line 804  namespace LinuxSampler { namespace sfz {
804              EGs[i]->suCutoffOnCC.pVoice = voice;              EGs[i]->suCutoffOnCC.pVoice = voice;
805              EGs[i]->suResOnCC.pVoice = voice;              EGs[i]->suResOnCC.pVoice = voice;
806              EGs[i]->suPanOnCC.pVoice = voice;              EGs[i]->suPanOnCC.pVoice = voice;
807                EGs[i]->SetVoice(voice); // class EqUnitSupport
808          }          }
809                    
810          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
# Line 710  namespace LinuxSampler { namespace sfz { Line 819  namespace LinuxSampler { namespace sfz {
819              LFOs[i]->suPanOnCC.pVoice = voice;              LFOs[i]->suPanOnCC.pVoice = voice;
820              LFOs[i]->suCutoffOnCC.pVoice = voice;              LFOs[i]->suCutoffOnCC.pVoice = voice;
821              LFOs[i]->suResOnCC.pVoice = voice;              LFOs[i]->suResOnCC.pVoice = voice;
822                LFOs[i]->SetVoice(voice); // class EqUnitSupport
823          }          }
824      }      }
825            
# Line 727  namespace LinuxSampler { namespace sfz { Line 837  namespace LinuxSampler { namespace sfz {
837          Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;          Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
838          Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;          Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
839                    
840            EqUnitSupport::InitCCLists(pCCPool, pSmootherPool);
841            
842          suVolOnCC.InitCCList(pCCPool, pSmootherPool);          suVolOnCC.InitCCList(pCCPool, pSmootherPool);
843            suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
844            suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
845            suResOnCC.InitCCList(pCCPool, pSmootherPool);
846          suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);          suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
847          suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);          suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
848          suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);          suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
# Line 745  namespace LinuxSampler { namespace sfz { Line 860  namespace LinuxSampler { namespace sfz {
860              EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);              EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
861              EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);              EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
862              EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);              EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
863                EGs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
864          }          }
865                    
866          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
# Line 756  namespace LinuxSampler { namespace sfz { Line 872  namespace LinuxSampler { namespace sfz {
872              LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);              LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
873              LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);              LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
874              LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);              LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
875                LFOs[i]->InitCCLists(pCCPool, pSmootherPool); // class EqUnitSupport
876          }          }
877      }      }
878            
# Line 766  namespace LinuxSampler { namespace sfz { Line 883  namespace LinuxSampler { namespace sfz {
883          filEGs.clear();          filEGs.clear();
884          resEGs.clear();          resEGs.clear();
885          panEGs.clear();          panEGs.clear();
886            eqEGs.clear();
887                    
888          LFOs.clear();          LFOs.clear();
889          volLFOs.clear();          volLFOs.clear();
# Line 773  namespace LinuxSampler { namespace sfz { Line 891  namespace LinuxSampler { namespace sfz {
891          filLFOs.clear();          filLFOs.clear();
892          resLFOs.clear();          resLFOs.clear();
893          panLFOs.clear();          panLFOs.clear();
894            eqLFOs.clear();
895                    
896          ::sfz::Region* const pRegion = pVoice->pRegion;          ::sfz::Region* const pRegion = pVoice->pRegion;
897                    
898          suVolOnCC.SetCCs(pRegion->volume_oncc);          suVolOnCC.SetCCs(pRegion->volume_oncc);
899            suPitchOnCC.SetCCs(pRegion->pitch_oncc);
900            suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
901            suResOnCC.SetCCs(pRegion->resonance_oncc);
902                    
903          for (int i = 0; i < pRegion->eg.size(); i++) {          for (int i = 0; i < pRegion->eg.size(); i++) {
904              if (pRegion->eg[i].node.size() == 0) continue;              if (pRegion->eg[i].node.size() == 0) continue;
# Line 791  namespace LinuxSampler { namespace sfz { Line 913  namespace LinuxSampler { namespace sfz {
913                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);                  EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
914                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);                  EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
915                  EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);                  EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
916                    if (pVoice->bEqSupport) {
917                        EGs[EGs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->eg[i].eq1freq_oncc);
918                        EGs[EGs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->eg[i].eq2freq_oncc);
919                        EGs[EGs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->eg[i].eq3freq_oncc);
920                        EGs[EGs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->eg[i].eq1gain_oncc);
921                        EGs[EGs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->eg[i].eq2gain_oncc);
922                        EGs[EGs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->eg[i].eq3gain_oncc);
923                        EGs[EGs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->eg[i].eq1bw_oncc);
924                        EGs[EGs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->eg[i].eq2bw_oncc);
925                        EGs[EGs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->eg[i].eq3bw_oncc);
926                    }
927              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
928                            
929              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||              if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
# Line 819  namespace LinuxSampler { namespace sfz { Line 952  namespace LinuxSampler { namespace sfz {
952                  if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);                  if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
953                  else std::cerr << "Maximum number of EGs reached!" << std::endl;                  else std::cerr << "Maximum number of EGs reached!" << std::endl;
954              }              }
955                
956                if (pRegion->eg[i].HasEq()) {
957                    if(eqEGs.size() < eqEGs.capacity()) eqEGs.add(EGs[EGs.size() - 1]);
958                    else std::cerr << "Maximum number of EGs reached!" << std::endl;
959                }
960          }          }
961                    
962          if (pRegion->ampeg_sustain == -1) {          if (pRegion->ampeg_sustain == -1) {
# Line 828  namespace LinuxSampler { namespace sfz { Line 966  namespace LinuxSampler { namespace sfz {
966                    
967          // LFO          // LFO
968          for (int i = 0; i < pRegion->lfos.size(); i++) {          for (int i = 0; i < pRegion->lfos.size(); i++) {
969              if (pRegion->lfos[i].freq == -1) continue; // Not initialized              if (pRegion->lfos[i].freq <= 0) {
970                    if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
971                    else pRegion->lfos[i].freq = 0;
972                }
973                            
974              if(LFOs.size() < LFOs.capacity()) {              if(LFOs.size() < LFOs.capacity()) {
975                  LFOv2Unit lfo(this);                  LFOv2Unit lfo(this);
# Line 840  namespace LinuxSampler { namespace sfz { Line 981  namespace LinuxSampler { namespace sfz {
981                  LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);                  LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
982                  LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);                  LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
983                  LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);                  LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
984                    if (pVoice->bEqSupport) {
985                        LFOs[LFOs.size() - 1]->suEq1FreqOnCC.SetCCs(pRegion->lfos[i].eq1freq_oncc);
986                        LFOs[LFOs.size() - 1]->suEq2FreqOnCC.SetCCs(pRegion->lfos[i].eq2freq_oncc);
987                        LFOs[LFOs.size() - 1]->suEq3FreqOnCC.SetCCs(pRegion->lfos[i].eq3freq_oncc);
988                        LFOs[LFOs.size() - 1]->suEq1GainOnCC.SetCCs(pRegion->lfos[i].eq1gain_oncc);
989                        LFOs[LFOs.size() - 1]->suEq2GainOnCC.SetCCs(pRegion->lfos[i].eq2gain_oncc);
990                        LFOs[LFOs.size() - 1]->suEq3GainOnCC.SetCCs(pRegion->lfos[i].eq3gain_oncc);
991                        LFOs[LFOs.size() - 1]->suEq1BwOnCC.SetCCs(pRegion->lfos[i].eq1bw_oncc);
992                        LFOs[LFOs.size() - 1]->suEq2BwOnCC.SetCCs(pRegion->lfos[i].eq2bw_oncc);
993                        LFOs[LFOs.size() - 1]->suEq3BwOnCC.SetCCs(pRegion->lfos[i].eq3bw_oncc);
994                    }
995              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }              } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
996                            
997              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {              if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
# Line 866  namespace LinuxSampler { namespace sfz { Line 1018  namespace LinuxSampler { namespace sfz {
1018                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);                  if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1019                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;                  else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1020              }              }
1021                
1022                if (pRegion->lfos[i].HasEq()) {
1023                    if(eqLFOs.size() < eqLFOs.capacity()) eqLFOs.add(LFOs[LFOs.size() - 1]);
1024                    else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1025                }
1026            }
1027            
1028            if (!pVoice->bEqSupport) {
1029                bHasEq = false;
1030            } else {
1031                suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
1032                suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
1033                suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
1034                suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
1035                suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
1036                suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
1037                suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
1038                suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
1039                suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
1040            
1041                bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
1042                         pRegion->eq1_vel2gain || pRegion->eq2_vel2gain || pRegion->eq3_vel2gain ||
1043                         suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs() ||
1044                         eqEGs.size() > 0 || eqLFOs.size() > 0;
1045          }          }
1046                    
1047          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);          suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
# Line 879  namespace LinuxSampler { namespace sfz { Line 1055  namespace LinuxSampler { namespace sfz {
1055                    
1056          Units.clear();          Units.clear();
1057                    
1058            EqUnitSupport::ImportUnits(this);
1059            
1060          Units.add(&suVolOnCC);          Units.add(&suVolOnCC);
1061            Units.add(&suPitchOnCC);
1062            Units.add(&suCutoffOnCC);
1063            Units.add(&suResOnCC);
1064                    
1065          Units.add(&suVolEG);          Units.add(&suVolEG);
1066          Units.add(&suFilEG);          Units.add(&suFilEG);
# Line 908  namespace LinuxSampler { namespace sfz { Line 1089  namespace LinuxSampler { namespace sfz {
1089              Units.add(&(EGs[i]->suCutoffOnCC));              Units.add(&(EGs[i]->suCutoffOnCC));
1090              Units.add(&(EGs[i]->suResOnCC));              Units.add(&(EGs[i]->suResOnCC));
1091              Units.add(&(EGs[i]->suPanOnCC));              Units.add(&(EGs[i]->suPanOnCC));
1092                EGs[i]->ImportUnits(this); // class EqUnitSupport
1093          }          }
1094                    
1095          for (int i = 0; i < LFOs.size(); i++) {          for (int i = 0; i < LFOs.size(); i++) {
# Line 919  namespace LinuxSampler { namespace sfz { Line 1101  namespace LinuxSampler { namespace sfz {
1101              Units.add(&(LFOs[i]->suPanOnCC));              Units.add(&(LFOs[i]->suPanOnCC));
1102              Units.add(&(LFOs[i]->suCutoffOnCC));              Units.add(&(LFOs[i]->suCutoffOnCC));
1103              Units.add(&(LFOs[i]->suResOnCC));              Units.add(&(LFOs[i]->suResOnCC));
1104                LFOs[i]->ImportUnits(this); // class EqUnitSupport
1105          }          }
1106                    
1107          Units.add(&suEndpoint);          Units.add(&suEndpoint);
# Line 940  namespace LinuxSampler { namespace sfz { Line 1123  namespace LinuxSampler { namespace sfz {
1123              volEGs[i]->EG.enterFadeOutStage();              volEGs[i]->EG.enterFadeOutStage();
1124          }          }
1125      }      }
1126        
1127        void SfzSignalUnitRack::EnterFadeOutStage(int maxFadeOutSteps) {
1128            suVolEG.EG.enterFadeOutStage(maxFadeOutSteps);
1129            for (int i = 0; i < volEGs.size(); i++) {
1130                volEGs[i]->EG.enterFadeOutStage(maxFadeOutSteps);
1131            }
1132        }
1133    
1134      void SfzSignalUnitRack::Reset() {      void SfzSignalUnitRack::Reset() {
1135            EqUnitSupport::ResetUnits();
1136            
1137          suVolOnCC.RemoveAllCCs();          suVolOnCC.RemoveAllCCs();
1138            suPitchOnCC.RemoveAllCCs();
1139            suCutoffOnCC.RemoveAllCCs();
1140            suResOnCC.RemoveAllCCs();
1141          suEndpoint.suXFInCC.RemoveAllCCs();          suEndpoint.suXFInCC.RemoveAllCCs();
1142          suEndpoint.suXFOutCC.RemoveAllCCs();          suEndpoint.suXFOutCC.RemoveAllCCs();
1143          suEndpoint.suPanOnCC.RemoveAllCCs();          suEndpoint.suPanOnCC.RemoveAllCCs();
# Line 960  namespace LinuxSampler { namespace sfz { Line 1155  namespace LinuxSampler { namespace sfz {
1155              EGs[i]->suCutoffOnCC.RemoveAllCCs();              EGs[i]->suCutoffOnCC.RemoveAllCCs();
1156              EGs[i]->suResOnCC.RemoveAllCCs();              EGs[i]->suResOnCC.RemoveAllCCs();
1157              EGs[i]->suPanOnCC.RemoveAllCCs();              EGs[i]->suPanOnCC.RemoveAllCCs();
1158                EGs[i]->ResetUnits(); // class EqUnitSupport
1159          }          }
1160                    
1161          for (int i = 0; i < LFOs.capacity(); i++) {          for (int i = 0; i < LFOs.capacity(); i++) {
# Line 971  namespace LinuxSampler { namespace sfz { Line 1167  namespace LinuxSampler { namespace sfz {
1167              LFOs[i]->suPanOnCC.RemoveAllCCs();              LFOs[i]->suPanOnCC.RemoveAllCCs();
1168              LFOs[i]->suCutoffOnCC.RemoveAllCCs();              LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1169              LFOs[i]->suResOnCC.RemoveAllCCs();              LFOs[i]->suResOnCC.RemoveAllCCs();
1170                LFOs[i]->ResetUnits(); // class EqUnitSupport
1171            }
1172        }
1173    
1174        void SfzSignalUnitRack::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
1175            suVolEG.EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1176            for (int i = 0; i < EGs.capacity(); i++) {
1177                EGs[i]->EG.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
1178            }
1179        }
1180        
1181        void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1182            if (!pEqSupport->HasSupport()) return;
1183            if (pEqSupport->GetBandCount() < 3) {
1184                std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1185                return;
1186            }
1187            
1188            ::sfz::Region* const pRegion = pVoice->pRegion;
1189            
1190            float dB1 = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1191            float dB2 = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1192            float dB3 = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1193            
1194            float freq1 = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1195            float freq2 = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1196            float freq3 = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1197            
1198            float bw1 = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1199            float bw2 = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1200            float bw3 = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1201            
1202            const float vel = pVoice->MIDIVelocity() / 127.0f;
1203            
1204            dB1 += pRegion->eq1_vel2gain * vel;
1205            dB2 += pRegion->eq2_vel2gain * vel;
1206            dB3 += pRegion->eq3_vel2gain * vel;
1207            
1208            freq1 += pRegion->eq1_vel2freq * vel;
1209            freq2 += pRegion->eq2_vel2freq * vel;
1210            freq3 += pRegion->eq3_vel2freq * vel;
1211            
1212            for (int i = 0; i < eqEGs.size(); i++) {
1213                EGv2Unit* eg = eqEGs[i];
1214                if (!eg->Active()) continue;
1215                
1216                float l = eg->GetLevel();
1217                dB1 += ((eg->suEq1GainOnCC.Active() ? eg->suEq1GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq1gain) * l;
1218                dB2 += ((eg->suEq2GainOnCC.Active() ? eg->suEq2GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq2gain) * l;
1219                dB3 += ((eg->suEq3GainOnCC.Active() ? eg->suEq3GainOnCC.GetLevel() : 0) + eg->pEGInfo->eq3gain) * l;
1220                
1221                freq1 += ((eg->suEq1FreqOnCC.Active() ? eg->suEq1FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq1freq) * l;
1222                freq2 += ((eg->suEq2FreqOnCC.Active() ? eg->suEq2FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq2freq) * l;
1223                freq3 += ((eg->suEq3FreqOnCC.Active() ? eg->suEq3FreqOnCC.GetLevel() : 0) + eg->pEGInfo->eq3freq) * l;
1224                
1225                bw1 += ((eg->suEq1BwOnCC.Active() ? eg->suEq1BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq1bw) * l;
1226                bw2 += ((eg->suEq2BwOnCC.Active() ? eg->suEq2BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq2bw) * l;
1227                bw3 += ((eg->suEq3BwOnCC.Active() ? eg->suEq3BwOnCC.GetLevel() : 0) + eg->pEGInfo->eq3bw) * l;
1228          }          }
1229            
1230            for (int i = 0; i < eqLFOs.size(); i++) {
1231                LFOv2Unit* lfo = eqLFOs[i];
1232                if (!lfo->Active()) continue;
1233                
1234                float l = lfo->GetLevel();
1235                dB1 += ((lfo->suEq1GainOnCC.Active() ? lfo->suEq1GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1gain) * l;
1236                dB2 += ((lfo->suEq2GainOnCC.Active() ? lfo->suEq2GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2gain) * l;
1237                dB3 += ((lfo->suEq3GainOnCC.Active() ? lfo->suEq3GainOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3gain) * l;
1238                
1239                freq1 += ((lfo->suEq1FreqOnCC.Active() ? lfo->suEq1FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1freq) * l;
1240                freq2 += ((lfo->suEq2FreqOnCC.Active() ? lfo->suEq2FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2freq) * l;
1241                freq3 += ((lfo->suEq3FreqOnCC.Active() ? lfo->suEq3FreqOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3freq) * l;
1242                
1243                bw1 += ((lfo->suEq1BwOnCC.Active() ? lfo->suEq1BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq1bw) * l;
1244                bw2 += ((lfo->suEq2BwOnCC.Active() ? lfo->suEq2BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq2bw) * l;
1245                bw3 += ((lfo->suEq3BwOnCC.Active() ? lfo->suEq3BwOnCC.GetLevel() : 0) + lfo->pLfoInfo->eq3bw) * l;
1246            }
1247            
1248            pEqSupport->SetGain(0, dB1);
1249            pEqSupport->SetGain(1, dB2);
1250            pEqSupport->SetGain(2, dB3);
1251            
1252            pEqSupport->SetFreq(0, freq1);
1253            pEqSupport->SetFreq(1, freq2);
1254            pEqSupport->SetFreq(2, freq3);
1255            
1256            pEqSupport->SetBandwidth(0, bw1);
1257            pEqSupport->SetBandwidth(1, bw2);
1258            pEqSupport->SetBandwidth(2, bw3);
1259        }
1260        
1261        EqUnitSupport::EqUnitSupport(SfzSignalUnitRack* pRack, Voice* pVoice)
1262            : suEq1GainOnCC(pRack), suEq2GainOnCC(pRack), suEq3GainOnCC(pRack),
1263              suEq1FreqOnCC(pRack), suEq2FreqOnCC(pRack), suEq3FreqOnCC(pRack),
1264              suEq1BwOnCC(pRack), suEq2BwOnCC(pRack), suEq3BwOnCC(pRack)
1265        {
1266            SetVoice(pVoice);
1267        }
1268        
1269        void EqUnitSupport::SetVoice(Voice* pVoice) {
1270            suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = pVoice;
1271            suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = pVoice;
1272            suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = pVoice;
1273        }
1274        
1275        void EqUnitSupport::ImportUnits(SfzSignalUnitRack* pRack) {
1276            if (suEq1GainOnCC.HasCCs()) pRack->Units.add(&suEq1GainOnCC);
1277            if (suEq2GainOnCC.HasCCs()) pRack->Units.add(&suEq2GainOnCC);
1278            if (suEq3GainOnCC.HasCCs()) pRack->Units.add(&suEq3GainOnCC);
1279            if (suEq1FreqOnCC.HasCCs()) pRack->Units.add(&suEq1FreqOnCC);
1280            if (suEq2FreqOnCC.HasCCs()) pRack->Units.add(&suEq2FreqOnCC);
1281            if (suEq3FreqOnCC.HasCCs()) pRack->Units.add(&suEq3FreqOnCC);
1282            if (suEq1BwOnCC.HasCCs()) pRack->Units.add(&suEq1BwOnCC);
1283            if (suEq2BwOnCC.HasCCs()) pRack->Units.add(&suEq2BwOnCC);
1284            if (suEq3BwOnCC.HasCCs()) pRack->Units.add(&suEq3BwOnCC);
1285        }
1286        
1287        void EqUnitSupport::ResetUnits() {
1288            suEq1GainOnCC.RemoveAllCCs();
1289            suEq2GainOnCC.RemoveAllCCs();
1290            suEq3GainOnCC.RemoveAllCCs();
1291            suEq1FreqOnCC.RemoveAllCCs();
1292            suEq2FreqOnCC.RemoveAllCCs();
1293            suEq3FreqOnCC.RemoveAllCCs();
1294            suEq1BwOnCC.RemoveAllCCs();
1295            suEq2BwOnCC.RemoveAllCCs();
1296            suEq3BwOnCC.RemoveAllCCs();
1297        }
1298        
1299        void EqUnitSupport::InitCCLists(Pool<CCSignalUnit::CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
1300            suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
1301            suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
1302            suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
1303            suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1304            suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1305            suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
1306            suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
1307            suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
1308            suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
1309      }      }
1310            
1311  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2244  
changed lines
  Added in v.3054

  ViewVC Help
Powered by ViewVC