/[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 1906 by persson, Sat May 16 12:14:27 2009 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 - 2009 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 45  namespace LinuxSampler { namespace gig { Line 47  namespace LinuxSampler { namespace gig {
47                      case event_release:                      case event_release:
48                          enterReleasePart1Stage();                          enterReleasePart1Stage();
49                          break;                          break;
                     case event_cancel_release:  
                         enterSustainStage();  
                         break;  
50                      case event_stage_end:                      case event_stage_end:
51                          if (HoldAttack)                          if (HoldAttack)
52                              enterAttackHoldStage();                              enterAttackHoldStage();
# Line 69  namespace LinuxSampler { namespace gig { Line 68  namespace LinuxSampler { namespace gig {
68                      case event_release:                      case event_release:
69                          enterReleasePart1Stage();                          enterReleasePart1Stage();
70                          break;                          break;
                     case event_cancel_release:  
                         if (InfiniteSustain)  
                             enterSustainStage();  
                         else  
                             enterDecay1Part1Stage(SampleRate);  
                         break;  
71                  }                  }
72                  break;                  break;
73              case stage_decay1_part1:              case stage_decay1_part1:
# Line 82  namespace LinuxSampler { namespace gig { Line 75  namespace LinuxSampler { namespace gig {
75                      case event_stage_end:                      case event_stage_end:
76                          enterDecay1Part2Stage(SampleRate);                          enterDecay1Part2Stage(SampleRate);
77                          break;                          break;
                     case event_release:  
                         enterReleasePart1Stage();  
                         break;  
78                      case event_cancel_release:                      case event_cancel_release:
79                          if (InfiniteSustain)                          if (InfiniteSustain)
80                              enterSustainStage();                              enterSustainStage();
# Line 98  namespace LinuxSampler { namespace gig { Line 88  namespace LinuxSampler { namespace gig {
88                      case event_release:                      case event_release:
89                          enterReleasePart1Stage();                          enterReleasePart1Stage();
90                          break;                          break;
91                      case event_stage_end: // fall through                      case event_stage_end:
                     case event_cancel_release:  
92                          if (Level < CONFIG_EG_BOTTOM)                          if (Level < CONFIG_EG_BOTTOM)
93                              enterEndStage();                              enterEndStage();
94                          else if (InfiniteSustain)                          else if (InfiniteSustain)
# Line 209  namespace LinuxSampler { namespace gig { Line 198  namespace LinuxSampler { namespace gig {
198              Level = (float) PreAttack / 1000.0;              Level = (float) PreAttack / 1000.0;
199              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
200          } else { // attack is zero - immediately jump to the next stage          } else { // attack is zero - immediately jump to the next stage
201              Level = 1.0;              Level = 1.029f; // a bit higher than max sustain
202              if (HoldAttack) enterAttackHoldStage();              if (HoldAttack) enterAttackHoldStage();
203              else            enterDecay1Part1Stage(SampleRate);              else            enterDecay1Part1Stage(SampleRate);
204          }          }
# Line 234  namespace LinuxSampler { namespace gig { Line 223  namespace LinuxSampler { namespace gig {
223          // (where d is 1/SampleRate). The transition from f to g is          // (where d is 1/SampleRate). The transition from f to g is
224          // done when f(x) has reached Level2 = 25% of full volume.          // done when f(x) has reached Level2 = 25% of full volume.
225          StepsLeft = (int) (Decay1Time * SampleRate);          StepsLeft = (int) (Decay1Time * SampleRate);
226          if (StepsLeft && SustainLevel < 1.0 && Level > SustainLevel) {          if (StepsLeft && Level > SustainLevel) {
227              Stage        = stage_decay1_part1;              Stage        = stage_decay1_part1;
228              Segment      = segment_lin;              Segment      = segment_lin;
229              Decay1Slope  = 1.365 * (SustainLevel - 1.0) / StepsLeft;              Decay1Slope = (1.347f * SustainLevel - 1.361f) / StepsLeft;
230              Coeff        = Decay1Slope * invVolume;              Coeff        = Decay1Slope * invVolume;
231              Decay1Level2 = 0.25 * invVolume;              Decay1Level2 = 0.25 * invVolume;
232              if (Level < Decay1Level2) enterDecay1Part2Stage(SampleRate);              StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
233              else StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);              if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
234          } else {          } else {
235              if (InfiniteSustain) enterSustainStage();              if (InfiniteSustain) enterSustainStage();
236              else                 enterDecay2Stage(SampleRate);              else                 enterDecay2Stage(SampleRate);
# Line 256  namespace LinuxSampler { namespace gig { Line 245  namespace LinuxSampler { namespace gig {
245              Coeff  = exp(Decay1Slope);              Coeff  = exp(Decay1Slope);
246              Offset = ExpOffset * (1 - Coeff);              Offset = ExpOffset * (1 - Coeff);
247              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
248          } else {              if (StepsLeft > 0) return;
             if (InfiniteSustain) enterSustainStage();  
             else                 enterDecay2Stage(SampleRate);  
249          }          }
250            if (InfiniteSustain) enterSustainStage();
251            else                 enterDecay2Stage(SampleRate);
252      }      }
253    
254      void EGADSR::enterDecay2Stage(const uint SampleRate) {      void EGADSR::enterDecay2Stage(const uint SampleRate) {
255          Stage      = stage_decay2;          Stage      = stage_decay2;
256          Segment    = segment_lin;          Segment    = segment_lin;
257          Decay2Time = RTMath::Max(Decay2Time, CONFIG_EG_MIN_RELEASE_TIME);          Decay2Time = RTMath::Max(Decay2Time, 0.05f);
258          StepsLeft  = (int) (Decay2Time * SampleRate);          StepsLeft  = (int) (Decay2Time * SampleRate);
259          Coeff      = (-1.03 / StepsLeft) * invVolume;          Coeff      = (-1.03 / StepsLeft) * invVolume;
260          //FIXME: do we really have to calculate 'StepsLeft' two times?          //FIXME: do we really have to calculate 'StepsLeft' two times?
261          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);
262          if (StepsLeft == 0) enterEndStage();          if (StepsLeft <= 0) enterEndStage();
263      }      }
264    
265      void EGADSR::enterSustainStage() {      void EGADSR::enterSustainStage() {
# Line 286  namespace LinuxSampler { namespace gig { Line 275  namespace LinuxSampler { namespace gig {
275          Segment   = segment_lin;          Segment   = segment_lin;
276          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
277          Coeff     = ReleaseCoeff;          Coeff     = ReleaseCoeff;
278            if (StepsLeft <= 0) enterReleasePart2Stage();
279      }      }
280    
281      void EGADSR::enterReleasePart2Stage() {      void EGADSR::enterReleasePart2Stage() {
# Line 294  namespace LinuxSampler { namespace gig { Line 284  namespace LinuxSampler { namespace gig {
284          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);
285          Coeff     = ReleaseCoeff2;          Coeff     = ReleaseCoeff2;
286          Offset    = ReleaseCoeff3;          Offset    = ReleaseCoeff3;
287            if (StepsLeft <= 0) enterFadeOutStage();
288      }      }
289    
290      void EGADSR::enterFadeOutStage() {      void EGADSR::enterFadeOutStage() {
# Line 301  namespace LinuxSampler { namespace gig { Line 292  namespace LinuxSampler { namespace gig {
292          Segment   = segment_lin;          Segment   = segment_lin;
293          StepsLeft = int(Level / (-FadeOutCoeff));          StepsLeft = int(Level / (-FadeOutCoeff));
294          Coeff     = FadeOutCoeff;          Coeff     = FadeOutCoeff;
295          if (StepsLeft == 0) enterEndStage();          if (StepsLeft <= 0) enterEndStage();
296        }
297    
298        void EGADSR::enterFadeOutStage(int maxFadeOutSteps) {
299            Stage     = stage_fadeout;
300            Segment   = segment_lin;
301            StepsLeft = int(Level / (-FadeOutCoeff));
302            if (StepsLeft > maxFadeOutSteps) {
303                StepsLeft = maxFadeOutSteps;
304                Coeff = -Level / maxFadeOutSteps;
305            } else {
306                Coeff = FadeOutCoeff;
307            }
308            if (StepsLeft <= 0) enterEndStage();
309      }      }
310    
311      void EGADSR::enterEndStage() {      void EGADSR::enterEndStage() {

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

  ViewVC Help
Powered by ViewVC