I am having issues with my implementation of a FIR high pass filter. The low pass filter has an acceptable level of attenuation in the stopband, but the high pass filter has poor attenuation in the stopband. I have not seen any mention of this occurring in the sources that I read and I am unsure why this is occurring.
I am referencing The Scientist and Engineer's Guide to Digital Signal Processing (Page 271 regarding LPF to HPF). I am using white noise to test the frequency response of the filters, and the attached image is from an external program. Here is the relevant part of my code (just audio boilerplate has been removed):
constexpr int rate = 44100;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> distrib(-1.0f, 1.0f);
constexpr int buf_len = rate * 3;
float* in = new float[buf_len];
float* out = new float[buf_len]();
constexpr int M = 200;
float fc = 2100.0f / rate;
double h[M + 1]{0.0f};
for (int i = 0; i < buf_len; i++)
{
in[i] = distrib(gen);
}
for (int i = 0; i <= M; i++)
{
if ((i - M/2) == 0)
{
h[i] = 2*M_PI*fc;
}
else
{
h[i] = std::sin(2.0*M_PI*fc*(i - M/2)) / (i - M/2);
}
h[i] *= 0.42 - 0.5 * std::cos((2.0*M_PI*i)/M) + 0.08 * std::cos((4.0*M_PI*i)/M);
}
double sum = 0;
for (int i = 0; i <= M; i++)
{
sum += h[i];
}
for (int i = 0; i <= M; i++)
{
h[i] /= sum;
}
//change to high pass
for (int i = 0; i <= M; i++)
{
h[i] *= -1.0;
}
h[M/2] += 1.0f;
// Convolve
for (int i = M; i < buf_len; i++)
{
for (int j = 0; j <= M; j++)
{
out[i] += in[i - j] * h[j];
}
}