Building high pass filter using low pass (FIR)


#1

Hi, I am writing a plugin and want to use high-pass and low-pass filter in it. For sharp roll off I choosed FIR low pass with window method

lowPassFilter(dsp::FilterDesign::designFIRLowpassWindowMethod(5000.0f,44100,20,dsp::WindowingFunction::hann))

When I’m using it as low pass everything works fine. But I also want high pass filter.

I tried to do it this way:

		for (int sample = 0; sample < buffer.getNumSamples(); ++sample) {
		float in = channelData[sample];
		float fin = filter.processSample(in);
		channelData[sample] =  in - fin;
	}

I get something like a comb filter, definitely NOT a high pass (as I expected it to be).

Can you please help me and tell what am I doing wrong and should do ?


#2

Linear-phase filters (your FIR) has a constant group delay for all frequencies, in other terms, latency.
So what actually happens is that your FIR filter output is delayed by (fir_length -1) / 2
To get rid of that comb artifact, you’ll have to delay the input sample by the same amount.


#3

Also, if your FIR coefficients length is longer than 64, you should consider using the dsp::Convolution class, as it is more efficient.


#4

I haven’t done much work with filters in years, so forgive me if I say something illogical. But what you’re doing is a little confusing to me. I don’t understand why you would want to use the co-efficients of a low pass filter and then treat that as a high pass filter.

If I’m remembering the science behind all this correctly, you need different kinds of co-efficients for high pass filters vs low pass filters. And you seem to be ignoring this and using the same low pass filter co-efficient for the wrong purpose.

I have never used the JUCE class for designing low pass filters. But I have written myown FIR filters in pure standard C++. So I can’t tell you what JUCE class to use. All I can say is look for a JUCE class specifically intended for high pass filters.


#5

The reason it sounds like a comb filter is because you basically have created a comb filter. You are subtracting the bass from the full signal, which theoretically should work as a high pass filter. But the problem is that the bass that is coming out of your low pass filter, is coming out of phase with the full signal… in other words your filtered bass is delayed by some number of miliseconds. Which means that it is failing to properly filter out the bass signal of the original signal since they are not occurring at the exact same time. Just use a normal high pass filter and avoid trying to be too clever with this kind of custom filtering.