From c70aa00b23341a395f5d0509720d5c4d1b2b9a1f 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 a3db2ec8af507afa2af2eb57706fa8d48412508e 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 a7cb88f3b2d1d53facca1ddac2e622a4d7766850 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 {