#ifndef __ADSR_H__ #define __ADSR_H__ #include #include "util.h" class ADSR { public: struct Envelope { float attackStep; float decayStep; float sustain; float releaseStep; }; ADSR(); void setEnvelope(const Envelope* envelope); void noteOn(); void noteOff(); float tick() { float out = curve(gain); switch(state) { case IDLE: break; case ATTACK: if(gain < 1) { gain += envelope->attackStep; } else { state = DECAY; gain = 1; } break; case DECAY: if(gain > envelope->sustain) { gain -= envelope->decayStep; } else { state = SUSTAIN; gain = envelope->sustain; } break; case SUSTAIN: break; case RELEASE: if(gain > 0) { gain -= envelope->releaseStep; } else { state = IDLE; gain = 0; } break; } return out; } private: enum { IDLE, ATTACK, DECAY, SUSTAIN, RELEASE } state; static const Envelope DEFAULT_ENVELOPE; const Envelope* envelope; float gain; float curve(float gain) { return 0.5 - 0.5 * cos(clamp(gain * M_PI, 0, M_PI)); } }; #endif