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.
 
 
 

74 lines
1.5 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;
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