From 31268ad7cd76cf4ceef4a9c6e2fb3ba7d0eea4be Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 16 Oct 2020 18:18:15 +0200 Subject: [PATCH] decoder/opus: fix track/album ReplayGain fallback Fixes regression by commit 23d5a2b8620cea69958d087fc7e13fe1e5adb83d - that commit always pretended that any Opus file has both track and album gain, and thus disabled the fallback to the other if one is not set. This patch changes the logic to only submit ReplayGain if at least one value is set, and apply the offset only to that value. If none is available, then the new check in HandleAudio() will submit only the output gain. Closes https://github.com/MusicPlayerDaemon/MPD/issues/977 --- NEWS | 1 + src/decoder/plugins/OpusDecoderPlugin.cxx | 13 ++++++++++--- src/decoder/plugins/OpusTags.cxx | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index dae8a13eb..07e13ff13 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.22.1 (not yet released) * decoder - opus: apply the OpusHead output gain even if there is no EBU R128 tag + - opus: fix track/album ReplayGain fallback * output - alsa: don't deadlock when the ALSA driver is buggy - jack, pulse: reduce the delay when stopping or pausing playback diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx index e3022d8fc..0343e201c 100644 --- a/src/decoder/plugins/OpusDecoderPlugin.cxx +++ b/src/decoder/plugins/OpusDecoderPlugin.cxx @@ -268,7 +268,6 @@ MPDOpusDecoder::HandleTags(const ogg_packet &packet) { ReplayGainInfo rgi; rgi.Clear(); - rgi.track.gain = rgi.album.gain = EbuR128ToReplayGain(output_gain); TagBuilder tag_builder; AddTagHandler h(tag_builder); @@ -276,8 +275,16 @@ MPDOpusDecoder::HandleTags(const ogg_packet &packet) if (!ScanOpusTags(packet.packet, packet.bytes, &rgi, h)) return; - client.SubmitReplayGain(&rgi); - submitted_replay_gain = true; + if (rgi.IsDefined()) { + /* submit all valid EBU R128 values with output_gain + applied */ + if (rgi.track.IsDefined()) + rgi.track.gain += EbuR128ToReplayGain(output_gain); + if (rgi.album.IsDefined()) + rgi.album.gain += EbuR128ToReplayGain(output_gain); + client.SubmitReplayGain(&rgi); + submitted_replay_gain = true; + } if (!tag_builder.empty()) { Tag tag = tag_builder.Commit(); diff --git a/src/decoder/plugins/OpusTags.cxx b/src/decoder/plugins/OpusTags.cxx index c78586065..ee1d0cb22 100644 --- a/src/decoder/plugins/OpusTags.cxx +++ b/src/decoder/plugins/OpusTags.cxx @@ -61,7 +61,7 @@ ScanOneOpusTag(StringView name, StringView value, const char *endptr; const auto l = ParseInt64(value, &endptr, 10); if (endptr > value.begin() && endptr == value.end()) - rgi->track.gain += float(l) / 256.0f; + rgi->track.gain = float(l) / 256.0f; } else if (rgi != nullptr && name.EqualsIgnoreCase("R128_ALBUM_GAIN")) { /* R128_ALBUM_GAIN is a Q7.8 fixed point number in @@ -70,7 +70,7 @@ ScanOneOpusTag(StringView name, StringView value, const char *endptr; const auto l = ParseInt64(value, &endptr, 10); if (endptr > value.begin() && endptr == value.end()) - rgi->album.gain += float(l) / 256.0f; + rgi->album.gain = float(l) / 256.0f; } handler.OnPair(name, value);