Mozzi  version 2015-05-11-20:23
sound synthesis library for Arduino
 All Classes Functions Typedefs Groups
ADSR.h
1 /*
2  * ADSR.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef ADSR_H_
13 #define ADSR_H_
14 
15 #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 //#include <util/atomic.h>
21 #include "Line.h"
22 #include "mozzi_fixmath.h"
23 
24 
44 template <unsigned int CONTROL_UPDATE_RATE, unsigned int LERP_RATE>
45 class ADSR
46 {
47 private:
48 
49  const unsigned int LERPS_PER_CONTROL;
50 
51  unsigned int update_step_counter;
52  unsigned int num_update_steps;
53 
54  enum {ATTACK,DECAY,SUSTAIN,RELEASE,IDLE};
55 
56 
57  struct phase{
58  byte phase_type;
59  unsigned int update_steps;
60  long lerp_steps; // signed, to match params to transition (line) type Q15n16, below
61  Q8n0 level;
62  }attack,decay,sustain,release,idle;
63 
64  phase * current_phase;
65 
66  // Linear audio rate transitions for envelope
67  //Line <unsigned long> transition;
68  Line <Q15n16> transition; // scale up unsigned char levels for better accuracy, then scale down again for output
69 
70  inline
71  unsigned int convertMsecToControlUpdateSteps(unsigned int msec){
72  return (uint16_t) (((uint32_t)msec*CONTROL_UPDATE_RATE)>>10); // approximate /1000 with shift
73  }
74 
75 
76  inline
77  void setPhase(phase * next_phase) {
78  update_step_counter = 0;
79  num_update_steps = next_phase->update_steps;
80  transition.set(Q8n0_to_Q15n16(next_phase->level),next_phase->lerp_steps);
81  current_phase = next_phase;
82  }
83 
84 
85 
86  inline
87  void checkForAndSetNextPhase(phase * next_phase) {
88  if (++update_step_counter >= num_update_steps){
89  setPhase(next_phase);
90  }
91  }
92 
93 
94 
95  inline
96  void setTime(phase * p, unsigned int msec)
97  {
98  p->update_steps = convertMsecToControlUpdateSteps(msec);
99  p->lerp_steps = (long) p->update_steps * LERPS_PER_CONTROL;
100  }
101 
102 
103  inline
104  void setUpdateSteps(phase * p, unsigned int steps)
105  {
106  p->update_steps = steps;
107  p->lerp_steps = (long) steps * LERPS_PER_CONTROL;
108  }
109 
110 
111 
112 public:
113 
116  ADSR():LERPS_PER_CONTROL(LERP_RATE/CONTROL_UPDATE_RATE)
117  {
118  attack.phase_type = ATTACK;
119  decay.phase_type = DECAY;
120  sustain.phase_type = SUSTAIN;
121  release.phase_type = RELEASE;
122  idle.phase_type = IDLE;
123  release.level = 0;
124  }
125 
126 
127 
131  void update(){ // control rate
132 
133  switch(current_phase->phase_type) {
134 
135  case ATTACK:
136  checkForAndSetNextPhase(&decay);
137  break;
138 
139  case DECAY:
140  checkForAndSetNextPhase(&sustain);
141  break;
142 
143  case SUSTAIN:
144  checkForAndSetNextPhase(&release);
145  break;
146 
147  case RELEASE:
148  checkForAndSetNextPhase(&idle);
149  //checkForAndSetIdle();
150  break;
151 
152  case IDLE:
153  break;
154  }
155  }
156 
157 
158 
163  inline
164  unsigned char next()
165  {
166  return Q15n16_to_Q8n0(transition.next());
167  }
168 
169 
170 
173  inline
174  void noteOn(){
175  setPhase(&attack);
176  }
177 
178 
179 
183  inline
184  void noteOff(){
185  setPhase(&release);
186  }
187 
188 
189 
193  inline
194  void setAttackLevel(byte value)
195  {
196  attack.level=value;
197  }
198 
199 
200 
204  inline
205  void setDecayLevel(byte value)
206  {
207  decay.level=value;
208  }
209 
210 
215  inline
216  void setSustainLevel(byte value)
217  {
218  sustain.level=value;
219  }
220 
225  inline
226  void setReleaseLevel(byte value)
227  {
228  release.level=value;
229  }
230 
231 
232  inline
233  void setIdleLevel(byte value)
234  {
235  idle.level=value;
236  }
237 
238 
244  inline
245  void setADLevels(byte attack, byte decay)
246  {
247  setAttackLevel(attack);
248  setDecayLevel(decay);
249  setSustainLevel(decay); // stay at decay level
250  setReleaseLevel(1);
251  setIdleLevel(0);
252  }
253 
254 
261  inline
262  void setLevels(byte attack, byte decay, byte sustain, byte release)
263  {
264  setAttackLevel(attack);
265  setDecayLevel(decay);
266  setSustainLevel(sustain);
267  setReleaseLevel(release);
268  setIdleLevel(0);
269  }
270 
271 
278  inline
279  void setAttackTime(unsigned int msec)
280  {
281  setTime(&attack, msec);
282  }
283 
284 
291  inline
292  void setDecayTime(unsigned int msec)
293  {
294  setTime(&decay, msec);
295  }
296 
297 
305  inline
306  void setSustainTime(unsigned int msec)
307  {
308  setTime(&sustain, msec);
309  }
310 
311 
312 
319  inline
320  void setReleaseTime(unsigned int msec)
321  {
322  setTime(&release, msec);
323  }
324 
325 
326  inline
327  void setIdleTime(unsigned int msec)
328  {
329  setTime(&idle, msec);
330  }
331 
332 
342  inline
343  void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
344  {
345  setAttackTime(attack_ms);
346  setDecayTime(decay_ms);
347  setSustainTime(sustain_ms);
348  setReleaseTime(release_ms);
349  setIdleTime(65535); // guarantee step size of line will be 0
350  }
351 
352 
353 
357  inline
358  void setAttackUpdateSteps(unsigned int steps)
359  {
360  setUpdateSteps(&attack, steps);
361  }
362 
363 
367  inline
368  void setDecayUpdateSteps(unsigned int steps)
369  {
370  setUpdateSteps(&decay, steps);
371  }
372 
373 
377  inline
378  void setSustainUpdateSteps(unsigned int steps)
379  {
380  setUpdateSteps(&sustain, steps);
381  }
382 
383 
387  inline
388  void setReleaseUpdateSteps(unsigned int steps)
389  {
390  setUpdateSteps(&release, steps);
391  }
392 
393 
394  inline
395  void setIdleUpdateSteps(unsigned int steps)
396  {
397  setUpdateSteps(&idle, steps);
398  }
399 
406  inline
407  void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
408  {
409  setAttackUpdateSteps(attack_steps);
410  setDecayUpdateSteps(decay_steps);
411  setSustainUpdateSteps(sustain_steps);
412  setReleaseUpdateSteps(release_steps);
413  setIdleUpdateSteps(65535); // guarantee step size of line will be 0
414  }
415 
416 
417 
421  inline
422  bool playing()
423  {
424  return !(current_phase->phase_type==IDLE);
425  }
426 
427 
428 };
429 
430 
435 #endif /* ADSR_H_ */
void set(T value)
Set the current value of the line.
Definition: Line.h:77
unsigned char next()
Advances one audio step along the ADSR and returns the level.
Definition: ADSR.h:164
void setSustainLevel(byte value)
Set the sustain level of the ADSR.
Definition: ADSR.h:216
void setDecayLevel(byte value)
Set the decay level of the ADSR.
Definition: ADSR.h:205
void setReleaseUpdateSteps(unsigned int steps)
Set the release time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:388
void setTimes(unsigned int attack_ms, unsigned int decay_ms, unsigned int sustain_ms, unsigned int release_ms)
Set the attack, decay and release times of the ADSR in milliseconds.
Definition: ADSR.h:343
void setAttackUpdateSteps(unsigned int steps)
Set the attack time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolat...
Definition: ADSR.h:358
void setLevels(byte attack, byte decay, byte sustain, byte release)
Set the attack, decay, sustain and release levels.
Definition: ADSR.h:262
void setReleaseTime(unsigned int msec)
Set the release time of the ADSR in milliseconds.
Definition: ADSR.h:320
Q8n0 Q15n16_to_Q8n0(Q15n16 a)
Convert Q15n16 fixed to Q8n0 uint8_t.
void setAllUpdateSteps(unsigned int attack_steps, unsigned int decay_steps, unsigned int sustain_steps, unsigned int release_steps)
Set the attack, decay and release times of the ADSR, expressed in update steps (not ADSR::next() inte...
Definition: ADSR.h:407
void setSustainTime(unsigned int msec)
Set the sustain time of the ADSR in milliseconds.
Definition: ADSR.h:306
void noteOff()
Start the release phase of the ADSR.
Definition: ADSR.h:184
void setAttackTime(unsigned int msec)
Set the attack time of the ADSR in milliseconds.
Definition: ADSR.h:279
Q15n16 Q8n0_to_Q15n16(Q8n0 a)
Convert Q8n0 uint8_t to Q15n16 fix.
void setDecayTime(unsigned int msec)
Set the decay time of the ADSR in milliseconds.
Definition: ADSR.h:292
void setDecayUpdateSteps(unsigned int steps)
Set the decay time of the ADSR, expressed as the number of update steps (not ADSR::next() interpolati...
Definition: ADSR.h:368
void setReleaseLevel(byte value)
Set the release level of the ADSR.
Definition: ADSR.h:226
void setSustainUpdateSteps(unsigned int steps)
Set the sustain time of the ADSR, expressed as the number of update steps (not ADSR::next() interpola...
Definition: ADSR.h:378
void update()
Updates the internal controls of the ADSR.
Definition: ADSR.h:131
void setADLevels(byte attack, byte decay)
Set the attack and decay levels of the ADSR.
Definition: ADSR.h:245
uint8_t Q8n0
normal uint8_t with 0 fractional bits, represents 0.0 to 255.0
Definition: mozzi_fixmath.h:28
void noteOn()
Start the attack phase of the ADSR.
Definition: ADSR.h:174
ADSR()
Constructor.
Definition: ADSR.h:116
void setAttackLevel(byte value)
Set the attack level of the ADSR.
Definition: ADSR.h:194
A simple ADSR envelope generator.
Definition: ADSR.h:45
T next()
Increments one step along the line.
Definition: Line.h:59
bool playing()
Tells if the envelope is currently playing.
Definition: ADSR.h:422