Arduino STK  4.6.2
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_ = STK_PI * phase; };
50 
52 
55  StkFloat getPhase() const { return phase_ / STK_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_ >= STK_PI ) phase_ -= STK_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
STK band-limited impulse train class.
Definition: Blit.h:34
StkFloat lastOut(void) const
Return the last computed output value.
Definition: Blit.h:76
StkFloat tick(void)
Compute and return one output sample.
Definition: Blit.h:103
void setFrequency(StkFloat frequency)
Set the impulse train rate in terms of a frequency in Hz.
void setPhase(StkFloat phase)
Set the phase of the signal.
Definition: Blit.h:49
void setHarmonics(unsigned int nHarmonics=0)
Set the number of harmonics generated in the signal.
Blit(StkFloat frequency=220.0)
Default constructor that initializes BLIT frequency to 220 Hz.
StkFloat getPhase() const
Get the current phase of the signal.
Definition: Blit.h:55
void reset()
Resets the oscillator state and phase to 0.
~Blit()
Class destructor.
STK abstract unit generator parent class.
Definition: Generator.h:21
An STK class to handle vectorized audio data.
Definition: Stk.h:287
unsigned int channels(void) const
Return the number of channels represented by the data.
Definition: Stk.h:415
unsigned int frames(void) const
Return the number of sample frames represented by the data.
Definition: Stk.h:418
static void handleError(const char *message, StkError::Type type)
Static function for error reporting and handling using c-strings.
The STK namespace.
Definition: ADSR.h:8