diff --git a/src/libs/subsonic/CMakeLists.txt b/src/libs/subsonic/CMakeLists.txt index cd6f55a8..3756e8ea 100644 --- a/src/libs/subsonic/CMakeLists.txt +++ b/src/libs/subsonic/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(lmssubsonic SHARED impl/responses/DiscTitle.cpp impl/responses/Genre.cpp impl/responses/Playlist.cpp + impl/responses/ReplayGain.cpp impl/responses/Song.cpp impl/responses/User.cpp impl/ProtocolVersion.cpp diff --git a/src/libs/subsonic/impl/SubsonicResponse.cpp b/src/libs/subsonic/impl/SubsonicResponse.cpp index f2f00252..51101396 100644 --- a/src/libs/subsonic/impl/SubsonicResponse.cpp +++ b/src/libs/subsonic/impl/SubsonicResponse.cpp @@ -195,6 +195,8 @@ namespace API::Subsonic res.put("." + itAttribute.first, std::get(itAttribute.second)); else if (std::holds_alternative(itAttribute.second)) res.put("." + itAttribute.first, std::get(itAttribute.second)); + else if (std::holds_alternative(itAttribute.second)) + res.put("." + itAttribute.first, std::get(itAttribute.second)); else if (std::holds_alternative(itAttribute.second)) res.put("." + itAttribute.first, std::get(itAttribute.second)); } @@ -248,6 +250,8 @@ namespace API::Subsonic return Json::Value {std::get(value)}; else if (std::holds_alternative(value)) return Json::Value {std::get(value)}; + else if (std::holds_alternative(value)) + return Json::Value{ std::get(value) }; else if (std::holds_alternative(value)) return Json::Value {std::get(value)}; diff --git a/src/libs/subsonic/impl/SubsonicResponse.hpp b/src/libs/subsonic/impl/SubsonicResponse.hpp index c5f13aae..395df598 100644 --- a/src/libs/subsonic/impl/SubsonicResponse.hpp +++ b/src/libs/subsonic/impl/SubsonicResponse.hpp @@ -198,8 +198,12 @@ namespace API::Subsonic { if constexpr (std::is_same::value) _attributes[std::string{ key }] = value; - else + else if constexpr (std::is_floating_point::value) + _attributes[std::string{ key }] = static_cast(value); + else if constexpr (std::is_integral::value) _attributes[std::string{ key }] = static_cast(value); + else + static_assert("Unhandled type"); } // A Node has either a single value or an array of values or some children @@ -218,7 +222,7 @@ namespace API::Subsonic void setVersionAttribute(ProtocolVersion version); friend class Response; - using ValueType = std::variant; + using ValueType = std::variant; std::map _attributes; std::optional _value; std::map> _children; diff --git a/src/libs/subsonic/impl/responses/ReplayGain.cpp b/src/libs/subsonic/impl/responses/ReplayGain.cpp new file mode 100644 index 00000000..e022a3d8 --- /dev/null +++ b/src/libs/subsonic/impl/responses/ReplayGain.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Emeric Poupon + * + * This file is part of LMS. + * + * LMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LMS. If not, see . + */ + +#include "responses/ReplayGain.hpp" + +#include "services/database/Track.hpp" + +namespace API::Subsonic +{ + Response::Node createReplayGainNode(const Database::ObjectPtr& track) + { + Response::Node replayGainNode; + + if (const auto trackReplayGain{ track->getTrackReplayGain() }) + replayGainNode.setAttribute("trackGain", *trackReplayGain); + + if (const auto releaseReplayGain{ track->getReleaseReplayGain() }) + replayGainNode.setAttribute("albumGain", *releaseReplayGain); + + return replayGainNode; + } +} \ No newline at end of file diff --git a/src/libs/subsonic/impl/responses/ReplayGain.hpp b/src/libs/subsonic/impl/responses/ReplayGain.hpp new file mode 100644 index 00000000..9d5db182 --- /dev/null +++ b/src/libs/subsonic/impl/responses/ReplayGain.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Emeric Poupon + * + * This file is part of LMS. + * + * LMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LMS. If not, see . + */ + +#pragma once + +#include "services/database/Object.hpp" +#include "SubsonicResponse.hpp" + +namespace Database +{ + class Track; +} + +namespace API::Subsonic +{ + Response::Node createReplayGainNode(const Database::ObjectPtr& track); +} \ No newline at end of file diff --git a/src/libs/subsonic/impl/responses/Song.cpp b/src/libs/subsonic/impl/responses/Song.cpp index 65bd8f2f..b21cea78 100644 --- a/src/libs/subsonic/impl/responses/Song.cpp +++ b/src/libs/subsonic/impl/responses/Song.cpp @@ -32,6 +32,7 @@ #include "utils/String.hpp" #include "responses/Artist.hpp" #include "responses/Contributor.hpp" +#include "responses/ReplayGain.hpp" #include "SubsonicId.hpp" #include "Utils.hpp" @@ -217,6 +218,8 @@ namespace API::Subsonic addClusters("genres", "GENRE"); addClusters("moods", "MOOD"); + trackResponse.addChild("replayGain", createReplayGainNode(track)); + return trackResponse; } } \ No newline at end of file