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.
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.
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.