From a2b85f7e6b6052f1797c0c4d05fd2d6533bba2fc Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 26 Apr 2020 14:57:33 +0200 Subject: [PATCH] ReplayGain: added a dedicated preamp gain for tracks that do not have RG info. ref #38 --- approot/messages.xml | 3 ++- approot/settings.xml | 14 +++++++++++++- src/lms/ui/MediaPlayer.cpp | 2 ++ src/lms/ui/MediaPlayer.hpp | 5 +++-- src/lms/ui/PlayQueueView.cpp | 8 ++++++-- src/lms/ui/SettingsView.cpp | 22 ++++++++++++++++++++-- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/approot/messages.xml b/approot/messages.xml index 580032ec..e6746547 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -169,7 +169,8 @@ Auto Track Album -Replay gain preAmp +ReplayGain preamp +ReplayGain preamp (if no info) Artist list mode All artists Album artists diff --git a/approot/settings.xml b/approot/settings.xml index 6d8e2409..24bd864a 100644 --- a/approot/settings.xml +++ b/approot/settings.xml @@ -5,7 +5,7 @@
-
+
${tr:Lms.Settings.appearance}
@@ -74,6 +74,18 @@ ${replaygain-preamp-info class="help-block"}
+
+ +
+
+ ${replaygain-preamp-no-rg-info} + dB +
+ ${replaygain-preamp-no-rg-info-info class="help-block"} +
+
${} ${tr:Lms.Settings.subsonic-api} diff --git a/src/lms/ui/MediaPlayer.cpp b/src/lms/ui/MediaPlayer.cpp index 632d025d..b61c7236 100644 --- a/src/lms/ui/MediaPlayer.cpp +++ b/src/lms/ui/MediaPlayer.cpp @@ -59,6 +59,7 @@ static std::string settingsToJSString(const MediaPlayer::Settings& settings) Json::Object replayGain; replayGain["mode"] = static_cast(settings.replayGain.mode); replayGain["preAmpGain"] = settings.replayGain.preAmpGain; + replayGain["preAmpGainIfNoInfo"] = settings.replayGain.preAmpGainIfNoInfo; res["replayGain"] = std::move(replayGain); } @@ -180,6 +181,7 @@ static MediaPlayer::Settings settingsfromJSString(const std::string& strSettings const Json::Object replayGain {replayGainValue}; settings.replayGain.mode = replayGainModeFromString(replayGain.get("mode").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultMode); settings.replayGain.preAmpGain = replayGainPreAmpGainFromString(replayGain.get("preAmpGain").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultPreAmpGain); + settings.replayGain.preAmpGainIfNoInfo = replayGainPreAmpGainFromString(replayGain.get("preAmpGainIfNoInfo").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultPreAmpGain); } } diff --git a/src/lms/ui/MediaPlayer.hpp b/src/lms/ui/MediaPlayer.hpp index 1b78e192..58f7b432 100644 --- a/src/lms/ui/MediaPlayer.hpp +++ b/src/lms/ui/MediaPlayer.hpp @@ -73,8 +73,9 @@ class MediaPlayer : public Wt::WTemplate static inline constexpr Gain minPreAmpGain {-15}; static inline constexpr Gain maxPreAmpGain {15}; - Mode mode; - Gain preAmpGain; + Mode mode {defaultMode}; + Gain preAmpGain {defaultPreAmpGain}; + Gain preAmpGainIfNoInfo {defaultPreAmpGain}; }; Transcode transcode; diff --git a/src/lms/ui/PlayQueueView.cpp b/src/lms/ui/PlayQueueView.cpp index 222d5299..b634429d 100644 --- a/src/lms/ui/PlayQueueView.cpp +++ b/src/lms/ui/PlayQueueView.cpp @@ -453,7 +453,7 @@ PlayQueue::getReplayGain(std::size_t pos, const Database::Track::pointer& track) switch (settings->replayGain.mode) { case MediaPlayer::Settings::ReplayGain::Mode::None: - break; + return std::nullopt; case MediaPlayer::Settings::ReplayGain::Mode::Track: gain = track->getTrackReplayGain(); @@ -461,6 +461,8 @@ PlayQueue::getReplayGain(std::size_t pos, const Database::Track::pointer& track) case MediaPlayer::Settings::ReplayGain::Mode::Release: gain = track->getReleaseReplayGain(); + if (!gain) + gain = track->getTrackReplayGain(); break; case MediaPlayer::Settings::ReplayGain::Mode::Auto: @@ -476,6 +478,8 @@ PlayQueue::getReplayGain(std::size_t pos, const Database::Track::pointer& track) (nextTrack && nextTrack->getRelease() && nextTrack->getRelease() == track->getRelease())) { gain = track->getReleaseReplayGain(); + if (!gain) + gain = track->getTrackReplayGain(); } else { @@ -488,7 +492,7 @@ PlayQueue::getReplayGain(std::size_t pos, const Database::Track::pointer& track) if (gain) return *gain + settings->replayGain.preAmpGain; - return std::nullopt; + return settings->replayGain.preAmpGainIfNoInfo; } } // namespace UserInterface diff --git a/src/lms/ui/SettingsView.cpp b/src/lms/ui/SettingsView.cpp index a06db8b8..92a6aa31 100644 --- a/src/lms/ui/SettingsView.cpp +++ b/src/lms/ui/SettingsView.cpp @@ -55,6 +55,7 @@ class SettingsModel : public Wt::WFormModel static inline const Field TranscodeBitrateField {"transcode-bitrate"}; static inline const Field ReplayGainModeField {"replaygain-mode"}; static inline const Field ReplayGainPreAmpGainField {"replaygain-preamp"}; + static inline const Field ReplayGainPreAmpGainIfNoInfoField {"replaygain-preamp-no-rg-info"}; static inline const Field SubsonicArtistListModeField {"subsonic-artist-list-mode"}; static inline const Field SubsonicTranscodeEnableField {"subsonic-transcode-enable"}; static inline const Field SubsonicTranscodeFormatField {"subsonic-transcode-format"}; @@ -77,6 +78,7 @@ class SettingsModel : public Wt::WFormModel addField(TranscodeFormatField); addField(ReplayGainModeField); addField(ReplayGainPreAmpGainField); + addField(ReplayGainPreAmpGainIfNoInfoField); addField(SubsonicTranscodeEnableField); addField(SubsonicTranscodeBitrateField); addField(SubsonicTranscodeFormatField); @@ -91,11 +93,16 @@ class SettingsModel : public Wt::WFormModel setValidator(TranscodeBitrateField, createMandatoryValidator()); setValidator(TranscodeFormatField, createMandatoryValidator()); setValidator(ReplayGainModeField, createMandatoryValidator()); + + auto createPreAmpValidator = [] { auto preampGainValidator {std::make_unique()}; preampGainValidator->setRange(MediaPlayer::Settings::ReplayGain::minPreAmpGain, MediaPlayer::Settings::ReplayGain::maxPreAmpGain); - setValidator(ReplayGainPreAmpGainField, std::move(preampGainValidator)); - } + return preampGainValidator; + }; + + setValidator(ReplayGainPreAmpGainField, createPreAmpValidator()); + setValidator(ReplayGainPreAmpGainIfNoInfoField, createPreAmpValidator()); setValidator(SubsonicTranscodeBitrateField, createMandatoryValidator()); setValidator(SubsonicTranscodeFormatField, createMandatoryValidator()); @@ -147,6 +154,7 @@ class SettingsModel : public Wt::WFormModel settings.replayGain.mode = _replayGainModeModel->getValue(*replayGainModeRow); settings.replayGain.preAmpGain = Wt::asNumber(value(ReplayGainPreAmpGainField)); + settings.replayGain.preAmpGainIfNoInfo = Wt::asNumber(value(ReplayGainPreAmpGainIfNoInfoField)); LmsApp->getMediaPlayer()->setSettings(settings); } @@ -202,6 +210,7 @@ class SettingsModel : public Wt::WFormModel setValue(ReplayGainModeField, _replayGainModeModel->getString(*replayGainModeRow)); setValue(ReplayGainPreAmpGainField, settings.replayGain.preAmpGain); + setValue(ReplayGainPreAmpGainIfNoInfoField, settings.replayGain.preAmpGainIfNoInfo); } setValue(SubsonicTranscodeEnableField, LmsApp->getUser()->getSubsonicTranscodeEnable()); @@ -434,15 +443,24 @@ SettingsView::refreshView() replayGainPreampGain->setRange(MediaPlayer::Settings::ReplayGain::minPreAmpGain, MediaPlayer::Settings::ReplayGain::maxPreAmpGain); t->setFormWidget(SettingsModel::ReplayGainPreAmpGainField, std::move(replayGainPreampGain)); + // Replay gain preampGain if no info + auto replayGainPreampGainIfNoInfo {std::make_unique()}; + replayGainPreampGainIfNoInfo->setRange(MediaPlayer::Settings::ReplayGain::minPreAmpGain, MediaPlayer::Settings::ReplayGain::maxPreAmpGain); + t->setFormWidget(SettingsModel::ReplayGainPreAmpGainIfNoInfoField, std::move(replayGainPreampGainIfNoInfo)); + replayGainModeRaw->activated().connect([=](int row) { const bool enable {model->getReplayGainModeModel()->getValue(row) != MediaPlayer::Settings::ReplayGain::Mode::None}; model->setReadOnly(SettingsModel::SettingsModel::ReplayGainPreAmpGainField, !enable); + model->setReadOnly(SettingsModel::SettingsModel::ReplayGainPreAmpGainIfNoInfoField, !enable); t->updateModel(model.get()); t->updateView(model.get()); }); if (LmsApp->getMediaPlayer()->getSettings()->replayGain.mode == MediaPlayer::Settings::ReplayGain::Mode::None) + { model->setReadOnly(SettingsModel::SettingsModel::ReplayGainPreAmpGainField, true); + model->setReadOnly(SettingsModel::SettingsModel::ReplayGainPreAmpGainIfNoInfoField, true); + } } // Subsonic