Careful with audio resampling using FFmpeg

In my line of work transcoding videos for dr.dk/pirattv i use FFmpeg extensively. I have written a tool in C# that automates this task and in doing so, i discovered that FFmpeg is not a good choice for downsampling audio. The downsampling does not suffer from aliasing because the signal is properly attenuated at the Nyquist frequency – but the quality of this lowpass filter is terrible. The problem lies with the lowpass filter which is by no means steep enough so it unnecessarily cuts a lot of high frequencies fairly far from the Nyquist frequency. The only good thing about the filter, is that the resampling is really fast. I have not found a setting in FFmpeg that forces it to use a better filter so i wanted to find a better way:

From looking at this awesome site i learned that one of the very best resamplers around: SSRC – is free and even open source! So now i treat the audio separately from the video and do all downsampling using SSRC which preserves the treble which is indeed audible when transcoding music.

Original sweep
A 96 kHz sweep taken from infinitewave visualized using Audacity.

This is the same sweep downsampled to 44.1 kHz using FFmpeg.
Notice the server attentuation already at 17-18 kHz

Here the same downsampling is done using SSRC. The filter is extremely steep as we want it to be. In fact so steep that you can”t even see the attentuation right before Nyquist – but it’s there!
Notice that the y-axis is different than that on the FFmpeg version.

Update: I ended up using SoX, because I needed more than just great resampling. SSRC is in theory slightly better but the difference is inaudible to me and SoX provides me with an array of additional possibilities.

Update II – FFmpeg now includes the SoX resampler – but only utilizes it if you tells it to – the┬ádefault resampler is still the simple one with its limitations.
To use the better resampler from SoX, eg resampling to 44.1 kHz, add the following to your command line:

-af aresample=resampler=soxr -ar 44100

2 Comments

  1. Michael Niedermayer

    2012/07/08 at 3:53 AM

    You can easily tune the lowpass filter used in ffmpeg. The cutoff parameter to the aresample filter controls the cutoff frequency, 1 would be the nyquist, 0.8 is what was probably used in your test of ffmpeg. filter_size controls the length of the filter, with longer leading to steeper cutoff, 16 was probably used in your test. For example
    -af aresample=osr=44100:filter_size=256:cutoff=1
    should produce results with a steep cutoff at the nyquist, this filter of course will be slower than the default.
    filter_size allows tuning the speed vs. the steepness of the cutoff. There are many more parameters that can be tuned, see ffmpeg –help or the source code

    If you find further issues (like SSRC or SOX being better at similar speed once all sides are tuned to produce good results) please open a bug report at the ffmpeg bug tracker. Resamplers arent rocket science its not hard to fix/improve them if such issues are reported.

    Also there are plans to add the possibility to use SSRC through ffmpeg. And considering your test here we should probably change the defaults used for our resampler. Ill make sure this gets discussed before our next release

    Michael

Leave a Reply

Your email address will not be published.

*