Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_ADSR_H 00002 #define STK_ADSR_H 00003 00004 #include "Generator.h" 00005 00006 namespace stk { 00007 00008 /***************************************************/ 00021 /***************************************************/ 00022 00023 class ADSR : public Generator 00024 { 00025 public: 00026 00028 enum { 00029 ATTACK, 00030 DECAY, 00031 SUSTAIN, 00032 RELEASE, 00033 IDLE 00034 }; 00035 00037 ADSR( void ); 00038 00040 ~ADSR( void ); 00041 00043 void keyOn( void ); 00044 00046 void keyOff( void ); 00047 00049 void setAttackRate( StkFloat rate ); 00050 00052 void setAttackTarget( StkFloat target ); 00053 00055 void setDecayRate( StkFloat rate ); 00056 00058 void setSustainLevel( StkFloat level ); 00059 00061 void setReleaseRate( StkFloat rate ); 00062 00064 void setAttackTime( StkFloat time ); 00065 00067 void setDecayTime( StkFloat time ); 00068 00070 void setReleaseTime( StkFloat time ); 00071 00073 void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime ); 00074 00076 void setTarget( StkFloat target ); 00077 00079 int getState( void ) const { return state_; }; 00080 00082 void setValue( StkFloat value ); 00083 00085 StkFloat lastOut( void ) const { return lastFrame_[0]; }; 00086 00088 StkFloat tick( void ); 00089 00091 00098 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00099 00100 protected: 00101 00102 void sampleRateChanged( StkFloat newRate, StkFloat oldRate ); 00103 00104 int state_; 00105 StkFloat value_; 00106 StkFloat target_; 00107 StkFloat attackRate_; 00108 StkFloat decayRate_; 00109 StkFloat releaseRate_; 00110 StkFloat releaseTime_; 00111 StkFloat sustainLevel_; 00112 }; 00113 00114 inline StkFloat ADSR :: tick( void ) 00115 { 00116 switch ( state_ ) { 00117 00118 case ATTACK: 00119 value_ += attackRate_; 00120 if ( value_ >= target_ ) { 00121 value_ = target_; 00122 target_ = sustainLevel_; 00123 state_ = DECAY; 00124 } 00125 lastFrame_[0] = value_; 00126 break; 00127 00128 case DECAY: 00129 if ( value_ > sustainLevel_ ) { 00130 value_ -= decayRate_; 00131 if ( value_ <= sustainLevel_ ) { 00132 value_ = sustainLevel_; 00133 state_ = SUSTAIN; 00134 } 00135 } 00136 else { 00137 value_ += decayRate_; // attack target < sustain level 00138 if ( value_ >= sustainLevel_ ) { 00139 value_ = sustainLevel_; 00140 state_ = SUSTAIN; 00141 } 00142 } 00143 lastFrame_[0] = value_; 00144 break; 00145 00146 case RELEASE: 00147 value_ -= releaseRate_; 00148 if ( value_ <= 0.0 ) { 00149 value_ = 0.0; 00150 state_ = IDLE; 00151 } 00152 lastFrame_[0] = value_; 00153 00154 } 00155 00156 return value_; 00157 } 00158 00159 inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel ) 00160 { 00161 #if defined(_STK_DEBUG_) 00162 if ( channel >= frames.channels() ) { 00163 oStream_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!"; 00164 handleError( StkError::FUNCTION_ARGUMENT ); 00165 } 00166 #endif 00167 00168 StkFloat *samples = &frames[channel]; 00169 unsigned int hop = frames.channels(); 00170 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00171 *samples = ADSR::tick(); 00172 00173 return frames; 00174 } 00175 00176 } // stk namespace 00177 00178 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2011 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |