Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


ADSR.h

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.