Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


TapDelay.h

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.