OpenWareLaboratory
AdsrEnvelope.h
Go to the documentation of this file.
1 #ifndef __ADSR_ENVELOPE_H
2 #define __ADSR_ENVELOPE_H
3 
4 #include "Envelope.h"
5 
9 template<bool linear>
10 class AdsrEnvelope : public Envelope {
11 protected:
12  static const float MINLEVEL;
15  float calculateIncrement(float startValue, float endValue, float time);
16  float increment(float level, float amount);
17  float decrement(float level, float amount);
18 public:
21  stage(kIdle),
22  trig(kGate),
23  level(MINLEVEL),
24  gateState(false),
25  gateTime(-1) {
28  setSustain(1.0);
30  setRetrigger(false);
31  }
32 
33  using Envelope::process;
34  using Envelope::trigger;
36  void setSampleRate(float value){
37  sampleRate = value;
38  }
39  void setAttack(float value){
41  }
42  void setDecay(float value){
44  }
45  void setRelease(float value){
47  }
48  void setSustain(float newSustain){
49  sustain = newSustain;
50  }
51  void trigger(bool state, int delay){
52  gate(state, delay);
53  trig = kTrigger;
54  }
55  void setRetrigger(bool state){
56  retrigger = state;
57  }
58  void gate(bool state){
59  gate(state, 0);
60  }
61  void gate(bool state, int delay){
62  if(gateState != state){
63  gateTime = delay;
64  gateState = state;
65  }
66  trig = kGate;
67  }
68  float getLevel(){
69  return level;
70  }
71  void setLevel(float newLevel){
72  level = newLevel;
73  }
77  float generate(){
78  if(gateTime == 0){
79  stage = kAttack;
80  if(trig == kTrigger){
81  gateState = false;
82  }
83  }
84  if(gateTime >= 0){
85  gateTime--; // this will stop at -1
86  }
87  switch (stage) {
88  case kAttack:
89  // attack ramp
91  if(level >= 1.0){
92  level = 1.0;
93  stage = kDecay;
94  }else if(gateState == false && trig == kGate){
95  stage = kRelease;
96  }
97  break;
98  case kDecay:
99  // decay ramp
101  if(level <= sustain){
102  level = sustain;
103  if(trig == kGate){
104  stage = kSustain;
105  } else { // (trig == kTrigger)
106  stage = kRelease;
107  }
108  } else if(gateState == false && trig == kGate){
109  stage = kRelease;
110  }
111  break;
112  case kSustain:
113  level = sustain;
114  if(gateState == false){
115  stage = kRelease;
116  }
117  break;
118  case kRelease:
119  // release ramp
121  if(level <= MINLEVEL){
122  level = MINLEVEL;
123  if (retrigger == true)
124  trigger();
125  else // (retrigger == false)
126  stage = kIdle;
127  }else if(gateState == true ){ // if during release the gate is on again, start over from the current level
128  stage = kAttack;
129  }
130  break;
131  case kIdle:
132  level = MINLEVEL;
133  if(gateState == true)
134  stage = kAttack;
135  break;
136  }
137  return level;
138  }
139  [[deprecated("use generate() instead.")]]
140  float getNextSample(){
141  return generate(); // increments envelope one step
142  }
143  [[deprecated("use generate() instead.")]]
144  void getEnvelope(FloatArray output){
145  generate(output); // increments envelope by output buffer length
146  }
147  [[deprecated("use process() instead.")]]
149  process(buf, buf); // increments envelope by buffer length
150  }
152  return new AdsrEnvelope<linear>(sampleRate);
153  }
154  static void destroy(AdsrEnvelope<linear>* env){
155  delete env;
156  }
157 protected:
158  float sampleRate;
161  bool retrigger;
162  float level;
166  float sustain;
167  bool gateState;
168  int gateTime;
169 };
170 
171 template<>
172 float AdsrEnvelope<true>::increment(float level, float amount){
173  return level + amount;
174 }
175 
176 template<>
177 float AdsrEnvelope<true>::decrement(float level, float amount){
178  return level + amount;
179 }
180 
181 template<>
182 float AdsrEnvelope<false>::increment(float level, float amount){
183  return level + (1.01-level)*amount; // aim slightly higher to ensure we reach 1.0
184 }
185 
186 template<>
187 float AdsrEnvelope<false>::decrement(float level, float amount){
188  return level + level * amount;
189 }
190 
191 template<>
192 float AdsrEnvelope<true>::calculateIncrement(float startValue, float endValue, float time){
193  return (endValue-startValue)/(sampleRate*time+1);
194 }
195 
196 template<>
197 float AdsrEnvelope<false>::calculateIncrement(float startValue, float endValue, float time) {
198  // Ref: Christian Schoenebeck http://www.musicdsp.org/showone.php?id=189
199  return (logf(endValue) - logf(startValue)) / (time*sampleRate+10);
200 }
201 
202 template<>
204 
205 template<>
206 const float AdsrEnvelope<false>::MINLEVEL = 0.00001; // -100dB
207 
210 
211 #endif /* __ADSR_ENVELOPE_H */
AdsrEnvelope< true > LinearAdsrEnvelope
Definition: AdsrEnvelope.h:208
AdsrEnvelope< false > ExponentialAdsrEnvelope
Definition: AdsrEnvelope.h:209
ADSR Envelope, either linear or exponential.
Definition: AdsrEnvelope.h:10
void getEnvelope(FloatArray output)
Definition: AdsrEnvelope.h:144
static void destroy(AdsrEnvelope< linear > *env)
Definition: AdsrEnvelope.h:154
void setRelease(float value)
Definition: AdsrEnvelope.h:45
float getLevel()
Definition: AdsrEnvelope.h:68
void setAttack(float value)
Definition: AdsrEnvelope.h:39
EnvelopeTrigger trig
Definition: AdsrEnvelope.h:160
void setSampleRate(float value)
Definition: AdsrEnvelope.h:36
void attenuate(FloatArray buf)
Definition: AdsrEnvelope.h:148
float decayIncrement
Definition: AdsrEnvelope.h:164
void gate(bool state)
Definition: AdsrEnvelope.h:58
AdsrEnvelope(float sampleRate)
Definition: AdsrEnvelope.h:19
float decrement(float level, float amount)
virtual void trigger()
Definition: Envelope.h:11
void setDecay(float value)
Definition: AdsrEnvelope.h:42
void setSustain(float newSustain)
Definition: AdsrEnvelope.h:48
float getNextSample()
Definition: AdsrEnvelope.h:140
float increment(float level, float amount)
virtual float process(float input)
Definition: Envelope.h:22
float attackIncrement
Definition: AdsrEnvelope.h:163
EnvelopeStage stage
Definition: AdsrEnvelope.h:159
float sampleRate
Definition: AdsrEnvelope.h:158
void setRetrigger(bool state)
Definition: AdsrEnvelope.h:55
void setLevel(float newLevel)
Definition: AdsrEnvelope.h:71
static const float MINLEVEL
Definition: AdsrEnvelope.h:12
void gate(bool state, int delay)
Definition: AdsrEnvelope.h:61
static AdsrEnvelope< linear > * create(float sampleRate)
Definition: AdsrEnvelope.h:151
void trigger(bool state, int delay)
Definition: AdsrEnvelope.h:51
float releaseIncrement
Definition: AdsrEnvelope.h:165
float generate()
Produce the next envelope sample.
Definition: AdsrEnvelope.h:77
float calculateIncrement(float startValue, float endValue, float time)
virtual void trigger()
Definition: Envelope.h:11
virtual float process(float input)
Definition: Envelope.h:22
This class contains useful methods for manipulating arrays of floats.
Definition: FloatArray.h:12
virtual float generate()
Produce the next consecutive sample.