Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

# BlitSquare.h

    00001 #ifndef STK_BLITSQUARE_H
    00002 #define STK_BLITSQUARE_H
    00003
    00004 #include "Generator.h"
    00005 #include <cmath>
    00006 #include <limits>
    00007
    00008 namespace stk {
    00009
    00010 /***************************************************/
    00040 /***************************************************/
    00041
    00042 class BlitSquare: public Generator
    00043 {
    00044  public:
    00046   BlitSquare( StkFloat frequency = 220.0 );
    00047
    00049   ~BlitSquare();
    00050
    00052   void reset();
    00053
    00055
    00058   void setPhase( StkFloat phase ) { phase_ = PI * phase; };
    00059
    00061
    00064   StkFloat getPhase() const { return phase_ / PI; };
    00065
    00067   void setFrequency( StkFloat frequency );
    00068
    00070
    00082   void setHarmonics( unsigned int nHarmonics = 0 );
    00083
    00085   StkFloat lastOut( void ) const { return lastFrame_[0]; };
    00086
    00088   StkFloat tick( void );
    00089
    00091
    00098   StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
    00099
    00100  protected:
    00101
    00102   void updateHarmonics( void );
    00103
    00104   unsigned int nHarmonics_;
    00105   unsigned int m_;
    00106   StkFloat rate_;
    00107   StkFloat phase_;
    00108   StkFloat p_;
    00109   StkFloat a_;
    00110   StkFloat lastBlitOutput_;
    00111   StkFloat dcbState_;
    00112 };
    00113
    00114 inline StkFloat BlitSquare :: tick( void )
    00115 {
    00116   StkFloat temp = lastBlitOutput_;
    00117
    00118   // A fully  optimized version of this would replace the two sin calls
    00119   // with a pair of fast sin oscillators, for which stable fast
    00120   // two-multiply algorithms are well known. In the spirit of STK,
    00121   // which favors clarity over performance, the optimization has
    00122   // not been made here.
    00123
    00124   // Avoid a divide by zero, or use of a denomralized divisor
    00125   // at the sinc peak, which has a limiting value of 1.0.
    00126   StkFloat denominator = sin( phase_ );
    00127   if ( fabs( denominator )  < std::numeric_limits<StkFloat>::epsilon() ) {
    00128     // Inexact comparison safely distinguishes betwen *close to zero*, and *close to PI*.
    00129     if ( phase_ < 0.1f || phase_ > TWO_PI - 0.1f )
    00130       lastBlitOutput_ = a_;
    00131     else
    00132       lastBlitOutput_ = -a_;
    00133   }
    00134   else {
    00135     lastBlitOutput_ =  sin( m_ * phase_ );
    00136     lastBlitOutput_ /= p_ * denominator;
    00137   }
    00138
    00139   lastBlitOutput_ += temp;
    00140
    00141   // Now apply DC blocker.
    00142   lastFrame_[0] = lastBlitOutput_ - dcbState_ + 0.999 * lastFrame_[0];
    00143   dcbState_ = lastBlitOutput_;
    00144
    00145   phase_ += rate_;
    00146   if ( phase_ >= TWO_PI ) phase_ -= TWO_PI;
    00147
    00148          return lastFrame_[0];
    00149 }
    00150
    00151 inline StkFrames& BlitSquare :: tick( StkFrames& frames, unsigned int channel )
    00152 {
    00153 #if defined(_STK_DEBUG_)
    00154   if ( channel >= frames.channels() ) {
    00155     errorString_ << "BlitSquare::tick(): channel and StkFrames arguments are incompatible!";
    00156     handleError( StkError::FUNCTION_ARGUMENT );
    00157   }
    00158 #endif
    00159
    00160   StkFloat *samples = &frames[channel];
    00161   unsigned int hop = frames.channels();
    00162   for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
    00163     *samples = BlitSquare::tick();
    00164
    00165   return frames;
    00166 }
    00167
    00168 } // stk namespace
    00169
    00170 #endif

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