FSRC - A sample rate conversion library

The available sample rate converters suck. They suck either at conversion quality, performance, code quality, or all of the above. FSRC aims to be a converter that doesn't suck.

Specifically, it aims to provide:

At this stage it is not feature complete and existing features are not debugged. If you want to play around, your best choice is the source tarball. You will also need FFTW (Windows binaries here) and CMake. (Oh, and a compiler. Tested using GCC, MSVC, and Sun C.)

The details

Linear phase FIR filters are currently designed using Lawson's algorithm with weight update envelopes (see A weighted least squares algorithm for quasi-equiripple FIR and IIR digital filter design). The filters it produces are nearly optimal in the minimax sense (It can also be modified for least squares stopbands - see this). While not strictly elegant, it has the advantage that each iteration requires the solution of a Toeplitz system of linear equations and a couple of FFTs. The linear systems are solved quickly using preconditioned conjugate gradient.

While comparably fast, filter design using this method can still take a couple of seconds at high quality settings, therefore FSRC is able to store the designs for later re-use, so it becomes a one-time effort. For this purpose, the included test program uses the %APP_DATA%\fsrc directory on Windows and ~/.libfsrc on *NIX.

Currently, FSRC implements the usual polyphase rate conversion, as well as frequency domain resampling which, assuming a conversion factor of L/M, boils down to:

The downside is that the transforms sizes need to be of the form K*M and K*L respectively for the input and output, where K is an arbitrary positive integer. The rest is the same as in the usual block filtering. For optimal performance, a careful adjustment of the buffer sizes is required. This is not currently done, so the performance of this method should improve in the future.

AFAIK, FSRC is also the only library which is able to perform optimal multistage decomposition of arbitrary (sans prime) conversion ratios on the fly.

Performance

As a teaser, this page will present a tiny comparison to libsamplerate. It might not be entirely fair, since libsamplerate allows time-varying conversion factors, while FSRC does not (yet, at least). Still, libsamplerate seems to be the only library which is both high-quality and has a decent programming interface. I'll try to add a couple more into the mix later (like SOX).

For the comparison, I've tried to use settings that match libsamplerate's best quality converter. RMAA was used to compare the quality - the 44.1kHz test signal was resampled to 96kHz and back. I've finally settled on the following:

Those were the specs fed into the API. The actual design might slightly exceed this spec. The results produced were as follows:

libsamplerate
fsrc

RightMark Audio Analyzer test


Testing chain:
Sampling mode: 32-bit, 44 kHz




Summary

Testlibsampleratefsrc
Frequency response (from 40 Hz to 15 kHz), dB: +0.00, -0.00+0.00, -0.00
Noise level, dB (A): -194.1-210.8
Dynamic range, dB (A): 133.2133.2
THD, %: 0.00000.0000
IMD + Noise, %: 0.00020.0002
Stereo crosstalk, dB: -194.5-213.2



Frequency response

Spectrum graph


Dynamic range

Spectrum graph


THD + Noise (at -3 dB FS)

Spectrum graph


THD Closeup

Spectrum graph


Intermodulation distortion

Spectrum graph


IMD Closeup

Spectrum graph

 

To compare performance, I wrote a program which resamples a 5min long sine wave from 44.1kHz to 96kHz. You can find the code and Windows x64 binaries here (libfsrc-libsamplerate-x64-bin.rar). You will also need the FFTW binaries and the MSVC runtime (if you don't have it already).

The numbers were (Core 2 Duo T5600):

Keep in mind, the FFT resampling is not working at its peak, as mentioned at the top of the page.