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