/[svn]/linuxsampler/trunk/src/engines/gig/EGADSR.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/EGADSR.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 830 by persson, Sun Jan 15 18:23:11 2006 UTC revision 1748 by persson, Sun Jun 22 14:46:46 2008 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 Christian Schoenebeck                              *   *   Copyright (C) 2005 - 2007 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   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 23  Line 23 
23    
24  #include "EGADSR.h"  #include "EGADSR.h"
25    
26    #include "../../common/global_private.h"
27    
28  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
29    
30      EGADSR::EGADSR() {      EGADSR::EGADSR() {
# Line 209  namespace LinuxSampler { namespace gig { Line 211  namespace LinuxSampler { namespace gig {
211              Level = (float) PreAttack / 1000.0;              Level = (float) PreAttack / 1000.0;
212              Coeff = 0.896f * (1.0f - Level) / StepsLeft; // max level is a bit lower if attack != 0              Coeff = 0.896f * (1.0f - Level) / StepsLeft; // max level is a bit lower if attack != 0
213          } else { // attack is zero - immediately jump to the next stage          } else { // attack is zero - immediately jump to the next stage
214              Level = 1.0;              Level = 1.029f; // a bit higher than max sustain
215              if (HoldAttack) enterAttackHoldStage();              if (HoldAttack) enterAttackHoldStage();
216              else            enterDecay1Part1Stage(SampleRate);              else            enterDecay1Part1Stage(SampleRate);
217          }          }
# Line 234  namespace LinuxSampler { namespace gig { Line 236  namespace LinuxSampler { namespace gig {
236          // (where d is 1/SampleRate). The transition from f to g is          // (where d is 1/SampleRate). The transition from f to g is
237          // done when f(x) has reached Level2 = 25% of full volume.          // done when f(x) has reached Level2 = 25% of full volume.
238          StepsLeft = (int) (Decay1Time * SampleRate);          StepsLeft = (int) (Decay1Time * SampleRate);
239          if (StepsLeft && SustainLevel < 1.0 && Level > SustainLevel) {          if (StepsLeft && Level > SustainLevel) {
240              Stage        = stage_decay1_part1;              Stage        = stage_decay1_part1;
241              Segment      = segment_lin;              Segment      = segment_lin;
242              Decay1Slope  = 1.365 * (SustainLevel - 1.0) / StepsLeft;              Decay1Slope = (1.347f * SustainLevel - 1.361f) / StepsLeft;
243              Coeff        = Decay1Slope * invVolume;              Coeff        = Decay1Slope * invVolume;
244              Decay1Level2 = 0.25 * invVolume;              Decay1Level2 = 0.25 * invVolume;
245              if (Level < Decay1Level2) enterDecay1Part2Stage(SampleRate);              StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
246              else StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);              if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
247          } else {          } else {
248              if (InfiniteSustain) enterSustainStage();              if (InfiniteSustain) enterSustainStage();
249              else                 enterDecay2Stage(SampleRate);              else                 enterDecay2Stage(SampleRate);
# Line 256  namespace LinuxSampler { namespace gig { Line 258  namespace LinuxSampler { namespace gig {
258              Coeff  = exp(Decay1Slope);              Coeff  = exp(Decay1Slope);
259              Offset = ExpOffset * (1 - Coeff);              Offset = ExpOffset * (1 - Coeff);
260              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
261          } else {              if (StepsLeft > 0) return;
             if (InfiniteSustain) enterSustainStage();  
             else                 enterDecay2Stage(SampleRate);  
262          }          }
263            if (InfiniteSustain) enterSustainStage();
264            else                 enterDecay2Stage(SampleRate);
265      }      }
266    
267      void EGADSR::enterDecay2Stage(const uint SampleRate) {      void EGADSR::enterDecay2Stage(const uint SampleRate) {
268          Stage      = stage_decay2;          Stage      = stage_decay2;
269          Segment    = segment_lin;          Segment    = segment_lin;
270          Decay2Time = RTMath::Max(Decay2Time, CONFIG_EG_MIN_RELEASE_TIME);          Decay2Time = RTMath::Max(Decay2Time, 0.05f);
271          StepsLeft  = (int) (Decay2Time * SampleRate);          StepsLeft  = (int) (Decay2Time * SampleRate);
272          Coeff      = (-1.03 / StepsLeft) * invVolume;          Coeff      = (-1.03 / StepsLeft) * invVolume;
273          //FIXME: do we really have to calculate 'StepsLeft' two times?          //FIXME: do we really have to calculate 'StepsLeft' two times?
274          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);
275          if (StepsLeft == 0) enterEndStage();          if (StepsLeft <= 0) enterEndStage();
276      }      }
277    
278      void EGADSR::enterSustainStage() {      void EGADSR::enterSustainStage() {
# Line 286  namespace LinuxSampler { namespace gig { Line 288  namespace LinuxSampler { namespace gig {
288          Segment   = segment_lin;          Segment   = segment_lin;
289          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
290          Coeff     = ReleaseCoeff;          Coeff     = ReleaseCoeff;
291            if (StepsLeft <= 0) enterReleasePart2Stage();
292      }      }
293    
294      void EGADSR::enterReleasePart2Stage() {      void EGADSR::enterReleasePart2Stage() {
# Line 294  namespace LinuxSampler { namespace gig { Line 297  namespace LinuxSampler { namespace gig {
297          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);
298          Coeff     = ReleaseCoeff2;          Coeff     = ReleaseCoeff2;
299          Offset    = ReleaseCoeff3;          Offset    = ReleaseCoeff3;
300            if (StepsLeft <= 0) enterFadeOutStage();
301      }      }
302    
303      void EGADSR::enterFadeOutStage() {      void EGADSR::enterFadeOutStage() {
# Line 301  namespace LinuxSampler { namespace gig { Line 305  namespace LinuxSampler { namespace gig {
305          Segment   = segment_lin;          Segment   = segment_lin;
306          StepsLeft = int(Level / (-FadeOutCoeff));          StepsLeft = int(Level / (-FadeOutCoeff));
307          Coeff     = FadeOutCoeff;          Coeff     = FadeOutCoeff;
308          if (StepsLeft == 0) enterEndStage();          if (StepsLeft <= 0) enterEndStage();
309        }
310    
311        void EGADSR::enterFadeOutStage(int maxFadeOutSteps) {
312            Stage     = stage_fadeout;
313            Segment   = segment_lin;
314            StepsLeft = int(Level / (-FadeOutCoeff));
315            if (StepsLeft > maxFadeOutSteps) {
316                StepsLeft = maxFadeOutSteps;
317                Coeff = -Level / maxFadeOutSteps;
318            } else {
319                Coeff = FadeOutCoeff;
320            }
321            if (StepsLeft <= 0) enterEndStage();
322      }      }
323    
324      void EGADSR::enterEndStage() {      void EGADSR::enterEndStage() {

Legend:
Removed from v.830  
changed lines
  Added in v.1748

  ViewVC Help
Powered by ViewVC