You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

85 lines
1.8 KiB

#ifndef __ADSR_H__
#define __ADSR_H__
#include <cmath>
#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