[FFmpeg-trac] #8785(avfilter:new): af_loudnorm: Limiter does not handle new peaks in ATTACK/RELEASE states
FFmpeg
trac at avcodec.org
Sat Jul 11 15:13:43 EEST 2020
#8785: af_loudnorm: Limiter does not handle new peaks in ATTACK/RELEASE states
----------------------------------+---------------------------------------
Reporter: slomo | Type: defect
Status: new | Priority: normal
Component: avfilter | Version: unspecified
Keywords: | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
----------------------------------+---------------------------------------
Currently the limiter would cause output with too high peaks if a new,
higher peak occurs while inside the ATTACK/RELEASE states. These states
don't check for any new peaks but simply reduce/increase the gain over the
given window based on the previous peak / no peak being found before. This
potentially causes clipping and did so when I tested my implementation.
I've found this while porting the filter to Rust for a GStreamer plugin,
the code of which can be found here:
https://gitlab.freedesktop.org/gstreamer/gst-plugins-
rs/-/blob/master/audio/audiofx/src/audioloudnorm.rs . This also contains
lots of code comments for all the steps, which might be helpful to take
over to the ffmpeg code too.
My solutions to these issues might not be the best or most simple
approach, but during my testing they worked so feel free to adapt them for
the ffmpeg code.
ATTACK happens over a 10ms window, RELEASE over a 100ms window and the
peak detection uses a 10ms lookahead and returns the first true peak it
found.
ATTACK state:
===================
This happens over a window of 10ms and the gain reduction is slowly
increased until the peak that was detected (and is at the end of the
window) would have exactly the configured maximum peak.
Now what can happen is that during processing this window there is a new
(higher!) peak after the end of the window (remember: 10ms window and 10ms
lookahead for peak detection) that would require a steeper slope. We
wouldn't detect this as no peak detection at all happens in ATTACK mode,
and would let the peak through.
So peak detection has to run, and once we're exactly 10ms before that
higher peak the ATTACK state needs to be restarted with the steeper slope.
A possible implementation for this can be found here:
https://gitlab.freedesktop.org/gstreamer/gst-plugins-
rs/-/blob/1730de6cea10cb73ff1ab882a8235d540bfa5061/audio/audiofx/src/audioloudnorm.rs#L924
See also the comments, there are a few tricky corner-cases to consider
that also affect the SUSTAIN state.
RELEASE state:
===================
This happens over a window of 100ms, the gain reduction is slowly
decreased until it is at 0 again. No search for a new peak inside this
window or 10ms after it is performed, that means if a new peak is found
during this window there are two possible cases
a) New peak requires lower/equal gain reduction to the *current* gain
reduction: in this case we have to switch back to SUSTAIN with the current
gain reduction to ensure that this peak is reduced enough to stay below
the configured maximum peak.
A possible implementation can be found here:
https://gitlab.freedesktop.org/gstreamer/gst-plugins-
rs/-/blob/1730de6cea10cb73ff1ab882a8235d540bfa5061/audio/audiofx/src/audioloudnorm.rs#L1321-1331
b) New peak requires higher gain reduction: We need to go back to ATTACK
mode, but we can SUSTAIN the current gain reduction until we're 10ms
before the peak. ATTACK mode can start at the current gain reduction and
go to the target necessary reduction as usual.
A possible implementation can be found here:
https://gitlab.freedesktop.org/gstreamer/gst-plugins-
rs/-/blob/1730de6cea10cb73ff1ab882a8235d540bfa5061/audio/audiofx/src/audioloudnorm.rs#L1280-1319
--
Ticket URL: <https://trac.ffmpeg.org/ticket/8785>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list