From 26cfc8158819791b907aa16c313789907339baef Mon Sep 17 00:00:00 2001 From: junkerderprovinz Date: Sun, 9 Aug 2026 14:14:01 +0200 Subject: [PATCH] fix(ui): fall back to track ReplayGain when album gain is missing Signed-off-by: junkerderprovinz --- ui/src/utils/calculateReplayGain.js | 10 ++++++ ui/src/utils/calculateReplayGain.test.js | 46 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 ui/src/utils/calculateReplayGain.test.js diff --git a/ui/src/utils/calculateReplayGain.js b/ui/src/utils/calculateReplayGain.js index 0ce69fa4b..e73ab5559 100644 --- a/ui/src/utils/calculateReplayGain.js +++ b/ui/src/utils/calculateReplayGain.js @@ -11,6 +11,16 @@ const calculateReplayGain = (preAmp, gain, peak) => { export const calculateGain = (gainInfo, song) => { switch (gainInfo.gainMode) { case 'album': { + // Fall back to track gain when the album gain is missing (singles, or + // tracks without album ReplayGain tags), matching common ReplayGain + // players instead of applying no adjustment at all. + if (song.rgAlbumGain === undefined || song.rgAlbumPeak === undefined) { + return calculateReplayGain( + gainInfo.preAmp, + song.rgTrackGain, + song.rgTrackPeak, + ) + } return calculateReplayGain( gainInfo.preAmp, song.rgAlbumGain, diff --git a/ui/src/utils/calculateReplayGain.test.js b/ui/src/utils/calculateReplayGain.test.js new file mode 100644 index 000000000..dc3e54196 --- /dev/null +++ b/ui/src/utils/calculateReplayGain.test.js @@ -0,0 +1,46 @@ +import { describe, it, expect } from 'vitest' +import { calculateGain } from './calculateReplayGain' + +describe('calculateGain', () => { + const preAmp = 0 + + const albumSong = { + rgAlbumGain: -6, + rgAlbumPeak: 1, + rgTrackGain: -3, + rgTrackPeak: 1, + } + const trackOnlySong = { + rgTrackGain: -3, + rgTrackPeak: 1, + } + const noGainSong = {} + + it('uses album gain in album mode when it is present', () => { + const result = calculateGain({ gainMode: 'album', preAmp }, albumSong) + expect(result).toBeCloseTo(10 ** (-6 / 20)) + }) + + it('falls back to track gain in album mode when the album gain is missing', () => { + const result = calculateGain({ gainMode: 'album', preAmp }, trackOnlySong) + // Without the fallback this returned 1 (no adjustment). It should now use + // the track gain instead. + expect(result).toBeCloseTo(10 ** (-3 / 20)) + expect(result).not.toBe(1) + }) + + it('returns 1 in album mode when neither album nor track gain is present', () => { + const result = calculateGain({ gainMode: 'album', preAmp }, noGainSong) + expect(result).toBe(1) + }) + + it('uses track gain in track mode', () => { + const result = calculateGain({ gainMode: 'track', preAmp }, albumSong) + expect(result).toBeCloseTo(10 ** (-3 / 20)) + }) + + it('returns 1 when gain is disabled', () => { + const result = calculateGain({ gainMode: 'none', preAmp }, albumSong) + expect(result).toBe(1) + }) +})