Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


Cubic.h

00001 #ifndef STK_CUBIC_H
00002 #define STK_CUBIC_H
00003 
00004 #include "Function.h"
00005 #include <cmath>
00006 
00007 namespace stk {
00008 
00009 /***************************************************/
00027 /***************************************************/
00028 
00029 class Cubic : public Function
00030 {
00031 public:
00033   Cubic( void ) : a1_(0.5), a2_(0.5), a3_(0.5), gain_(1.0), threshold_(1.0) {};
00034 
00036   void setA1( StkFloat a1 ) { a1_ = a1; };
00037 
00039   void setA2( StkFloat a2 )  { a2_ = a2; };
00040 
00042   void setA3( StkFloat a3 )  { a3_ = a3; };
00043 
00045   void setGain( StkFloat gain ) { gain_ = gain; };
00046 
00048   void setThreshold( StkFloat threshold ) { threshold_ = threshold; };
00049 
00051   StkFloat tick( StkFloat input );
00052 
00054 
00062   StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
00063 
00065 
00073   StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
00074 
00075 protected:
00076 
00077   StkFloat a1_;
00078   StkFloat a2_;
00079   StkFloat a3_;
00080   StkFloat gain_; 
00081   StkFloat threshold_;
00082 };
00083 
00084 inline StkFloat Cubic :: tick( StkFloat input )
00085 {
00086   StkFloat inSquared = input * input;
00087   StkFloat inCubed = inSquared * input;
00088 
00089   lastFrame_[0] = gain_ * (a1_ * input + a2_ * inSquared + a3_ * inCubed);
00090 
00091   // Apply threshold if we are out of range.
00092   if ( fabs( lastFrame_[0] ) > threshold_ ) {
00093     lastFrame_[0] = ( lastFrame_[0] < 0 ? -threshold_ : threshold_ );
00094   }
00095 
00096   return lastFrame_[0];
00097 }
00098 
00099 inline StkFrames& Cubic :: tick( StkFrames& frames, unsigned int channel )
00100 {
00101 #if defined(_STK_DEBUG_)
00102   if ( channel >= frames.channels() ) {
00103     oStream_ << "Cubic::tick(): channel and StkFrames arguments are incompatible!";
00104     handleError( StkError::FUNCTION_ARGUMENT );
00105   }
00106 #endif
00107 
00108   StkFloat *samples = &frames[channel];
00109   unsigned int hop = frames.channels();
00110   for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
00111     *samples = tick( *samples );
00112 
00113   lastFrame_[0] = *(samples-hop);
00114   return frames;
00115 }
00116 
00117 inline StkFrames& Cubic :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
00118 {
00119 #if defined(_STK_DEBUG_)
00120   if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
00121     oStream_ << "Cubic::tick(): channel and StkFrames arguments are incompatible!";
00122     handleError( StkError::FUNCTION_ARGUMENT );
00123   }
00124 #endif
00125 
00126   StkFloat *iSamples = &iFrames[iChannel];
00127   StkFloat *oSamples = &oFrames[oChannel];
00128   unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
00129   for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
00130     *oSamples = tick( *iSamples );
00131 
00132   lastFrame_[0] = *(oSamples-oHop);
00133   return iFrames;
00134 }
00135 
00136 } // stk namespace
00137 
00138 #endif

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