synththing-plusplus/src/utils/envelope.cpp

118 lines
2.5 KiB
C++

/*
* Filename: envelope.cpp
*
* Description:
*
*
* Version:
* Created: Fri Nov 1 00:06:43 2019
* Revision: None
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
*
*/
#include "envelope.h"
float Envelope::run() {
switch (this->envstate) {
case _e_off:
if (this->gate) {
this->t = 0;
this->envstate = _e_attack;
return this->run();
}
break;
case _e_attack:
if (this->gate) {
if ( this->t < this->attack ) {
float stepsize = (this->max_level - this->min_level) / this->attack;
this->t++;
return this->t * stepsize;
} else {
if (this->ar) {
this->t = 0;
this->envstate = _e_sustain;
return this->max_level;
} else {
this->t = 0;
this->envstate = _e_decay;
return this->max_level;
}
}
} else {
this->envstate = _e_attackrelease;
return this->run();
}
break;
case _e_decay:
if (this->gate) {
if (this->t < this->decay) {
float stepsize = (this->max_level - this->sustain_level) / this->decay;
this->t++;
return (this->max_level - (this->t * stepsize));
} else {
this->envstate = _e_sustain;
return this->sustain_level;
}
} else {
this->envstate = _e_attackrelease;
return this->run();
}
break;
case _e_sustain:
if (!this->sustain) {
this->envstate = _e_release;
this->t = 0;
return this->run();;
}
if (!this->gate) {
this->t = 0;
this->envstate = _e_release;
if (this->ar)
return this->max_level;
return this->sustain_level;
}
if (this->ar)
return this->max_level;
return this->sustain_level;
break;
case _e_release:
if (this->gate && this->sustain) {
// reset envelope.
this->envstate=_e_off;
return this->run();;
}
if (this->t < this->release) {
float stepsize = ((this->ar ? this->max_level : this->sustain_level) - this->min_level) / this->release;
this->t++;
return (this->ar ? this->max_level : this->sustain_level) - (stepsize * this->t);
} else {
this->envstate = _e_off;
return this->min_level;
}
break;
case _e_attackrelease:
if (this->gate) {
//reset envelope
this->envstate=_e_off;
return this->run();;
}
return 0.0f;
break;
}
return 0.0f; // if this is reached, something went wrong or an unhandled function was used.
}
Envelope::Envelope() {
this->envstate = _e_off;
this->t = 0;
this->max_level = 1.0f;
this->sustain_level = 1.0f;
this->min_level = 0.0f;
}