How to Use FFmpeg loudnorm for EBU R128 Normalization

This article provides a practical, step-by-step guide on how to use the loudnorm filter in FFmpeg to achieve EBU R128 loudness normalization. You will learn the difference between single-pass and double-pass normalization, how to configure key parameters like integrated loudness, loudness range, and true peak, and the exact commands needed to process your audio files.


Understanding loudnorm Parameters

The loudnorm filter in FFmpeg uses the EBU R128 standard to analyze and adjust audio levels. Before running the commands, it is important to understand the primary parameters:

  • I (Integrated Loudness): The target loudness in LUFS (Loudness Units Full Scale). The EBU R128 standard for broadcast is -24.0 LUFS. For online platforms like podcasts or YouTube, -16.0 or -14.0 LUFS is often used.
  • TP (True Peak): The maximum peak level in dBTP (Decibels True Peak) to prevent clipping. The standard target is -2.0 or -1.0 dBTP.
  • LRA (Loudness Range): The target range of loudness in LU (Loudness Units). The default is 7.0 LU.

Method 1: Single-Pass Normalization (Quick)

Single-pass normalization is fast and suitable for real-time streaming or quick file conversions. Because FFmpeg analyzes and adjusts the audio on the fly, it relies on dynamic compression to hit the targets, which can sometimes alter the transients of the audio.

To apply single-pass normalization to a file, use the following command:

ffmpeg -i input.wav -filter:a loudnorm=I=-24:TP=-2.0:LRA=7.0 output.wav

Command Breakdown:

  • -i input.wav: Specifies the input audio file.
  • -filter:a loudnorm=...: Applies the audio filter.
  • I=-24: Sets the target integrated loudness to -24 LUFS.
  • TP=-2.0: Sets the maximum true peak to -2.0 dBTP.
  • LRA=7.0: Sets the target loudness range to 7.0 LU.

Two-pass normalization is the industry standard for post-production. The first pass analyzes the entire audio file and outputs statistical data. The second pass uses this data to apply precise linear normalization, preserving the original dynamic structure of the audio without unnecessary compression.

Step 1: Run the Analysis Pass

Run the following command to analyze your input file. This command will print the analysis results in JSON format to the terminal without writing an output file.

ffmpeg -i input.wav -filter:a loudnorm=I=-24:TP=-2.0:LRA=7.0:print_format=json -f null -

Look at the end of the terminal output for the JSON block, which will look similar to this:

{
    "input_i" : "-15.20",
    "input_tp" : "1.20",
    "input_lra" : "11.50",
    "input_thresh" : "-26.40",
    "output_i" : "-24.10",
    "output_tp" : "-2.00",
    "output_lra" : "7.20",
    "output_thresh" : "-34.50",
    "normalization_type" : "dynamic",
    "target_offset" : "0.10"
}

Step 2: Run the Normalization Pass

Take the input_* values and the target_offset value from the JSON output and feed them back into the loudnorm filter for the second pass.

Using the values from the example above, the command is:

ffmpeg -i input.wav -filter:a loudnorm=I=-24:TP=-2.0:LRA=7.0:measured_I=-15.20:measured_TP=1.20:measured_LRA=11.50:measured_thresh=-26.40:offset=0.10 output.wav

By providing these measurement parameters, FFmpeg performs true linear normalization, ensuring the output perfectly conforms to the EBU R128 standard.