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.
 
 

76 lines
1.5 KiB

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