Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


Blit.h

00001 #ifndef STK_BLIT_H
00002 #define STK_BLIT_H
00003 
00004 #include "Generator.h"
00005 #include <cmath>
00006 #include <limits>
00007 
00008 namespace stk {
00009 
00010 /***************************************************/
00031 /***************************************************/
00032 
00033 class Blit: public Generator
00034 {
00035  public:
00037   Blit( StkFloat frequency = 220.0 );
00038 
00040   ~Blit();
00041 
00043   void reset();
00044 
00046 
00049   void setPhase( StkFloat phase ) { phase_ = PI * phase; };
00050 
00052 
00055   StkFloat getPhase() const { return phase_ / PI; };
00056 
00058   void setFrequency( StkFloat frequency );
00059 
00061 
00073   void setHarmonics( unsigned int nHarmonics = 0 );
00074 
00076   StkFloat lastOut( void ) const { return lastFrame_[0]; };
00077 
00079   StkFloat tick( void );
00080 
00082 
00089   StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
00090 
00091  protected:
00092 
00093   void updateHarmonics( void );
00094 
00095   unsigned int nHarmonics_;
00096   unsigned int m_;
00097   StkFloat rate_;
00098   StkFloat phase_;
00099   StkFloat p_;
00100 
00101 };
00102 
00103 inline StkFloat Blit :: tick( void )
00104 {
00105   // The code below implements the SincM algorithm of Stilson and
00106   // Smith with an additional scale factor of P / M applied to
00107   // normalize the output.
00108 
00109   // A fully optimized version of this code would replace the two sin
00110   // calls with a pair of fast sin oscillators, for which stable fast
00111   // two-multiply algorithms are well known. In the spirit of STK,
00112   // which favors clarity over performance, the optimization has not
00113   // been made here.
00114 
00115   // Avoid a divide by zero at the sinc peak, which has a limiting
00116   // value of 1.0.
00117   StkFloat tmp, denominator = sin( phase_ );
00118   if ( denominator <= std::numeric_limits<StkFloat>::epsilon() )
00119     tmp = 1.0;
00120   else {
00121     tmp =  sin( m_ * phase_ );
00122     tmp /= m_ * denominator;
00123   }
00124 
00125   phase_ += rate_;
00126   if ( phase_ >= PI ) phase_ -= PI;
00127 
00128   lastFrame_[0] = tmp;
00129          return lastFrame_[0];
00130 }
00131 
00132 inline StkFrames& Blit :: tick( StkFrames& frames, unsigned int channel )
00133 {
00134 #if defined(_STK_DEBUG_)
00135   if ( channel >= frames.channels() ) {
00136     oStream_ << "Blit::tick(): channel and StkFrames arguments are incompatible!";
00137     handleError( StkError::FUNCTION_ARGUMENT );
00138   }
00139 #endif
00140 
00141   StkFloat *samples = &frames[channel];
00142   unsigned int hop = frames.channels();
00143   for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
00144     *samples = Blit::tick();
00145 
00146   return frames;
00147 }
00148 
00149 } // stk namespace
00150 
00151 #endif

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