The Synthesis ToolKit in C++ (STK)

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--2017 Perry R. Cook and Gary P. Scavone. All Rights Reserved.