13 void BiquadFilter_setParams(BiquadFilter
*filter
, BiquadType type
, ALfloat gain
, ALfloat f0norm
, ALfloat rcpQ
)
15 ALfloat alpha
, sqrtgain_alpha_2
;
16 ALfloat w0
, sin_w0
, cos_w0
;
17 ALfloat a
[3] = { 1.0f
, 0.0f
, 0.0f
};
18 ALfloat b
[3] = { 1.0f
, 0.0f
, 0.0f
};
20 // Limit gain to -100dB
21 assert(gain
> 0.00001f
);
24 sin_w0
= std::sin(w0
);
25 cos_w0
= std::cos(w0
);
26 alpha
= sin_w0
/2.0f
* rcpQ
;
28 /* Calculate filter coefficients depending on filter type */
31 case BiquadType::HighShelf
:
32 sqrtgain_alpha_2
= 2.0f
* std::sqrt(gain
) * alpha
;
33 b
[0] = gain
*((gain
+1.0f
) + (gain
-1.0f
)*cos_w0
+ sqrtgain_alpha_2
);
34 b
[1] = -2.0f
*gain
*((gain
-1.0f
) + (gain
+1.0f
)*cos_w0
);
35 b
[2] = gain
*((gain
+1.0f
) + (gain
-1.0f
)*cos_w0
- sqrtgain_alpha_2
);
36 a
[0] = (gain
+1.0f
) - (gain
-1.0f
)*cos_w0
+ sqrtgain_alpha_2
;
37 a
[1] = 2.0f
* ((gain
-1.0f
) - (gain
+1.0f
)*cos_w0
);
38 a
[2] = (gain
+1.0f
) - (gain
-1.0f
)*cos_w0
- sqrtgain_alpha_2
;
40 case BiquadType::LowShelf
:
41 sqrtgain_alpha_2
= 2.0f
* std::sqrt(gain
) * alpha
;
42 b
[0] = gain
*((gain
+1.0f
) - (gain
-1.0f
)*cos_w0
+ sqrtgain_alpha_2
);
43 b
[1] = 2.0f
*gain
*((gain
-1.0f
) - (gain
+1.0f
)*cos_w0
);
44 b
[2] = gain
*((gain
+1.0f
) - (gain
-1.0f
)*cos_w0
- sqrtgain_alpha_2
);
45 a
[0] = (gain
+1.0f
) + (gain
-1.0f
)*cos_w0
+ sqrtgain_alpha_2
;
46 a
[1] = -2.0f
* ((gain
-1.0f
) + (gain
+1.0f
)*cos_w0
);
47 a
[2] = (gain
+1.0f
) + (gain
-1.0f
)*cos_w0
- sqrtgain_alpha_2
;
49 case BiquadType::Peaking
:
50 gain
= std::sqrt(gain
);
51 b
[0] = 1.0f
+ alpha
* gain
;
52 b
[1] = -2.0f
* cos_w0
;
53 b
[2] = 1.0f
- alpha
* gain
;
54 a
[0] = 1.0f
+ alpha
/ gain
;
55 a
[1] = -2.0f
* cos_w0
;
56 a
[2] = 1.0f
- alpha
/ gain
;
59 case BiquadType::LowPass
:
60 b
[0] = (1.0f
- cos_w0
) / 2.0f
;
62 b
[2] = (1.0f
- cos_w0
) / 2.0f
;
64 a
[1] = -2.0f
* cos_w0
;
67 case BiquadType::HighPass
:
68 b
[0] = (1.0f
+ cos_w0
) / 2.0f
;
69 b
[1] = -(1.0f
+ cos_w0
);
70 b
[2] = (1.0f
+ cos_w0
) / 2.0f
;
72 a
[1] = -2.0f
* cos_w0
;
75 case BiquadType::BandPass
:
80 a
[1] = -2.0f
* cos_w0
;
85 filter
->a1
= a
[1] / a
[0];
86 filter
->a2
= a
[2] / a
[0];
87 filter
->b0
= b
[0] / a
[0];
88 filter
->b1
= b
[1] / a
[0];
89 filter
->b2
= b
[2] / a
[0];
93 void BiquadFilter_processC(BiquadFilter
*filter
, ALfloat
*RESTRICT dst
, const ALfloat
*RESTRICT src
, ALsizei numsamples
)
95 const ALfloat a1
= filter
->a1
;
96 const ALfloat a2
= filter
->a2
;
97 const ALfloat b0
= filter
->b0
;
98 const ALfloat b1
= filter
->b1
;
99 const ALfloat b2
= filter
->b2
;
100 ALfloat z1
= filter
->z1
;
101 ALfloat z2
= filter
->z2
;
104 ASSUME(numsamples
> 0);
106 /* Processing loop is Transposed Direct Form II. This requires less storage
107 * compared to Direct Form I (only two delay components, instead of a four-
108 * sample history; the last two inputs and outputs), and works better for
109 * floating-point which favors summing similarly-sized values while being
110 * less bothered by overflow.
112 * See: http://www.earlevel.com/main/2003/02/28/biquads/
114 for(i
= 0;i
< numsamples
;i
++)
116 ALfloat input
= src
[i
];
117 ALfloat output
= input
*b0
+ z1
;
118 z1
= input
*b1
- output
*a1
+ z2
;
119 z2
= input
*b2
- output
*a2
;