/[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 797 by persson, Wed Nov 2 19:26:15 2005 UTC revision 3034 by schoenebeck, Mon Oct 31 00:05:00 2016 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 - 2016 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();
44                          else                          else
45                              enterDecay1Part1Stage(SampleRate);                              enterDecay1Part1Stage(SampleRate);
46                          break;                          break;
47                        default: ; // noop
48                  }                  }
49                  break;                  break;
50              case stage_attack_hold:              case stage_attack_hold:
# Line 69  namespace LinuxSampler { namespace gig { Line 60  namespace LinuxSampler { namespace gig {
60                      case event_release:                      case event_release:
61                          enterReleasePart1Stage();                          enterReleasePart1Stage();
62                          break;                          break;
63                      case event_cancel_release:                      default: ; // noop
                         if (InfiniteSustain)  
                             enterSustainStage();  
                         else  
                             enterDecay1Part1Stage(SampleRate);  
                         break;  
64                  }                  }
65                  break;                  break;
66              case stage_decay1_part1:              case stage_decay1_part1:
# Line 85  namespace LinuxSampler { namespace gig { Line 71  namespace LinuxSampler { namespace gig {
71                      case event_release:                      case event_release:
72                          enterReleasePart1Stage();                          enterReleasePart1Stage();
73                          break;                          break;
74                      case event_cancel_release:                      default: ; // noop
                         if (InfiniteSustain)  
                             enterSustainStage();  
                         else  
                             enterDecay2Stage(SampleRate);  
                         break;  
75                  }                  }
76                  break;                  break;
77              case stage_decay1_part2:              case stage_decay1_part2:
# Line 98  namespace LinuxSampler { namespace gig { Line 79  namespace LinuxSampler { namespace gig {
79                      case event_release:                      case event_release:
80                          enterReleasePart1Stage();                          enterReleasePart1Stage();
81                          break;                          break;
82                      case event_stage_end: // fall through                      case event_stage_end:
                     case event_cancel_release:  
83                          if (Level < CONFIG_EG_BOTTOM)                          if (Level < CONFIG_EG_BOTTOM)
84                              enterEndStage();                              enterEndStage();
85                          else if (InfiniteSustain)                          else if (InfiniteSustain)
# Line 107  namespace LinuxSampler { namespace gig { Line 87  namespace LinuxSampler { namespace gig {
87                          else                          else
88                              enterDecay2Stage(SampleRate);                              enterDecay2Stage(SampleRate);
89                          break;                          break;
90                        default: ; // noop
91                  }                  }
92                  break;                  break;
93              case stage_decay2:              case stage_decay2:
# Line 120  namespace LinuxSampler { namespace gig { Line 101  namespace LinuxSampler { namespace gig {
101                      case event_hold_end:                      case event_hold_end:
102                          enterDecay1Part1Stage(SampleRate);                          enterDecay1Part1Stage(SampleRate);
103                          break;                          break;
104                        default: ; // noop
105                  }                  }
106                  break;                  break;
107              case stage_sustain:              case stage_sustain:
# Line 135  namespace LinuxSampler { namespace gig { Line 117  namespace LinuxSampler { namespace gig {
117                      case event_hold_end:                      case event_hold_end:
118                          enterDecay1Part1Stage(SampleRate);                          enterDecay1Part1Stage(SampleRate);
119                          break;                          break;
120                        default: ; // noop
121                  }                  }
122                  break;                  break;
123              case stage_release_part1:              case stage_release_part1:
# Line 148  namespace LinuxSampler { namespace gig { Line 131  namespace LinuxSampler { namespace gig {
131                          else                          else
132                              enterDecay2Stage(SampleRate);                              enterDecay2Stage(SampleRate);
133                          break;                          break;
134                        default: ; // noop
135                  }                  }
136                  break;                  break;
137              case stage_release_part2:              case stage_release_part2:
# Line 161  namespace LinuxSampler { namespace gig { Line 145  namespace LinuxSampler { namespace gig {
145                          else                          else
146                              enterDecay2Stage(SampleRate);                              enterDecay2Stage(SampleRate);
147                          break;                          break;
148                        default: ; // noop
149                  }                  }
150                  break;                  break;
151              case stage_fadeout:              case stage_fadeout:
152                  switch (Event) {              case stage_end:
153                      case event_stage_end:                  ; // noop
                         enterEndStage();  
                         break;  
                 }  
                 break;  
