mirror of
https://github.com/thestk/stk
synced 2026-01-11 20:11:52 +00:00
96 lines
3.0 KiB
C++
96 lines
3.0 KiB
C++
/***************************************************/
|
|
/*! \class BlitSquare
|
|
\brief STK band-limited square wave class.
|
|
|
|
This class generates a band-limited square wave signal. It is
|
|
derived in part from the approach reported by Stilson and Smith in
|
|
"Alias-Free Digital Synthesis of Classic Analog Waveforms", 1996.
|
|
The algorithm implemented in this class uses a SincM function with
|
|
an even M value to achieve a bipolar bandlimited impulse train.
|
|
This signal is then integrated to achieve a square waveform. The
|
|
integration process has an associated DC offset so a DC blocking
|
|
filter is applied at the output.
|
|
|
|
The user can specify both the fundamental frequency of the
|
|
waveform and the number of harmonics contained in the resulting
|
|
signal.
|
|
|
|
If nHarmonics is 0, then the signal will contain all harmonics up
|
|
to half the sample rate. Note, however, that this setting may
|
|
produce aliasing in the signal when the frequency is changing (no
|
|
automatic modification of the number of harmonics is performed by
|
|
the setFrequency() function). Also note that the harmonics of a
|
|
square wave fall at odd integer multiples of the fundamental, so
|
|
aliasing will happen with a lower fundamental than with the other
|
|
Blit waveforms. This class is not guaranteed to be well behaved
|
|
in the presence of significant aliasing.
|
|
|
|
Based on initial code of Robin Davies, 2005
|
|
Modified algorithm code by Gary Scavone, 2005 - 2010.
|
|
*/
|
|
/***************************************************/
|
|
|
|
#include "BlitSquare.h"
|
|
|
|
namespace stk {
|
|
|
|
BlitSquare:: BlitSquare( StkFloat frequency )
|
|
{
|
|
if ( frequency <= 0.0 ) {
|
|
oStream_ << "BlitSquare::BlitSquare: argument (" << frequency << ") must be positive!";
|
|
handleError( StkError::FUNCTION_ARGUMENT );
|
|
}
|
|
|
|
nHarmonics_ = 0;
|
|
this->setFrequency( frequency );
|
|
this->reset();
|
|
}
|
|
|
|
BlitSquare :: ~BlitSquare()
|
|
{
|
|
}
|
|
|
|
void BlitSquare :: reset()
|
|
{
|
|
phase_ = 0.0;
|
|
lastFrame_[0] = 0.0;
|
|
dcbState_ = 0.0;
|
|
lastBlitOutput_ = 0;
|
|
}
|
|
|
|
void BlitSquare :: setFrequency( StkFloat frequency )
|
|
{
|
|
if ( frequency <= 0.0 ) {
|
|
oStream_ << "BlitSquare::setFrequency: argument (" << frequency << ") must be positive!";
|
|
handleError( StkError::WARNING ); return;
|
|
}
|
|
|
|
// By using an even value of the parameter M, we get a bipolar blit
|
|
// waveform at half the blit frequency. Thus, we need to scale the
|
|
// frequency value here by 0.5. (GPS, 2006).
|
|
p_ = 0.5 * Stk::sampleRate() / frequency;
|
|
rate_ = PI / p_;
|
|
this->updateHarmonics();
|
|
}
|
|
|
|
void BlitSquare :: setHarmonics( unsigned int nHarmonics )
|
|
{
|
|
nHarmonics_ = nHarmonics;
|
|
this->updateHarmonics();
|
|
}
|
|
|
|
void BlitSquare :: updateHarmonics( void )
|
|
{
|
|
// Make sure we end up with an even value of the parameter M here.
|
|
if ( nHarmonics_ <= 0 ) {
|
|
unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );
|
|
m_ = 2 * (maxHarmonics + 1);
|
|
}
|
|
else
|
|
m_ = 2 * (nHarmonics_ + 1);
|
|
|
|
a_ = m_ / p_;
|
|
}
|
|
|
|
} // stk namespace
|