Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


BlitSaw.h
1#ifndef STK_BLITSAW_H
2#define STK_BLITSAW_H
3
4#include "Generator.h"
5#include <cmath>
6#include <limits>
7
8namespace stk {
9
10/***************************************************/
29/***************************************************/
30
31class BlitSaw: public Generator
32{
33 public:
35 BlitSaw( StkFloat frequency = 220.0 );
36
39
41 void reset();
42
44 void setFrequency( StkFloat frequency );
45
47
59 void setHarmonics( unsigned int nHarmonics = 0 );
60
62 StkFloat lastOut( void ) const { return lastFrame_[0]; };
63
65 StkFloat tick( void );
66
68
75 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
76
77 protected:
78
79 void updateHarmonics( void );
80
81 unsigned int nHarmonics_;
82 unsigned int m_;
83 StkFloat rate_;
84 StkFloat phase_;
85 StkFloat p_;
86 StkFloat C2_;
87 StkFloat a_;
88 StkFloat state_;
89
90};
91
92inline StkFloat BlitSaw :: tick( void )
93{
94 // The code below implements the BLIT algorithm of Stilson and
95 // Smith, followed by a summation and filtering operation to produce
96 // a sawtooth waveform. After experimenting with various approaches
97 // to calculate the average value of the BLIT over one period, I
98 // found that an estimate of C2_ = 1.0 / period (in samples) worked
99 // most consistently. A "leaky integrator" is then applied to the
100 // difference of the BLIT output and C2_. (GPS - 1 October 2005)
101
102 // A fully optimized version of this code would replace the two sin
103 // calls with a pair of fast sin oscillators, for which stable fast
104 // two-multiply algorithms are well known. In the spirit of STK,
105 // which favors clarity over performance, the optimization has
106 // not been made here.
107
108 // Avoid a divide by zero, or use of a denormalized divisor
109 // at the sinc peak, which has a limiting value of m_ / p_.
110 StkFloat tmp, denominator = sin( phase_ );
111 if ( fabs(denominator) <= std::numeric_limits<StkFloat>::epsilon() )
112 tmp = a_;
113 else {
114 tmp = sin( m_ * phase_ );
115 tmp /= p_ * denominator;
116 }
117
118 tmp += state_ - C2_;
119 state_ = tmp * 0.995;
120
121 phase_ += rate_;
122 if ( phase_ >= PI ) phase_ -= PI;
123
124 lastFrame_[0] = tmp;
125 return lastFrame_[0];
126}
127
128inline StkFrames& BlitSaw :: tick( StkFrames& frames, unsigned int channel )
129{
130#if defined(_STK_DEBUG_)
131 if ( channel >= frames.channels() ) {
132 oStream_ << "BlitSaw::tick(): channel and StkFrames arguments are incompatible!";
133 handleError( StkError::FUNCTION_ARGUMENT );
134 }
135#endif
136
137
138 StkFloat *samples = &frames[channel];
139 unsigned int hop = frames.channels();
140 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
141 *samples = BlitSaw::tick();
142
143 return frames;
144}
145
146} // stk namespace
147
148#endif
STK band-limited sawtooth wave class.
Definition BlitSaw.h:32
StkFloat tick(void)
Compute and return one output sample.
Definition BlitSaw.h:92
~BlitSaw()
Class destructor.
void reset()
Resets the oscillator state and phase to 0.
BlitSaw(StkFloat frequency=220.0)
Class constructor.
void setHarmonics(unsigned int nHarmonics=0)
Set the number of harmonics generated in the signal.
StkFloat lastOut(void) const
Return the last computed output value.
Definition BlitSaw.h:62
void setFrequency(StkFloat frequency)
Set the sawtooth oscillator rate in terms of a frequency in Hz.
STK abstract unit generator parent class.
Definition Generator.h:21
An STK class to handle vectorized audio data.
Definition Stk.h:279
unsigned int channels(void) const
Return the number of channels represented by the data.
Definition Stk.h:416
unsigned int frames(void) const
Return the number of sample frames represented by the data.
Definition Stk.h:419
The STK namespace.
Definition ADSR.h:6

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