Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_ENVELOPE_H 00002 #define STK_ENVELOPE_H 00003 00004 #include "Generator.h" 00005 00006 namespace stk { 00007 00008 /***************************************************/ 00019 /***************************************************/ 00020 00021 class Envelope : public Generator 00022 { 00023 public: 00024 00026 Envelope( void ); 00027 00029 ~Envelope( void ); 00030 00032 Envelope& operator= ( const Envelope& e ); 00033 00035 void keyOn( void ) { this->setTarget( 1.0 ); }; 00036 00038 void keyOff( void ) { this->setTarget( 0.0 ); }; 00039 00041 void setRate( StkFloat rate ); 00042 00044 void setTime( StkFloat time ); 00045 00047 void setTarget( StkFloat target ); 00048 00050 void setValue( StkFloat value ); 00051 00053 int getState( void ) const { return state_; }; 00054 00056 StkFloat lastOut( void ) const { return lastFrame_[0]; }; 00057 00059 StkFloat tick( void ); 00060 00062 00069 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00070 00071 protected: 00072 00073 void sampleRateChanged( StkFloat newRate, StkFloat oldRate ); 00074 00075 StkFloat value_; 00076 StkFloat target_; 00077 StkFloat rate_; 00078 int state_; 00079 }; 00080 00081 inline void Envelope :: setRate( StkFloat rate ) 00082 { 00083 #if defined(_STK_DEBUG_) 00084 if ( rate < 0.0 ) { 00085 errorString_ << "Envelope::setRate: negative rates not allowed ... correcting!"; 00086 handleError( StkError::WARNING ); 00087 rate_ = -rate; 00088 } 00089 else 00090 #endif 00091 rate_ = rate; 00092 } 00093 00094 inline void Envelope :: setTime( StkFloat time ) 00095 { 00096 #if defined(_STK_DEBUG_) 00097 if ( time < 0.0 ) { 00098 errorString_ << "Envelope::setTime: negative times not allowed ... correcting!"; 00099 handleError( StkError::WARNING ); 00100 rate_ = 1.0 / ( -time * Stk::sampleRate() ); 00101 } 00102 else 00103 #endif 00104 rate_ = 1.0 / ( time * Stk::sampleRate() ); 00105 } 00106 00107 inline void Envelope :: setTarget( StkFloat target ) 00108 { 00109 target_ = target; 00110 if ( value_ != target_ ) state_ = 1; 00111 } 00112 00113 inline void Envelope :: setValue( StkFloat value ) 00114 { 00115 state_ = 0; 00116 target_ = value; 00117 value_ = value; 00118 } 00119 00120 inline StkFloat Envelope :: tick( void ) 00121 { 00122 if ( state_ ) { 00123 if ( target_ > value_ ) { 00124 value_ += rate_; 00125 if ( value_ >= target_ ) { 00126 value_ = target_; 00127 state_ = 0; 00128 } 00129 } 00130 else { 00131 value_ -= rate_; 00132 if ( value_ <= target_ ) { 00133 value_ = target_; 00134 state_ = 0; 00135 } 00136 } 00137 lastFrame_[0] = value_; 00138 } 00139 00140 return value_; 00141 } 00142 00143 inline StkFrames& Envelope :: tick( StkFrames& frames, unsigned int channel ) 00144 { 00145 #if defined(_STK_DEBUG_) 00146 if ( channel >= frames.channels() ) { 00147 errorString_ << "Envelope::tick(): channel and StkFrames arguments are incompatible!"; 00148 handleError( StkError::FUNCTION_ARGUMENT ); 00149 } 00150 #endif 00151 00152 StkFloat *samples = &frames[channel]; 00153 unsigned int hop = frames.channels(); 00154 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00155 *samples = tick(); 00156 00157 return frames; 00158 } 00159 00160 } // stk namespace 00161 00162 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2010 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |