1
$\begingroup$

I am working on an audio resampler that is realized as a polyphase FIR filter. While testing, I found that it does not suppress aliasing as well as I would have expected. For testing, a sine sweep is upsampled by a factor of 8, distorted by $\tanh(kx)$, and downsampled to its original rate. For $k \lessapprox 3.7$, the resulting signal does not contain audible aliasing. At higher values for $k$, however, aliasing becomes increasingly noticeable (e.g. at 15000 Hz for $k = 4$). Audio examples:

Additionally, when examining the distorted signal, its amplitude increases with time, even for lower $k$. I believe this is also due to aliased signal content: The original and the distorted signal in Audacity.

I'm assuming that my polyphase implementation is correct, so the resampler's antialiasing performance is likely bounded by the filter. The filter that has been used for the examples above was obtained in Octave using fir1(799, 0.12, 'low', kaiser(800, 10)) .* 8 (the multiplication by 8 is done so that the upsampler does not have to perform gain compensation).

The filter's frequency response.

Since the resampler is intended to be used in real-time distortion audio effects for DAWs, I am looking for ways to generate a filter that better suppresses aliasing and, ideally, has fewer coefficients (currently 800).

Apart from fir1, I also tried fir2, this sinc filter generator by Nigel Redmon, and the Parks-McClellan method, but all of the filters I was able to generate were worse than the above filter in the following ways:

  • incresed passband droop in the high frequencies, or
  • worse stopband rejection in the low frequencies, or
  • overall worse stopband rejection, leading to even more noticeable aliasing.

Is there a way to design a filter that has both fewer coefficients and better antialiasing performance or is this about as good as FIR resampling can get?

$\endgroup$
4
  • $\begingroup$ Instead of one long, tightly specified filter, a cascade of looser, shorter filters gives better performance. Instead of one decimate by 8 stage, cascade 3 stages of decimate by 2, for example. $\endgroup$
    – Andy Walls
    Commented Dec 29, 2023 at 15:50
  • $\begingroup$ @AndyWalls I would not do that, if what they want are FIR coefficient sets for each fractional delay. $\endgroup$ Commented Dec 31, 2023 at 4:20
  • $\begingroup$ @robertbristow-johnson That would be optimal but I'm starting to think it's not feasible. Based on the little information I could find, everybody (e.g. JUCE) seems to do multiple half-band filters in series, so maybe that's just the better approach. That being said, perhaps for real-time use, an IIR filter would be better for performance, but I wanna see how far I can get with a FIR filter, as linear phase is desirable. $\endgroup$
    – wolframw
    Commented Apr 9 at 7:49
  • $\begingroup$ @wolframw , I realize that this is nearly two months later. Sorry, I hadn't seen this or it slipped by. Have you solved your problem? If not, I have MATLAB code that will design really good polyphase FIR interpolation filters using either firpm() (Parks-McClellan), firls() (Least-Squares), or kaiser() (Kaiser-windowed sinc). If you want it, we have to figure out a way for me to email you this MATLAB code. $\endgroup$ Commented May 29 at 17:51

1 Answer 1

0
$\begingroup$

To optimize FIR filter rejection for resampling applications, I recommend using the least squares algorithm (firls in Matlab, Octave and Python scipy.signal) with multi-band targets concentrating the zeros at the image frequency locations. This will provide the maximum rejection where it matters for a given number of coefficients. The plots below depict a simple example of interpolate by 4.

interpolation images

interpolation FIR

The resulting coefficients are then used directly in the polyphase interpolator implementation as I have previously detailed at this post.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.