Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
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 errorString_ << "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-2010 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |