Nucleo F446 Envelope Generator

Dependencies:   mbed

Committer:
ryood
Date:
Sat Jun 30 08:51:09 2018 +0000
Revision:
0:c5e94349541f
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ryood 0:c5e94349541f 1 /*
ryood 0:c5e94349541f 2 * ADSR Type Envelope Class
ryood 0:c5e94349541f 3 *
ryood 0:c5e94349541f 4 * 2018.06.28
ryood 0:c5e94349541f 5 *
ryood 0:c5e94349541f 6 */
ryood 0:c5e94349541f 7
ryood 0:c5e94349541f 8 #ifndef _ENVELOPE_ADSR_H_
ryood 0:c5e94349541f 9 #define _ENVELOPE_ADSR_H_
ryood 0:c5e94349541f 10
ryood 0:c5e94349541f 11 class EnvelopeADSR
ryood 0:c5e94349541f 12 {
ryood 0:c5e94349541f 13 private:
ryood 0:c5e94349541f 14 enum EnvelopeState {
ryood 0:c5e94349541f 15 ST_ATTACK,
ryood 0:c5e94349541f 16 ST_DECAY,
ryood 0:c5e94349541f 17 ST_SUSTAIN,
ryood 0:c5e94349541f 18 ST_RELEASE
ryood 0:c5e94349541f 19 };
ryood 0:c5e94349541f 20
ryood 0:c5e94349541f 21 public:
ryood 0:c5e94349541f 22 EnvelopeADSR()
ryood 0:c5e94349541f 23 {
ryood 0:c5e94349541f 24 count = 0;
ryood 0:c5e94349541f 25 amplitude = 0;
ryood 0:c5e94349541f 26 setADSR(0, 0, 0.0f, 0);
ryood 0:c5e94349541f 27 }
ryood 0:c5e94349541f 28
ryood 0:c5e94349541f 29 void setADSR(int _attack, int _decay, float _sustain, int _release)
ryood 0:c5e94349541f 30 {
ryood 0:c5e94349541f 31 attack = _attack;
ryood 0:c5e94349541f 32 decay = _decay;
ryood 0:c5e94349541f 33 sustain = _sustain;
ryood 0:c5e94349541f 34 release = _release;
ryood 0:c5e94349541f 35
ryood 0:c5e94349541f 36 if (attack != 0) {
ryood 0:c5e94349541f 37 attackRatio = 1.0f / attack;
ryood 0:c5e94349541f 38 }
ryood 0:c5e94349541f 39 else {
ryood 0:c5e94349541f 40 attackRatio = 0.0f;
ryood 0:c5e94349541f 41 }
ryood 0:c5e94349541f 42 if (decay != 0) {
ryood 0:c5e94349541f 43 decayRatio = -(1.0f - sustain) / decay;
ryood 0:c5e94349541f 44 }
ryood 0:c5e94349541f 45 else {
ryood 0:c5e94349541f 46 decayRatio = 0.0f;
ryood 0:c5e94349541f 47 }
ryood 0:c5e94349541f 48 if (release != 0) {
ryood 0:c5e94349541f 49 releaseRatio = -sustain / release;
ryood 0:c5e94349541f 50 }
ryood 0:c5e94349541f 51 else {
ryood 0:c5e94349541f 52 releaseRatio = 0.0f;
ryood 0:c5e94349541f 53 }
ryood 0:c5e94349541f 54 }
ryood 0:c5e94349541f 55
ryood 0:c5e94349541f 56 void gateOn()
ryood 0:c5e94349541f 57 {
ryood 0:c5e94349541f 58 isGateOn = true;
ryood 0:c5e94349541f 59 count = 0;
ryood 0:c5e94349541f 60 amplitude = 0.0f;
ryood 0:c5e94349541f 61 state = ST_ATTACK;
ryood 0:c5e94349541f 62 }
ryood 0:c5e94349541f 63
ryood 0:c5e94349541f 64 void gateOff()
ryood 0:c5e94349541f 65 {
ryood 0:c5e94349541f 66 isGateOn = false;
ryood 0:c5e94349541f 67 state = ST_RELEASE;
ryood 0:c5e94349541f 68 }
ryood 0:c5e94349541f 69
ryood 0:c5e94349541f 70 float getAmplitude()
ryood 0:c5e94349541f 71 {
ryood 0:c5e94349541f 72 return amplitude;
ryood 0:c5e94349541f 73 }
ryood 0:c5e94349541f 74
ryood 0:c5e94349541f 75 long getCount()
ryood 0:c5e94349541f 76 {
ryood 0:c5e94349541f 77 return count;
ryood 0:c5e94349541f 78 }
ryood 0:c5e94349541f 79
ryood 0:c5e94349541f 80 int getState()
ryood 0:c5e94349541f 81 {
ryood 0:c5e94349541f 82 return state;
ryood 0:c5e94349541f 83 }
ryood 0:c5e94349541f 84
ryood 0:c5e94349541f 85 float tick()
ryood 0:c5e94349541f 86 {
ryood 0:c5e94349541f 87 float currentAmplitude = amplitude;
ryood 0:c5e94349541f 88
ryood 0:c5e94349541f 89 switch (state) {
ryood 0:c5e94349541f 90 case ST_ATTACK:
ryood 0:c5e94349541f 91 amplitude += attackRatio;
ryood 0:c5e94349541f 92 break;
ryood 0:c5e94349541f 93 case ST_DECAY:
ryood 0:c5e94349541f 94 amplitude += decayRatio;
ryood 0:c5e94349541f 95 break;
ryood 0:c5e94349541f 96 case ST_SUSTAIN:
ryood 0:c5e94349541f 97 // do nothing
ryood 0:c5e94349541f 98 break;
ryood 0:c5e94349541f 99 case ST_RELEASE:
ryood 0:c5e94349541f 100 amplitude += releaseRatio;
ryood 0:c5e94349541f 101 break;
ryood 0:c5e94349541f 102 }
ryood 0:c5e94349541f 103
ryood 0:c5e94349541f 104 // Limiter
ryood 0:c5e94349541f 105 if (amplitude < 0.0f) {
ryood 0:c5e94349541f 106 amplitude = 0.0f;
ryood 0:c5e94349541f 107 }
ryood 0:c5e94349541f 108 else if (amplitude > 1.0f) {
ryood 0:c5e94349541f 109 amplitude = 1.0f;
ryood 0:c5e94349541f 110 }
ryood 0:c5e94349541f 111
ryood 0:c5e94349541f 112 count++;
ryood 0:c5e94349541f 113 if (count < attack) {
ryood 0:c5e94349541f 114 state = ST_ATTACK;
ryood 0:c5e94349541f 115 } else if (count < attack + decay) {
ryood 0:c5e94349541f 116 state = ST_DECAY;
ryood 0:c5e94349541f 117 } else if (isGateOn) {
ryood 0:c5e94349541f 118 state = ST_SUSTAIN;
ryood 0:c5e94349541f 119 }
ryood 0:c5e94349541f 120
ryood 0:c5e94349541f 121 return currentAmplitude;
ryood 0:c5e94349541f 122 }
ryood 0:c5e94349541f 123
ryood 0:c5e94349541f 124 private:
ryood 0:c5e94349541f 125 int attack;
ryood 0:c5e94349541f 126 int decay;
ryood 0:c5e94349541f 127 float sustain;
ryood 0:c5e94349541f 128 int release;
ryood 0:c5e94349541f 129
ryood 0:c5e94349541f 130 float attackRatio;
ryood 0:c5e94349541f 131 float decayRatio;
ryood 0:c5e94349541f 132 float releaseRatio;
ryood 0:c5e94349541f 133
ryood 0:c5e94349541f 134 long count;
ryood 0:c5e94349541f 135 bool isGateOn;
ryood 0:c5e94349541f 136 EnvelopeState state;
ryood 0:c5e94349541f 137
ryood 0:c5e94349541f 138 float amplitude;
ryood 0:c5e94349541f 139 };
ryood 0:c5e94349541f 140
ryood 0:c5e94349541f 141 #endif //_ENVELOPE_ADSR_H_