mirror of
https://github.com/thestk/stk
synced 2026-01-13 21:11:53 +00:00
Version 4.3.0
This commit is contained in:
committed by
Stephen Sinclair
parent
2cbce2d8bd
commit
27d9b79dc7
@@ -8,8 +8,8 @@
|
||||
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 but that is
|
||||
subtracted off the output signal.
|
||||
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
|
||||
@@ -19,17 +19,21 @@
|
||||
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).
|
||||
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.
|
||||
Modified algorithm code by Gary Scavone, 2005 - 2006.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "BlitSquare.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
|
||||
BlitSquare:: BlitSquare( StkFloat frequency )
|
||||
{
|
||||
nHarmonics_ = 0;
|
||||
@@ -45,6 +49,8 @@ void BlitSquare :: reset()
|
||||
{
|
||||
phase_ = 0.0;
|
||||
lastOutput_ = 0;
|
||||
dcbState_ = 0.0;
|
||||
lastBlitOutput_ = 0;
|
||||
}
|
||||
|
||||
void BlitSquare :: setFrequency( StkFloat frequency )
|
||||
@@ -56,8 +62,8 @@ void BlitSquare :: setFrequency( StkFloat frequency )
|
||||
|
||||
// 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 2.0. (GPS, 2005).
|
||||
p_ = 2.0 * Stk::sampleRate() / frequency;
|
||||
// frequency value here by 0.5. (GPS, 2006).
|
||||
p_ = 0.5 * Stk::sampleRate() / frequency;
|
||||
rate_ = PI / p_;
|
||||
this->updateHarmonics();
|
||||
}
|
||||
@@ -73,13 +79,12 @@ 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;
|
||||
m_ = 2 * (maxHarmonics + 1);
|
||||
}
|
||||
else
|
||||
m_ = 2 * nHarmonics_;
|
||||
m_ = 2 * (nHarmonics_ + 1);
|
||||
|
||||
// This offset value was derived empirically. (GPS, 2005)
|
||||
offset_ = 1.0 - 0.5 * m_ / p_;
|
||||
a_ = m_ / p_;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlitSquare::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';
|
||||
@@ -89,7 +94,7 @@ void BlitSquare :: updateHarmonics( void )
|
||||
|
||||
StkFloat BlitSquare :: computeSample( void )
|
||||
{
|
||||
StkFloat temp = lastOutput_;
|
||||
StkFloat temp = lastBlitOutput_;
|
||||
|
||||
// A fully optimized version of this would replace the two sin calls
|
||||
// with a pair of fast sin oscillators, for which stable fast
|
||||
@@ -103,20 +108,24 @@ StkFloat BlitSquare :: computeSample( void )
|
||||
if ( fabs( denominator ) < std::numeric_limits<StkFloat>::epsilon() ) {
|
||||
// Inexact comparison safely distinguishes betwen *close to zero*, and *close to PI*.
|
||||
if ( phase_ < 0.1f || phase_ > TWO_PI - 0.1f )
|
||||
lastOutput_ = 1.0;
|
||||
lastBlitOutput_ = a_;
|
||||
else
|
||||
lastOutput_ = -1.0;
|
||||
lastBlitOutput_ = -a_;
|
||||
}
|
||||
else {
|
||||
lastOutput_ = sin( m_ * phase_ );
|
||||
lastOutput_ /= p_ * denominator;
|
||||
lastBlitOutput_ = sin( m_ * phase_ );
|
||||
lastBlitOutput_ /= p_ * denominator;
|
||||
}
|
||||
|
||||
lastOutput_ += temp;
|
||||
lastBlitOutput_ += temp;
|
||||
|
||||
// Now apply DC blocker.
|
||||
lastOutput_ = lastBlitOutput_ - dcbState_ + 0.999 * lastOutput_;
|
||||
dcbState_ = lastBlitOutput_;
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= TWO_PI ) phase_ -= TWO_PI;
|
||||
|
||||
return lastOutput_ - offset_;
|
||||
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user