# Biquad high-pass filter not working as expected

I'm trying to implement a high-pass filter using the the coefficients described in RBJ's well-known EQ cookbook (see https://www.w3.org/2011/audio/audio-eq-cookbook.html). However, when I run white noise through the filter, the output doesn't sound high-passed at all, at times it even sounds slightly low-passed.

Here is an audio example with the cut-off frequency being modulated between 20 Hz and 18 kHz and the Q factor being set at 0.707: https://www.youtube.com/watch?v=eGE41VAnn0s

The filter is implemented in C++ as follows:

float process( float const in )
{
float const omega = PI2 * frequency / 44100.0f;
float const alpha = std::sin( omega ) / 2.0f * q;

b2 = b0 = (1 + std::cos( omega )) / 2.0f;
b1 = -(1 + std::cos( omega ));
a0 = 1.0f + alpha;
a1 = -2.0f * std::cos( omega );
a2 = 1.0f - alpha;

b0 /= a0; b1 /= a0; b2 /= a0; a1 /= a0; a2 /= a0;

float const out =
b0 * in +
b1 * x1 +
b2 * x2 -
a1 * y1 -
a2 * y2;

x2 = x1;
x1 = in;
y2 = y1;
y1 = out;

return out;
}


Oddly enough, I have also tried to use the low-pass coefficients and that seems to work as expected.

Now what's the reason for the high-pass filter above not sounding like it should? Have I made a mistake that I can't find?

There is (at least) one error in your routine. It concerns the definition of alpha. The correct formula is

$$\alpha=\frac{\sin(\omega_0)}{2Q}$$

However, you implemented

$$\alpha=\frac{\sin(\omega_0)\cdot Q}{2}$$

But that shouldn't influence the function of the filter as a high pass filter; it just implements the inverse of the given $$Q$$ value.

Other than that, it's of course important that the variables x1, x2, y1, and y2 retain their value between function calls. I'm not sure if and where you take care of that.

As a final remark, you might want to think about if it's really necessary to recompute the filter coefficients each time a new sample arrives.