4 stable releases
| new 1.4.1 | Jan 16, 2026 |
|---|---|
| 1.4.0 | Jan 15, 2026 |
| 1.3.0 | Jan 14, 2026 |
| 1.2.0 | Jan 12, 2026 |
#218 in Audio
52KB
929 lines
headroom
Audio loudness analyzer and gain adjustment tool for mastering and DJ workflows.
What is this?
headroom simulates the behavior of Rekordbox's Auto Gain feature, but with a key difference: it identifies files with available headroom (True Peak below the target ceiling) and applies gain adjustment without using a limiter.
This tool is designed for DJs and producers who want to maximize loudness while preserving dynamics, ensuring tracks hit the optimal True Peak ceiling without clipping.
Key Features
- Single binary: mp3rgain is built-in as a library — only ffmpeg required as external dependency
- Smart True Peak ceiling: Based on AES TD1008, uses -0.5 dBTP for high-quality files, -1.0 dBTP for low-bitrate
- Multiple processing methods: ffmpeg for lossless formats, built-in mp3rgain for lossless MP3, ffmpeg re-encode for precise MP3/AAC gain
- Non-destructive workflow: Original files are backed up before processing
- Metadata preservation: Files are overwritten in place, so Rekordbox tags, cue points, and other metadata remain intact
- No limiter: Pure gain adjustment only — dynamics are preserved
- Interactive CLI: Guided step-by-step process with two-stage confirmation
Supported Formats & Processing Methods
| Format | Extension | Method | Precision | Notes |
|---|---|---|---|---|
| FLAC | .flac | ffmpeg | Arbitrary | Lossless re-encode |
| AIFF | .aiff, .aif | ffmpeg | Arbitrary | Lossless re-encode |
| WAV | .wav | ffmpeg | Arbitrary | Lossless re-encode |
| MP3 | .mp3 | mp3rgain (built-in) | 1.5dB steps | Truly lossless (global_gain modification) |
| MP3 | .mp3 | ffmpeg re-encode | Arbitrary | For files needing precise gain |
| AAC/M4A | .m4a, .aac, .mp4 | ffmpeg re-encode | Arbitrary | Always requires re-encode |
MP3 Processing: Three-Tier Approach
headroom intelligently chooses the best method for each MP3 file:
1. Native Lossless (Built-in mp3rgain, bitrate-aware ceiling)
For MP3 files with ≥1.5 dB headroom to bitrate-aware ceiling:
- Truly lossless global_gain header modification
- 1.5 dB step increments (MP3 format specification)
- Uses built-in mp3rgain library
- ≥256kbps: -0.5 dBTP ceiling (requires TP ≤ -2.0 dBTP)
- <256kbps: -1.0 dBTP ceiling (requires TP ≤ -2.5 dBTP)
2. Re-encode (Precise, bitrate-aware ceiling)
For MP3 files with headroom but <1.5 dB to ceiling:
- Uses ffmpeg for arbitrary precision gain
- Preserves original bitrate
- Requires explicit user confirmation
3. Skip (No headroom)
Files already at or above the target ceiling are not processed.
AAC/M4A Processing
AAC/M4A files are supported with the following characteristics:
- Always requires re-encoding: Unlike MP3, AAC has no lossless gain adjustment mechanism
- Bitrate-aware ceiling: Same strategy as MP3 re-encode (-0.5 dBTP for ≥256kbps, -1.0 dBTP for lower)
- High-quality encoder: Prefers libfdk_aac when available, falls back to built-in aac encoder
- Preserves original bitrate: Maintains audio quality matching the source file
- Grouped with MP3 re-encode: AAC files are processed together with MP3 re-encode files in the second confirmation stage
Why Re-encode AAC is Safe at High Bitrates
Same principles apply as MP3 re-encoding:
- At ≥256kbps, quantization noise stays below -90dB (inaudible)
- Only gain is applied (no EQ, compression, or dynamics processing)
- Original bitrate is preserved
- Requires explicit user opt-in
True Peak Ceiling Strategy
Based on AES TD1008 recommendations:
| Format | Method | Ceiling | Rationale |
|---|---|---|---|
| Lossless (FLAC, AIFF, WAV) | ffmpeg | -0.5 dBTP | Will be distributed via high-bitrate streaming |
| MP3 ≥256kbps (lossless) | mp3rgain | -0.5 dBTP | Requires TP ≤ -2.0 dBTP for 1.5dB steps |
| MP3 <256kbps (lossless) | mp3rgain | -1.0 dBTP | Requires TP ≤ -2.5 dBTP for 1.5dB steps |
| MP3 ≥256kbps (re-encode) | ffmpeg | -0.5 dBTP | High-bitrate codecs have minimal overshoot |
| MP3 <256kbps (re-encode) | ffmpeg | -1.0 dBTP | Lower bitrates cause more codec overshoot |
| AAC ≥256kbps | ffmpeg | -0.5 dBTP | High-bitrate AAC has minimal overshoot |
| AAC <256kbps | ffmpeg | -1.0 dBTP | Lower bitrates cause more codec overshoot |
How It Works
- Scans the current directory for audio files (FLAC, AIFF, WAV, MP3, AAC/M4A)
- Measures LUFS (Integrated Loudness) and True Peak using ffmpeg
- Categorizes files by processing method:
- Green: Lossless files (ffmpeg)
- Yellow: MP3 files with enough headroom for native lossless gain
- Magenta: MP3/AAC files requiring re-encode
- Displays categorized report
- Two-stage confirmation:
- First: "Apply lossless gain adjustment?" (lossless + native MP3)
- Second: "Also process files with re-encoding?" (MP3/AAC requiring re-encode)
- Creates backups and processes files
Example
$ cd ~/Music/DJ-Tracks
$ headroom
╭─────────────────────────────────────╮
│ headroom v1.4.1 │
│ Audio Loudness Analyzer & Gain │
╰─────────────────────────────────────╯
▸ Target directory: /Users/xxx/Music/DJ-Tracks
✓ Found 28 audio files
✓ Analyzed 28 files
● 3 lossless files (ffmpeg, precise gain)
Filename LUFS True Peak Target Gain
track01.flac -13.3 -3.2 dBTP -0.5 dBTP +2.7 dB
track02.aif -14.1 -4.5 dBTP -0.5 dBTP +4.0 dB
track03.wav -12.5 -2.8 dBTP -0.5 dBTP +2.3 dB
● 2 MP3 files (native lossless, 1.5dB steps, target: -2.0 dBTP)
Filename LUFS True Peak Target Gain
track04.mp3 -14.0 -5.5 dBTP -2.0 dBTP +3.0 dB
track05.mp3 -13.5 -6.0 dBTP -2.0 dBTP +3.0 dB
● 2 MP3 files (re-encode required for precise gain)
Filename LUFS True Peak Target Gain
track06.mp3 -12.0 -1.5 dBTP -0.5 dBTP +1.0 dB
track07.mp3 -11.5 -1.2 dBTP -0.5 dBTP +0.7 dB
● 2 AAC/M4A files (re-encode required)
Filename LUFS True Peak Target Gain
track08.m4a -13.0 -2.5 dBTP -0.5 dBTP +2.0 dB
track09.m4a -12.5 -1.8 dBTP -0.5 dBTP +1.3 dB
✓ Report saved: ./headroom_report_20250109_123456.csv
? Apply lossless gain adjustment to 3 lossless + 2 MP3 (lossless gain) files? [y/N] y
ℹ 2 MP3 + 2 AAC/M4A files have headroom but require re-encoding for precise gain.
• Re-encoding causes minor quality loss (inaudible at 256kbps+)
• Original bitrate will be preserved
? Also process these files with re-encoding? [y/N] y
? Create backup before processing? [Y/n] y
✓ Backup directory: ./backup
✓ Done! 9 files processed.
• 3 lossless files (ffmpeg)
• 2 MP3 files (native, lossless)
• 2 MP3 files (re-encoded)
• 2 AAC/M4A files (re-encoded)
Installation
Quick Install
| Platform | Command |
|---|---|
| macOS | brew install M-Igashi/tap/headroom |
| Windows (Scoop) | scoop bucket add headroom https://github.com/M-Igashi/scoop-bucket && scoop install headroom |
| Windows (Binary) | Download from Releases |
| All platforms | cargo install headroom + install ffmpeg |
Prerequisites
headroom requires one external tool:
- ffmpeg: For audio analysis and lossless format processing
Note: As of v1.3.0, mp3rgain is built-in as a library dependency. No separate installation required. v1.4.1 uses mp3rgain 1.4.0.
macOS (Homebrew) — Recommended
brew install M-Igashi/tap/headroom
ffmpeg is installed automatically as a dependency.
Windows (Scoop)
scoop bucket add headroom https://github.com/M-Igashi/scoop-bucket
scoop install headroom
ffmpeg is installed automatically as a dependency.
Cargo (All Platforms)
If you have Rust installed, you can install headroom via cargo:
cargo install headroom
Then install ffmpeg for your platform:
# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt install ffmpeg
# Fedora
sudo dnf install ffmpeg
# Arch
sudo pacman -S ffmpeg
# Windows (winget)
winget install ffmpeg
# Windows (choco)
choco install ffmpeg
Pre-built Binaries
Download pre-built binaries from the Releases page:
| Platform | File |
|---|---|
| macOS (Universal) | headroom-vX.X.X-macos-universal.tar.gz |
| Linux x86_64 | headroom-vX.X.X-linux-x86_64.tar.gz |
| Linux ARM64 | headroom-vX.X.X-linux-aarch64.tar.gz |
| Windows x86_64 | headroom-vX.X.X-windows-x86_64.zip |
Note: You must install ffmpeg separately (see platform-specific commands above).
Build from Source
git clone https://github.com/M-Igashi/headroom.git
cd headroom
cargo build --release
# Binary location:
# - Unix: target/release/headroom
# - Windows: target\release\headroom.exe
Usage
cd ~/Music/DJ-Tracks
headroom
The tool will guide you through:
- Scanning and analyzing all audio files
- Reviewing the categorized report
- Confirming lossless processing
- Optionally enabling MP3/AAC re-encoding
- Creating backups (recommended)
Output
CSV Report
| Filename | Format | Bitrate (kbps) | LUFS | True Peak (dBTP) | Target (dBTP) | Headroom (dB) | Method | Effective Gain (dB) |
|---|---|---|---|---|---|---|---|---|
| track01.flac | Lossless | - | -13.3 | -3.2 | -0.5 | +2.7 | ffmpeg | +2.7 |
| track04.mp3 | MP3 | 320 | -14.0 | -5.5 | -2.0 | +3.5 | mp3rgain | +3.0 |
| track06.mp3 | MP3 | 320 | -12.0 | -1.5 | -0.5 | +1.0 | re-encode | +1.0 |
| track08.m4a | AAC | 256 | -13.0 | -2.5 | -0.5 | +2.0 | re-encode | +2.0 |
Backup Structure
./
├── track01.flac ← Modified
├── track04.mp3 ← Modified
├── track08.m4a ← Modified
├── subfolder/
│ └── track06.mp3 ← Modified
└── backup/ ← Created by headroom
├── track01.flac ← Original
├── track04.mp3 ← Original
├── track08.m4a ← Original
└── subfolder/
└── track06.mp3 ← Original
Important Notes
- Files are overwritten in place after backup — Rekordbox metadata remains linked
- Only files with positive effective gain are shown and processed
- MP3 native lossless requires at least 1.5dB headroom to -2.0 dBTP to be processed
- MP3/AAC re-encoding is opt-in and requires explicit confirmation
- macOS resource fork files (
._*) are automatically ignored
Technical Details
Why 1.5dB Steps for Native MP3 Gain?
The MP3 format stores a "global_gain" value as an 8-bit integer (0-255). When decoding, samples are multiplied by 2^(gain/4):
- +1 to global_gain =
2^(1/4)= +1.5 dB - -1 to global_gain =
2^(-1/4)= -1.5 dB
This is a fundamental limitation of the MP3 format, not a tool limitation. headroom uses the built-in mp3rgain library to directly manipulate this field in each MP3 frame's side information.
Why Bitrate-Aware Ceiling for Native MP3?
With 1.5dB step limitation, the ceiling is calculated based on bitrate to match re-encode targets:
- ≥256kbps: Target -0.5 dBTP, so native lossless requires TP ≤ -2.0 dBTP (allowing at least 1 step)
- <256kbps: Target -1.0 dBTP, so native lossless requires TP ≤ -2.5 dBTP (more conservative)
- Example: 320kbps file at -3.5 dBTP gets 2 steps (+3.0dB) → -0.5 dBTP (optimal)
- Example: 128kbps file at -3.5 dBTP gets 1 step (+1.5dB) → -2.0 dBTP (within -1.0 ceiling)
Why AAC Always Requires Re-encoding
Unlike MP3, AAC doesn't have a lossless gain adjustment mechanism like the global_gain field. The only way to apply gain to AAC files is through re-encoding. However, at high bitrates (≥256kbps), the quality loss is imperceptible.
MP3/AAC Re-encode Quality
When re-encoding is chosen:
- MP3: Uses
libmp3lameencoder with-q:a 0(best VBR quality) - AAC: Prefers
libfdk_aac(highest quality), falls back to built-inaacencoder - Preserves original bitrate
- Only applies volume filter (no other processing)
At 320kbps, the re-encode introduces quantization noise below -90dB—far below audible threshold.
Processing Method Comparison
| Method | Format | Precision | Quality Loss | External Deps | Use Case |
|---|---|---|---|---|---|
| ffmpeg (lossless) | FLAC, AIFF, WAV | Arbitrary | None | ffmpeg | Lossless files |
| mp3rgain (built-in) | MP3 | 1.5dB steps | None | None | MP3 with ≥1.5dB to bitrate ceiling |
| ffmpeg re-encode | MP3 | Arbitrary | Inaudible at ≥256kbps | ffmpeg | MP3 needing precise gain |
| ffmpeg re-encode | AAC/M4A | Arbitrary | Inaudible at ≥256kbps | ffmpeg | AAC files (always) |
License
MIT
Dependencies
~7–18MB
~187K SLoC