* Fix OpenSubsonic ReplayGain loudness calculation
The OpenSubsonic provider was passing raw ReplayGain gain values
(in dB) directly to set_loudness(), but set_loudness() expects
integrated loudness values (in LUFS).
This caused tracks with ReplayGain tags to show incorrect loudness
values when accessed via OpenSubsonic/Navidrome. For example, a
quiet track with +0.39 dB gain was being stored as 0.39 LUFS
instead of -18.39 LUFS, resulting in massive gain reduction
(-17.39 dB) instead of a small boost.
Fixed by converting ReplayGain values to loudness before storing:
Loudness (LUFS) = -18 - Gain (dB)
This matches the ReplayGain 2.0 specification and how the
filesystem provider handles ReplayGain tags.
Only affects users connecting to Navidrome/Subsonic servers.
Users with local filesystem music were not affected.
* Remove unnecessary comment
---------
Co-authored-by: Claude <noreply@anthropic.com>
return await asyncio.to_thread(call, *args, **kwargs)
def _set_loudness(self, item: SonicItem) -> None:
- if item.replay_gain and item.replay_gain.track_gain:
+ if item.replay_gain and item.replay_gain.track_gain is not None:
+ # Convert ReplayGain values (gain in dB) to integrated loudness (LUFS)
+ track_loudness = -18 - item.replay_gain.track_gain
+ album_loudness = (
+ -18 - item.replay_gain.album_gain
+ if item.replay_gain.album_gain is not None
+ else None
+ )
self.mass.create_task(
self.mass.music.set_loudness(
item.id,
self.instance_id,
- item.replay_gain.track_gain,
- item.replay_gain.album_gain,
+ track_loudness,
+ album_loudness,
)
)