Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


Blit.h
1 #ifndef STK_BLIT_H
2 #define STK_BLIT_H
3 
4 #include "Generator.h"
5 #include <cmath>
6 #include <limits>
7 
8 namespace stk {
9 
10 /***************************************************/
31 /***************************************************/
32 
33 class Blit: public Generator
34 {
35  public:
37  Blit( StkFloat frequency = 220.0 );
38 
40  ~Blit();
41 
43  void reset();
44 
46 
49  void setPhase( StkFloat phase ) { phase_ = PI * phase; };
50 
52 
55  StkFloat getPhase() const { return phase_ / PI; };
56 
58  void setFrequency( StkFloat frequency );
59 
61 
73  void setHarmonics( unsigned int nHarmonics = 0 );
74 
76  StkFloat lastOut( void ) const { return lastFrame_[0]; };
77 
79  StkFloat tick( void );
80 
82 
89  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
90 
91  protected:
92 
93  void updateHarmonics( void );
94 
95  unsigned int nHarmonics_;
96  unsigned int m_;
97  StkFloat rate_;
98  StkFloat phase_;
99  StkFloat p_;
100 
101 };
102 
103 inline StkFloat Blit :: tick( void )
104 {
105  // The code below implements the SincM algorithm of Stilson and
106  // Smith with an additional scale factor of P / M applied to
107  // normalize the output.
108 
109  // A fully optimized version of this code would replace the two sin
110  // calls with a pair of fast sin oscillators, for which stable fast
111  // two-multiply algorithms are well known. In the spirit of STK,
112  // which favors clarity over performance, the optimization has not
113  // been made here.
114 
115  // Avoid a divide by zero at the sinc peak, which has a limiting
116  // value of 1.0.
117  StkFloat tmp, denominator = sin( phase_ );
118  if ( denominator <= std::numeric_limits<StkFloat>::epsilon() )
119  tmp = 1.0;
120  else {
121  tmp = sin( m_ * phase_ );
122  tmp /= m_ * denominator;
123  }
124 
125  phase_ += rate_;
126  if ( phase_ >= PI ) phase_ -= PI;
127 
128  lastFrame_[0] = tmp;
129  return lastFrame_[0];
130 }
131 
132 inline StkFrames& Blit :: tick( StkFrames& frames, unsigned int channel )
133 {
134 #if defined(_STK_DEBUG_)
135  if ( channel >= frames.channels() ) {
136  oStream_ << "Blit::tick(): channel and StkFrames arguments are incompatible!";
137  handleError( StkError::FUNCTION_ARGUMENT );
138  }
139 #endif
140 
141  StkFloat *samples = &frames[channel];
142  unsigned int hop = frames.channels();
143  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
144  *samples = Blit::tick();
145 
146  return frames;
147 }
148 
149 } // stk namespace
150 
151 #endif

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