How to implement oversampling C++

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Thanks Dave,
I think i understand the process now. My question is :
How can i make this, so that it will be a CPU friendly process ?
A.F.

Post

When we're talking about a simple 2x or 4x sample rate incrase, zero-stuffing, as Fire Sledge says, is the *only* way to go - forget using any form of naive interpolation. If you take a buffer of samples and insert a zero in between every element,
What would happen, if I'd use interpolated values instead of zeros? I'd still filter the signal.


/edit: Thanks, anyway.

Post

Why not copy the same value into the 'oversampled' places in the buffer? You will already have it in a register anyway.
Wouldn't the filter would work better then?
Zero stuffing gives you a specific result in the frequency domain - it leaves the original signal (anything below SR/4 in the oversampled buffer) completely unharmed. Additionally, it creates a mirror image of the original spectrum which can be found starting at SR/4 and ranging up to SR/2 - this does not overlap in any way with our original source signal, and so can be easily filtered off with a lowpass filter, leaving you with exactly what you started with but at a higher sample rate. This is the goal of upsampling.

If you try and muck about with any of the nearest neighbour, cubic hermite, linear or whatever else naive time-domain non-bandlimited forms of interpolation exist out there you are guaranteed to do three things:

a) alter the spectrum below SR/4 that we're supposed to be leaving untouched.
b) create aliasing
c) create spectral images that may overlap with the source material or be otherwise difficult to remove

If you read the classical texts on multirate DSP you'll see that zero-stuffing is pretty much the textbook approach. If you are doing something simple like increasing the sample rate by an integer factor this gives results that are as good as the filter you have designed.

For noninteger sample rate conversions you can cascade integer stages and make assumptions about where and when filtering should takes place to optimise the overall process.

Kind regards
Dave
Last edited by Muon Software Ltd on Mon Mar 08, 2004 1:28 pm, edited 1 time in total.

Post

How can i make this, so that it will be a CPU friendly process ?
A large zero-phase FIR will do the job best, at the expense of a lot of CPU cycles. You could do three other things I guess:-

a) if your buffer is always going to be a power of two in size you could do the filtering entirely in the frequency domain by taking an FFT, zeroing out all bins above SR/4 and then doing an IFFT.

b) Use a high-order elliptical filter. With careful filter design you could trade off speed for quality by reducing the filter order an putting up with some stopband ripple. This will work for non-power-of-two sized audio buffers and oversampling factors.

c) Assuming you are always oversampling and decimating by a power of two you could look into polyphase filters. I posted some code to the Music DSP archive ages ago, but it was more for teaching the DSP and design rather than speed. You could take the code and optimise it.

Before launching into this though I'd create some 96khz samples with nothing above SR/4 in them, and run your process on them. If you can't see any significant energy above SR/4 in the resulting sample, you don't need to oversample as your process hasn't produced anything that will alias!

Regards
Dave

Post

Filters are always a trade off. Pass-band ripple, phase linearity, efficiency, etc, etc...

It occurs to me that, whilst for many applications low pass-band ripple is critical, this may not be the case for synth oscillators. Analog oscillators are revered by many because of their imperfections.

Freed of the need for precision, your filters could be better optimised for more musically or computationally significant factors.

Just a thought. Anyone got a view?

Post

Muon Software Ltd wrote:
How can i make this, so that it will be a CPU friendly process ?
A large zero-phase FIR will do the job best, at the expense of a lot of CPU cycles. You could do three other things I guess:-

a) if your buffer is always going to be a power of two in size you could do the filtering entirely in the frequency domain by taking an FFT, zeroing out all bins above SR/4 and then doing an IFFT.

b) Use a high-order elliptical filter. With careful filter design you could trade off speed for quality by reducing the filter order an putting up with some stopband ripple. This will work for non-power-of-two sized audio buffers and oversampling factors.

c) Assuming you are always oversampling and decimating by a power of two you could look into polyphase filters. I posted some code to the Music DSP archive ages ago, but it was more for teaching the DSP and design rather than speed. You could take the code and optimise it.

Before launching into this though I'd create some 96khz samples with nothing above SR/4 in them, and run your process on them. If you can't see any significant energy above SR/4 in the resulting sample, you don't need to oversample as your process hasn't produced anything that will alias!

Regards
Dave
Thanks Dave! I think we all learned something from it.
All my respects,
A.F.

