1 /***************************************************/
2 /*! \class BiQuad
3 \brief STK biquad (two-pole, two-zero) filter class.
4
5 This protected Filter subclass implements a
6 two-pole, two-zero digital filter. A method
7 is provided for creating a resonance in the
8 frequency response while maintaining a constant
9 filter gain.
10
11 by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
12 */
13 /***************************************************/
14
15 #include "BiQuad.h"
16 #include <cmath>
17
18 using namespace Nyq;
19
BiQuad()20 BiQuad :: BiQuad() : Filter()
21 {
22 std::vector<StkFloat> b(3, 0.0);
23 std::vector<StkFloat> a(3, 0.0);
24 b[0] = 1.0;
25 a[0] = 1.0;
26 Filter::setCoefficients( b, a );
27 }
28
~BiQuad()29 BiQuad :: ~BiQuad()
30 {
31 }
32
clear(void)33 void BiQuad :: clear(void)
34 {
35 Filter::clear();
36 }
37
setB0(StkFloat b0)38 void BiQuad :: setB0(StkFloat b0)
39 {
40 b_[0] = b0;
41 }
42
setB1(StkFloat b1)43 void BiQuad :: setB1(StkFloat b1)
44 {
45 b_[1] = b1;
46 }
47
setB2(StkFloat b2)48 void BiQuad :: setB2(StkFloat b2)
49 {
50 b_[2] = b2;
51 }
52
setA1(StkFloat a1)53 void BiQuad :: setA1(StkFloat a1)
54 {
55 a_[1] = a1;
56 }
57
setA2(StkFloat a2)58 void BiQuad :: setA2(StkFloat a2)
59 {
60 a_[2] = a2;
61 }
62
setResonance(StkFloat frequency,StkFloat radius,bool normalize)63 void BiQuad :: setResonance(StkFloat frequency, StkFloat radius, bool normalize)
64 {
65 a_[2] = radius * radius;
66 a_[1] = -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate());
67
68 if ( normalize ) {
69 // Use zeros at +- 1 and normalize the filter peak gain.
70 b_[0] = 0.5 - 0.5 * a_[2];
71 b_[1] = 0.0;
72 b_[2] = -b_[0];
73 }
74 }
75
setNotch(StkFloat frequency,StkFloat radius)76 void BiQuad :: setNotch(StkFloat frequency, StkFloat radius)
77 {
78 // This method does not attempt to normalize the filter gain.
79 b_[2] = radius * radius;
80 b_[1] = (StkFloat) -2.0 * radius * cos(TWO_PI * (double) frequency / Stk::sampleRate());
81 }
82
setEqualGainZeroes()83 void BiQuad :: setEqualGainZeroes()
84 {
85 b_[0] = 1.0;
86 b_[1] = 0.0;
87 b_[2] = -1.0;
88 }
89
setGain(StkFloat gain)90 void BiQuad :: setGain(StkFloat gain)
91 {
92 Filter::setGain(gain);
93 }
94
getGain(void) const95 StkFloat BiQuad :: getGain(void) const
96 {
97 return Filter::getGain();
98 }
99
lastOut(void) const100 StkFloat BiQuad :: lastOut(void) const
101 {
102 return Filter::lastOut();
103 }
104
computeSample(StkFloat input)105 StkFloat BiQuad :: computeSample( StkFloat input )
106 {
107 inputs_[0] = gain_ * input;
108 outputs_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
109 outputs_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
110 inputs_[2] = inputs_[1];
111 inputs_[1] = inputs_[0];
112 outputs_[2] = outputs_[1];
113 outputs_[1] = outputs_[0];
114
115 return outputs_[0];
116 }
117
tick(StkFloat input)118 StkFloat BiQuad :: tick( StkFloat input )
119 {
120 return this->computeSample( input );
121 }
122
tick(StkFrames & frames,unsigned int channel)123 StkFrames& BiQuad :: tick( StkFrames& frames, unsigned int channel )
124 {
125 return Filter::tick( frames, channel );
126 }
127