/[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 3327 by schoenebeck, Mon Oct 31 00:05:00 2016 UTC revision 3328 by schoenebeck, Sun Jul 23 18:27:29 2017 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 - 2016 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2017 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 27  Line 27 
27    
28  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
29    
30        EGADSR::EGADSR() : EG() {
31            AttackCancel     = true;
32            AttackHoldCancel = true;
33            Decay1Cancel     = true;
34            Decay2Cancel     = true;
35            ReleaseCancel    = true;
36        }
37    
38        #define isTransitionEvent(type) \
39            ( type == event_release || type == event_cancel_release )
40    
41      void EGADSR::update(event_t Event, uint SampleRate) {      void EGADSR::update(event_t Event, uint SampleRate) {
42          if (atEnd(Event)) return;          if (atEnd(Event)) return;
43    
# Line 36  namespace LinuxSampler { namespace gig { Line 47  namespace LinuxSampler { namespace gig {
47              case stage_attack:              case stage_attack:
48                  switch (Event) {                  switch (Event) {
49                      case event_release:                      case event_release:
50                          enterReleasePart1Stage();                          if (AttackCancel)
51                                enterNextStageForReleaseEvent(SampleRate);
52                            else
53                                PostponedEvent = Event;
54                          break;                          break;
55                      case event_stage_end:                      case event_stage_end:
56                          if (HoldAttack)                          if (PostponedEvent == event_release)
57                                enterNextStageForReleaseEvent(SampleRate);
58                            else if (HoldAttack)
59                              enterAttackHoldStage();                              enterAttackHoldStage();
60                          else                          else
61                              enterDecay1Part1Stage(SampleRate);                              enterDecay1Part1Stage(SampleRate);
# Line 55  namespace LinuxSampler { namespace gig { Line 71  namespace LinuxSampler { namespace gig {
71                          break;                          break;
72                      }                      }
73                      case event_hold_end:                      case event_hold_end:
74                          enterDecay1Part1Stage(SampleRate);                          if (PostponedEvent == event_release)
75                                enterNextStageForReleaseEvent(SampleRate);
76                            else
77                                enterDecay1Part1Stage(SampleRate);
78                          break;                          break;
79                      case event_release:                      case event_release:
80                          enterReleasePart1Stage();                          if (AttackHoldCancel)
81                                enterNextStageForReleaseEvent(SampleRate);
82                            else
83                                PostponedEvent = Event;
84                          break;                          break;
85                      default: ; // noop                      default: ; // noop
86                  }                  }
# Line 69  namespace LinuxSampler { namespace gig { Line 91  namespace LinuxSampler { namespace gig {
91                          enterDecay1Part2Stage(SampleRate);                          enterDecay1Part2Stage(SampleRate);
92                          break;                          break;
93                      case event_release:                      case event_release:
94                          enterReleasePart1Stage();                          if (Decay1Cancel)
95                                enterNextStageForReleaseEvent(SampleRate);
96                            else
97                                PostponedEvent = Event;
98                          break;                          break;
99                      default: ; // noop                      default: ; // noop
100                  }                  }
# Line 77  namespace LinuxSampler { namespace gig { Line 102  namespace LinuxSampler { namespace gig {
102              case stage_decay1_part2:              case stage_decay1_part2:
103                  switch (Event) {                  switch (Event) {
104                      case event_release:                      case event_release:
105                          enterReleasePart1Stage();                          if (Decay1Cancel)
106                                enterNextStageForReleaseEvent(SampleRate);
107                            else
108                                PostponedEvent = Event;
109                          break;                          break;
110                      case event_stage_end:                      case event_stage_end:
111                          if (Level < CONFIG_EG_BOTTOM)                          if (Level < CONFIG_EG_BOTTOM)
112                              enterEndStage();                              enterEndStage();
113                            else if (PostponedEvent == event_release)
114                                enterNextStageForReleaseEvent(SampleRate);
115                          else if (InfiniteSustain)                          else if (InfiniteSustain)
116                              enterSustainStage();                              enterSustainStage();
117                          else                          else
# Line 96  namespace LinuxSampler { namespace gig { Line 126  namespace LinuxSampler { namespace gig {
126                          enterFadeOutStage();                          enterFadeOutStage();
127                          break;                          break;
128                      case event_release:                      case event_release:
129                          enterReleasePart1Stage();                          if (Decay2Cancel)
130                                enterReleasePart1Stage();
131                            else
132                                PostponedEvent = Event;
133                          break;                          break;
134                      case event_hold_end:                      case event_hold_end:
135                          enterDecay1Part1Stage(SampleRate);                          if (PostponedEvent == event_release && Decay1Cancel)
136                                enterReleasePart1Stage();
137                            else
138                                enterDecay1Part1Stage(SampleRate);
139                          break;                          break;
140                      default: ; // noop                      default: ; // noop
141                  }                  }
# Line 126  namespace LinuxSampler { namespace gig { Line 162  namespace LinuxSampler { namespace gig {
162                          enterReleasePart2Stage();                          enterReleasePart2Stage();
163                          break;                          break;
164                      case event_cancel_release:                      case event_cancel_release:
165                            if (!ReleaseCancel)
166                                break;
167                          if (InfiniteSustain)                          if (InfiniteSustain)
168                              enterSustainStage();                              enterSustainStage();
169                          else                          else
# Line 140  namespace LinuxSampler { namespace gig { Line 178  namespace LinuxSampler { namespace gig {
178                          enterFadeOutStage();                          enterFadeOutStage();
179                          break;                          break;
180                      case event_cancel_release:                      case event_cancel_release:
181                            if (!ReleaseCancel)
182                                break;
183                          if (InfiniteSustain)                          if (InfiniteSustain)
184                              enterSustainStage();                              enterSustainStage();
185                          else                          else
# Line 175  namespace LinuxSampler { namespace gig { Line 215  namespace LinuxSampler { namespace gig {
215          ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);          ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);
216          ReleaseLevel2 = 0.25 * invVolume;          ReleaseLevel2 = 0.25 * invVolume;
217    
218            PostponedEvent = (event_t) -1; // init with anything except release or cancel_release
219    
220          enterFirstStage();          enterFirstStage();
221          enterAttackStage(PreAttack, AttackTime, SampleRate);          enterAttackStage(PreAttack, AttackTime, SampleRate);
222      }      }
223    
224        void EGADSR::setStateOptions(bool AttackCancel, bool AttackHoldCancel, bool Decay1Cancel, bool Decay2Cancel, bool ReleaseCancel) {
225            this->AttackCancel     = AttackCancel;
226            this->AttackHoldCancel = AttackHoldCancel;
227            this->Decay1Cancel     = Decay1Cancel;
228            this->Decay2Cancel     = Decay2Cancel;
229            this->ReleaseCancel    = ReleaseCancel;
230        }
231    
232        void EGADSR::enterNextStageForReleaseEvent(uint SampleRate) {
233            switch (Stage) {
234                case stage_attack:
235                    if (HoldAttack && !AttackHoldCancel) {
236                        enterAttackHoldStage();
237                        return;
238                    }
239                case stage_attack_hold:
240                    if (!Decay1Cancel) {
241                        enterDecay1Part1Stage(SampleRate);
242                        return;
243                    }
244                case stage_decay1_part1:
245                case stage_decay1_part2:
246                    if (InfiniteSustain) {
247                        enterReleasePart1Stage();
248                        return;
249                    } else if (!Decay2Cancel) {
250                        enterDecay2Stage(SampleRate);
251                        return;
252                    }
253                default:
254                    enterReleasePart1Stage();
255            }
256        }
257    
258      void EGADSR::enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate) {      void EGADSR::enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate) {
259          Stage   = stage_attack;          Stage   = stage_attack;
260          Segment = segment_lin;          Segment = segment_lin;
# Line 225  namespace LinuxSampler { namespace gig { Line 301  namespace LinuxSampler { namespace gig {
301              StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);              StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
302              if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);              if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
303          } else {          } else {
304              if (InfiniteSustain) enterSustainStage();              if (PostponedEvent == event_release) {
305              else                 enterDecay2Stage(SampleRate);                  Stage = stage_decay1_part2; // pretend decay 1 part 2 was completed
306                    enterNextStageForReleaseEvent(SampleRate);
307                } else if (InfiniteSustain) {
308                    enterSustainStage();
309                } else {
310                    enterDecay2Stage(SampleRate);
311                }
312          }          }
313      }      }
314    
# Line 240  namespace LinuxSampler { namespace gig { Line 322  namespace LinuxSampler { namespace gig {
322              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);              StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
323              if (StepsLeft > 0) return;              if (StepsLeft > 0) return;
324          }          }
325          if (InfiniteSustain) enterSustainStage();          if (PostponedEvent == event_release) {
326          else                 enterDecay2Stage(SampleRate);              Stage = stage_decay1_part2;
327                enterNextStageForReleaseEvent(SampleRate);
328            } else if (InfiniteSustain) {
329                enterSustainStage();
330            } else {
331                enterDecay2Stage(SampleRate);
332            }
333      }      }
334    
335      void EGADSR::enterDecay2Stage(const uint SampleRate) {      void EGADSR::enterDecay2Stage(const uint SampleRate) {
# Line 261  namespace LinuxSampler { namespace gig { Line 349  namespace LinuxSampler { namespace gig {
349          Coeff   = 0.0f; // don't change the envelope level in this stage          Coeff   = 0.0f; // don't change the envelope level in this stage
350          const int intMax = (unsigned int) -1 >> 1;          const int intMax = (unsigned int) -1 >> 1;
351          StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)          StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)
352            PostponedEvent = (event_t) -1; // reset with anything except release or cancel_release
353      }      }
354    
355      void EGADSR::enterReleasePart1Stage() {      void EGADSR::enterReleasePart1Stage() {
# Line 268  namespace LinuxSampler { namespace gig { Line 357  namespace LinuxSampler { namespace gig {
357          Segment   = segment_lin;          Segment   = segment_lin;
358          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);          StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
359          Coeff     = ReleaseCoeff;          Coeff     = ReleaseCoeff;
360            PostponedEvent = (event_t) -1; // reset with anything except release or cancel_release
361          if (StepsLeft <= 0) enterReleasePart2Stage();          if (StepsLeft <= 0) enterReleasePart2Stage();
362      }      }
363    

Legend:
Removed from v.3327  
changed lines
  Added in v.3328

  ViewVC Help
Powered by ViewVC