Mozzi  version 2015-05-11-20:23
sound synthesis library for Arduino
 All Classes Functions Typedefs Groups
Ead.h
1 /*
2  * Ead.h
3  *
4  * Adapted from ead~.c puredata external (creb library)
5  * Copyright (c) 2000-2003 by Tom Schouten
6  *
7  * Copyright 2012 Tim Barrass, 2000-2003 Tom Schouten
8  *
9  * This file is part of Mozzi.
10  *
11  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
12  *
13  */
14 
15 #ifndef EAD_H_
16 #define EAD_H_
17 
18 #include "math.h"
19 #include "mozzi_fixmath.h"
20 
21 
29 class Ead
30 {
31 
32 public:
33 
41  Ead(unsigned int update_rate) : UPDATE_RATE(update_rate)
42  {
43  ;
44  }
45 
50  inline
51  void setAttack(unsigned int attack_ms)
52  {
53  Q8n8attack = float_to_Q8n8(millisToOneMinusRealPole(attack_ms));
54  }
55 
56 
61  inline
62  void setDecay(unsigned int decay_ms)
63  {
64  Q8n8decay = float_to_Q8n8(millisToOneMinusRealPole(decay_ms));
65  }
66 
67 
74  inline
75  void set(unsigned int attack_ms, unsigned int decay_ms)
76  {
77  setAttack(attack_ms);
78  setDecay(decay_ms);
79  }
80 
81 
85  inline
86  void start()
87  {
88  Q8n24state = 0;
89  attack_phase = true;
90  }
91 
92 
100  inline
101  void start(unsigned int attack_ms, unsigned int decay_ms)
102  {
103  set(attack_ms, decay_ms);
104  //Q8n24state = 0; // don't restart from 0, just go from whatever the current level is, to avoid glitches
105  attack_phase = true;
106  }
107 
108 
113  inline
114  uint8_t next()
115  {
116  if(attack_phase)
117  {
118  // multiply A(a1,b1) * A(a2,b2) = A(a1+a2, b1+b2)
119  Q8n24state += (((Q8n24)(Q8n24_FIX1 - Q8n24state) * Q8n8attack)) >> 8; // Q8n24, shifts all back into n24
120  if (Q8n24state >= Q8n24_FIX1-256)
121  {
122  Q8n24state = Q8n24_FIX1-256;
123  attack_phase = false;
124  }
125  }else{ /* decay phase */
126  Q8n24state -= (Q8n24state * Q8n8decay)>>8;
127  }
128  return Q8n24_to_Q0n8(Q8n24state);
129  }
130 
131 
132 private:
133 
134  Q8n8 Q8n8attack;
135  Q8n8 Q8n8decay;
136  Q8n24 Q8n24state;
137  bool attack_phase;
138  const unsigned int UPDATE_RATE;
139 
140 
141  /* convert milliseconds to 1-p, with p a real pole */
142  inline
143  float millisToOneMinusRealPole(unsigned int milliseconds)
144  {
145  static const float NUMERATOR = 1000.0f * log(0.001f);
146  return -expm1(NUMERATOR / ((float)UPDATE_RATE * milliseconds));
147  }
148 
149 
150  // Compute exp(x) - 1 without loss of precision for small values of x.
151  inline
152  float expm1(float x)
153  {
154  if (fabs(x) < 1e-5)
155  {
156  return x + 0.5*x*x;
157  }
158  else
159  {
160  return exp(x) - 1.0;
161  }
162  }
163 
164 };
165 
171 #endif /* EAD_H_ */
uint16_t Q8n8
unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:35
void start(unsigned int attack_ms, unsigned int decay_ms)
Set attack and decay times in milliseconds, and start the envelope from the beginning.
Definition: Ead.h:101
void set(unsigned int attack_ms, unsigned int decay_ms)
Set attack and decay times in milliseconds.
Definition: Ead.h:75
Exponential attack decay envelope.
Definition: Ead.h:29
Ead(unsigned int update_rate)
Constructor.
Definition: Ead.h:41
void start()
Start the envelope from the beginning.
Definition: Ead.h:86
Q8n8 float_to_Q8n8(float a)
Convert float to Q8n8 fix.
void setAttack(unsigned int attack_ms)
Set the attack time in milliseconds.
Definition: Ead.h:51
void setDecay(unsigned int decay_ms)
Set the decay time in milliseconds.
Definition: Ead.h:62
uint8_t next()
Calculate and return the next envelope value, in the range -128 to 127.
Definition: Ead.h:114
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:44
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:64
Q0n8 Q8n24_to_Q0n8(Q8n24 a)
Convert Q8n24 fixed to Q0n8 uint8_t.