mp3gain alternatives: mp3rgain vs mp3gain, aacgain, rsgain, and ffmpeg
Updated · mp3rgain v3.16.2
To replace mp3gain or aacgain with something maintained that works the same lossless way, use mp3rgain: it takes the same flags, covers MP3 and AAC, and can undo. If every player you use reads ReplayGain tags, or you have FLAC or Opus, use rsgain. On a Windows desktop, foobar2000 is the reference ReplayGain scanner. ffmpeg loudnorm hits an exact loudness target but re-encodes.
Nearly every tool here is a ReplayGain tool, and they all measure loudness the same way in principle. What separates them is where the correction ends up: in a tag the player reads, in the bitstream itself, or in re-encoded samples. This page starts there, then places each tool, mp3rgain included, on that map.
One measurement, three destinations
- Write ReplayGain tags. Measure loudness, store the result as metadata,
and let the player apply it. Nothing about the audio changes. rsgain, loudgain, foobar2000,
and
ffmpeg -af replaygainall do this. - Re-encode the audio. Decode, apply gain to the samples, encode again.
Works everywhere, at the cost of a generation of lossy quality on every pass.
ffmpeg loudnormis the usual example. - Rewrite the gain field inside the bitstream. MP3 and AAC frames carry a
global_gainvalue that scales decoder output. Change it and the volume changes permanently, for every player, without decoding a single sample. mp3gain, aacgain, foobar2000, and mp3rgain do this.
1 and 3 are not rival camps. mp3gain, aacgain, and mp3rgain do both: they
run a ReplayGain analysis, bake the result into the bitstream, and write standard
REPLAYGAIN_TRACK_GAIN / REPLAYGAIN_ALBUM_GAIN tags describing the
residual, so a ReplayGain-aware player and a dumb one arrive at the same loudness.
foobar2000 covers both routes too. "Tagger versus gain tool" is the wrong axis. The real
question is whether a tool can touch the bitstream at all, and whether it can put it back.
mp3rgain can also stop at tags: --tags-only writes them and leaves the audio
alone.
Where those tags land, on MP3
"Writes ReplayGain tags" hides a detail that decides whether your player ever sees them. MP3 has two competing metadata containers, and the classic lineage picked the one modern players do not read. APEv2 ReplayGain on MP3 is not merely unpopular; it is close to unreadable:
- ffmpeg does not read APEv2 on MP3 at all. A well-formed APEv2 tag
(correct
APETAGEXheader and footer, read back happily by mp3rgain itself) yields no tags whatsoever fromffprobe -show_entries format_tags. The same file written as ID3v2 shows every value. That covers mpv, VLC, Kodi, and everything else built on libavformat. - Rockbox handles APE tags only for WavPack and Musepack, not for MP3.
- foobar2000 writes ReplayGain to ID3v2 and expects it there.
So the two tag families mp3rgain writes have genuinely different audiences, and since 3.2.0 each one goes where its readers are:
| Tag | Container | Read by |
|---|---|---|
REPLAYGAIN_* | ID3v2 TXXX | Players. Also where foobar2000, rsgain, and loudgain put theirs |
MP3GAIN_UNDO, MP3GAIN_MINMAX | APEv2 | Nothing but the mp3gain lineage, which is exactly why -u still rolls back a library mp3gain 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
Reading is forgiving in both directions: -s c merges both containers and
-u finds the undo tag in either, so files tagged by mp3gain, or by an older
mp3rgain, still inspect and roll back correctly. Re-running the default over an APEv2-tagged
file moves the ReplayGain values to ID3v2 and clears the APEv2 copies, so the two can never
drift apart. MP3GAIN_ALBUM_MINMAX is only ever written to APEv2, and not at all
with -s i.
None of this affects AAC in MP4, which always uses iTunes freeform atoms that foobar2000
reads, or raw ADTS .aac, which always uses ID3v2. Nor does it affect the bitstream
rewrite itself: the volume change is in the frames either way, so a ReplayGain-blind player is
right whichever container won.
Upgrading from 3.1.x or earlier? Those versions put everything in APEv2.
Nothing breaks: your files keep playing at the corrected volume, because that correction is
baked into the frames, not the tags. Re-run mp3rgain to move the ReplayGain values where
players can see them, or pass -s a to keep the old layout exactly.
Which destination do you want? If every device you use honours ReplayGain tags, stop at approach 1: it is reversible by definition and stores track and album values side by side. If some do not (car stereos, older hardware players, DJ gear, cheap DAPs, many phone apps), the tags are silently ignored and approach 3 is the only lossless answer.
Where each tool sits
| Tool | Status | ReplayGain | Gain applied by | Formats | Undo | Platform |
|---|---|---|---|---|---|---|
| mp3rgain | Active | RG1 default, --rg2 / --r128 opt-in; writes tags | Bitstream gain field, or tags only with --tags-only | MP3, AAC/M4A, raw ADTS .aac | Yes | macOS, Linux, Windows (CLI + GUI) |
| mp3gain | No release since 1.6.2 | RG1 only; writes tags | Bitstream gain field | MP3 | Yes | Windows binary (unpatched); patched distro packages |
| aacgain | Last release 2019, last commit 2022 | RG1 only; writes tags | Bitstream gain field | MP3, AAC/M4A | Yes | Windows binary; build from source elsewhere |
| foobar2000 | Active | RG2 / R128; the reference implementation | Tags, or bitstream gain field | Tags for most formats; bitstream for MP3 and AAC in MP4/MKA | Tags yes, baked-in gain no | Windows GUI only |
| rsgain | Active | RG2 / R128; writes tags | Player, from the tags | Many | N/A (tags only) | Cross-platform CLI |
| loudgain | Superseded by rsgain | RG2 / R128; writes tags | Player, from the tags | Many | N/A (tags only) | Linux, macOS |
| ffmpeg loudnorm | Active | No: an R128 normalizer, not a tagger | Re-encoded samples | Everything | No (lossy) | Cross-platform CLI |
Two rows deserve a footnote. foobar2000 is not just another entry here: the
Hydrogenaudio community around it is where the ReplayGain 2.0 specification was worked out, and
its scanner is the practical reference other implementations get checked against. If you want
textbook-correct ReplayGain and you are on Windows, that is the answer, and mp3rgain's
--rg2 mode exists to agree with it rather than to compete with it. And the three
bitstream tools at the top are also taggers: the classic mp3gain lineage has always
written ReplayGain tags next to the gain it bakes in.
Why the classic tools ran out
What stalled was never ReplayGain itself; foobar2000 and rsgain carry the standard forward in better shape than ever. What lapsed was the lineage that pairs a ReplayGain analysis with a lossless bitstream rewrite on the command line. mp3gain has made no release since 1.6.2, so that release and its Windows binaries are unpatched; Debian, Ubuntu, and some other distributions ship patched builds, and upstream master carries APE tag fixes (2025-11) without a new release. aacgain's last release was 2.0.0 in December 2019 and its last commit was in July 2022, with no security fixes applied (the CVE list is on Is mp3gain safe?). aacgain is the harder loss: it is the tool people reach for when a library contains M4A files. That left two practical options for lossless AAC gain: run a binary that gets no security fixes, or sit at a Windows desktop with foobar2000, which does the job well but only from the GUI and without an undo path.
mp3rgain covers the case neither one does: one Rust binary for both MP3 and AAC, scriptable and headless, with undo on both. That is what makes it usable in a container or a cron job where a mistake needs to be reversible. If you are at a Windows desktop, foobar2000 remains an excellent answer.
Reference levels
A recurring source of confusion when comparing tools is that they normalise to different targets, so identical inputs legitimately produce different numbers:
| Standard | Reference | Measured by | mp3rgain flag |
|---|---|---|---|
| ReplayGain 1.0 | 89 dB | mp3gain, aacgain, mp3rgain (default) | default |
| ReplayGain 2.0 | −18 LUFS | foobar2000 (reference), rsgain, loudgain | --rg2 |
| EBU R128 | −23 LUFS | ffmpeg ebur128, broadcast tooling | --r128 |
mp3rgain defaults to ReplayGain 1.0 so re-scanning an mp3gain-processed library lands on
the same gain steps instead of shifting everything. --rg2 and --r128
switch to ITU-R BS.1770 gated measurement when you would rather match the modern taggers; the
target is foobar2000's numbers, not a separate dialect of them. In those modes mp3rgain also
writes a REPLAYGAIN_ALGORITHM tag, so a library scanned in mixed modes stays
legible.
Peak values on AAC
The other place identical inputs legitimately produce different numbers. On an AAC file, mp3rgain can report a noticeably higher peak than rsgain or foobar2000 while the gain values agree to 0.01 dB. Neither tool is wrong; they are not measuring the same signal.
Lossy AAC decodes to samples that can exceed full scale, and some encoders leave isolated bursts that decode well above 1.0. Decoders disagree about what to do with them. symphonia (which mp3rgain uses) and ffmpeg's native decoder pass them through; Apple's AudioToolbox decoder hard-limits at exactly 1.0. mp3rgain reports the peak of the decoded signal as it is, so a tool measuring a clamped decode necessarily reports less.
One track of a ffmpeg -c:a aac -b:a 256k encode, measured every way:
| Measurement | Value | dBFS |
|---|---|---|
| mp3rgain sample peak | 1.790314 | +5.06 |
| ffmpeg's decoder, same frame | 1.790310 | +5.06 |
mp3rgain true peak (--true-peak) | 2.287768 | +7.19 |
ffmpeg ebur128=peak=true | (7.3 print) | +7.30 |
| ideal band-limited interpolation | 2.310848 | +7.27 |
| the same, after clamping to [−1, 1] | 1.321509 | +2.42 |
rsgain -t | 1.307024 | +2.33 |
mp3rgain lands 0.09 dB under the exact unclamped answer and rsgain 0.10 dB under the exact clamped one: the residual a 49-tap 4× oversampling filter leaves in both cases. The two tools agree with their own inputs to the same precision.
mp3rgain does not clamp because the peak should describe the file rather than whichever decoder the listener happens to use, and float playback paths (CoreAudio, WASAPI shared mode, PipeWire, most software players) really do reach the DAC with those samples. Over-reporting costs a little unnecessary attenuation; under-reporting clips.
In practice it rarely changes anything: applying each track's own gain to the unclamped peak
on the album this was reported against gives a worst case of 0.84, so no player attenuates
further either way. It matters only on a quiet recording carrying the same kind of burst, where
peak-based clipping prevention would cap the gain differently. If you want the bursts gone at
source, they come from the encoder: re-encoding with Apple's
(ffmpeg -c:a aac_at) dropped that track from 1.790314 to 1.276827. The full
investigation is in
issue #350.
Migrating from mp3gain or aacgain
The CLI flags, the TSV output layout, and the APEv2 MP3GAIN_UNDO tag are all
mp3gain-compatible. For most setups migration is a single substitution:
sed -i 's/\bmp3gain\b/mp3rgain/g' your_script.sh
Undo tags written by mp3gain remain valid, so a library that mp3gain already processed can
be rolled back with mp3rgain -u. A few things differ on purpose:
- Stored tags. mp3gain applies from stored tags unless you pass
-s r; mp3rgain re-analyses unless you pass-s R(v3.4+), which applies from stored tags and rescans only files whose tags are missing. - A file listed twice is processed once (v3.10+); mp3gain applies it once per listing.
- Read-only files are refused by both tools (mp3rgain since v3.11). The
exception is
-s d: mp3gain reports success on a read-only file and leaves the tags in place, while mp3rgain reports the refusal. - Tag layout. On MP3,
REPLAYGAIN_*goes to ID3v2 by default;-s akeeps mp3gain's all-APEv2 layout. - AAC undo uses mp3rgain's own
mp3rgain_undoatom.
The full flag-equivalence table and Dockerfile substitution patterns are in the migration guide, and the bit-level verification against the original mp3gain is in the compatibility report.
When not to use mp3rgain
An honest boundary is more useful than a feature list:
- Your whole playback chain honours ReplayGain tags. Use rsgain, which covers far more formats. Tags are non-destructive and carry track and album values side by side. (For MP3 and AAC,
mp3rgain --tags-onlydoes the same.) - You want the most standards-faithful ReplayGain, and you are on Windows. Use foobar2000. It is the closest thing ReplayGain 2.0 has to a reference implementation: a full BS.1770 scanner, correct tags across far more formats than mp3rgain handles, and an "apply to file content" pass that bakes gain into MP3 and AAC bitstreams when you need that. Reach for mp3rgain instead when you need a command line, a non-Windows host, or an undo path.
- You need FLAC, Ogg (Vorbis, Opus), or WAV. mp3rgain does not read them. Tag-based tools are the answer.
- You are preparing a DJ library for CDJs. mp3rgain aims at a ReplayGain listening level and covers MP3 and AAC only. Bake'n Deck, by the same author, uses mp3rgain for those two, adds exact gain for FLAC, AIFF, WAV, and ALAC, and brings every track to one true peak ceiling (gain only, no limiter) with rekordbox cues and beatgrids kept linked. Why rekordbox Auto Gain does not reach the CDJ.
- You are producing a delivery master. Broadcast and streaming delivery usually wants a measured, documented loudness pass in a DAW or with
ffmpeg loudnorm, not a gain-field rewrite. - You want playback to switch between per-track and per-album loudness. mp3rgain writes both tag sets, but the gain baked into the bitstream is a single choice made at apply time; only a tag-driven player can flip between the two afterwards (which
--tags-onlyallows, at the cost of baking nothing in).