Single Binary
mp3rgain is built-in as of v1.3.0. Only ffmpeg required as external dependency, and rbsort doesn't even need that. Simple installation.
Rekordbox's Auto Gain doesn't survive USB export, and Rekordbox has never offered compound Key+BPM playlist sort (Serato had it for years — but never exported to CDJs). headroom bakes both into the files themselves.
Rekordbox prep doesn't fully reach the booth. Two software-only features get left behind on the way to the CDJ.
Rekordbox's Auto Gain feature analyzes your tracks and calculates gain adjustments to normalize loudness. It works great with controllers.
But when you export to USB for CDJs, Auto Gain values are ignored.
Harmonic mixing wants a playlist sorted by Camelot Key, then by BPM within each key group. Rekordbox's UI has never offered compound sort: its Sort by Key view is single-column, so BPMs scatter inside each key group.
Serato has had Shift-click multi-column sort for years — but Serato can't export to USB for standalone CDJs. The compound sort never reaches the booth.
Whether it's gain or playlist order — headroom takes the prep work Rekordbox does in software and writes it into something the CDJ will actually read: the audio file itself (for gain), or the playlist itself (for Key+BPM order).
The Loudness Normalizer measures True Peak and bakes safe gain directly into your audio files — the same analysis Rekordbox Auto Gain does, but with a permanent result. rbsort takes a Rekordbox playlist and bakes Camelot Key + BPM order into the playlist itself.
rbsort rewrites playlist order in collection.xml — originals stay intactPillar one: bake gain into your audio files before USB export. headroom picks the optimal method per format and headroom amount, preserving original bitrate and Rekordbox metadata.
Files already at optimal level are automatically skipped.
A common concern is quality loss when re-encoding MP3/AAC. However, for gain adjustment only at high bitrates (≥256 kbps), the degradation is completely inaudible.
All the formats Rekordbox DJs actually use.
| Format | Method | Precision | Quality |
|---|---|---|---|
| FLAC | ffmpeg volume filter | Arbitrary | Lossless |
| AIFF | ffmpeg volume filter | Arbitrary | Lossless |
| WAV | ffmpeg volume filter | Arbitrary | Lossless |
| MP3 | mp3rgain (built-in) | 1.5dB steps | Lossless |
| MP3 | ffmpeg re-encode (opt-in) | Arbitrary | Inaudible at ≥256kbps |
| AAC/M4A | mp3rgain (built-in) | 1.5dB steps | Lossless |
| AAC/M4A | ffmpeg re-encode (opt-in) | Arbitrary | Inaudible at ≥256kbps |
Pillar two: bake Camelot Key + BPM order into the playlist itself. Feed rbsort your exported collection.xml and get back a Sorted (Key+BPM)/ folder containing each playlist re-sorted 1A (lowest BPM) → 12B (highest BPM) for harmonic mixing. Run with --playlist to target one, or omit it to sort every TrackID-referenced playlist in one pass. Export the result to USB and CDJs read it in that exact order — the harmonic flow reaches the deck, not just the laptop.
headroom exists because Rekordbox's Auto Gain doesn't follow your tracks onto the CDJ — the analyzer fixes that by baking gain into the audio files, so the loudness work survives USB export.
rbsort is the same idea applied to playlist order. Rekordbox can't multi-column sort, and even if it could, CDJs play tracks in playlist order, not by software sort. rbsort bakes the Key+BPM order into the playlist itself, so the harmonic-mix prep you do at home shows up on the deck without any reordering at the gig.
headroom rbsort against the exported XML (omit --playlist to sort every TrackID-referenced playlist at once, or pass --playlist "Name" to target one)rekordbox xml tree in the left sidebar — it's a separate tree from your main library, accessed via the sidebar icon column on the far left. The sorted results live in a new folder at rekordbox xml → Playlists → Sorted (Key+BPM)/, each playlist named after its sourceSorted (Key+BPM)/: tracks run 1A (lowest BPM) → 1B → 2A → … → 12B (highest BPM)Sorted (Key+BPM)/ into your main Playlists to use them in your sets — your originals are untouchedDon't see it? The sorted results live only inside the rekordbox xml → Sorted (Key+BPM)/ folder, not in your main Playlists. If you only see the originals, switch sidebar trees.
1A → 1B → 2A → 2B → … → 12A → 12Bcollection.xml is never modified — output goes to a separate file with a new Sorted (Key+BPM)/ folder appendedSorted (Key+BPM)/ and reuse the source playlist names (same pattern as the analyzer's backup/ directory)Rekordbox and the CDJ-3000 / XDJ-1000MK2 can sort a list by Key or BPM — but never both at once. Given the same input playlist, the three sort modes produce different orderings:
| Sort mode | Key order | BPM within key group |
|---|---|---|
| Sort by Key (single column) | ✓ aligned | ✗ playlist registration order |
| Sort by BPM (single column) | ✗ scattered across the wheel | ✓ aligned (but Key grouping is gone) |
rbsort (multi-column: Key → BPM) |
✓ aligned | ✓ ascending |
See docs/rbsort-sort-comparison.md for a 6-track walk-through showing the actual track ordering each mode produces.
What both pillars give you, beyond the headline.
mp3rgain is built-in as of v1.3.0. Only ffmpeg required as external dependency, and rbsort doesn't even need that. Simple installation.
Native lossless gain for AAC/M4A via mp3rgain. Re-encode fallback for precise gain.
Uses the same LUFS/True Peak analysis as Rekordbox. Calculates maximum safe gain to hit the optimal ceiling.
Files are modified in-place. All your cue points, hot cues, beat grids, and tags remain intact.
Original files are backed up before processing. rbsort writes to a separate XML file — your collection.xml is never modified.
Default -0.5 dBTP for every file — the most aggressive value AES TD1008 §7B sanctions for any limiter in the chain. Tunable via --tp-target; legacy bitrate split available via --tp-split-bitrate.
The rbsort subcommand bakes Camelot Key (1A→12B) then BPM ascending into the playlist itself — the compound sort Rekordbox doesn't expose and Serato can't get to USB. Export to USB and CDJs play it in that exact order. Originals untouched.
Bare headroom runs a guided two-stage wizard. Pass paths, globs, or flags (--lossless, --reencode, --backup, --report, --analyze-only) for non-interactive use in pipelines and CI.
The free, open-source DJ loudness normalizer — with features paid tools don't offer.
| Feature | headroom | Paid Alternatives |
|---|---|---|
| Price | Free & Open Source (MIT) | €15+ |
| macOS | ✓ | ✗ Windows only |
| Linux | ✓ | ✗ |
| AIFF Support | ✓ Lossless | ✗ |
| AAC/M4A Support | ✓ Lossless gain | ✗ |
| Lossless MP3 Gain | ✓ global_gain mod | Unknown |
| True Peak Ceiling | AES TD1008 §7B uniform -0.5 dBTP, fully tunable | Basic |
| Rekordbox Metadata | ✓ Preserved | Unknown |
| Automatic Backup | ✓ | ✗ |
| Sort Playlist by Key + BPM | ✓ rbsort (v2.0.0+) |
✗ |
| GUI | ✗ CLI only | ✓ |
headroom is a CLI tool designed for DJs who want maximum control and transparency over their loudness normalization workflow.
Requires ffmpeg. Package managers install it automatically.
brew install M-Igashi/tap/headroom
winget install M-Igashi.headroom
yay -S headroom-bin
cargo install headroom
ffmpeg must be installed separately. Pre-built binaries on GitHub Releases.
Trim-riding and tag-hunting belong in prep, not in the mix. headroom moves both off the deck and into your files.