1 /***************************************************/
2 /*! \class TwoZero
3     \brief STK two-zero filter class.
4 
5     This class implements a two-zero digital filter.  A method is
6     provided for creating a "notch" in the frequency response while
7     maintaining a constant filter gain.
8 
9     by Perry R. Cook and Gary P. Scavone, 1995--2021.
10 */
11 /***************************************************/
12 
13 #include "TwoZero.h"
14 #include <cmath>
15 
16 namespace stk {
17 
TwoZero(void)18 TwoZero :: TwoZero( void )
19 {
20   b_.resize( 3, 0.0 );
21   inputs_.resize( 3, 1, 0.0 );
22   b_[0] = 1.0;
23 
24   Stk::addSampleRateAlert( this );
25 }
26 
~TwoZero()27 TwoZero :: ~TwoZero()
28 {
29   Stk::removeSampleRateAlert( this );
30 }
31 
sampleRateChanged(StkFloat newRate,StkFloat oldRate)32 void TwoZero :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
33 {
34   if ( !ignoreSampleRateChange_ ) {
35     oStream_ << "TwoZero::sampleRateChanged: you may need to recompute filter coefficients!";
36     handleError( StkError::WARNING );
37   }
38 }
39 
setCoefficients(StkFloat b0,StkFloat b1,StkFloat b2,bool clearState)40 void TwoZero :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, bool clearState )
41 {
42   b_[0] = b0;
43   b_[1] = b1;
44   b_[2] = b2;
45 
46   if ( clearState ) this->clear();
47 }
48 
setNotch(StkFloat frequency,StkFloat radius)49 void TwoZero :: setNotch( StkFloat frequency, StkFloat radius )
50 {
51 #if defined(_STK_DEBUG_)
52   if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
53     oStream_ << "TwoZero::setNotch: frequency argument (" << frequency << ") is out of range!";
54     handleError( StkError::WARNING ); return;
55   }
56   if ( radius < 0.0 ) {
57     oStream_ << "TwoZero::setNotch: radius argument (" << radius << ") is negative!";
58     handleError( StkError::WARNING ); return;
59   }
60 #endif
61 
62   b_[2] = radius * radius;
63   b_[1] = -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate());
64 
65   // Normalize the filter gain.
66   if ( b_[1] > 0.0 ) // Maximum at z = 0.
67     b_[0] = 1.0 / ( 1.0 + b_[1] + b_[2] );
68   else            // Maximum at z = -1.
69     b_[0] = 1.0 / ( 1.0 - b_[1] + b_[2] );
70   b_[1] *= b_[0];
71   b_[2] *= b_[0];
72 }
73 
74 } // stk namespace
75