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 /***************************************************/ 00022 /***************************************************/ 00023 00024 class ADSR : public Generator 00025 { 00026 public: 00027 00029 enum { 00030 ATTACK, 00031 DECAY, 00032 SUSTAIN, 00033 RELEASE, 00034 IDLE 00035 }; 00036 00038 ADSR( void ); 00039 00041 ~ADSR( void ); 00042 00044 void keyOn( void ); 00045 00047 void keyOff( void ); 00048 00050 void setAttackRate( StkFloat rate ); 00051 00053 void setAttackTarget( StkFloat target ); 00054 00056 void setDecayRate( StkFloat rate ); 00057 00059 void setSustainLevel( StkFloat level ); 00060 00062 void setReleaseRate( StkFloat rate ); 00063 00065 void setAttackTime( StkFloat time ); 00066 00068 void setDecayTime( StkFloat time ); 00069 00071 void setReleaseTime( StkFloat time ); 00072 00074 void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime ); 00075 00077 void setTarget( StkFloat target ); 00078 00080 int getState( void ) const { return state_; }; 00081 00083 void setValue( StkFloat value ); 00084 00086 StkFloat lastOut( void ) const { return lastFrame_[0]; }; 00087 00089 StkFloat tick( void ); 00090 00092 00099 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00100 00101 protected: 00102 00103 void sampleRateChanged( StkFloat newRate, StkFloat oldRate ); 00104 00105 int state_; 00106 StkFloat value_; 00107 StkFloat target_; 00108 StkFloat attackRate_; 00109 StkFloat decayRate_; 00110 StkFloat releaseRate_; 00111 StkFloat releaseTime_; 00112 StkFloat sustainLevel_; 00113 }; 00114 00115 inline StkFloat ADSR :: tick( void ) 00116 { 00117 switch ( state_ ) { 00118 00119 case ATTACK: 00120 value_ += attackRate_; 00121 if ( value_ >= target_ ) { 00122 value_ = target_; 00123 target_ = sustainLevel_; 00124 state_ = DECAY; 00125 } 00126 lastFrame_[0] = value_; 00127 break; 00128 00129 case DECAY: 00130 if ( value_ > sustainLevel_ ) { 00131 value_ -= decayRate_; 00132 if ( value_ <= sustainLevel_ ) { 00133 value_ = sustainLevel_; 00134 state_ = SUSTAIN; 00135 } 00136 } 00137 else { 00138 value_ += decayRate_; // attack target < sustain level 00139 if ( value_ >= sustainLevel_ ) { 00140 value_ = sustainLevel_; 00141 state_ = SUSTAIN; 00142 } 00143 } 00144 lastFrame_[0] = value_; 00145 break; 00146 00147 case RELEASE: 00148 value_ -= releaseRate_; 00149 if ( value_ <= 0.0 ) { 00150 value_ = 0.0; 00151 state_ = IDLE; 00152 } 00153 lastFrame_[0] = value_; 00154 00155 } 00156 00157 return value_; 00158 } 00159 00160 inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel ) 00161 { 00162 #if defined(_STK_DEBUG_) 00163 if ( channel >= frames.channels() ) { 00164 oStream_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!"; 00165 handleError( StkError::FUNCTION_ARGUMENT ); 00166 } 00167 #endif 00168 00169 StkFloat *samples = &frames[channel]; 00170 unsigned int hop = frames.channels(); 00171 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00172 *samples = ADSR::tick(); 00173 00174 return frames; 00175 } 00176 00177 } // stk namespace 00178 00179 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |