Oversampling for an EQ

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

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]

Post

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?

Post

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.
Last edited by Max M. on Thu Sep 20, 2018 12:03 pm, edited 1 time in total.

Post

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

Post

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:

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
};
There's a softer order 12 one which it claims has less stop band ripple so I should probably try that one:

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
};
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
Last edited by JustinJ on Thu Sep 20, 2018 1:24 pm, edited 1 time in total.

Post

By the way it's worth checking in the musicdsp comments as one of the coefficients in one of the 12th order filters is wrong and needs to be corrected

Post

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.

Post

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°).
Last edited by Max M. on Thu Sep 20, 2018 10:53 pm, edited 2 times in total.

Post

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

Post

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

Post

Did you try to add simply a gain factor of 2 to your output in the zero stuffing case ?

Post

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:

Code: Select all

y0 = do_filter_eqs(input);
y1 = do_filter_eqs(0);

output = half_band_process(y0) * 2;
half_band_process(y1);
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.

Post

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);
Well, doesn't your FIR have a process function? It would just be as simple as:

Code: Select all

y0 = do_filter_eqs(input);
y1 = do_filter_eqs(0);

output = FirProcess(y0) * 2; 
FirProcess(y1);
JustinJ wrote:The linear phase FIR filter I've got has a variable cutoff. There's no state to track
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.

Although it's hard to tell from your question what exactly you're having trouble with implementation wise

Post

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!

Post

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

Post Reply

Return to “DSP and Plugin Development”