Post

Just a thought. Anyone got a view?
Agreed - let your ears and your code profiler be your guides... :)

Cheers
D

Post

Muon Software Ltd wrote: Zero stuffing gives you a specific result in the frequency domain - it leaves the original signal (anything below SR/4 in the oversampled buffer) completely unharmed.
I'm kind of guessing here (I'm certainly no expert), but if you use zero stuffingwouldn't this reduce the magnitude of everything below SR/4 significantly after filtering?
Also, if you simply packed the same values without any interpolation (linear/hermite etc) would this not have the same effect as the zero stuffing, except that the frequencies above SR/4 would already be greatly attenuated at no cost, meaning that you could have a lower order filter?

Post

I'm kind of guessing here (I'm certainly no expert), but if you use zero stuffingwouldn't this reduce the magnitude of everything below SR/4 significantly?
No, absolutely not. Zero stuffing does not harm the original spectrum that we want to keep in any way. This is exactly why we do it. Then, the filtering removes the mirrored spectrum, and we are left with a resample that is as good as the filter used.
Also, if you simply packed the same values without any interpolation (linear/hermite etc) would this not have the same effect as the zero stuffing, except that the frequencies above SR/4 would already be greatly attenuated at no cost, meaning that you could have a lower order filter?
No, this would not work. Nearest Neighbour interpolation will corrupt the spectrum below SR/4 in such a way that filtering above SR/4 will no longer give you a perfect resample. Remember, the goal of resampling is to get back what you put in, only at a different sample rate.

There is plenty of information about multirate DSP out there - no need to take my word for it :D

If I get a free minute today I'll do a little GIF.

Regards
Dave

Post

texture wrote:I'm kind of guessing here (I'm certainly no expert), but if you use zero stuffingwouldn't this reduce the magnitude of everything below SR/4 significantly after filtering?
Yes it would reduce the overall volume. But this question of gain is easy to solve. If you're oversampling by a factor N, apply a gain of N.
Also, if you simply packed the same values without any interpolation (linear/hermite etc) would this not have the same effect as the zero stuffing, except that the frequencies above SR/4 would already be greatly attenuated at no cost, meaning that you could have a lower order filter?
It depends on the overall design you want do to, and what compromise you are ready to do. All these interpolators (sample blocking, linear interpolation, cubic, etc) have their own, non-bandlimited frequency response, so they act a bit like an additional filter.

-- Laurent

Post

Yes it would reduce the overall volume. But this question of gain is easy to solve. If you're oversampling by a factor N, apply a gain of N.
Quite right, I forgot about that. Gain is the term for a relative difference in amplitude and is expressed in terms of +/- dB, for example. Since the magnitude for a given bin in the FFT is pretty much a meaningless number taken on its own, people tend to normalise an FFT by its peak bin - in that sense, the spectrums before and after are still identical. After zero-stuffing and filtering a gain boost will most likely be needed.

Cheers
Dave

Post

What about upsampling by FTT? Do a FFT double the spectrum and set the new bins to zero, than do an iFFT and you have a perfect upsampled signal. Same could be done to downsample.

Post

Yes, of course. Anything you can do in the time domain can be done in the frequency domain. Convolving x[n] with h[n] to get y[n] (where the arrays are real numbers representing audio samples) is the same as multiplying x[n] with h[n] in the frequency domain (where the arrays are complex numbers representing FFT coefficients).

The devil of course is in the details. Most FFT routines aren't at all faster than a good IIR filter - and remember, you need to do an FFT->iFFT pair so that's two lots of processing. The other problem is that most FFT routines rely on buffers being a power of two in size - with a VST host you can't guarantee this is going to happen unless you introduce some additional latency....and I wonder if you don't do some sort of windowing and overlapping if you'd get artefacts around the edges of your blocks. Using an FIR, IIR (elliptical or polyphase) filter, given the design tools out there on the net and the simple implementation is probably all-round easier for pretty good results.

Regards
Dave

Post

If anybody is interested in an excelent FFT-library:
look at FFTW. This is the fastest FFT-library I know and it's pretty flexible. OK this is a bit off-topic, sorry.

Post

Or use FFTReal, a free library to do FFT on real numbers. Easy to use, quite well optimized, and free.

-- Laurent

Post Reply

Return to “DSP and Plugin Development”