ReplayGain 2.0 values (gain to -18 LUFS, linear peak) derived from the
stored track and album loudness:
- Web: GET /api/tracks/replay-gain?ids=... (up to 200), a lookup the
player calls for its queue, rather than a field on every TrackRef
surface.
- Android: track_gain/track_peak and album_gain/album_peak on the sync
views, so cached tracks level offline. Storing a measurement logs a
track change, and an album's values moving logs an album change, both
before the write (#2704), so caches pick the gains up.
- OpenSubsonic: replayGain on every song (album, getSong, search3,
starred), as a JSON object and an XML element.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Album-mode normalization plays a whole album at one gain. That gain comes
from album_loudness (migration 0066): BS.1770's gated loudness over every
block on the album, computed by summing the tracks' stored histograms and
gating the sum. No audio is decoded again. Album true peak is the loudest
track's.
- Recomputed by the loudness worker each tick, after the track pass and
whether or not analysis is switched on. ListAlbumsNeedingLoudness lists
albums whose md5 over (present track id, measurement version and time) no
longer matches the stored digest. One comparison covers every way
membership changes (scan retag, duplicate merge, delete, missing and
restored) without hooking each.
- No album value until every present track has a settled measurement, so
an album's gain doesn't shift mid-listen as the rest is measured. Silent
and unreadable tracks count as settled.
- Rows for albums with no present track left are dropped.
- The parser and the merge share trimBins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>