Oversampling for an EQ
-
- KVRian
- 1273 posts since 9 Jan, 2006
Yes, with zero padding you preserve the same amount of energy, but half of this is in the mirror that you then filter away. Because of this you will be left with half the magnitude of the original signal. To fix it just multiply the end result by 2. Sorry, I omitted that fact earlier.
When you feed the same sample twice you are essentially zero padding then using a two tap FIR [0.5, 0.5], note that this averaging halves the amplitude, but by simply repeating the input sample you have built in the x2 factor into the coefficients [1.0, 1.0]
When you feed the same sample twice you are essentially zero padding then using a two tap FIR [0.5, 0.5], note that this averaging halves the amplitude, but by simply repeating the input sample you have built in the x2 factor into the coefficients [1.0, 1.0]
-
- KVRist
- Topic Starter
- 143 posts since 31 Oct, 2017
Yes, I thought feeding the same thing twice would amount to a FIR.
I put the zero padding in and multiplied the final result by 2. Works a treat. Still doesn't null but the only difference now is in the high frequencies and it's not much. The frequency response is good so I'm figuring it's the phase that has been shifted by the polyphase half band filter. Would that be right?
I put the zero padding in and multiplied the final result by 2. Works a treat. Still doesn't null but the only difference now is in the high frequencies and it's not much. The frequency response is good so I'm figuring it's the phase that has been shifted by the polyphase half band filter. Would that be right?
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
I'm figuring it's the phase that has been shifted by the polyphase half band filter. Would that be right?
Most likely, but not only phase. Note that no antiaiasing filter is ideal (an instant brickwall from 1 to 0) and it's always non-zero signal suppression below Fn (i.e. basically = lowpass filtering). So there's always some difference in HF range between the original and the processed signals (even if a linear-phase filter was used).
I can't access music-dsp archive right now (it seems to be down for the moment) - so I can't see what halfband filter you use, but in general it's pretty trivial to analyse the filter coefficients (or its impulse response) to know for sure how much of difference comes from the phase-shifting and how much just from the lowpass slope.
Most likely, but not only phase. Note that no antiaiasing filter is ideal (an instant brickwall from 1 to 0) and it's always non-zero signal suppression below Fn (i.e. basically = lowpass filtering). So there's always some difference in HF range between the original and the processed signals (even if a linear-phase filter was used).
I can't access music-dsp archive right now (it seems to be down for the moment) - so I can't see what halfband filter you use, but in general it's pretty trivial to analyse the filter coefficients (or its impulse response) to know for sure how much of difference comes from the phase-shifting and how much just from the lowpass slope.
Last edited by Max M. on Thu Sep 20, 2018 12:03 pm, edited 1 time in total.
-
- KVRian
- 1273 posts since 9 Jan, 2006
Yeah, true. I don't know which variant is being used, but the highest orders are very steep brick wall filters. If using those I expect the vast bulk of the difference to be the phase shift
-
- KVRist
- Topic Starter
- 143 posts since 31 Oct, 2017
The reason I think it's mainly phase is because I've analysed it using an FFT noise generator and MAnalyzer set to show stable frequency response over the 0..20kHz range. It's all level as it should be, there's no dip in magnitude at 20kHz so I'm assuming it near brick walls closer to 22050.
The musicdsp.org polyphase coefficients I'm using are steep order 12 ones:
There's a softer order 12 one which it claims has less stop band ripple so I should probably try that one:
BTW, the musicdsp.org archive can be found in PDF format from a few sources like this one:
http://www.naiant.com/SM/SM%20Forum%20A ... %20DSP.pdf
The musicdsp.org polyphase coefficients I'm using are steep order 12 ones:
Code: Select all
//rejection=104dB, transition band=0.01
double a_coefficients[6]=
{0.036681502163648017
,0.2746317593794541
,0.56109896978791948
,0.769741833862266
,0.8922608180038789
,0.962094548378084
};
double b_coefficients[6]=
{0.13654762463195771
,0.42313861743656667
,0.6775400499741616
,0.839889624849638
,0.9315419599631839
,0.9878163707328971
};
Code: Select all
//rejection=150dB, transition band=0.05
double a_coefficients[6]=
{0.01677466677723562
,0.13902148819717805
,0.3325011117394731
,0.53766105314488
,0.7214184024215805
,0.8821858402078155
};
double b_coefficients[6]=
{0.06501319274445962
,0.23094129990840923
,0.4364942348420355
,0.6329609551399348
,0.80378086794111226
,0.9599687404800694
};
http://www.naiant.com/SM/SM%20Forum%20A ... %20DSP.pdf
Last edited by JustinJ on Thu Sep 20, 2018 1:24 pm, edited 1 time in total.
-
- KVRist
- Topic Starter
- 143 posts since 31 Oct, 2017
I checked the comments (using WaybackMachine, the musicdsp.org site is currently down).
Contrary to what the comment says, the correction is for the less steep 12 order coefficients:
"the 4th b coefficient 0.06329609551399348, should be 0.6329609551399348."
I've corrected my comment with the coefficients in just in case somebody copies them.
Contrary to what the comment says, the correction is for the less steep 12 order coefficients:
"the 4th b coefficient 0.06329609551399348, should be 0.6329609551399348."
I've corrected my comment with the coefficients in just in case somebody copies them.
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
For some reason I thought that was one of those quasi-linear phase IIR (and my previous post with that in mind). Now by looking at code and the coefficients I see it's pretty much regular elliptic lowpass (implemented as a polyphase one). In that case, sure - the HF error you get with the difference test is overwhelmingly because of the phase-shifting. And sure, the slope of 12-multiplier IIR is steep enough to be assumed to have no significant impact.
I won't post any phase graphs because I'm looking at the graphs of the impulse-response before decimation (which is a bit tricky to interpret taking the overall latency and further decimation into account) - but basically it's as any regular elliptic IIR: phase-shift slowly growing from 0 to Fn (with the last octave growing per exp). Something like reaching 1 sample group-delay at 12k (~25 degrees) then hitting ~10 samples at 20k (~250°).
I won't post any phase graphs because I'm looking at the graphs of the impulse-response before decimation (which is a bit tricky to interpret taking the overall latency and further decimation into account) - but basically it's as any regular elliptic IIR: phase-shift slowly growing from 0 to Fn (with the last octave growing per exp). Something like reaching 1 sample group-delay at 12k (~25 degrees) then hitting ~10 samples at 20k (~250°).
Last edited by Max M. on Thu Sep 20, 2018 10:53 pm, edited 2 times in total.
-
- KVRist
- Topic Starter
- 143 posts since 31 Oct, 2017
Yes, that explains the difference at HF.
Which has led me to start looking at linear phase FIR for implementing the low pass filter. I've got some JSFX for that and with a steep low pass at 20kHz+ it nulls, no phase shift. More latency though I'm guessing?
Now trying to figure out how to integrate that into the 2x oversampling I've got, essentially replacing the half band filter from musicdsp.org...
Which has led me to start looking at linear phase FIR for implementing the low pass filter. I've got some JSFX for that and with a steep low pass at 20kHz+ it nulls, no phase shift. More latency though I'm guessing?
Now trying to figure out how to integrate that into the 2x oversampling I've got, essentially replacing the half band filter from musicdsp.org...
-
- KVRian
- 1273 posts since 9 Jan, 2006
Yes, you'll add latency, half the length of your FIR kernel. As to how to implement it, if you're unsure how, I suggest reading up on convolution. The Scientist and Engineers Guide to DSP, which is available as a free ebook, has good practical and theoretical explanations on it. http://www.dspguide.com
-
- KVRian
- 1153 posts since 11 Aug, 2004 from Breuillet, France
Did you try to add simply a gain factor of 2 to your output in the zero stuffing case ?
-
- KVRist
- Topic Starter
- 143 posts since 31 Oct, 2017
Yes, I added the gain factor of 2 into the zero stuffing case and it works perfectly.
I have a decent linear phase FIR low pass filter implementation. The part that's foxing me currently is how to integrate it with my oversampling x2:
The linear phase FIR filter I've got has a variable cutoff. There's no state to track (except the window?) like there is for the current half band polyphase filter. The linear phase FIR filter code takes an input and gives a filtered output.
I'm not sure (yet) how it replaces the last two lines in my code above.
I have a decent linear phase FIR low pass filter implementation. The part that's foxing me currently is how to integrate it with my oversampling x2:
Code: Select all
y0 = do_filter_eqs(input);
y1 = do_filter_eqs(0);
output = half_band_process(y0) * 2;
half_band_process(y1);
I'm not sure (yet) how it replaces the last two lines in my code above.
-
- KVRian
- 1273 posts since 9 Jan, 2006
Well, doesn't your FIR have a process function? It would just be as simple as:JustinJ wrote:I have a decent linear phase FIR low pass filter implementation. The part that's foxing me currently is how to integrate it with my oversampling x2:
Code: Select all
y0 = do_filter_eqs(input); y1 = do_filter_eqs(0); output = half_band_process(y0) * 2; half_band_process(y1);
Code: Select all
y0 = do_filter_eqs(input);
y1 = do_filter_eqs(0);
output = FirProcess(y0) * 2;
FirProcess(y1);
Actually there is state to track. The algorithm is organised differently than for IIR filters as there are typically much more states to keep track of. Also there can be input or output buffered variants, but if you check the algo you're using then you should be able to see how state is handled.JustinJ wrote:The linear phase FIR filter I've got has a variable cutoff. There's no state to track
Although it's hard to tell from your question what exactly you're having trouble with implementation wise
-
- KVRist
- Topic Starter
- 143 posts since 31 Oct, 2017
I think it's just down to the FIR filter implementation I'm using. There's a number of existing JSFX that do linear phase FIR low pass filters but they either don't work or don't null. Looks like I'll roll my own.
By state I meant that the filter is convolving using a buffer of samples. Probably not the right way to describe it.
I'll check out the dspguide and see what I come up with. Thanks!
By state I meant that the filter is convolving using a buffer of samples. Probably not the right way to describe it.
I'll check out the dspguide and see what I come up with. Thanks!
-
- KVRian
- 1273 posts since 9 Jan, 2006
Have you taken the latency into account for the null tests? This will make a big difference. Even with that taken into account there will be some difference due to pre and post ringing of the filter, but this should be small, I assume, I've never ran a null test on a linear phase filter.
You could try TFilter (just Google it), an online FIR designer and also this page on FIR filters by windowing
You could try TFilter (just Google it), an online FIR designer and also this page on FIR filters by windowing