Mercurial > hg > apm2s
comparison stk/src/ADSR.cpp @ 0:4606bd505630 tip
first import
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Sat, 13 Jun 2015 15:08:10 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4606bd505630 |
---|---|
1 /***************************************************/ | |
2 /*! \class ADSR | |
3 \brief STK ADSR envelope class. | |
4 | |
5 This class implements a traditional ADSR (Attack, Decay, Sustain, | |
6 Release) envelope. It responds to simple keyOn and keyOff | |
7 messages, keeping track of its state. The \e state = ADSR::IDLE | |
8 before being triggered and after the envelope value reaches 0.0 in | |
9 the ADSR::RELEASE state. All rate, target and level settings must | |
10 be non-negative. All time settings must be positive. | |
11 | |
12 by Perry R. Cook and Gary P. Scavone, 1995--2014. | |
13 */ | |
14 /***************************************************/ | |
15 | |
16 #include "../include/ADSR.h" | |
17 | |
18 namespace stk { | |
19 | |
20 ADSR :: ADSR( void ) | |
21 { | |
22 target_ = 0.0; | |
23 value_ = 0.0; | |
24 attackRate_ = 0.001; | |
25 decayRate_ = 0.001; | |
26 releaseRate_ = 0.005; | |
27 releaseTime_ = -1.0; | |
28 sustainLevel_ = 0.5; | |
29 state_ = IDLE; | |
30 Stk::addSampleRateAlert( this ); | |
31 } | |
32 | |
33 ADSR :: ~ADSR( void ) | |
34 { | |
35 } | |
36 | |
37 void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate ) | |
38 { | |
39 if ( !ignoreSampleRateChange_ ) { | |
40 attackRate_ = oldRate * attackRate_ / newRate; | |
41 decayRate_ = oldRate * decayRate_ / newRate; | |
42 releaseRate_ = oldRate * releaseRate_ / newRate; | |
43 } | |
44 } | |
45 | |
46 void ADSR :: keyOn() | |
47 { | |
48 if ( target_ <= 0.0 ) target_ = 1.0; | |
49 state_ = ATTACK; | |
50 } | |
51 | |
52 void ADSR :: keyOff() | |
53 { | |
54 target_ = 0.0; | |
55 state_ = RELEASE; | |
56 | |
57 // FIXED October 2010 - Nick Donaldson | |
58 // Need to make release rate relative to current value!! | |
59 // Only update if we have set a TIME rather than a RATE, | |
60 // in which case releaseTime_ will be -1 | |
61 if ( releaseTime_ > 0.0 ) | |
62 releaseRate_ = value_ / ( releaseTime_ * Stk::sampleRate() ); | |
63 } | |
64 | |
65 void ADSR :: setAttackRate( StkFloat rate ) | |
66 { | |
67 if ( rate < 0.0 ) { | |
68 oStream_ << "ADSR::setAttackRate: argument must be >= 0.0!"; | |
69 handleError( StkError::WARNING ); return; | |
70 } | |
71 | |
72 attackRate_ = rate; | |
73 } | |
74 | |
75 void ADSR :: setAttackTarget( StkFloat target ) | |
76 { | |
77 if ( target < 0.0 ) { | |
78 oStream_ << "ADSR::setAttackTarget: negative target not allowed!"; | |
79 handleError( StkError::WARNING ); return; | |
80 } | |
81 | |
82 target_ = target; | |
83 } | |
84 | |
85 void ADSR :: setDecayRate( StkFloat rate ) | |
86 { | |
87 if ( rate < 0.0 ) { | |
88 oStream_ << "ADSR::setDecayRate: negative rates not allowed!"; | |
89 handleError( StkError::WARNING ); return; | |
90 } | |
91 | |
92 decayRate_ = rate; | |
93 } | |
94 | |
95 void ADSR :: setSustainLevel( StkFloat level ) | |
96 { | |
97 if ( level < 0.0 ) { | |
98 oStream_ << "ADSR::setSustainLevel: negative level not allowed!"; | |
99 handleError( StkError::WARNING ); return; | |
100 } | |
101 | |
102 sustainLevel_ = level; | |
103 } | |
104 | |
105 void ADSR :: setReleaseRate( StkFloat rate ) | |
106 { | |
107 if ( rate < 0.0 ) { | |
108 oStream_ << "ADSR::setReleaseRate: negative rates not allowed!"; | |
109 handleError( StkError::WARNING ); return; | |
110 } | |
111 | |
112 releaseRate_ = rate; | |
113 | |
114 // Set to negative value so we don't update the release rate on keyOff() | |
115 releaseTime_ = -1.0; | |
116 } | |
117 | |
118 void ADSR :: setAttackTime( StkFloat time ) | |
119 { | |
120 if ( time <= 0.0 ) { | |
121 oStream_ << "ADSR::setAttackTime: negative or zero times not allowed!"; | |
122 handleError( StkError::WARNING ); return; | |
123 } | |
124 | |
125 attackRate_ = 1.0 / ( time * Stk::sampleRate() ); | |
126 } | |
127 | |
128 void ADSR :: setDecayTime( StkFloat time ) | |
129 { | |
130 if ( time <= 0.0 ) { | |
131 oStream_ << "ADSR::setDecayTime: negative or zero times not allowed!"; | |
132 handleError( StkError::WARNING ); return; | |
133 } | |
134 | |
135 decayRate_ = (1.0 - sustainLevel_) / ( time * Stk::sampleRate() ); | |
136 } | |
137 | |
138 void ADSR :: setReleaseTime( StkFloat time ) | |
139 { | |
140 if ( time <= 0.0 ) { | |
141 oStream_ << "ADSR::setReleaseTime: negative or zero times not allowed!"; | |
142 handleError( StkError::WARNING ); return; | |
143 } | |
144 | |
145 releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() ); | |
146 releaseTime_ = time; | |
147 } | |
148 | |
149 void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime ) | |
150 { | |
151 this->setAttackTime( aTime ); | |
152 this->setSustainLevel( sLevel ); | |
153 this->setDecayTime( dTime ); | |
154 this->setReleaseTime( rTime ); | |
155 } | |
156 | |
157 void ADSR :: setTarget( StkFloat target ) | |
158 { | |
159 if ( target < 0.0 ) { | |
160 oStream_ << "ADSR::setTarget: negative target not allowed!"; | |
161 handleError( StkError::WARNING ); return; | |
162 } | |
163 | |
164 target_ = target; | |
165 | |
166 this->setSustainLevel( target_ ); | |
167 if ( value_ < target_ ) state_ = ATTACK; | |
168 if ( value_ > target_ ) state_ = DECAY; | |
169 } | |
170 | |
171 void ADSR :: setValue( StkFloat value ) | |
172 { | |
173 state_ = SUSTAIN; | |
174 target_ = value; | |
175 value_ = value; | |
176 this->setSustainLevel( value ); | |
177 lastFrame_[0] = value; | |
178 } | |
179 | |
180 } // stk namespace |