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 /***************************************************/
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.