Anti-aliasing through oversampling

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I'm coding my first DSP project, a virtual analog synth, just for fun and for building familiarity with realtime audio programming.

I've got some nonlinear elements (in particular a distortion) which alias significantly. I understand that I should upsample, perform the distortion, then downsample. What are the best techniques for doing upsampling and downsampling in this context, where I want to prioritize simplicity, low latency and low CPU usage?

The information about resampling that I have found on the web seems to focus on FIR filters with sinc kernels with very long tails -- which may be great for non-realtime samplerate conversion, but afaics is not so useful for realtime processing.

Post

No real solution except indeed FIR, processing in high frequency (which uselly is the most costly), then filtering and finally downsampling.
I've given here several times the paper I used for ATK SD1, and it is "simple" (not as simple as the low pass filter, but still simple), as well as cheap for CPU power.

Post

Here is some decimator code, those are optimized FIRs

You can use decimator9, the Calc method takes two input samples and provide one output sample.

https://github.com/2DaT/Obxd/blob/maste ... ecimator.h

Nota: this code is based on the good old french book "Traitement Numérique du Signal" by Maurice Bellanger.
See you here and there... Youtube, Google Play, SoundCloud...

Post

i usually use elliptic filters for up- and downsampling. they give the most bang for the buck. they are not linear phase though, but i don't care very much about that.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

The method that I have recently discovered is using half-band filters. Dirt cheap and can be cascaded for higher degrees of oversampling, e.g. 8x is 2x then 2x then 2x. Beats the hell out of the linear phase FIR I was using before.

Post

In my attempts I have used adaptive oversampling, based on note frequency against sampling frequency and with a cap on 8x or 16x. You have to be a little careful on sweeps, but my theremin test turned out beautifully with little to no aliasing on sine, saw and squares up to bat distractions! :lol:

Post

Here's a decimator implementation that works great. Articles linked to in the src are a good read, too.

https://gist.github.com/kbob/045978eb044be88fe568

Post

pendejo wrote:Here's a decimator implementation that works great. Articles linked to in the src are a good read, too.

https://gist.github.com/kbob/045978eb044be88fe568
Hey guys...Sorry to bring this post back up, but very interested in this decimator concept. If I"m understanding this right, you do the following:

1. Use pre-rendered oversampling to reduce aliasing. Oversampling will create more harmonics and frequencies to mask the aliasing.

2. Then you use a decimator live, as it is lower CPU than oversampling?

3. Proceed forward with your linear interpolation if using wavetables?
GospelMusicians.com - #1 Site for Gospel Musicians.

NeoSoulKeys.com - One of the Most Authentic, Realistic, and buttery EP

Post

1. Run the synth (generate your waveforms) at a higher samplerate.
2. Perform nonlinear function (waveshaping, distortion, compression, etc).
3. Filter out the higher frequencies.
4. Decimate to project samplerate.

So whether it's polyBLEP or interpolating your wavetables, do it at that oversampled rate, then after your nonlinear processes, then filter, then throw away the unneeded samples. Often the final two steps are incorporated into the same process.

Post

In other words, if I'm running at 8x oversampled then my oscillator will be generating 8 samples instead of one. Which is expected, since you are running 8x faster than the project samplerate. Presumably your oscillators are bandlimited and aren't aliasing on their own. Interpolating wavetables or something quasi-bandlimited like polyBLEP would both work, for example.

Okay, got your 8 samples, now distort them or whatever else happens. Then on to filtering. The decimators mentioned above are good examples of this. The goal of filtering is to eliminate the top 7/8ths of the frequency spectrum, because when you throw away your unneeded samples anything in that region will fold back and alias, which is exactly what you don't want.

One way to do it would be with an IIR filter. This is presumably what Music Engineer mentioned earlier. It's going to be less computationally expensive, but it will skew phase. Sometimes preserving phase is important, sometimes it isn't. Maybe for a synth it wouldn't be. Usually you want to preserve phase, so you use some kind of a symmetric FIR lowpass filter instead. Tons of different ways to do it. One way is to use a sinc filter with a Blackmann window, that's what pendejo suggested. Smashed Transistors suggests using a 17 point halfband filter, which is a result that I've gone with that I've found to be very effective. In the example above, you would need to cascade three halfband filters (8x->4x, 4x->2x, 2x->1x). Another option is to do an L-th band filter, which is less efficient but would go from 8x to 1x in one swoop. I'm experimenting with a 31-point 4-th band filter (meaning it would go from 4x to 1x in one pass) right now, actually, but to do an 8-th band filter it would take even more points to get it to work well enough to prevent any folding over. Halfband filters are really efficient because almost half of the coefficients are zero. That's a big reason why you see oversampling in multiples of 2...

Okay, to sum. Normally we do this - take our sample, zero stuff, filter, process, filter, throw away all but one sample. You can do the first three steps at the same time by running your oscillator at that higher samplerate, and you can do some consolidation in the algorithm to do the last two steps at the same time.

And that, as they say, is that.

Post

I tried following the advice in this discussion for my synthesizer, but I'm not certain that I've done everything correctly. I've tried this with an FIR filter, and now with a PolyPhase filter, and in both cases, I am losing a lot of amplitude. Is this normal? My best guess is that all the zeros that I inserted during the upsampling stage have something to do with it. And I suppose I could just amplify the results to compensate for the loss of amplitude.
Any thoughts?

BTW I'm oversampling 8x, but am currently doing so AFTER the oscillators.

Post

Never mind. I've decided to use interpolation during the upsampling phase and this seems to have solved things.

Post

Yes, when you insert zeroes you want to compensate level. Multiply your signal by L. So a halfband filter (L=2) you would want to multiply the input by 2 OR multiply all of the coefficients by 2 to "pre-bake" the gain in. In my particular case the coefficients are local to both the upsampler and downsampler so the DC gain is 1 and I multiply the input by 2.

Filter before you downsample or you could alias.

Post Reply

Return to “DSP and Plugin Development”