/[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 2408 by persson, Sat Feb 2 08:22:49 2013 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 - 2013 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  namespace LinuxSampler { namespace gig {  #include "../../common/global_private.h"
   
     EGADSR::EGADSR() {  
         enterEndStage();  
         Level = 0.0;  
         CalculateFadeOutCoeff(CONFIG_EG_MIN_RELEASE_TIME, 44100.0); // even if the sample rate will be 192kHz it won't hurt at all  
     }  
27    
28      void EGADSR::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {  namespace LinuxSampler { namespace gig {
         const float killSteps = FadeOutTime * SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;  
         FadeOutCoeff = -1.0f / killSteps;  
     }  
29    
30      void EGADSR::update(event_t Event, uint SampleRate) {      void EGADSR::update(event_t Event, uint SampleRate) {
31            if (atEnd(Event)) return;
32    
33          if (Event == event_hold_end) HoldAttack = false;          if (Event == event_hold_end) HoldAttack = false;
34    
35          switch (Stage) {          switch (Stage) {
# Line 45  namespace LinuxSampler { namespace gig { Line 38  namespace LinuxSampler { namespace gig {
38                      case event_release:                      case event_release:
39                          enterReleasePart1Stage();                          enterReleasePart1Stage();
40                          break;                          break;
                     case event_cancel_release:  
                         enterSustainStage();  
                         break;  
41                      case event_stage_end:                      case event_stage_end:
42                          if (HoldAttack)                          if (HoldAttack)
43                              enterAttackHoldStage();                              enterAttackHoldStage();
# Line 69  namespace LinuxSampler { namespace gig { Line 59  namespace LinuxSampler { namespace gig {
59                      case event_release:                      case event_release:
60                          enterReleasePart1Stage();                          enterReleasePart1Stage();
61                          break;                          break;
                     case event_cancel_release:  
                         if (InfiniteSustain)  
                             enterSustainStage();  
                         else  
                             enterDecay1Part1Stage(SampleRate);  
                         break;  
62                  }                  }
63                  break;                  break;
64              case stage_decay1_part1:              case stage_decay1_part1:
# Line 85  namespace LinuxSampler { namespace gig { Line 69  namespace LinuxSampler { namespace gig {
69                      case event_release:                      case event_release:
70                          enterReleasePart1Stage();                          enterReleasePart1Stage();
71                          break;                          break;
                     case event_cancel_release:  
                         if (InfiniteSustain)  
                             enterSustainStage();  
                         else  
                             enterDecay2Stage(SampleRate);  
                         break;  
72                  }                  }
73                  break;                  break;
74              case stage_decay1_part2:              case stage_decay1_part2:
# Line 98  namespace LinuxSampler { namespace gig { Line 76  namespace LinuxSampler { namespace gig {
76                      case event_release:                      case event_release:
77                          enterReleasePart1Stage();                          enterReleasePart1Stage();
78                          break;                          break;
79                      case event_stage_end: // fall through                      case event_stage_end:
                     case event_cancel_release:  
80                          if (Level < CONFIG_EG_BOTTOM)                          if (Level < CONFIG_EG_BOTTOM)
81                              enterEndStage();                              enterEndStage();
82                          else if (InfiniteSustain)                          else if (InfiniteSustain)
# Line 163  namespace LinuxSampler { namespace gig { Line 140  namespace LinuxSampler { namespace gig {
140                          break;                          break;
141                  }                  }
142                  break;                  break;
             case stage_fadeout:  
                 switch (Event) {  
                     case event_stage_end:  
                         enterEndStage();  
                         break;  
                 }  
                 break;  
143          }          }
144      }      }
145    
# Line 194  namespace LinuxSampler { namespace gig { Line 164  namespace LinuxSampler { namespace gig {
164          ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);          ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);
165          ReleaseLevel2 = 0.25 * invVolume;          ReleaseLevel2 = 0.25 * invVolume;
166    
167            enterFirstStage();
168          enterAttackStage(PreAttack, AttackTime, SampleRate);          enterAttackStage(PreAttack, AttackTime, SampleRate);
169      }      }
170    
# Line 201  namespace LinuxSampler { namespace gig { Line 172  namespace LinuxSampler { namespace gig {
172          Stage   = stage_attack;          Stage   = stage_attack;
173          Segment = segment_lin;          Segment = segment_lin;
174    
175          if (AttackTime >= 0.0005f) {          if (AttackTime >= 1e-8) {
176              // Measurements of GSt output shows that the real attack time              // Measurements of GSt output shows that the real attack time
177              // is about 65.5% of the value specified in the gig file.              // is about 65.5% of the value specified in the gig file.
178              // The minimum attack value used is 0.032.              // The minimum attack value used is 0.0316.
179              StepsLeft = int(0.655f * RTMath::Max(AttackTime, 0.032f) * SampleRate);              StepsLeft = int(0.655f * RTMath::Max(AttackTime, 0.0316f) * SampleRate);
180              Level = (float) PreAttack / 1000.0;              Level = (float) PreAttack / 1000.0;
181              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
182          } else { // attack is zero - immediately jump to the next stage          } else { // attack is zero - immediately jump to the next stage
183              Level = 1.0;              Level = 1.029f; // a bit higher than max sustain
184              if (HoldAttack) enterAttackHoldStage();              if (HoldAttack) enterAttackHoldStage();
185              else            enterDecay1Part1Stage(SampleRate);              else            enterDecay1Part1Stage(SampleRate);
186          }          }
# Line 234  namespace LinuxSampler { namespace gig { Line 205  namespace LinuxSampler { namespace gig {
205          // (where d is 1/SampleRate). The transition from f to g is          // (where d is 1/SampleRate). The transition from f to g is
206          // done when f(x) has reached Level2 = 25% of full volume.          // done when f(x) has reached Level2 = 25% of full volume.
207          StepsLeft = (int) (Decay1Time * SampleRate);          StepsLeft = (int) (Decay1Time * SampleRate);
208          if (StepsLeft && SustainLevel < 1.0 && Level > SustainLevel) {          if (StepsLeft && Level > SustainLevel) {
209              Stage        = stage_decay1_part1;              Stage        = stage_decay1_part1;
210              Segment      = segment_lin;              Segment      = segment_lin;
211              Decay1Slope  = 1.365 * (SustainLevel - 1.0) / StepsLeft;              Decay1Slope = (1.347f * SustainLevel - 1.361f) / StepsLeft;
212              Coeff        = Decay1Slope * invVolume;              Coeff        = Decay1Slope * invVolume;
213              Decay1Level2 = 0.25 * invVolume;              Decay1Level2 = 0.25 * invVolume;
214              if (Level < Decay1Level2) enterDecay1Part2Stage(SampleRate);              StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
215              else StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);              if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
216          } else {          } else {
217              if (InfiniteSustain) enterSustainStage();              if (InfiniteSustain) enterSustainStage();
218              else                 enterDecay2Stage(SampleRate);              else                 enterDecay2Stage(SampleRate);
# Line 256  namespace LinuxSampler { namespace gig { Line 227  namespace LinuxSampler { namespace gig {
227              Coeff  = exp(Decay1Slope);              Coeff  = exp(Decay1Slope);
228              Offset = ExpOffset * (1 - Coeff);              Offset = ExpOffset * (1 - Coeff);
229              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
230          } else {              if (StepsLeft > 0) return;
             if (InfiniteSustain) enterSustainStage();  
             else                 enterDecay2Stage(SampleRate);  
231          }          }
232            if (InfiniteSustain) enterSustainStage();
233            else                 enterDecay2Stage(SampleRate);
234      }      }
235    
236      void EGADSR::enterDecay2Stage(const uint SampleRate) {      void EGADSR::enterDecay2Stage(const uint SampleRate) {
237          Stage      = stage_decay2;          Stage      = stage_decay2;
238          Segment    = segment_lin;          Segment    = segment_lin;
239          Decay2Time = RTMath::Max(Decay2Time, CONFIG_EG_MIN_RELEASE_TIME);          Decay2Time = RTMath::Max(Decay2Time, 0.05f);
240          StepsLeft  = (int) (Decay2Time * SampleRate);          StepsLeft  = (int) (Decay2Time * SampleRate);
241          Coeff      = (-1.03 / StepsLeft) * invVolume;          Coeff      = (-1.03 / StepsLeft) * invVolume;
242          //FIXME: do we really have to calculate 'StepsLeft' two times?          //FIXME: do we really have to calculate 'StepsLeft' two times?
243          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);
244          if (StepsLeft == 0) enterEndStage();          if (StepsLeft <= 0) enterEndStage();
245      }      }
246    
247      void EGADSR::enterSustainStage() {      void EGADSR::enterSustainStage() {
# Line 286  namespace LinuxSampler { namespace gig { Line 257  namespace LinuxSampler { namespace gig {
257          Segment   = segment_lin;          Segment   = segment_lin;
258          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
259          Coeff     = ReleaseCoeff;          Coeff     = ReleaseCoeff;
260            if (StepsLeft <= 0) enterReleasePart2Stage();
261      }      }
262    
263      void EGADSR::enterReleasePart2Stage() {      void EGADSR::enterReleasePart2Stage() {
# Line 294  namespace LinuxSampler { namespace gig { Line 266  namespace LinuxSampler { namespace gig {
266          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);
267          Coeff     = ReleaseCoeff2;          Coeff     = ReleaseCoeff2;
268          Offset    = ReleaseCoeff3;          Offset    = ReleaseCoeff3;
269      }          if (StepsLeft <= 0) enterFadeOutStage();
   
     void EGADSR::enterFadeOutStage() {  
         Stage     = stage_fadeout;  
         Segment   = segment_lin;  
         StepsLeft = int(Level / (-FadeOutCoeff));  
         Coeff     = FadeOutCoeff;  
         if (StepsLeft == 0) enterEndStage();  
     }  
   
     void EGADSR::enterEndStage() {  
         Stage   = stage_end;  
         Segment = segment_end;  
         Level   = 0;  
270      }      }
271    
272  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

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

  ViewVC Help
Powered by ViewVC