robert@464: // robert@464: // ADRS.h robert@464: // robert@464: // Created by Nigel Redmon on 12/18/12. robert@464: // EarLevel Engineering: earlevel.com robert@464: // Copyright 2012 Nigel Redmon robert@464: // robert@464: // For a complete explanation of the ADSR envelope generator and code, robert@464: // read the series of articles by the author, starting here: robert@464: // http://www.earlevel.com/main/2013/06/01/envelope-generators/ robert@464: // robert@464: // License: robert@464: // robert@464: // This source code is provided as is, without warranty. robert@464: // You may copy and distribute verbatim copies of this document. robert@464: // You may modify and use this source code to create binary code for your own purposes, free or commercial. robert@464: // robert@464: robert@464: #ifndef ADRS_h robert@464: #define ADRS_h robert@464: robert@464: #include robert@464: #include robert@464: robert@464: using namespace std; robert@464: robert@464: enum envState { robert@464: env_idle = 0, robert@464: env_attack, robert@464: env_decay, robert@464: env_sustain, robert@464: env_release robert@464: }; robert@464: robert@464: class ADSR { robert@464: public: robert@464: ADSR(void); robert@464: ~ADSR(void); robert@464: float process(void); robert@464: float process(int sampleCount); robert@464: float getOutput(void); robert@464: int getState(void); robert@464: void gate(int on); robert@464: void setAttackRate(float rate); robert@464: void setDecayRate(float rate); robert@464: void setReleaseRate(float rate); robert@464: void setSustainLevel(float level); robert@464: void setTargetRatioA(float targetRatio); robert@464: void setTargetRatioDR(float targetRatio); robert@464: void reset(void); robert@464: robert@464: protected: robert@464: int state; robert@464: float output; robert@464: float attackRate; robert@464: float decayRate; robert@464: float releaseRate; robert@464: float attackCoef; robert@464: float decayCoef; robert@464: float releaseCoef; robert@464: float sustainLevel; robert@464: float targetRatioA; robert@464: float targetRatioDR; robert@464: float attackBase; robert@464: float decayBase; robert@464: float releaseBase; robert@464: string name; robert@464: float calcCoef(float rate, float targetRatio); robert@464: }; robert@464: robert@464: inline float ADSR::process() { robert@464: switch (state) { robert@464: case env_idle: robert@464: break; robert@464: case env_attack: robert@464: output = attackBase + output * attackCoef; robert@464: if (output >= 1.0) { robert@464: output = 1.0; robert@464: state = env_decay; robert@464: } robert@464: break; robert@464: case env_decay: robert@464: output = decayBase + output * decayCoef; robert@464: if (output <= sustainLevel) { robert@464: output = sustainLevel; robert@464: state = env_sustain; robert@464: } robert@464: break; robert@464: case env_sustain: robert@464: break; robert@464: case env_release: robert@464: output = releaseBase + output * releaseCoef; robert@464: if (output <= 0.0) { robert@464: output = 0.0; robert@464: state = env_idle; robert@464: } robert@464: break; robert@464: } robert@464: return output; robert@464: } robert@464: robert@464: inline float ADSR::process(int sampleCount) robert@464: { robert@464: float retVal = 0; robert@464: robert@464: if(state != env_idle) robert@464: { robert@464: for(int i=0; i