From ecd3afdc8e38ba98b5744f168efce27f2ab2fccc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 17 Mar 2019 20:47:03 -0400 Subject: [PATCH 1/3] service/am: Unstub SetExpectedMasterVolume() This function passes in the desired main applet and library applet volume levels. We can then just pass those values back within the relevant volume getter functions, allowing us to unstub those as well. The initial values for the library and main applet volumes differ. The main applet volume is 0.25 by default, while the library applet volume is initialized to 1.0 by default in the services themselves. --- src/core/hle/service/am/am.cpp | 32 ++++++++++++++++++++++---------- src/core/hle/service/am/am.h | 6 +++++- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 3f009d2b7c..4f1541e9d0 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include #include -#include #include "audio_core/audio_renderer.h" #include "core/core.h" #include "core/file_sys/savedata_factory.h" @@ -93,38 +93,50 @@ void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) } IAudioController::IAudioController() : ServiceFramework("IAudioController") { + // clang-format off static const FunctionInfo functions[] = { {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"}, - {1, &IAudioController::GetMainAppletExpectedMasterVolume, - "GetMainAppletExpectedMasterVolume"}, - {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, - "GetLibraryAppletExpectedMasterVolume"}, + {1, &IAudioController::GetMainAppletExpectedMasterVolume, "GetMainAppletExpectedMasterVolume"}, + {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, "GetLibraryAppletExpectedMasterVolume"}, {3, nullptr, "ChangeMainAppletMasterVolume"}, {4, nullptr, "SetTransparentVolumeRate"}, }; + // clang-format on + RegisterHandlers(functions); } IAudioController::~IAudioController() = default; void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const float main_applet_volume_tmp = rp.Pop(); + const float library_applet_volume_tmp = rp.Pop(); + + LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}", + main_applet_volume_tmp, library_applet_volume_tmp); + + // Ensure the volume values remain within the 0-100% range + main_applet_volume = std::clamp(main_applet_volume_tmp, min_allowed_volume, max_allowed_volume); + library_applet_volume = + std::clamp(library_applet_volume_tmp, min_allowed_volume, max_allowed_volume); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called. main_applet_volume={}", main_applet_volume); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(volume); + rb.Push(main_applet_volume); } void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called. library_applet_volume={}", library_applet_volume); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(volume); + rb.Push(library_applet_volume); } IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index b6113cfdd1..bca06c25d2 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -82,7 +82,11 @@ private: void GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); - u32 volume{100}; + static constexpr float min_allowed_volume = 0.0f; + static constexpr float max_allowed_volume = 1.0f; + + float main_applet_volume{0.25f}; + float library_applet_volume{max_allowed_volume}; }; class IDisplayController final : public ServiceFramework { From c07ebeac19921d376979b420f5287f7016fa558c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 17 Mar 2019 21:09:25 -0400 Subject: [PATCH 2/3] service/am: Unstub SetTransparentVolumeRate() Like the other volume setter, this mainly just sets a data member within the service, nothing too special. --- src/core/hle/service/am/am.cpp | 16 +++++++++++++++- src/core/hle/service/am/am.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 4f1541e9d0..4ef449ccbc 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -99,7 +99,7 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") { {1, &IAudioController::GetMainAppletExpectedMasterVolume, "GetMainAppletExpectedMasterVolume"}, {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, "GetLibraryAppletExpectedMasterVolume"}, {3, nullptr, "ChangeMainAppletMasterVolume"}, - {4, nullptr, "SetTransparentVolumeRate"}, + {4, &IAudioController::SetTransparentAudioRate, "SetTransparentVolumeRate"}, }; // clang-format on @@ -139,6 +139,20 @@ void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestCo rb.Push(library_applet_volume); } +void IAudioController::SetTransparentAudioRate(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const float transparent_volume_rate_tmp = rp.Pop(); + + LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate_tmp); + + // Clamp volume range to 0-100%. + transparent_volume_rate = + std::clamp(transparent_volume_rate_tmp, min_allowed_volume, max_allowed_volume); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") { // clang-format off static const FunctionInfo functions[] = { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index bca06c25d2..b77a8c96c9 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -81,12 +81,14 @@ private: void SetExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); + void SetTransparentAudioRate(Kernel::HLERequestContext& ctx); static constexpr float min_allowed_volume = 0.0f; static constexpr float max_allowed_volume = 1.0f; float main_applet_volume{0.25f}; float library_applet_volume{max_allowed_volume}; + float transparent_volume_rate{min_allowed_volume}; }; class IDisplayController final : public ServiceFramework { From 26b809549b7cdadd75b55a1799d6cb7a2184b0a1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 17 Mar 2019 22:39:29 -0400 Subject: [PATCH 3/3] service/am: Add basic implementation of ChangeMainAppletMasterVolume All this does is supply a new volume level and a fade time in nanoseconds for the volume transition to occur within. --- src/core/hle/service/am/am.cpp | 22 +++++++++++++++++++++- src/core/hle/service/am/am.h | 8 ++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 4ef449ccbc..c750d70ac2 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -98,7 +98,7 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") { {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"}, {1, &IAudioController::GetMainAppletExpectedMasterVolume, "GetMainAppletExpectedMasterVolume"}, {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, "GetLibraryAppletExpectedMasterVolume"}, - {3, nullptr, "ChangeMainAppletMasterVolume"}, + {3, &IAudioController::ChangeMainAppletMasterVolume, "ChangeMainAppletMasterVolume"}, {4, &IAudioController::SetTransparentAudioRate, "SetTransparentVolumeRate"}, }; // clang-format on @@ -139,6 +139,26 @@ void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestCo rb.Push(library_applet_volume); } +void IAudioController::ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx) { + struct Parameters { + float volume; + s64 fade_time_ns; + }; + static_assert(sizeof(Parameters) == 16); + + IPC::RequestParser rp{ctx}; + const auto parameters = rp.PopRaw(); + + LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", parameters.volume, + parameters.fade_time_ns); + + main_applet_volume = std::clamp(parameters.volume, min_allowed_volume, max_allowed_volume); + fade_time_ns = std::chrono::nanoseconds{parameters.fade_time_ns}; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void IAudioController::SetTransparentAudioRate(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const float transparent_volume_rate_tmp = rp.Pop(); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index b77a8c96c9..565dd8e9eb 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "core/hle/kernel/writable_event.h" @@ -81,6 +82,7 @@ private: void SetExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); + void ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx); void SetTransparentAudioRate(Kernel::HLERequestContext& ctx); static constexpr float min_allowed_volume = 0.0f; @@ -89,6 +91,12 @@ private: float main_applet_volume{0.25f}; float library_applet_volume{max_allowed_volume}; float transparent_volume_rate{min_allowed_volume}; + + // Volume transition fade time in nanoseconds. + // e.g. If the main applet volume was 0% and was changed to 50% + // with a fade of 50ns, then over the course of 50ns, + // the volume will gradually fade up to 50% + std::chrono::nanoseconds fade_time_ns{0}; }; class IDisplayController final : public ServiceFramework {