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