robert@464
|
1 //
|
robert@464
|
2 // ADSR.cpp
|
robert@464
|
3 //
|
robert@464
|
4 // Created by Nigel Redmon on 12/18/12.
|
robert@464
|
5 // EarLevel Engineering: earlevel.com
|
robert@464
|
6 // Copyright 2012 Nigel Redmon
|
robert@464
|
7 //
|
robert@464
|
8 // For a complete explanation of the ADSR envelope generator and code,
|
robert@464
|
9 // read the series of articles by the author, starting here:
|
robert@464
|
10 // http://www.earlevel.com/main/2013/06/01/envelope-generators/
|
robert@464
|
11 //
|
robert@464
|
12 // License:
|
robert@464
|
13 //
|
robert@464
|
14 // This source code is provided as is, without warranty.
|
robert@464
|
15 // You may copy and distribute verbatim copies of this document.
|
robert@464
|
16 // You may modify and use this source code to create binary code for your own purposes, free or commercial.
|
robert@464
|
17 //
|
robert@464
|
18
|
robert@464
|
19 #include "ADSR.h"
|
robert@464
|
20 #include <math.h>
|
robert@464
|
21
|
robert@464
|
22
|
robert@464
|
23 ADSR::ADSR(void) {
|
robert@464
|
24 reset();
|
robert@464
|
25 setAttackRate(0);
|
robert@464
|
26 setDecayRate(0);
|
robert@464
|
27 setReleaseRate(0);
|
robert@464
|
28 setSustainLevel(1.0);
|
robert@464
|
29 setTargetRatioA(0.3);
|
robert@464
|
30 setTargetRatioDR(0.0001);
|
robert@464
|
31 }
|
robert@464
|
32
|
robert@464
|
33 ADSR::~ADSR(void) {
|
robert@464
|
34 }
|
robert@464
|
35
|
robert@464
|
36 void ADSR::setAttackRate(float rate) {
|
robert@464
|
37 attackRate = rate;
|
robert@464
|
38 attackCoef = calcCoef(rate, targetRatioA);
|
robert@464
|
39 attackBase = (1.0 + targetRatioA) * (1.0 - attackCoef);
|
robert@464
|
40 }
|
robert@464
|
41
|
robert@464
|
42 void ADSR::setDecayRate(float rate) {
|
robert@464
|
43 decayRate = rate;
|
robert@464
|
44 decayCoef = calcCoef(rate, targetRatioDR);
|
robert@464
|
45 decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef);
|
robert@464
|
46 }
|
robert@464
|
47
|
robert@464
|
48 void ADSR::setReleaseRate(float rate) {
|
robert@464
|
49 releaseRate = rate;
|
robert@464
|
50 releaseCoef = calcCoef(rate, targetRatioDR);
|
robert@464
|
51 releaseBase = -targetRatioDR * (1.0 - releaseCoef);
|
robert@464
|
52 }
|
robert@464
|
53
|
robert@464
|
54 float ADSR::calcCoef(float rate, float targetRatio) {
|
robert@464
|
55 return exp(-log((1.0 + targetRatio) / targetRatio) / rate);
|
robert@464
|
56 }
|
robert@464
|
57
|
robert@464
|
58 void ADSR::setSustainLevel(float level) {
|
robert@464
|
59 sustainLevel = level;
|
robert@464
|
60 decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef);
|
robert@464
|
61 }
|
robert@464
|
62
|
robert@464
|
63 void ADSR::setTargetRatioA(float targetRatio) {
|
robert@464
|
64 if (targetRatio < 0.000000001)
|
robert@464
|
65 targetRatio = 0.000000001; // -180 dB
|
robert@464
|
66 targetRatioA = targetRatio;
|
robert@464
|
67 attackBase = (1.0 + targetRatioA) * (1.0 - attackCoef);
|
robert@464
|
68 }
|
robert@464
|
69
|
robert@464
|
70 void ADSR::setTargetRatioDR(float targetRatio) {
|
robert@464
|
71 if (targetRatio < 0.000000001)
|
robert@464
|
72 targetRatio = 0.000000001; // -180 dB
|
robert@464
|
73 targetRatioDR = targetRatio;
|
robert@464
|
74 decayBase = (sustainLevel - targetRatioDR) * (1.0 - decayCoef);
|
robert@464
|
75 releaseBase = -targetRatioDR * (1.0 - releaseCoef);
|
robert@464
|
76 }
|