andrewm@0: // andrewm@0: // ADSR.cpp andrewm@0: // andrewm@0: // Created by Nigel Redmon on 12/18/12. andrewm@0: // EarLevel Engineering: earlevel.com andrewm@0: // Copyright 2012 Nigel Redmon andrewm@0: // andrewm@0: // For a complete explanation of the ADSR envelope generator and code, andrewm@0: // read the series of articles by the author, starting here: andrewm@0: // http://www.earlevel.com/main/2013/06/01/envelope-generators/ andrewm@0: // andrewm@0: // License: andrewm@0: // andrewm@0: // This source code is provided as is, without warranty. andrewm@0: // You may copy and distribute verbatim copies of this document. andrewm@0: // You may modify and use this source code to create binary code for your own purposes, free or commercial. andrewm@0: // andrewm@0: andrewm@0: #include "ADSR.h" andrewm@0: #include andrewm@0: andrewm@0: andrewm@0: ADSR::ADSR(void) { andrewm@0: reset(); andrewm@0: setAttackRate(0); andrewm@0: setDecayRate(0); andrewm@0: setReleaseRate(0); andrewm@0: setSustainLevel(1.0); andrewm@0: setTargetRatioA(0.3); andrewm@0: setTargetRatioDR(0.0001); andrewm@0: } andrewm@0: andrewm@0: ADSR::~ADSR(void) { andrewm@0: } andrewm@0: andrewm@0: void ADSR::setAttackRate(float rate) { andrewm@0: attackRate = rate; andrewm@0: attackCoef = calcCoef(rate, targetRatioA); andrewm@0: attackBase = (1.0 + targetRatioA) * (1.0 - attackCoef); andrewm@0: } andrewm@0: andrewm@0: void ADSR::setDecayRate(float rate) { andrewm@0: decayRate = rate; andrewm@0: decayCoef = calcCoef(rate, targetRatioDR); andrewm@0: decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef); andrewm@0: } andrewm@0: andrewm@0: void ADSR::setReleaseRate(float rate) { andrewm@0: releaseRate = rate; andrewm@0: releaseCoef = calcCoef(rate, targetRatioDR); andrewm@0: releaseBase = -targetRatioDR * (1.0 - releaseCoef); andrewm@0: } andrewm@0: andrewm@0: float ADSR::calcCoef(float rate, float targetRatio) { andrewm@0: return exp(-log((1.0 + targetRatio) / targetRatio) / rate); andrewm@0: } andrewm@0: andrewm@0: void ADSR::setSustainLevel(float level) { andrewm@0: sustainLevel = level; andrewm@0: decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef); andrewm@0: } andrewm@0: andrewm@0: void ADSR::setTargetRatioA(float targetRatio) { andrewm@0: if (targetRatio < 0.000000001) andrewm@0: targetRatio = 0.000000001; // -180 dB andrewm@0: targetRatioA = targetRatio; andrewm@0: attackBase = (1.0 + targetRatioA) * (1.0 - attackCoef); andrewm@0: } andrewm@0: andrewm@0: void ADSR::setTargetRatioDR(float targetRatio) { andrewm@0: if (targetRatio < 0.000000001) andrewm@0: targetRatio = 0.000000001; // -180 dB andrewm@0: targetRatioDR = targetRatio; andrewm@0: decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef); andrewm@0: releaseBase = -targetRatioDR * (1.0 - releaseCoef); andrewm@0: }