mp3rgain is a modern tool designed for lossless MP3 volume adjustment by modifying the global_gain field in each frame's side information. This approach preserves audio quality while enabling permanent volume changes without re-encoding.
Key Features:
Lossless & Reversible Adjustments: Volume changes are applied directly to the file, allowing for reversible adjustments without any loss of audio quality.
ReplayGain Analysis: Supports track and album gain analysis, ensuring consistent listening levels across tracks or albums.
AAC/M4A Support: Compatible with AAC and M4A files, expanding its utility beyond MP3s.
Cross-Platform Compatibility: Works seamlessly on macOS, Linux, and Windows (including x86_64 and ARM64 architectures).
Command-Line Compatibility: Fully compatible with the original mp3gain command-line interface, providing a familiar workflow for users.
Audience & Benefit:
Ideal for audiophiles, music producers, and anyone requiring precise volume control over their audio files. By eliminating the need for re-encoding, mp3rgain ensures that adjustments are lossless, maintaining the highest possible audio quality while achieving consistent listening levels across tracks or albums.
The software can be installed via winget on Windows for a streamlined experience.
README
mp3rgain
Lossless MP3/AAC volume adjustment - a modern mp3gain / aacgain replacement written in Rust
mp3rgain adjusts MP3 and AAC volume without re-encoding by modifying the global_gain field in each frame. This preserves audio quality while achieving permanent volume changes.
Features
CLI lossless AAC bitstream gain: re-encode-free global_gain rewrite for AAC/M4A — replacing the long-abandoned aacgain, with -u undo (foobar2000's GUI equivalent has no undo path)
Lossless & Reversible: No re-encoding, all changes can be undone (MP3 and AAC)
ReplayGain: Track and album gain analysis for MP3 and AAC/M4A, with standard REPLAYGAIN_* tags written alongside the bitstream change (APEv2, ID3v2 TXXX, or MP4 freeform)
Zero dependencies: Single static binary (no ffmpeg, no mp3gain, no aacgain)
Cross-platform: macOS, Linux, Windows (x86_64 and ARM64)
mp3gain / aacgain compatible: Drop-in replacement with identical CLI
GUI Application: Native desktop app for drag-and-drop workflow
Installation
Windows: download the installer
No terminal needed. The installer registers a Start Menu entry and an uninstaller,
covers both Intel and ARM machines, and needs no administrator rights.
On Windows, winget installs the GUI as a portable binary; use the
installer
above if you want a Start Menu entry and an uninstaller.
Binaries for all platforms are also available from GitHub Releases.
> [!NOTE]
> Windows: Defender occasionally flags mp3rgui.exe as a false positive.
> The GUI is an unsigned, statically linked Rust binary, which sometimes trips
> Microsoft Defender's cloud/ML heuristics. Any such detection is a false positive:
> every release is built from public source by a
> public GitHub Actions workflow, and each release
> ships .sha256 files so you can verify what you downloaded. Detections are
> reported to Microsoft when they appear — the v3.0.0 binaries were analysed and
> confirmed "Not malware". If you hit a detection on a newer release, please
> open an issue so it can be reported.
Quick Start
# Normalize a single track (ReplayGain)
mp3rgain -r song.mp3
# Normalize an album
mp3rgain -a *.mp3
# Manual gain adjustment (+3.0 dB)
mp3rgain -g 2 song.mp3
# Undo changes
mp3rgain -u song.mp3
# Show file info
mp3rgain song.mp3
Migrating from mp3gain?
Already running mp3gain (or aacgain) in a script, Dockerfile, or CI pipeline? mp3rgain is a drop-in replacement — the CLI flags, the TSV output format, and the APEv2 mp3gain_undo tag are all mp3gain-compatible, so existing parsers (e.g. beets) keep working unchanged. For most setups, migration is a one-line substitution:
sed -i 's/\bmp3gain\b/mp3rgain/g' your_script.sh
See docs/migrating-from-mp3gain.md for the full flag equivalence table, Dockerfile/CI substitution patterns, tag interop notes, and the small set of intentional behaviour differences. Bit-level verification lives in docs/compatibility-report.md.
GUI Application
A native GUI application (mp3rgui) is available for users who prefer a graphical interface.
> macOS manual download: If you see "mp3rgui cannot be opened" warning, run:
> bash > xattr -cr /path/to/mp3rgui.app >
> This is not needed when installing via Homebrew.
Command-Line Options
Option
Description
-r
Apply Track gain (ReplayGain)
-a
Apply Album gain (ReplayGain)
--rg2
Use ReplayGain 2.0 analysis (BS.1770, −18 LUFS reference)
--r128
Use EBU R128 analysis (BS.1770, −23 LUFS target)
--true-peak
Measure true peak (BS.1770-4 Annex 2) for REPLAYGAIN_*_PEAK (with --rg2 / --r128; default is sample peak)
-g <i>
Apply gain of i steps (1 step = 1.5 dB)
-d
Modify suggested dB gain by n (mp3gain-compatible; applied with -r / -a)
-u
Undo gain changes
-k
Prevent clipping
-R
Process directories recursively
--skip-errors
Keep album analysis (-a) going past unreadable files
-n
Dry-run mode
-j / --threads
Worker threads for analysis (default: auto, 0=auto, 1=serial)
-o [fmt]
Output format: text, json, tsv (default: tsv if no argument)
Run mp3rgain -h for the full list of options.
ReplayGain analysis runs in parallel by default
(std::thread::available_parallelism() worker threads). Use -j 1 or
MP3RGAIN_THREADS=1 for the legacy serial path. See
docs/perf-parallel.md for the design and
real-corpus benchmark numbers.
Documentation
Migration Guide - Drop-in replacement for mp3gain: flag equivalence, sed/Dockerfile/CI substitution patterns, beets config
Use Cases - Integration examples (beets, headroom, etc.)
Download Stats - Weekly download trends across all platforms
Why mp3rgain?
The original mp3gain has been unmaintained upstream since ~2015 (though distribution maintainers continue to apply security patches). aacgain, its AAC counterpart, has been unmaintained since ~2009 and is effectively unbuildable on modern 64-bit systems. mp3rgain is a modern, memory-safe replacement written in Rust that covers both.
These are all ReplayGain tools, mp3rgain included — it runs a ReplayGain analysis and writes the standard REPLAYGAIN_* tags like any tagger. What separates them is where the correction ends up. rsgain / loudgain / FFmpeg -af replaygain stop at the tags, which non-compliant players ignore; ffmpeg loudnorm re-encodes. The mp3gain lineage — mp3gain, aacgain, and now mp3rgain — writes the tags and bakes the gain into the bitstream, losslessly and reversibly.
AAC/M4A on the CLI is the differentiator. That combination is what has no other maintained CLI implementation: foobar2000 offers an equivalent "Apply ReplayGain to file content" pass for AAC in MP4/MKA, but it is Windows GUI only, has no undo, and is not built for batch, headless, or container workflows. mp3rgain fills the cross-platform, scriptable, reversible niche.
> [!TIP]
> Want the most standards-faithful ReplayGain, on Windows, in a GUI? Use foobar2000.
> It is the closest thing ReplayGain 2.0 has to a reference implementation — a full BS.1770 scanner
> whose numbers other tools get checked against — it tags far more formats than mp3rgain does, and
> it can bake gain into MP3 and AAC bitstreams too. mp3rgain is the better fit when you need a
> command line, a non-Windows host, mp3gain-identical ReplayGain 1.0 values, or an undo path — and
> the two coexist fine, since mp3rgain writes the same standard REPLAYGAIN_* tags foobar2000
> reads — in ID3v2, where it looks for them — with --rg2 deliberately matching its measurement.
mp3rgain implements the ReplayGain 1.0 algorithm (89 dB reference level) by default for full compatibility with the original mp3gain / aacgain — an existing library re-scans to identical values. Modern BS.1770 loudness measurement is available as an opt-in: --rg2 (ReplayGain 2.0, −18 LUFS reference) and --r128 (EBU R128, −23 LUFS target) produce values consistent with foobar2000, loudgain, and ffmpeg loudnorm.
Files scanned with --rg2 / --r128 also carry a REPLAYGAIN_ALGORITHM tag set to ITU-R BS.1770, so a player (or you, years later) can tell which measurement produced the stored values. The default RG1 mode writes no such tag — an absent one means the classic mp3gain measurement, which is what every pre-existing tagged file already implies.
Where the tags go (MP3)
MP3 has two competing metadata containers, and the two tag families mp3rgain writes have different audiences. By default each goes where its readers are:
Tag
Container
Read by
REPLAYGAIN_*
ID3v2 TXXX
Players. ffmpeg — and everything built on it — does not read APEv2 on MP3 at all, and Rockbox only handles APE tags for WavPack/Musepack. foobar2000 writes ReplayGain to ID3v2 and expects it there.
MP3GAIN_UNDO, MP3GAIN_MINMAX
APEv2
Nothing but the mp3gain lineage, which looks in APEv2. Keeping them there is what makes -u work on a library mp3gain already processed.
Two flags override the split when you want everything in one place:
mp3rgain -r *.mp3 # default: ReplayGain in ID3v2, undo in APEv2
mp3rgain -r -s a *.mp3 # everything in APEv2 — byte-for-byte mp3gain
mp3rgain -r -s i *.mp3 # everything in ID3v2
MP3GAIN_ALBUM_MINMAX is APEv2-only in every mode. AAC/M4A is unaffected — it always uses MP4 freeform atoms.
-s c reads both containers and merges them, and -u finds the undo tag in either, so files tagged by mp3gain or by an earlier -s i run still inspect and roll back correctly.
> Changed in 3.2.0. Earlier versions put everything in APEv2. If you depend on the old layout, -s a restores it exactly. Re-running the default over an APEv2-tagged file moves the ReplayGain values to ID3v2 and clears the APEv2 copies so the two cannot disagree.
Use mp3rgain in Docker / CI
Official multi-arch images (linux/amd64, linux/arm64) are published to GHCR:
ghcr.io/m-igashi/mp3rgain:latest
ghcr.io/m-igashi/mp3rgain:v3 # latest 3.x
ghcr.io/m-igashi/mp3rgain:v3.1.0 # exact version
The image is built FROM scratch with a fully static (musl) binary — no
shell, no runtime deps, ~2 MB. Drop-in replacement for mp3gain in
containerized batch / cron pipelines (e.g. Plex maintenance windows):
# Normalize a music library by mounting it into the container
docker run --rm \
-v /path/to/music:/music \
ghcr.io/m-igashi/mp3rgain:latest -r -R /music
# Run as your own user so written files keep correct ownership
docker run --rm \
--user "$(id -u):$(id -g)" \
-v /path/to/music:/music \
ghcr.io/m-igashi/mp3rgain:latest -r -R /music
Because the entrypoint is the binary itself, all mp3rgain flags work
exactly the same as the host CLI (-r, -a, -R, -k, -u, …).
Library Usage
use mp3rgain::{apply_gain, analyze};
use std::path::Path;
let frames = apply_gain(Path::new("song.mp3"), 2)?; // +3.0 dB
let info = analyze(Path::new("song.mp3"))?;