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 /***************************************************/
00019 /***************************************************/
00020 
00021 class ADSR : public Generator
00022 {
00023  public:
00024 
00026   enum {
00027     ATTACK,   
00028     DECAY,    
00029     SUSTAIN,  
00030     RELEASE,  
00031     DONE      
00032   };
00033 
00035   ADSR( void );
00036 
00038   ~ADSR( void );
00039 
00041   void keyOn( void );
00042 
00044   void keyOff( void );
00045 
00047   void setAttackRate( StkFloat rate );
00048 
00050   void setDecayRate( StkFloat rate );
00051 
00053   void setSustainLevel( StkFloat level );
00054 
00056   void setReleaseRate( StkFloat rate );
00057 
00059   void setAttackTime( StkFloat time );
00060 
00062   void setDecayTime( StkFloat time );
00063 
00065   void setReleaseTime( StkFloat time );
00066 
00068   void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime );
00069 
00071   void setTarget( StkFloat target );
00072 
00074   int getState( void ) const { return state_; };
00075 
00077   void setValue( StkFloat value );
00078 
00080   StkFloat lastOut( void ) const { return lastFrame_[0]; };
00081 
00083   StkFloat tick( void );
00084 
00086 
00093   StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
00094 
00095  protected:  
00096 
00097   void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
00098 
00099   int state_;
00100   StkFloat value_;
00101   StkFloat target_;
00102   StkFloat attackRate_;
00103   StkFloat decayRate_;
00104   StkFloat releaseRate_;
00105   StkFloat sustainLevel_;
00106 };
00107 
00108 inline StkFloat ADSR :: tick( void )
00109 {
00110   switch ( state_ ) {
00111 
00112   case ATTACK:
00113     value_ += attackRate_;
00114     if ( value_ >= target_ ) {
00115       value_ = target_;
00116       target_ = sustainLevel_;
00117              state_ = DECAY;
00118     }
00119     lastFrame_[0] = value_;
00120     break;
00121 
00122   case DECAY:
00123     value_ -= decayRate_;
00124     if ( value_ <= sustainLevel_ ) {
00125       value_ = sustainLevel_;
00126       state_ = SUSTAIN;
00127     }
00128     lastFrame_[0] = value_;
00129     break;
00130 
00131   case RELEASE:
00132     value_ -= releaseRate_;
00133     if ( value_ <= 0.0 ) {
00134       value_ = (StkFloat) 0.0;
00135       state_ = DONE;
00136     }
00137     lastFrame_[0] = value_;
00138 
00139   }
00140 
00141   return value_;
00142 }
00143 
00144 inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel )
00145 {
00146 #if defined(_STK_DEBUG_)
00147   if ( channel >= frames.channels() ) {
00148     errorString_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!";
00149     handleError( StkError::FUNCTION_ARGUMENT );
00150   }
00151 #endif
00152 
00153   StkFloat *samples = &frames[channel];
00154   unsigned int hop = frames.channels();
00155   for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
00156     *samples = ADSR::tick();
00157 
00158   return frames;
00159 }
00160 
00161 } // stk namespace
00162 
00163 #endif

The Synthesis ToolKit in C++ (STK)
©1995-2010 Perry R. Cook and Gary P. Scavone. All Rights Reserved.