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