154          }          }
155      }      }
156    
# Line 194  namespace LinuxSampler { namespace gig { Line 175  namespace LinuxSampler { namespace gig {
175          ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);          ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);
176          ReleaseLevel2 = 0.25 * invVolume;          ReleaseLevel2 = 0.25 * invVolume;
177    
178            enterFirstStage();
179          enterAttackStage(PreAttack, AttackTime, SampleRate);          enterAttackStage(PreAttack, AttackTime, SampleRate);
180      }      }
181    
# Line 201  namespace LinuxSampler { namespace gig { Line 183  namespace LinuxSampler { namespace gig {
183          Stage   = stage_attack;          Stage   = stage_attack;
184          Segment = segment_lin;          Segment = segment_lin;
185    
186          if (AttackTime >= 0.0005f) {          if (AttackTime >= 1e-8) {
187              // Measurements of GSt output shows that the real attack time              // Measurements of GSt output shows that the real attack time
188              // is about 65.5% of the value specified in the gig file.              // is about 65.5% of the value specified in the gig file.
189              // The minimum attack value used is 0.032.              // The minimum attack value used is 0.0316.
190              StepsLeft = int(0.655f * RTMath::Max(AttackTime, 0.032f) * SampleRate);              StepsLeft = int(0.655f * RTMath::Max(AttackTime, 0.0316f) * SampleRate);
191              Level = (float) PreAttack / 1000.0;              Level = (float) PreAttack / 1000.0;
192              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
193          } else { // attack is zero - immediately jump to the next stage          } else { // attack is zero - immediately jump to the next stage
194              Level = 1.0;              Level = 1.029f; // a bit higher than max sustain
195              if (HoldAttack) enterAttackHoldStage();              if (HoldAttack) enterAttackHoldStage();
196              else            enterDecay1Part1Stage(SampleRate);              else            enterDecay1Part1Stage(SampleRate);
197          }          }
# Line 234  namespace LinuxSampler { namespace gig { Line 216  namespace LinuxSampler { namespace gig {
216          // (where d is 1/SampleRate). The transition from f to g is          // (where d is 1/SampleRate). The transition from f to g is
217          // done when f(x) has reached Level2 = 25% of full volume.          // done when f(x) has reached Level2 = 25% of full volume.
218          StepsLeft = (int) (Decay1Time * SampleRate);          StepsLeft = (int) (Decay1Time * SampleRate);
219          if (StepsLeft && SustainLevel < 1.0 && Level > SustainLevel) {          if (StepsLeft && Level > SustainLevel) {
220              Stage        = stage_decay1_part1;              Stage        = stage_decay1_part1;
221              Segment      = segment_lin;              Segment      = segment_lin;
222              Decay1Slope  = 1.365 * (SustainLevel - 1.0) / StepsLeft;              Decay1Slope = (1.347f * SustainLevel - 1.361f) / StepsLeft;
223              Coeff        = Decay1Slope * invVolume;              Coeff        = Decay1Slope * invVolume;
224              Decay1Level2 = 0.25 * invVolume;              Decay1Level2 = 0.25 * invVolume;
225              if (Level < Decay1Level2) enterDecay1Part2Stage(SampleRate);              StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
226              else StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);              if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
227          } else {          } else {
228              if (InfiniteSustain) enterSustainStage();              if (InfiniteSustain) enterSustainStage();
229              else                 enterDecay2Stage(SampleRate);              else                 enterDecay2Stage(SampleRate);
# Line 256  namespace LinuxSampler { namespace gig { Line 238  namespace LinuxSampler { namespace gig {
238              Coeff  = exp(Decay1Slope);              Coeff  = exp(Decay1Slope);
239              Offset = ExpOffset * (1 - Coeff);              Offset = ExpOffset * (1 - Coeff);
240              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
241          } else {              if (StepsLeft > 0) return;
             if (InfiniteSustain) enterSustainStage();  
             else                 enterDecay2Stage(SampleRate);  
242          }          }
243            if (InfiniteSustain) enterSustainStage();
244            else                 enterDecay2Stage(SampleRate);
245      }      }
246    
247      void EGADSR::enterDecay2Stage(const uint SampleRate) {      void EGADSR::enterDecay2Stage(const uint SampleRate) {
248          Stage      = stage_decay2;          Stage      = stage_decay2;
249          Segment    = segment_lin;          Segment    = segment_lin;
250          Decay2Time = RTMath::Max(Decay2Time, CONFIG_EG_MIN_RELEASE_TIME);          Decay2Time = RTMath::Max(Decay2Time, 0.05f);
251          StepsLeft  = (int) (Decay2Time * SampleRate);          StepsLeft  = (int) (Decay2Time * SampleRate);
252          Coeff      = (-1.03 / StepsLeft) * invVolume;          Coeff      = (-1.03 / StepsLeft) * invVolume;
253          //FIXME: do we really have to calculate 'StepsLeft' two times?          //FIXME: do we really have to calculate 'StepsLeft' two times?
254          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);          StepsLeft  = int((CONFIG_EG_BOTTOM - Level) / Coeff);
255          if (StepsLeft == 0) enterEndStage();          if (StepsLeft <= 0) enterEndStage();
256      }      }
257    
258      void EGADSR::enterSustainStage() {      void EGADSR::enterSustainStage() {
# Line 286  namespace LinuxSampler { namespace gig { Line 268  namespace LinuxSampler { namespace gig {
268          Segment   = segment_lin;          Segment   = segment_lin;
269          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
270          Coeff     = ReleaseCoeff;          Coeff     = ReleaseCoeff;
271            if (StepsLeft <= 0) enterReleasePart2Stage();
272      }      }
273    
274      void EGADSR::enterReleasePart2Stage() {      void EGADSR::enterReleasePart2Stage() {
# Line 294  namespace LinuxSampler { namespace gig { Line 277  namespace LinuxSampler { namespace gig {
277          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);          StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);
278          Coeff     = ReleaseCoeff2;          Coeff     = ReleaseCoeff2;
279          Offset    = ReleaseCoeff3;          Offset    = ReleaseCoeff3;
280      }          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;  
281      }      }
282    
283  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.797  
changed lines
  Added in v.3034

  ViewVC Help
Powered by ViewVC