robert@464: // robert@464: // ADSR.cpp 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: #include "ADSR.h" robert@464: #include robert@464: robert@464: robert@464: ADSR::ADSR(void) { robert@464: reset(); robert@464: setAttackRate(0); robert@464: setDecayRate(0); robert@464: setReleaseRate(0); robert@464: setSustainLevel(1.0); robert@464: setTargetRatioA(0.3); robert@464: setTargetRatioDR(0.0001); robert@464: } robert@464: robert@464: ADSR::~ADSR(void) { robert@464: } robert@464: robert@464: void ADSR::setAttackRate(float rate) { robert@464: attackRate = rate; robert@464: attackCoef = calcCoef(rate, targetRatioA); robert@464: attackBase = (1.0 + targetRatioA) * (1.0 - attackCoef); robert@464: } robert@464: robert@464: void ADSR::setDecayRate(float rate) { robert@464: decayRate = rate; robert@464: decayCoef = calcCoef(rate, targetRatioDR); robert@464: decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef); robert@464: } robert@464: robert@464: void ADSR::setReleaseRate(float rate) { robert@464: releaseRate = rate; robert@464: releaseCoef = calcCoef(rate, targetRatioDR); robert@464: releaseBase = -targetRatioDR * (1.0 - releaseCoef); robert@464: } robert@464: robert@464: float ADSR::calcCoef(float rate, float targetRatio) { robert@464: return exp(-log((1.0 + targetRatio) / targetRatio) / rate); robert@464: } robert@464: robert@464: void ADSR::setSustainLevel(float level) { robert@464: sustainLevel = level; robert@464: decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef); robert@464: } robert@464: robert@464: void ADSR::setTargetRatioA(float targetRatio) { robert@464: if (targetRatio < 0.000000001) robert@464: targetRatio = 0.000000001; // -180 dB robert@464: targetRatioA = targetRatio; robert@464: attackBase = (1.0 + targetRatioA) * (1.0 - attackCoef); robert@464: } robert@464: robert@464: void ADSR::setTargetRatioDR(float targetRatio) { robert@464: if (targetRatio < 0.000000001) robert@464: targetRatio = 0.000000001; // -180 dB robert@464: targetRatioDR = targetRatio; robert@464: decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef); robert@464: releaseBase = -targetRatioDR * (1.0 - releaseCoef); robert@464: }