Multi-Band Compression in FFmpeg Using mcompand

This article provides a practical guide on how to use the mcompand (multi-band compander) filter in FFmpeg to process audio streams. You will learn the structure of the filter's syntax, how to define frequency crossover points, and how to configure attack, release, and volume threshold parameters for different audio bands to achieve a balanced and professional sound.


Understanding the mcompand Filter Syntax

The mcompand filter divides an audio signal into multiple frequency bands and applies compression or expansion to each band individually. The basic syntax for the filter requires defining the parameters for each band, separated by spaces, wrapped in single quotes:

ffmpeg -i input.wav -af "mcompand='band1 band2 band3'" output.wav

Each band is defined using the following sequence of parameters:

attacks releases [delay] points [crossover_frequency]
  • attacks: A comma-separated list of attack times (in seconds) for each channel.
  • releases: A comma-separated list of release times (in seconds) for each channel.
  • delay (optional): Delay (in seconds) for the signal to allow look-ahead compression.
  • points: A list of input and output decibel (dB) transfer points defining the compression curve (e.g., input_dB,output_dB,input_dB,output_dB...).
  • crossover_frequency: The upper limit of the frequency band in Hz. The last band does not require a crossover frequency, as it automatically extends to the highest available frequency.

Step-by-Step Implementation

To apply a 3-band compressor (Low, Mid, and High frequencies), you must construct three separate band definitions within the filter.

1. Define the Low-Frequency Band (Bass)

For the low frequencies (0 Hz to 200 Hz), we want a fast attack to catch heavy transients and moderate compression:

  • Attack / Release: 0.005,0.005 seconds attack, 0.1,0.1 seconds release.
  • Transfer Points: -60,-60,-20,-16,0,-10 (audio below -60 dB is untouched, -20 dB is compressed to -16 dB, and 0 dB is limited to -10 dB).
  • Crossover Frequency: 200 Hz.

2. Define the Mid-Frequency Band (Vocals/Instruments)

For mid-range frequencies (200 Hz to 3000 Hz), we use a slightly slower attack to keep vocals sounding natural:

  • Attack / Release: 0.01,0.01 seconds attack, 0.15,0.15 seconds release.
  • Transfer Points: -60,-60,-20,-18,0,-12
  • Crossover Frequency: 3000 Hz.

3. Define the High-Frequency Band (Treble/Air)

For the high frequencies (3000 Hz and above), we use very fast settings to control sibilance:

  • Attack / Release: 0.003,0.003 seconds attack, 0.08,0.08 seconds release.
  • Transfer Points: -60,-60,-20,-15,0,-10
  • Crossover Frequency: Omitted (covers everything above 3000 Hz).

Complete FFmpeg Command

Combining these three band definitions into a single FFmpeg command yields the following:

ffmpeg -i input.wav -af "mcompand='0.005,0.005 0.1,0.1 -60,-60,-20,-16,0,-10 200 0.01,0.01 0.15,0.15 -60,-60,-20,-18,0,-12 3000 0.003,0.003 0.08,0.08 -60,-60,-20,-15,0,-10'" output.wav

Key Considerations for Tuning

  • Stereo vs. Mono: In the example above, 0.005,0.005 specifies the attack time for both the left and right channels of a stereo stream. If you are processing a mono stream, use single values (e.g., 0.005 instead of 0.005,0.005).
  • Look-ahead Delay: Adding a small delay (e.g., 0.005 seconds) before the transfer points allows the compressor to "look ahead" and react to peaks before they occur, preventing digital clipping.
  • Level Matching: Adjust the final points of your transfer curves (e.g., the 0,-10 value) to balance the output volume across bands and prevent any single frequency range from dominating the mix.