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