forked from klang-modular/synthapp
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
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 |