Ryo Od
/
Nucleo_F446_EG
Nucleo F446 Envelope Generator
EnvelopeADSR.h@0:c5e94349541f, 2018-06-30 (annotated)
- Committer:
- ryood
- Date:
- Sat Jun 30 08:51:09 2018 +0000
- Revision:
- 0:c5e94349541f
first commit
Who changed what in which revision?
User | Revision | Line number | New 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_ |