Basic anti-aliasing for non-linear functions

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Alright, thanks a lot for the clarification.

Post

SciPy is also great for prototyping stuff:
https://www.scipy.org/

It contains lots of classes/functions that are useful for signal processing (FFTs, filter design algorithms, filtering, plotting, etc.).

Under Linux I use the Anaconda distribution and under Windows WinPython.
Passed 303 posts. Next stop: 808.

Post

Valenten wrote:Probably I should try that too. Why Python and not straight console-style C++ ? (sorry if it's a stupid question ;) )
Because I like Python a lot, I use the plotting capabilities a lot, as well as the numerical tools, so I can do more or less anything. And I can build a new pipeline without having to recompile anything. Or even create something on the fly (I have some ATK examples using scipy as well).

I would use Anaconda on all platforms, works fine on Windows as well (or OS X).

Post

Thanks a lot for the feedback.

I guess I will have to learn Python as well. In terms of programming I am coming from webdevelopment languages (PHP...), so I went for C++ first as it seemed to me to be the most powerful. I will check out how to use Python at some point then :)
BlitBit wrote: Last but not least, if you are looking for oversampling filters have a look at half band filters. Because they are symmetric and most of their coefficients are zero they can be implemented quite efficiently. Also please keep in mind that if you downsample you don't need to actually evaluate the samples that you will be throwing away anyway. You only have to push them into the delay line of the filter, so that the pattern looks as follows: push, evaluate, store, push, push, evaluate, store, push, push, evaluate, store, etc. Using these properties you can save a lot of computations.

Another advantage is that the higher the current oversampling factor the more relaxed the half band filters can be specified. So if you for example design the filter that's used to downsample from 8x to 4x the transition region can be quite wide (which means lesser coefficients and lesser computations) because the frequencies that will alias back into the audible range will be filtered out by the filters that follow (4x to 2x, 2x to 1x).
I'll follow up with my initial topic, as I see no point in creating a new thread.

I am now willing to implement half-band filters and polyphase decimation. The filtering works splendid, but I have a slight problem with the delay line management at each decimation phase.

Let me explain what I'm doing :
  • I've got a delayLine for each channel (Left/Right).
  • I apply the half-band FIR filter, do only the calculation for the non-zero coefficients and for the values that will not be discarded.
  • I store the result is my oversampled buffer, with an index running to half of the oversampled buffer size (something like that : writer[sample/2] = result;)
So far so good, no problem with the writer[sample/2] value because in the loop, sample++ is called 2 times so it will always be a multiple of 2.

Now the problem is the following :

To make the different FIR Filtering / Decimation phases work, I currently have a different DelayLine for each phase. Since I need to keep these delay lines correct between each buffer for real-time processing, is there any better way to do than having a delay line for each decimation phase ?

V.

Post

Valenten wrote: So far so good, no problem with the writer[sample/2] value because in the loop, sample++ is called 2 times so it will always be a multiple of 2.
Possibly, but there are hosts that have one sample buffers (fl studio for instance)
This may not even be relevant just thinking out loud :)

Post

way to do than having a delay line for each decimation phase ?
Remember that the second output of the halfband filter has only one multiplication - the center tap of 0.5. So for a 9-tap halfband filter, just use the 4th value (that is, array[3]) again. It helps to write it down to help visualize it. You should only need one delay line, as long as you plan your multiplications out correctly.

Post

Valenten, unless you are obsessed to retain linear phase near nyquist (which IMO may not be important for a sampler), these IIR polyphase halfband filters work great and run fairly fast considering the good quality of the filters. Read the article comments for slight corrections-- http://musicdsp.org/archive.php?classid=3#39

Re handling sample rate conversion buffers, here is how I used to do it but can't say if it is an optimal way--

It was based on an SRC, sample format conversion object I wrote, with various methods to manipulate the buffers.

As best I recall, my usual buffer was 32768 bytes in size. Which could hold 8192 samples Float32. Or obviously any sample format up to 8192 samples, occupying less than the full size of the buffer. There's no reason bigger "standard" buffer size couldn't be used, or a different size for different purposes, but wanted a fairly generic thang which would handle most cases.

For instance if receiving 512 samples of Int16 from a sound card, dump it into the buffer, then run an in-place int-to-float function on the buffer and have 512 samples of Float32.

If 8 X oversampling, run a 2X oversample in-place on the buffer, for three iterations. First iteration, 1024 samples, second iteration, 2048 samples, third iteration, 4096 samples. Then process the buffer however needed. Then to get back to the original samplerate, run three iterations of decimation in-place on the buffer, resulting in 512 samples again. Then if writing Int16 to file or soundcard, do an in-place float-to-int on the buffer and then send it to the hardware.

Sometimes this rigamarole was for sample-rate conversion. For instance if you have 44.1 k but you really need 96 k for a soundcard, or vice-versa, oversample, interpolate, decimate.

Object properties to remember the sample format, samplerate, and num samples currently in the buffer, are helpful to avoid confusion about what happens to be residing in the buffer at any particular time.

It took awhile to write the object many years ago, and it was only polished enough to suit my needs. But after the object was written, I just kept using the object for many years as a toolbox utility function, for lots of purposes.

If it turned out I needed it to do a new trick, would just write a new method for the big object.

Post

Valenten wrote:Thanks a lot for the feedback.

I guess I will have to learn Python as well. In terms of programming I am coming from webdevelopment languages (PHP...), so I went for C++ first as it seemed to me to be the most powerful. I will check out how to use Python at some point then :)
I'm also dipping my toes into DSP after doing a bit of webdev.
Python is much more thoughtfully designed than PHP.

pyo is a Python audio DSP library written in C that's very easy to use.

Post Reply

Return to “DSP and Plugin Development”