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