Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_TAPDELAY_H 00002 #define STK_TAPDELAY_H 00003 00004 #include "Filter.h" 00005 00006 namespace stk { 00007 00008 /***************************************************/ 00022 /***************************************************/ 00023 00024 class TapDelay : public Filter 00025 { 00026 public: 00027 00029 00034 TapDelay( std::vector<unsigned long> taps = std::vector<unsigned long>( 1, 0 ), unsigned long maxDelay = 4095 ); 00035 00037 ~TapDelay(); 00038 00040 00047 void setMaximumDelay( unsigned long delay ); 00048 00050 00053 void setTapDelays( std::vector<unsigned long> taps ); 00054 00056 std::vector<unsigned long> getTapDelays( void ) const { return delays_; }; 00057 00059 00067 StkFloat lastOut( unsigned int tap = 0 ) const; 00068 00070 00079 StkFrames& tick( StkFloat input, StkFrames& outputs ); 00080 00082 00091 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00092 00094 00105 StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0 ); 00106 00107 protected: 00108 00109 unsigned long inPoint_; 00110 std::vector<unsigned long> outPoint_; 00111 std::vector<unsigned long> delays_; 00112 00113 }; 00114 00115 inline StkFloat TapDelay :: lastOut( unsigned int tap ) const 00116 { 00117 #if defined(_STK_DEBUG_) 00118 if ( tap >= lastFrame_.size() ) ) { 00119 errorString_ << "TapDelay::lastOut(): tap argument and number of taps are incompatible!"; 00120 handleError( StkError::FUNCTION_ARGUMENT ); 00121 } 00122 #endif 00123 00124 return lastFrame_[tap]; 00125 } 00126 00127 inline StkFrames& TapDelay :: tick( StkFloat input, StkFrames& outputs ) 00128 { 00129 #if defined(_STK_DEBUG_) 00130 if ( outputs.channels() < outPoint_.size() ) { 00131 errorString_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!"; 00132 handleError( StkError::FUNCTION_ARGUMENT ); 00133 } 00134 #endif 00135 00136 inputs_[inPoint_++] = input * gain_; 00137 00138 // Check for end condition 00139 if ( inPoint_ == inputs_.size() ) 00140 inPoint_ = 0; 00141 00142 // Read out next values 00143 StkFloat *outs = &outputs[0]; 00144 for ( unsigned int i=0; i<outPoint_.size(); i++ ) { 00145 *outs++ = inputs_[outPoint_[i]]; 00146 lastFrame_[i] = *outs; 00147 if ( ++outPoint_[i] == inputs_.size() ) 00148 outPoint_[i] = 0; 00149 } 00150 00151 return outputs; 00152 } 00153 00154 inline StkFrames& TapDelay :: tick( StkFrames& frames, unsigned int channel ) 00155 { 00156 #if defined(_STK_DEBUG_) 00157 if ( channel >= frames.channels() ) { 00158 errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!"; 00159 handleError( StkError::FUNCTION_ARGUMENT ); 00160 } 00161 if ( frames.channels() < outPoint_.size() ) { 00162 errorString_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!"; 00163 handleError( StkError::FUNCTION_ARGUMENT ); 00164 } 00165 #endif 00166 00167 StkFloat *iSamples = &frames[channel]; 00168 StkFloat *oSamples = &frames[0]; 00169 unsigned int j, iHop = frames.channels(), oHop = frames.channels() - outPoint_.size(); 00170 for ( unsigned int i=0; i<frames.frames(); i++, iSamples += iHop, oSamples += oHop ) { 00171 inputs_[inPoint_++] = *iSamples * gain_; 00172 if ( inPoint_ == inputs_.size() ) inPoint_ = 0; 00173 for ( j=0; j<outPoint_.size(); j++ ) { 00174 *oSamples++ = inputs_[outPoint_[j]]; 00175 if ( ++outPoint_[j] == inputs_.size() ) outPoint_[j] = 0; 00176 } 00177 } 00178 00179 oSamples -= frames.channels(); 00180 for ( j=0; j<outPoint_.size(); j++ ) lastFrame_[j] = *oSamples++; 00181 return frames; 00182 } 00183 00184 inline StkFrames& TapDelay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel ) 00185 { 00186 #if defined(_STK_DEBUG_) 00187 if ( iChannel >= iFrames.channels() ) { 00188 errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!"; 00189 handleError( StkError::FUNCTION_ARGUMENT ); 00190 } 00191 if ( oFrames.channels() < outPoint_.size() ) { 00192 errorString_ << "TapDelay::tick(): number of taps > channels in output StkFrames argument!"; 00193 handleError( StkError::FUNCTION_ARGUMENT ); 00194 } 00195 #endif 00196 00197 StkFloat *iSamples = &iFrames[iChannel]; 00198 StkFloat *oSamples = &oFrames[0]; 00199 unsigned int j, iHop = iFrames.channels(), oHop = oFrames.channels() - outPoint_.size(); 00200 for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) { 00201 inputs_[inPoint_++] = *iSamples * gain_; 00202 if ( inPoint_ == inputs_.size() ) inPoint_ = 0; 00203 for ( j=0; j<outPoint_.size(); j++ ) { 00204 *oSamples++ = inputs_[outPoint_[j]]; 00205 if ( ++outPoint_[j] == inputs_.size() ) outPoint_[j] = 0; 00206 } 00207 } 00208 00209 oSamples -= oFrames.channels(); 00210 for ( j=0; j<outPoint_.size(); j++ ) lastFrame_[j] = *oSamples++; 00211 return iFrames; 00212 } 00213 00214 #endif 00215 00216 } // stk namespace
The Synthesis ToolKit in C++ (STK) |
©1995-2010 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |