Denoising With afftdn and anlmdn: Which Control Matters and From Which Noise Level It Pays Off, Measured

Contents
ffmpeg ships two denoisers. afftdn works through the fast Fourier transform and has two controls: noise reduction, set to 12 by default, and the noise floor, set to −50 dBFS. anlmdn works by non-local means and has one control for strength.
The usual test, listening once before and once after, does not answer the question that matters: in noisy material the wanted signal and the noise lie on top of each other, and what disappears cannot be told apart. This measurement separates the two by sending the denoiser through a clean programme in which there is nothing to remove.

How this was measured
- Material: 32 s of programme built from kick, snare, hi-hats, bass, pad and lead at −19.62 dBFS, with 0.3 s of silence at the end. White noise was added at a known level so that the error stays calculable.
- Yardstick: throughout, the distance to the known clean original, that is the root mean square of result minus original, relative to that of the original. Before denoising this is exactly the noise level. If it gets smaller, the filter helped; if it gets larger, the filter destroyed more than it removed.
- Damage: the same filter also runs over the clean programme. There is nothing to remove there, so everything missing at the output is damage.
- Alignment: both filters deliver their result late,
afftdnby 1102 samples or 24.99 ms,anlmdnby 353 or 8.00 ms. Every comparison is aligned first by cross-correlation. - Counter-check: both filters can output what they removed, through
output_mode=noise. That figure matches the measured difference to 0.00 dB, for both filters.
What disappears when there is nothing to remove
| Setting | Damage below the signal | Change in level |
|---|---|---|
afftdn, nr 6, nf −50 |
−43.29 dB | −0.00 dB |
afftdn, default nr 12, nf −50 |
−42.19 dB | −0.00 dB |
afftdn, nr 24, nf −50 |
−41.67 dB | −0.00 dB |
afftdn, nr 48, nf −40 |
−26.16 dB | −0.05 dB |
anlmdn, s 0.001 |
−151.94 dB | 0.00 dB |
anlmdn, s 0.01 |
−105.77 dB | −0.00 dB |
anlmdn, s 0.1 |
−67.83 dB | −0.00 dB |
The level does not change, the substance does. At its default, afftdn takes something out of faultless material that sits 42.19 dB below the signal. At nf −40 it is 26.16 dB below, and that is an order of magnitude that can be heard. anlmdn stays at −105 dB and lower in its small strengths, so it does practically nothing.
Which of the two controls works
| Control changed | Value | Change in the distance | Damage |
|---|---|---|---|
| noise reduction, nf fixed at −50 | nr 3 | +0.38 dB | −45.28 dB |
| noise reduction, nf fixed at −50 | nr 12 | +1.16 dB | −42.19 dB |
| noise reduction, nf fixed at −50 | nr 48 | +1.50 dB | −41.49 dB |
| noise reduction, nf fixed at −50 | nr 90 | +1.50 dB | −41.48 dB |
| noise floor, nr fixed at 12 | nf −70 | +0.55 dB | −48.71 dB |
| noise floor, nr fixed at 12 | nf −55 | +0.32 dB | −47.72 dB |
| noise floor, nr fixed at 12 | nf −45 | +6.74 dB | −33.70 dB |
| noise floor, nr fixed at 12 | nf −40 | +13.25 dB | −26.80 dB |
| noise floor, nr fixed at 12 | nf −30 | +21.23 dB | −18.78 dB |
Both series run over the same material with noise 40 dB below the signal, so over a real noise floor of −59.6 dBFS. A positive value in the third column means the distance to the clean original has grown.
Noise reduction changes 1.13 dB across its whole range and saturates from nr 48 onwards. The noise floor changes 20.91 dB. Turning the first control is turning nothing.
The second part of the table is the striking one: from nf −45 onwards, effect and damage rise almost in step. From −45 to −30 the change grows by 14.49 dB and the damage by 14.92 dB. At nf −30 the noise has vanished entirely, and what is left of the error, at −18.78 dB, is exactly the filter’s own damage.
From which noise level it pays off
| Noise below the signal | Real noise floor | Best nf | Best achievable change |
|---|---|---|---|
| 60 dB | −79.6 dBFS | −70 dBFS | −0.04 dB |
| 50 dB | −69.6 dBFS | −60 dBFS | −0.04 dB |
| 40 dB | −59.6 dBFS | −55 dBFS | −0.15 dB |
| 30 dB | −49.6 dBFS | −50 dBFS | −1.03 dB |
| 20 dB | −39.6 dBFS | −40 dBFS | −2.87 dB |
| 12 dB | −31.6 dBFS | −30 dBFS | −4.75 dB |
| 6 dB | −25.6 dBFS | −25 dBFS | −7.42 dB |
For every row, 23 settings were tried and the best one entered. Two things stand out.
First, the best setting follows the real noise floor. In the four rows where denoising achieves anything at all, the best nf sits between 0.4 dB below and 1.6 dB above it. The control is named after the thing it wants: the level of the noise, not a preference. The default of −50 dBFS fits material whose noise sits at −50 dBFS, and no other.
Second, there is nothing to gain on clean material. At a noise level of 50 dB below the signal the best of all settings brings 0.04 dB, at 40 dB it is 0.15 dB, and in both cases that result comes from anlmdn at a strength that does practically nothing. Only from 30 dB downwards does it become 1.03 dB, and even at 6 dB, which is plainly audible noise, it is 7.42 dB.
Where the filter reaches in
| Third-octave band | afftdn, default |
anlmdn, s 0.01 |
|---|---|---|
| 63 Hz | −127.02 dB | −155.92 dB |
| 250 Hz | −130.46 dB | −140.91 dB |
| 1 kHz | −85.79 dB | −114.97 dB |
| 2 kHz | −46.84 dB | −104.29 dB |
| 4 kHz | −32.70 dB | −95.24 dB |
| 8 kHz | −27.10 dB | −90.93 dB |
| 10 kHz | −23.26 dB | −87.18 dB |
| 16 kHz | −29.78 dB | −91.77 dB |
The figures say how far the intervention in each band sits below the signal in that same band, measured on clean material. Below 500 Hz afftdn touches nothing, where the figures stand at 115 to 130 dB. From 2 kHz upwards it becomes serious, and the filter reaches in most strongly at 10 kHz, 23.26 dB below the signal. Denoising is a treble affair.
The decay is spared at the default setting. A single hi-hat hit loses 0.00 dB at 50, 100 and 200 ms after the peak and 0.35 dB after 400 ms. At nf −40 with nr 48 it is 0.27 dB after 200 ms and 7.71 dB after 400 ms. The tail is shortened, then, but only at a firm setting.
And then there is the pause. In the silence at the end, afftdn at its default lowers the noise floor by 10.52 dB, at nr 48 by 19.98 dB, and anlmdn by 26.06 to 28.02 dB. Anyone listening only there takes anlmdn for the best of the candidates. On the music itself it changes 0.04 dB. The pause is the one place where the noise lies exposed, and that is exactly why it says nothing about what happened to the rest.
What follows from this
The noise floor belongs measured, not guessed. A passage without any wanted signal, with its level read off in dBFS, gives the value for nf; the noise floor meter finds that passage and prints the value together with the command. Audacity takes this route of its own accord and asks for a noise profile from a place where only noise stands, before it denoises anything. ffmpeg asks for a number instead, and a wrong number is the whole difference.
After that, noise reduction stays where it is. It brings 1.13 dB across its whole range while the noise floor control brings 20.91 dB, and past a certain point every one of those decibels is paid for with a decibel of damage.
On properly recorded material the tool is not worth reaching for. With noise 40 dB or more below the signal, the best possible gain is at most 0.15 dB, and setting a tool against that which reaches 23 dB below the signal in the treble is a poor trade. Where a noise floor is a nuisance without being loud, the subject is often not the noise but the bit depth; what really happens when exporting to 16 bit is covered in the article on dither on export.
What this covers and what it does not
- The measurement used white noise. Hum, tape hiss and room tone are distributed differently;
afftdncarries its own presets for vinyl and shellac, which were not tested here. - The yardstick is the distance to the clean original, not the listening impression. A filter can worsen that distance and still sound more pleasant, because even noise disturbs less than an equally large but uneven error.
- The best nf was sought from a grid of ten values in steps of 5 dB. The agreement with the real floor is therefore accurate to that step.
- At noise levels of 50 and 60 dB the real floor lies below the smallest nf tested. Since there is nothing to gain there anyway, that changes nothing about the result.
Questions and answers
What does the 25 ms delay do when the denoised track goes back into the mix?
In the measurement, afftdn delivered its result 1102 samples or 24.99 ms late, anlmdn 353 samples or 8.00 ms late. A file processed this way and placed next to the other tracks sits late by exactly that amount. For a single track such as a vocal recording, only the timing shifts; for tracks that belong together, such as several microphones on the same drum kit, an offset appears between signals that should line up.
It is most obvious in parallel mixing with the unprocessed original, a natural move with a denoiser to soften its effect. The sum of a signal and a copy delayed by 25 ms is a comb filter with notches spaced 40 Hz apart, which is exactly the colouration the softening was meant to avoid.
The offset therefore has to be compensated before mixing, for example by trimming the first 1102 samples. That number applies to the sample rate of this measurement, which follows from 1102 samples in 24.99 ms as 44.1 kHz; at another sample rate or with other filter settings it has to be determined again by cross-correlation, just as the measurement did before every comparison.
Can the right nf value be worked out from how far the noise lies below the signal?
Yes, if the level of the programme is known. The control expects the real noise floor, and that is the programme level minus the distance of the noise below the signal: for the material in this measurement at −19.62 dBFS, noise 30 dB below the signal gives −49.62 dBFS, and that is exactly where the best nf lay, at −50 dBFS. Usually that distance is unknown, though, which is why the safer route runs through a passage without any wanted signal.
Sources
- ffmpeg: Filters Documentation: the sections on
afftdnwithnoise_reduction,noise_floor,noise_typeandoutput_mode, and onanlmdnwithstrength,patchandresearch; the defaults come from the built-in help of ffmpeg 7.1.5. - Audacity: Noise Reduction: the noise profile as the first step, the advice to use the lowest value that suffices because higher values damage the material that remains, and the residue monitor as the means of judging that damage.
- ITU-R BS.1770: Algorithms to measure audio programme loudness and true-peak audio level: the basis of the level figures in this series.