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