From f54277364c773e1721028628b44655e71b5685d0 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 19 Feb 2024 21:11:18 -0500 Subject: [PATCH 01/16] audio: rewrite IAudioIn --- src/core/CMakeLists.txt | 2 + src/core/hle/service/audio/audin_u.cpp | 197 +----------------------- src/core/hle/service/audio/audio_in.cpp | 131 ++++++++++++++++ src/core/hle/service/audio/audio_in.h | 48 ++++++ 4 files changed, 182 insertions(+), 196 deletions(-) create mode 100644 src/core/hle/service/audio/audio_in.cpp create mode 100644 src/core/hle/service/audio/audio_in.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f67a12f8f..75a9bcde7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -491,6 +491,8 @@ add_library(core STATIC hle/service/apm/apm_interface.h hle/service/audio/audin_u.cpp hle/service/audio/audin_u.h + hle/service/audio/audio_in.cpp + hle/service/audio/audio_in.h hle/service/audio/audio.cpp hle/service/audio/audio.h hle/service/audio/audio_controller.cpp diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index de2aa6906..0937d6d12 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -1,209 +1,14 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "audio_core/in/audio_in_system.h" -#include "audio_core/renderer/audio_device.h" -#include "common/common_funcs.h" -#include "common/logging/log.h" -#include "common/scratch_buffer.h" #include "common/string_util.h" -#include "core/core.h" -#include "core/hle/kernel/k_event.h" #include "core/hle/service/audio/audin_u.h" +#include "core/hle/service/audio/audio_in.h" #include "core/hle/service/ipc_helpers.h" namespace Service::Audio { using namespace AudioCore::AudioIn; -class IAudioIn final : public ServiceFramework { -public: - explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id, - const std::string& device_name, const AudioInParameter& in_params, - Kernel::KProcess* handle, u64 applet_resource_user_id) - : ServiceFramework{system_, "IAudioIn"}, - service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")}, - process{handle}, impl{std::make_shared(system_, manager, event, session_id)} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IAudioIn::GetAudioInState, "GetAudioInState"}, - {1, &IAudioIn::Start, "Start"}, - {2, &IAudioIn::Stop, "Stop"}, - {3, &IAudioIn::AppendAudioInBuffer, "AppendAudioInBuffer"}, - {4, &IAudioIn::RegisterBufferEvent, "RegisterBufferEvent"}, - {5, &IAudioIn::GetReleasedAudioInBuffer, "GetReleasedAudioInBuffer"}, - {6, &IAudioIn::ContainsAudioInBuffer, "ContainsAudioInBuffer"}, - {7, &IAudioIn::AppendAudioInBuffer, "AppendUacInBuffer"}, - {8, &IAudioIn::AppendAudioInBuffer, "AppendAudioInBufferAuto"}, - {9, &IAudioIn::GetReleasedAudioInBuffer, "GetReleasedAudioInBuffersAuto"}, - {10, &IAudioIn::AppendAudioInBuffer, "AppendUacInBufferAuto"}, - {11, &IAudioIn::GetAudioInBufferCount, "GetAudioInBufferCount"}, - {12, &IAudioIn::SetDeviceGain, "SetDeviceGain"}, - {13, &IAudioIn::GetDeviceGain, "GetDeviceGain"}, - {14, &IAudioIn::FlushAudioInBuffers, "FlushAudioInBuffers"}, - }; - // clang-format on - - RegisterHandlers(functions); - - process->Open(); - - if (impl->GetSystem() - .Initialize(device_name, in_params, handle, applet_resource_user_id) - .IsError()) { - LOG_ERROR(Service_Audio, "Failed to initialize the AudioIn System!"); - } - } - - ~IAudioIn() override { - impl->Free(); - service_context.CloseEvent(event); - process->Close(); - } - - [[nodiscard]] std::shared_ptr GetImpl() { - return impl; - } - -private: - void GetAudioInState(HLERequestContext& ctx) { - const auto state = static_cast(impl->GetState()); - - LOG_DEBUG(Service_Audio, "called. State={}", state); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(state); - } - - void Start(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto result = impl->StartSystem(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void Stop(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto result = impl->StopSystem(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void AppendAudioInBuffer(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - u64 tag = rp.PopRaw(); - - const auto in_buffer_size{ctx.GetReadBufferSize()}; - if (in_buffer_size < sizeof(AudioInBuffer)) { - LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!"); - } - - const auto& in_buffer = ctx.ReadBuffer(); - AudioInBuffer buffer{}; - std::memcpy(&buffer, in_buffer.data(), sizeof(AudioInBuffer)); - - [[maybe_unused]] auto sessionid{impl->GetSystem().GetSessionId()}; - LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", sessionid, tag); - - auto result = impl->AppendBuffer(buffer, tag); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void RegisterBufferEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto& buffer_event = impl->GetBufferEvent(); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(buffer_event); - } - - void GetReleasedAudioInBuffer(HLERequestContext& ctx) { - const auto write_buffer_size = ctx.GetWriteBufferNumElements(); - released_buffer.resize_destructive(write_buffer_size); - released_buffer[0] = 0; - - const auto count = impl->GetReleasedBuffers(released_buffer); - - LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", - impl->GetSystem().GetSessionId(), count); - - ctx.WriteBuffer(released_buffer); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(count); - } - - void ContainsAudioInBuffer(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const u64 tag{rp.Pop()}; - const auto buffer_queued{impl->ContainsAudioBuffer(tag)}; - - LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", tag, buffer_queued); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(buffer_queued); - } - - void GetAudioInBufferCount(HLERequestContext& ctx) { - const auto buffer_count = impl->GetBufferCount(); - - LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(buffer_count); - } - - void SetDeviceGain(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto volume{rp.Pop()}; - LOG_DEBUG(Service_Audio, "called. Gain {}", volume); - - impl->SetVolume(volume); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetDeviceGain(HLERequestContext& ctx) { - auto volume{impl->GetVolume()}; - - LOG_DEBUG(Service_Audio, "called. Gain {}", volume); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(volume); - } - - void FlushAudioInBuffers(HLERequestContext& ctx) { - bool flushed{impl->FlushAudioInBuffers()}; - - LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(flushed); - } - - KernelHelpers::ServiceContext service_context; - Kernel::KEvent* event; - Kernel::KProcess* process; - std::shared_ptr impl; - Common::ScratchBuffer released_buffer; -}; - AudInU::AudInU(Core::System& system_) : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, impl{std::make_unique(system_)} { diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp new file mode 100644 index 000000000..d847e0fc8 --- /dev/null +++ b/src/core/hle/service/audio/audio_in.cpp @@ -0,0 +1,131 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/audio/audio_in.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::Audio { +using namespace AudioCore::AudioIn; + +IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, + const std::string& device_name, const AudioInParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id) + : ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"}, + event{service_context.CreateEvent("AudioInEvent")}, + impl{std::make_shared(system_, manager, event, session_id)} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IAudioIn::GetAudioInState>, "GetAudioInState"}, + {1, C<&IAudioIn::Start>, "Start"}, + {2, C<&IAudioIn::Stop>, "Stop"}, + {3, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"}, + {4, C<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"}, + {5, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffer"}, + {6, C<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"}, + {7, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"}, + {8, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBufferAuto"}, + {9, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffersAuto"}, + {10, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBufferAuto"}, + {11, C<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"}, + {12, C<&IAudioIn::SetDeviceGain>, "SetDeviceGain"}, + {13, C<&IAudioIn::GetDeviceGain>, "GetDeviceGain"}, + {14, C<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"}, + }; + // clang-format on + + RegisterHandlers(functions); + + process->Open(); + + if (impl->GetSystem() + .Initialize(device_name, in_params, handle, applet_resource_user_id) + .IsError()) { + LOG_ERROR(Service_Audio, "Failed to initialize the AudioIn System!"); + } +} + +IAudioIn::~IAudioIn() { + impl->Free(); + service_context.CloseEvent(event); + process->Close(); +} + +Result IAudioIn::GetAudioInState(Out out_state) { + *out_state = static_cast(impl->GetState()); + LOG_DEBUG(Service_Audio, "called. state={}", *out_state); + R_SUCCEED(); +} + +Result IAudioIn::Start() { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(impl->StartSystem()); +} + +Result IAudioIn::Stop() { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(impl->StopSystem()); +} + +Result IAudioIn::AppendAudioInBuffer(InArray buffer, + u64 buffer_client_ptr) { + if (buffer.empty()) { + LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!"); + R_THROW(Audio::ResultInsufficientBuffer); + } + + [[maybe_unused]] const auto session_id{impl->GetSystem().GetSessionId()}; + LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", session_id, + buffer_client_ptr); + + R_RETURN(impl->AppendBuffer(buffer[0], buffer_client_ptr)); +} + +Result IAudioIn::RegisterBufferEvent(OutCopyHandle out_event) { + LOG_DEBUG(Service_Audio, "called"); + *out_event = &impl->GetBufferEvent(); + R_SUCCEED(); +} + +Result IAudioIn::GetReleasedAudioInBuffer(OutArray out_audio_buffer, + Out out_count) { + *out_count = impl->GetReleasedBuffers(out_audio_buffer); + + LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", + impl->GetSystem().GetSessionId(), *out_count); + R_SUCCEED(); +} + +Result IAudioIn::ContainsAudioInBuffer(Out out_contains_buffer, u64 buffer_client_ptr) { + *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr); + + LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr, + *out_contains_buffer); + R_SUCCEED(); +} + +Result IAudioIn::GetAudioInBufferCount(Out out_buffer_count) { + *out_buffer_count = impl->GetBufferCount(); + LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count); + R_SUCCEED(); +} + +Result IAudioIn::SetDeviceGain(f32 device_gain) { + impl->SetVolume(device_gain); + LOG_DEBUG(Service_Audio, "called. Gain {}", device_gain); + R_SUCCEED(); +} + +Result IAudioIn::GetDeviceGain(Out out_device_gain) { + *out_device_gain = impl->GetVolume(); + LOG_DEBUG(Service_Audio, "called. Gain {}", *out_device_gain); + R_SUCCEED(); +} + +Result IAudioIn::FlushAudioInBuffers(Out out_flushed) { + *out_flushed = impl->FlushAudioInBuffers(); + LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed); + R_SUCCEED(); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_in.h b/src/core/hle/service/audio/audio_in.h new file mode 100644 index 000000000..8d6398ef6 --- /dev/null +++ b/src/core/hle/service/audio/audio_in.h @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/in/audio_in.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class IAudioIn final : public ServiceFramework { +public: + explicit IAudioIn(Core::System& system_, AudioCore::AudioIn::Manager& manager, + size_t session_id, const std::string& device_name, + const AudioCore::AudioIn::AudioInParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id); + ~IAudioIn() override; + + std::shared_ptr GetImpl() { + return impl; + } + + Result GetAudioInState(Out out_state); + Result Start(); + Result Stop(); + Result AppendAudioInBuffer( + InArray buffer, + u64 buffer_client_ptr); + Result RegisterBufferEvent(OutCopyHandle out_event); + Result GetReleasedAudioInBuffer(OutArray out_audio_buffer, + Out out_count); + Result ContainsAudioInBuffer(Out out_contains_buffer, u64 buffer_client_ptr); + Result GetAudioInBufferCount(Out out_buffer_count); + Result SetDeviceGain(f32 device_gain); + Result GetDeviceGain(Out out_device_gain); + Result FlushAudioInBuffers(Out out_flushed); + +private: + Kernel::KProcess* process; + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* event; + std::shared_ptr impl; + Common::ScratchBuffer released_buffer; +}; + +} // namespace Service::Audio From 2a2c92f1819f44a86f452654398d0fc16806c438 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 19 Feb 2024 21:45:48 -0500 Subject: [PATCH 02/16] audio: rewrite IAudioInManager --- src/audio_core/audio_in_manager.cpp | 7 +- src/audio_core/audio_in_manager.h | 4 +- src/core/CMakeLists.txt | 4 +- src/core/hle/service/audio/audin_u.cpp | 198 ------------------ src/core/hle/service/audio/audin_u.h | 38 ---- src/core/hle/service/audio/audio.cpp | 4 +- .../hle/service/audio/audio_in_manager.cpp | 126 +++++++++++ src/core/hle/service/audio/audio_in_manager.h | 57 +++++ 8 files changed, 191 insertions(+), 247 deletions(-) delete mode 100644 src/core/hle/service/audio/audin_u.cpp delete mode 100644 src/core/hle/service/audio/audin_u.h create mode 100644 src/core/hle/service/audio/audio_in_manager.cpp create mode 100644 src/core/hle/service/audio/audio_in_manager.h diff --git a/src/audio_core/audio_in_manager.cpp b/src/audio_core/audio_in_manager.cpp index a3667524f..63b064922 100644 --- a/src/audio_core/audio_in_manager.cpp +++ b/src/audio_core/audio_in_manager.cpp @@ -73,16 +73,15 @@ void Manager::BufferReleaseAndRegister() { } } -u32 Manager::GetDeviceNames(std::vector& names, - [[maybe_unused]] const u32 max_count, +u32 Manager::GetDeviceNames(std::span names, [[maybe_unused]] const bool filter) { std::scoped_lock l{mutex}; LinkToManager(); auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)}; - if (input_devices.size() > 1) { - names.emplace_back("Uac"); + if (!input_devices.empty() && !names.empty()) { + names[0] = Renderer::AudioDevice::AudioDeviceName("Uac"); return 1; } return 0; diff --git a/src/audio_core/audio_in_manager.h b/src/audio_core/audio_in_manager.h index 5c4614cd1..2179990e0 100644 --- a/src/audio_core/audio_in_manager.h +++ b/src/audio_core/audio_in_manager.h @@ -60,13 +60,11 @@ public: * Get a list of audio in device names. * * @param names - Output container to write names to. - * @param max_count - Maximum number of device names to write. Unused * @param filter - Should the list be filtered? Unused. * * @return Number of names written. */ - u32 GetDeviceNames(std::vector& names, u32 max_count, - bool filter); + u32 GetDeviceNames(std::span names, bool filter); /// Core system Core::System& system; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 75a9bcde7..51fe8c500 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -489,8 +489,8 @@ add_library(core STATIC hle/service/apm/apm_controller.h hle/service/apm/apm_interface.cpp hle/service/apm/apm_interface.h - hle/service/audio/audin_u.cpp - hle/service/audio/audin_u.h + hle/service/audio/audio_in_manager.cpp + hle/service/audio/audio_in_manager.h hle/service/audio/audio_in.cpp hle/service/audio/audio_in.h hle/service/audio/audio.cpp diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp deleted file mode 100644 index 0937d6d12..000000000 --- a/src/core/hle/service/audio/audin_u.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/string_util.h" -#include "core/hle/service/audio/audin_u.h" -#include "core/hle/service/audio/audio_in.h" -#include "core/hle/service/ipc_helpers.h" - -namespace Service::Audio { -using namespace AudioCore::AudioIn; - -AudInU::AudInU(Core::System& system_) - : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, - impl{std::make_unique(system_)} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &AudInU::ListAudioIns, "ListAudioIns"}, - {1, &AudInU::OpenAudioIn, "OpenAudioIn"}, - {2, &AudInU::ListAudioIns, "ListAudioInsAuto"}, - {3, &AudInU::OpenAudioIn, "OpenAudioInAuto"}, - {4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"}, - {5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -AudInU::~AudInU() = default; - -void AudInU::ListAudioIns(HLERequestContext& ctx) { - using namespace AudioCore::Renderer; - - LOG_DEBUG(Service_Audio, "called"); - - const auto write_count = - static_cast(ctx.GetWriteBufferNumElements()); - std::vector device_names{}; - - u32 out_count{0}; - if (write_count > 0) { - out_count = impl->GetDeviceNames(device_names, write_count, false); - ctx.WriteBuffer(device_names); - } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(out_count); -} - -void AudInU::ListAudioInsAutoFiltered(HLERequestContext& ctx) { - using namespace AudioCore::Renderer; - - LOG_DEBUG(Service_Audio, "called"); - - const auto write_count = - static_cast(ctx.GetWriteBufferNumElements()); - std::vector device_names{}; - - u32 out_count{0}; - if (write_count > 0) { - out_count = impl->GetDeviceNames(device_names, write_count, true); - ctx.WriteBuffer(device_names); - } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(out_count); -} - -void AudInU::OpenAudioIn(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto in_params{rp.PopRaw()}; - auto applet_resource_user_id{rp.PopRaw()}; - const auto device_name_data{ctx.ReadBuffer()}; - auto device_name = Common::StringFromBuffer(device_name_data); - auto handle{ctx.GetCopyHandle(0)}; - - auto process{ctx.GetObjectFromHandle(handle)}; - if (process.IsNull()) { - LOG_ERROR(Service_Audio, "Failed to get process handle"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultUnknown); - return; - } - - std::scoped_lock l{impl->mutex}; - auto link{impl->LinkToManager()}; - if (link.IsError()) { - LOG_ERROR(Service_Audio, "Failed to link Audio In to Audio Manager"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(link); - return; - } - - size_t new_session_id{}; - auto result{impl->AcquireSessionId(new_session_id)}; - if (result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id, - impl->num_free_sessions); - - auto audio_in = - std::make_shared(system, *impl, new_session_id, device_name, in_params, - process.GetPointerUnsafe(), applet_resource_user_id); - impl->sessions[new_session_id] = audio_in->GetImpl(); - impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; - - auto& out_system = impl->sessions[new_session_id]->GetSystem(); - AudioInParameterInternal out_params{.sample_rate = out_system.GetSampleRate(), - .channel_count = out_system.GetChannelCount(), - .sample_format = - static_cast(out_system.GetSampleFormat()), - .state = static_cast(out_system.GetState())}; - - IPC::ResponseBuilder rb{ctx, 6, 0, 1}; - - std::string out_name{out_system.GetName()}; - ctx.WriteBuffer(out_name); - - rb.Push(ResultSuccess); - rb.PushRaw(out_params); - rb.PushIpcInterface(audio_in); -} - -void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto protocol_specified{rp.PopRaw()}; - auto in_params{rp.PopRaw()}; - auto applet_resource_user_id{rp.PopRaw()}; - const auto device_name_data{ctx.ReadBuffer()}; - auto device_name = Common::StringFromBuffer(device_name_data); - auto handle{ctx.GetCopyHandle(0)}; - - auto process{ctx.GetObjectFromHandle(handle)}; - if (process.IsNull()) { - LOG_ERROR(Service_Audio, "Failed to get process handle"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultUnknown); - return; - } - - std::scoped_lock l{impl->mutex}; - auto link{impl->LinkToManager()}; - if (link.IsError()) { - LOG_ERROR(Service_Audio, "Failed to link Audio In to Audio Manager"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(link); - return; - } - - size_t new_session_id{}; - auto result{impl->AcquireSessionId(new_session_id)}; - if (result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id, - impl->num_free_sessions); - - auto audio_in = - std::make_shared(system, *impl, new_session_id, device_name, in_params, - process.GetPointerUnsafe(), applet_resource_user_id); - impl->sessions[new_session_id] = audio_in->GetImpl(); - impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; - - auto& out_system = impl->sessions[new_session_id]->GetSystem(); - AudioInParameterInternal out_params{.sample_rate = out_system.GetSampleRate(), - .channel_count = out_system.GetChannelCount(), - .sample_format = - static_cast(out_system.GetSampleFormat()), - .state = static_cast(out_system.GetState())}; - - IPC::ResponseBuilder rb{ctx, 6, 0, 1}; - - std::string out_name{out_system.GetName()}; - if (protocol_specified == 0) { - if (out_system.IsUac()) { - out_name = "UacIn"; - } else { - out_name = "DeviceIn"; - } - } - - ctx.WriteBuffer(out_name); - - rb.Push(ResultSuccess); - rb.PushRaw(out_params); - rb.PushIpcInterface(audio_in); -} - -} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h deleted file mode 100644 index 51e770ff9..000000000 --- a/src/core/hle/service/audio/audin_u.h +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "audio_core/audio_in_manager.h" -#include "audio_core/in/audio_in.h" -#include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace AudioCore::AudioOut { -class Manager; -class In; -} // namespace AudioCore::AudioOut - -namespace Service::Audio { - -class AudInU final : public ServiceFramework { -public: - explicit AudInU(Core::System& system_); - ~AudInU() override; - -private: - void ListAudioIns(HLERequestContext& ctx); - void ListAudioInsAutoFiltered(HLERequestContext& ctx); - void OpenInOutImpl(HLERequestContext& ctx); - void OpenAudioIn(HLERequestContext& ctx); - void OpenAudioInProtocolSpecified(HLERequestContext& ctx); - - KernelHelpers::ServiceContext service_context; - std::unique_ptr impl; -}; - -} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index 44af030eb..7dcfbbfad 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" -#include "core/hle/service/audio/audin_u.h" #include "core/hle/service/audio/audio.h" #include "core/hle/service/audio/audio_controller.h" +#include "core/hle/service/audio/audio_in_manager.h" #include "core/hle/service/audio/audout_u.h" #include "core/hle/service/audio/audrec_a.h" #include "core/hle/service/audio/audrec_u.h" @@ -19,8 +19,8 @@ void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("audctl", std::make_shared(system)); + server_manager->RegisterNamedService("audin:u", std::make_shared(system)); server_manager->RegisterNamedService("audout:u", std::make_shared(system)); - server_manager->RegisterNamedService("audin:u", std::make_shared(system)); server_manager->RegisterNamedService("audrec:a", std::make_shared(system)); server_manager->RegisterNamedService("audrec:u", std::make_shared(system)); server_manager->RegisterNamedService("audren:u", std::make_shared(system)); diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp new file mode 100644 index 000000000..0379a2f68 --- /dev/null +++ b/src/core/hle/service/audio/audio_in_manager.cpp @@ -0,0 +1,126 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/string_util.h" +#include "core/hle/service/audio/audio_in.h" +#include "core/hle/service/audio/audio_in_manager.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::Audio { +using namespace AudioCore::AudioIn; + +IAudioInManager::IAudioInManager(Core::System& system_) + : ServiceFramework{system_, "audin:u"}, + impl{std::make_unique(system_)} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IAudioInManager::ListAudioIns>, "ListAudioIns"}, + {1, C<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"}, + {2, C<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"}, + {3, C<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"}, + {4, C<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"}, + {5, C<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IAudioInManager::~IAudioInManager() = default; + +Result IAudioInManager::ListAudioIns( + OutArray out_audio_ins, Out out_count) { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count)); +} + +Result IAudioInManager::OpenAudioIn(Out out_parameter_internal, + Out> out_audio_in, + OutArray out_name, + InArray name, + AudioInParameter parameter, + InCopyHandle process_handle, + ClientAppletResourceUserId aruid) { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name, + name, {}, parameter, process_handle, aruid)); +} + +Result IAudioInManager::ListAudioInsAuto( + OutArray out_audio_ins, Out out_count) { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count)); +} + +Result IAudioInManager::OpenAudioInAuto( + Out out_parameter_internal, Out> out_audio_in, + OutArray out_name, + InArray name, AudioInParameter parameter, + InCopyHandle process_handle, ClientAppletResourceUserId aruid) { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name, + name, {}, parameter, process_handle, aruid)); +} + +Result IAudioInManager::ListAudioInsAutoFiltered( + OutArray out_audio_ins, Out out_count) { + LOG_DEBUG(Service_Audio, "called"); + *out_count = impl->GetDeviceNames(out_audio_ins, true); + R_SUCCEED(); +} + +Result IAudioInManager::OpenAudioInProtocolSpecified( + Out out_parameter_internal, Out> out_audio_in, + OutArray out_name, + InArray name, Protocol protocol, + AudioInParameter parameter, InCopyHandle process_handle, + ClientAppletResourceUserId aruid) { + LOG_DEBUG(Service_Audio, "called"); + + if (!process_handle) { + LOG_ERROR(Service_Audio, "Failed to get process handle"); + R_THROW(ResultUnknown); + } + if (name.empty() || out_name.empty()) { + LOG_ERROR(Service_Audio, "Invalid buffers"); + R_THROW(ResultUnknown); + } + + std::scoped_lock l{impl->mutex}; + + size_t new_session_id{}; + + R_TRY(impl->LinkToManager()); + R_TRY(impl->AcquireSessionId(new_session_id)); + + LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id, + impl->num_free_sessions); + + const auto name_buffer = std::span(reinterpret_cast(name[0].name.data()), 0x100); + const auto device_name = Common::StringFromBuffer(name_buffer); + *out_audio_in = std::make_shared(system, *impl, new_session_id, device_name, + parameter, process_handle.Get(), aruid.pid); + impl->sessions[new_session_id] = (*out_audio_in)->GetImpl(); + impl->applet_resource_user_ids[new_session_id] = aruid.pid; + + auto& out_system = impl->sessions[new_session_id]->GetSystem(); + *out_parameter_internal = + AudioInParameterInternal{.sample_rate = out_system.GetSampleRate(), + .channel_count = out_system.GetChannelCount(), + .sample_format = static_cast(out_system.GetSampleFormat()), + .state = static_cast(out_system.GetState())}; + + out_name[0] = AudioDeviceName(out_system.GetName()); + + if (protocol == Protocol{}) { + if (out_system.IsUac()) { + out_name[0] = AudioDeviceName("UacIn"); + } else { + out_name[0] = AudioDeviceName("DeviceIn"); + } + } + + R_SUCCEED(); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_in_manager.h b/src/core/hle/service/audio/audio_in_manager.h new file mode 100644 index 000000000..2a983bc60 --- /dev/null +++ b/src/core/hle/service/audio/audio_in_manager.h @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/audio_in_manager.h" +#include "audio_core/in/audio_in_system.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { + +using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName; +using Protocol = std::array; + +class IAudioIn; + +class IAudioInManager final : public ServiceFramework { +public: + explicit IAudioInManager(Core::System& system_); + ~IAudioInManager() override; + +private: + Result ListAudioIns(OutArray out_audio_ins, + Out out_count); + Result OpenAudioIn(Out out_parameter_internal, + Out> out_audio_in, + OutArray out_name, + InArray name, + AudioCore::AudioIn::AudioInParameter parameter, + InCopyHandle process_handle, + ClientAppletResourceUserId aruid); + + Result ListAudioInsAuto(OutArray out_audio_ins, + Out out_count); + Result OpenAudioInAuto(Out out_parameter_internal, + Out> out_audio_in, + OutArray out_name, + InArray name, + AudioCore::AudioIn::AudioInParameter parameter, + InCopyHandle process_handle, + ClientAppletResourceUserId aruid); + + Result ListAudioInsAutoFiltered( + OutArray out_audio_ins, Out out_count); + Result OpenAudioInProtocolSpecified( + Out out_parameter_internal, + Out> out_audio_in, + OutArray out_name, + InArray name, Protocol protocol, + AudioCore::AudioIn::AudioInParameter parameter, + InCopyHandle process_handle, ClientAppletResourceUserId aruid); + + std::unique_ptr impl; +}; + +} // namespace Service::Audio From a05bd3c47ef4d77411c150e5bdbd1efacc5bde68 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 19 Feb 2024 23:13:19 -0500 Subject: [PATCH 03/16] audio: rewrite IAudioOut --- src/audio_core/device/audio_buffers.h | 4 +- src/core/CMakeLists.txt | 2 + src/core/hle/service/audio/audio_in.cpp | 26 ++- src/core/hle/service/audio/audio_in.h | 9 +- src/core/hle/service/audio/audio_out.cpp | 146 ++++++++++++++++ src/core/hle/service/audio/audio_out.h | 58 +++++++ src/core/hle/service/audio/audout_u.cpp | 207 +---------------------- 7 files changed, 236 insertions(+), 216 deletions(-) create mode 100644 src/core/hle/service/audio/audio_out.cpp create mode 100644 src/core/hle/service/audio/audio_out.h diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h index 5d8ed0ef7..25da4c8a2 100644 --- a/src/audio_core/device/audio_buffers.h +++ b/src/audio_core/device/audio_buffers.h @@ -146,11 +146,11 @@ public: break; } - tags[released++] = tag; - if (released >= tags.size()) { break; } + + tags[released++] = tag; } return released; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 51fe8c500..1255ee6bf 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -493,6 +493,8 @@ add_library(core STATIC hle/service/audio/audio_in_manager.h hle/service/audio/audio_in.cpp hle/service/audio/audio_in.h + hle/service/audio/audio_out.cpp + hle/service/audio/audio_out.h hle/service/audio/audio.cpp hle/service/audio/audio.h hle/service/audio/audio_controller.cpp diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp index d847e0fc8..31d136077 100644 --- a/src/core/hle/service/audio/audio_in.cpp +++ b/src/core/hle/service/audio/audio_in.cpp @@ -21,12 +21,12 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, {2, C<&IAudioIn::Stop>, "Stop"}, {3, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"}, {4, C<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"}, - {5, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffer"}, + {5, C<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"}, {6, C<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"}, {7, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"}, - {8, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBufferAuto"}, - {9, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffersAuto"}, - {10, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBufferAuto"}, + {8, C<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"}, + {9, C<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"}, + {10, C<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"}, {11, C<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"}, {12, C<&IAudioIn::SetDeviceGain>, "SetDeviceGain"}, {13, C<&IAudioIn::GetDeviceGain>, "GetDeviceGain"}, @@ -69,6 +69,11 @@ Result IAudioIn::Stop() { Result IAudioIn::AppendAudioInBuffer(InArray buffer, u64 buffer_client_ptr) { + R_RETURN(this->AppendAudioInBufferAuto(buffer, buffer_client_ptr)); +} + +Result IAudioIn::AppendAudioInBufferAuto(InArray buffer, + u64 buffer_client_ptr) { if (buffer.empty()) { LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!"); R_THROW(Audio::ResultInsufficientBuffer); @@ -87,8 +92,17 @@ Result IAudioIn::RegisterBufferEvent(OutCopyHandle out_e R_SUCCEED(); } -Result IAudioIn::GetReleasedAudioInBuffer(OutArray out_audio_buffer, - Out out_count) { +Result IAudioIn::GetReleasedAudioInBuffers(OutArray out_audio_buffer, + Out out_count) { + R_RETURN(this->GetReleasedAudioInBuffersAuto(out_audio_buffer, out_count)); +} + +Result IAudioIn::GetReleasedAudioInBuffersAuto( + OutArray out_audio_buffer, Out out_count) { + + if (!out_audio_buffer.empty()) { + out_audio_buffer[0] = 0; + } *out_count = impl->GetReleasedBuffers(out_audio_buffer); LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", diff --git a/src/core/hle/service/audio/audio_in.h b/src/core/hle/service/audio/audio_in.h index 8d6398ef6..3fe1e1e87 100644 --- a/src/core/hle/service/audio/audio_in.h +++ b/src/core/hle/service/audio/audio_in.h @@ -28,9 +28,14 @@ public: Result AppendAudioInBuffer( InArray buffer, u64 buffer_client_ptr); + Result AppendAudioInBufferAuto( + InArray buffer, + u64 buffer_client_ptr); Result RegisterBufferEvent(OutCopyHandle out_event); - Result GetReleasedAudioInBuffer(OutArray out_audio_buffer, - Out out_count); + Result GetReleasedAudioInBuffers(OutArray out_audio_buffer, + Out out_count); + Result GetReleasedAudioInBuffersAuto(OutArray out_audio_buffer, + Out out_count); Result ContainsAudioInBuffer(Out out_contains_buffer, u64 buffer_client_ptr); Result GetAudioInBufferCount(Out out_buffer_count); Result SetDeviceGain(f32 device_gain); diff --git a/src/core/hle/service/audio/audio_out.cpp b/src/core/hle/service/audio/audio_out.cpp new file mode 100644 index 000000000..cd2dc1f6f --- /dev/null +++ b/src/core/hle/service/audio/audio_out.cpp @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "audio_core/out/audio_out.h" +#include "audio_core/out/audio_out_system.h" +#include "core/hle/kernel/k_process.h" +#include "core/hle/service/audio/audio_out.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { +using namespace AudioCore::AudioOut; + +IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id, + const std::string& device_name, const AudioOutParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id) + : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, + event{service_context.CreateEvent("AudioOutEvent")}, process{handle}, + impl{std::make_shared(system_, manager, event, session_id)} { + + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IAudioOut::GetAudioOutState>, "GetAudioOutState"}, + {1, C<&IAudioOut::Start>, "Start"}, + {2, C<&IAudioOut::Stop>, "Stop"}, + {3, C<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"}, + {4, C<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"}, + {5, C<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"}, + {6, C<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"}, + {7, C<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"}, + {8, C<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"}, + {9, C<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"}, + {10, C<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"}, + {11, C<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"}, + {12, C<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"}, + {13, C<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"}, + }; + // clang-format on + RegisterHandlers(functions); + + process->Open(); +} + +IAudioOut::~IAudioOut() { + impl->Free(); + service_context.CloseEvent(event); + process->Close(); +} + +Result IAudioOut::GetAudioOutState(Out out_state) { + *out_state = static_cast(impl->GetState()); + LOG_DEBUG(Service_Audio, "called. state={}", *out_state); + R_SUCCEED(); +} + +Result IAudioOut::Start() { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(impl->StartSystem()); +} + +Result IAudioOut::Stop() { + LOG_DEBUG(Service_Audio, "called"); + R_RETURN(impl->StopSystem()); +} + +Result IAudioOut::AppendAudioOutBuffer( + InArray audio_out_buffer, u64 buffer_client_ptr) { + R_RETURN(this->AppendAudioOutBufferAuto(audio_out_buffer, buffer_client_ptr)); +} + +Result IAudioOut::AppendAudioOutBufferAuto( + InArray audio_out_buffer, u64 buffer_client_ptr) { + if (audio_out_buffer.empty()) { + LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioOutBuffer!"); + R_THROW(Audio::ResultInsufficientBuffer); + } + + LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", + impl->GetSystem().GetSessionId(), buffer_client_ptr); + R_RETURN(impl->AppendBuffer(audio_out_buffer[0], buffer_client_ptr)); +} + +Result IAudioOut::RegisterBufferEvent(OutCopyHandle out_event) { + LOG_DEBUG(Service_Audio, "called"); + *out_event = &impl->GetBufferEvent(); + R_SUCCEED(); +} + +Result IAudioOut::GetReleasedAudioOutBuffers( + OutArray out_audio_buffer, Out out_count) { + R_RETURN(this->GetReleasedAudioOutBuffersAuto(out_audio_buffer, out_count)); +} + +Result IAudioOut::GetReleasedAudioOutBuffersAuto( + OutArray out_audio_buffer, Out out_count) { + + if (!out_audio_buffer.empty()) { + out_audio_buffer[0] = 0; + } + *out_count = impl->GetReleasedBuffers(out_audio_buffer); + + LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", + impl->GetSystem().GetSessionId(), *out_count); + R_SUCCEED(); +} + +Result IAudioOut::ContainsAudioOutBuffer(Out out_contains_buffer, u64 buffer_client_ptr) { + *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr); + + LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr, + *out_contains_buffer); + R_SUCCEED(); +} + +Result IAudioOut::GetAudioOutBufferCount(Out out_buffer_count) { + *out_buffer_count = impl->GetBufferCount(); + LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count); + R_SUCCEED(); +} + +Result IAudioOut::GetAudioOutPlayedSampleCount(Out out_played_sample_count) { + *out_played_sample_count = impl->GetPlayedSampleCount(); + LOG_DEBUG(Service_Audio, "called. Played samples={}", *out_played_sample_count); + R_SUCCEED(); +} + +Result IAudioOut::FlushAudioOutBuffers(Out out_flushed) { + *out_flushed = impl->FlushAudioOutBuffers(); + LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed); + R_SUCCEED(); +} + +Result IAudioOut::SetAudioOutVolume(f32 volume) { + LOG_DEBUG(Service_Audio, "called. Volume={}", volume); + impl->SetVolume(volume); + R_SUCCEED(); +} + +Result IAudioOut::GetAudioOutVolume(Out out_volume) { + *out_volume = impl->GetVolume(); + LOG_DEBUG(Service_Audio, "called. Volume={}", *out_volume); + R_SUCCEED(); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_out.h b/src/core/hle/service/audio/audio_out.h new file mode 100644 index 000000000..779b213e7 --- /dev/null +++ b/src/core/hle/service/audio/audio_out.h @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/audio_out_manager.h" +#include "audio_core/out/audio_out_system.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class KReadableEvent; +} + +namespace Service::Audio { + +class IAudioOut : public ServiceFramework { +public: + explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, + size_t session_id, const std::string& device_name, + const AudioCore::AudioOut::AudioOutParameter& in_params, + Kernel::KProcess* handle, u64 applet_resource_user_id); + ~IAudioOut() override; + + std::shared_ptr GetImpl() { + return impl; + } + + Result GetAudioOutState(Out out_state); + Result Start(); + Result Stop(); + Result AppendAudioOutBuffer( + InArray audio_out_buffer, + u64 buffer_client_ptr); + Result AppendAudioOutBufferAuto( + InArray audio_out_buffer, + u64 buffer_client_ptr); + Result RegisterBufferEvent(OutCopyHandle out_event); + Result GetReleasedAudioOutBuffers(OutArray out_audio_buffer, + Out out_count); + Result GetReleasedAudioOutBuffersAuto(OutArray out_audio_buffer, + Out out_count); + Result ContainsAudioOutBuffer(Out out_contains_buffer, u64 buffer_client_ptr); + Result GetAudioOutBufferCount(Out out_buffer_count); + Result GetAudioOutPlayedSampleCount(Out out_played_sample_count); + Result FlushAudioOutBuffers(Out out_flushed); + Result SetAudioOutVolume(f32 volume); + Result GetAudioOutVolume(Out out_volume); + +private: + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* event; + Kernel::KProcess* process; + std::shared_ptr impl; +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 8cc7b69f4..5364177ba 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -1,220 +1,15 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include -#include - -#include "audio_core/out/audio_out_system.h" -#include "audio_core/renderer/audio_device.h" -#include "common/common_funcs.h" -#include "common/logging/log.h" -#include "common/scratch_buffer.h" #include "common/string_util.h" -#include "common/swap.h" -#include "core/core.h" -#include "core/hle/kernel/k_event.h" +#include "core/hle/service/audio/audio_out.h" #include "core/hle/service/audio/audout_u.h" -#include "core/hle/service/audio/errors.h" #include "core/hle/service/ipc_helpers.h" #include "core/memory.h" namespace Service::Audio { using namespace AudioCore::AudioOut; -class IAudioOut final : public ServiceFramework { -public: - explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, - size_t session_id, const std::string& device_name, - const AudioOutParameter& in_params, Kernel::KProcess* handle, - u64 applet_resource_user_id) - : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, - event{service_context.CreateEvent("AudioOutEvent")}, process{handle}, - impl{std::make_shared(system_, manager, event, session_id)} { - - // clang-format off - static const FunctionInfo functions[] = { - {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, - {1, &IAudioOut::Start, "Start"}, - {2, &IAudioOut::Stop, "Stop"}, - {3, &IAudioOut::AppendAudioOutBuffer, "AppendAudioOutBuffer"}, - {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, - {5, &IAudioOut::GetReleasedAudioOutBuffers, "GetReleasedAudioOutBuffers"}, - {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"}, - {7, &IAudioOut::AppendAudioOutBuffer, "AppendAudioOutBufferAuto"}, - {8, &IAudioOut::GetReleasedAudioOutBuffers, "GetReleasedAudioOutBuffersAuto"}, - {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, - {10, &IAudioOut::GetAudioOutPlayedSampleCount, "GetAudioOutPlayedSampleCount"}, - {11, &IAudioOut::FlushAudioOutBuffers, "FlushAudioOutBuffers"}, - {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"}, - {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"}, - }; - // clang-format on - RegisterHandlers(functions); - - process->Open(); - } - - ~IAudioOut() override { - impl->Free(); - service_context.CloseEvent(event); - process->Close(); - } - - [[nodiscard]] std::shared_ptr GetImpl() { - return impl; - } - -private: - void GetAudioOutState(HLERequestContext& ctx) { - const auto state = static_cast(impl->GetState()); - - LOG_DEBUG(Service_Audio, "called. State={}", state); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(state); - } - - void Start(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto result = impl->StartSystem(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void Stop(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto result = impl->StopSystem(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void AppendAudioOutBuffer(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - u64 tag = rp.PopRaw(); - - const auto in_buffer_size{ctx.GetReadBufferSize()}; - if (in_buffer_size < sizeof(AudioOutBuffer)) { - LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioOutBuffer!"); - } - - const auto& in_buffer = ctx.ReadBuffer(); - AudioOutBuffer buffer{}; - std::memcpy(&buffer, in_buffer.data(), sizeof(AudioOutBuffer)); - - LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", - impl->GetSystem().GetSessionId(), tag); - - auto result = impl->AppendBuffer(buffer, tag); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void RegisterBufferEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto& buffer_event = impl->GetBufferEvent(); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(buffer_event); - } - - void GetReleasedAudioOutBuffers(HLERequestContext& ctx) { - const auto write_buffer_size = ctx.GetWriteBufferNumElements(); - released_buffer.resize_destructive(write_buffer_size); - released_buffer[0] = 0; - - const auto count = impl->GetReleasedBuffers(released_buffer); - - ctx.WriteBuffer(released_buffer); - - LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", - impl->GetSystem().GetSessionId(), count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(count); - } - - void ContainsAudioOutBuffer(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const u64 tag{rp.Pop()}; - const auto buffer_queued{impl->ContainsAudioBuffer(tag)}; - - LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", tag, buffer_queued); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(buffer_queued); - } - - void GetAudioOutBufferCount(HLERequestContext& ctx) { - const auto buffer_count = impl->GetBufferCount(); - - LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(buffer_count); - } - - void GetAudioOutPlayedSampleCount(HLERequestContext& ctx) { - const auto samples_played = impl->GetPlayedSampleCount(); - - LOG_DEBUG(Service_Audio, "called. Played samples={}", samples_played); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(samples_played); - } - - void FlushAudioOutBuffers(HLERequestContext& ctx) { - bool flushed{impl->FlushAudioOutBuffers()}; - - LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(flushed); - } - - void SetAudioOutVolume(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto volume = rp.Pop(); - - LOG_DEBUG(Service_Audio, "called. Volume={}", volume); - - impl->SetVolume(volume); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetAudioOutVolume(HLERequestContext& ctx) { - const auto volume = impl->GetVolume(); - - LOG_DEBUG(Service_Audio, "called. Volume={}", volume); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(volume); - } - - KernelHelpers::ServiceContext service_context; - Kernel::KEvent* event; - Kernel::KProcess* process; - std::shared_ptr impl; - Common::ScratchBuffer released_buffer; -}; - AudOutU::AudOutU(Core::System& system_) : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, impl{std::make_unique(system_)} { From a45b8bc9bc64c9a86dd7c5a3e20e0996503754ae Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 19 Feb 2024 23:38:09 -0500 Subject: [PATCH 04/16] audio: rewrite IAudioOutManager --- src/core/CMakeLists.txt | 4 +- src/core/hle/service/audio/audio.cpp | 4 +- .../hle/service/audio/audio_out_manager.cpp | 103 +++++++++++++++ .../hle/service/audio/audio_out_manager.h | 44 +++++++ src/core/hle/service/audio/audout_u.cpp | 118 ------------------ src/core/hle/service/audio/audout_u.h | 37 ------ 6 files changed, 151 insertions(+), 159 deletions(-) create mode 100644 src/core/hle/service/audio/audio_out_manager.cpp create mode 100644 src/core/hle/service/audio/audio_out_manager.h delete mode 100644 src/core/hle/service/audio/audout_u.cpp delete mode 100644 src/core/hle/service/audio/audout_u.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1255ee6bf..c0f828bce 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -493,14 +493,14 @@ add_library(core STATIC hle/service/audio/audio_in_manager.h hle/service/audio/audio_in.cpp hle/service/audio/audio_in.h + hle/service/audio/audio_out_manager.cpp + hle/service/audio/audio_out_manager.h hle/service/audio/audio_out.cpp hle/service/audio/audio_out.h hle/service/audio/audio.cpp hle/service/audio/audio.h hle/service/audio/audio_controller.cpp hle/service/audio/audio_controller.h - hle/service/audio/audout_u.cpp - hle/service/audio/audout_u.h hle/service/audio/audrec_a.cpp hle/service/audio/audrec_a.h hle/service/audio/audrec_u.cpp diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index 7dcfbbfad..aa5b9dbfe 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -5,7 +5,7 @@ #include "core/hle/service/audio/audio.h" #include "core/hle/service/audio/audio_controller.h" #include "core/hle/service/audio/audio_in_manager.h" -#include "core/hle/service/audio/audout_u.h" +#include "core/hle/service/audio/audio_out_manager.h" #include "core/hle/service/audio/audrec_a.h" #include "core/hle/service/audio/audrec_u.h" #include "core/hle/service/audio/audren_u.h" @@ -20,7 +20,7 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService("audctl", std::make_shared(system)); server_manager->RegisterNamedService("audin:u", std::make_shared(system)); - server_manager->RegisterNamedService("audout:u", std::make_shared(system)); + server_manager->RegisterNamedService("audout:u", std::make_shared(system)); server_manager->RegisterNamedService("audrec:a", std::make_shared(system)); server_manager->RegisterNamedService("audrec:u", std::make_shared(system)); server_manager->RegisterNamedService("audren:u", std::make_shared(system)); diff --git a/src/core/hle/service/audio/audio_out_manager.cpp b/src/core/hle/service/audio/audio_out_manager.cpp new file mode 100644 index 000000000..89cd6df94 --- /dev/null +++ b/src/core/hle/service/audio/audio_out_manager.cpp @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/string_util.h" +#include "core/hle/service/audio/audio_out.h" +#include "core/hle/service/audio/audio_out_manager.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/memory.h" + +namespace Service::Audio { +using namespace AudioCore::AudioOut; + +IAudioOutManager::IAudioOutManager(Core::System& system_) + : ServiceFramework{system_, "audout:u"}, impl{std::make_unique(system_)} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"}, + {1, C<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"}, + {2, C<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"}, + {3, C<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IAudioOutManager::~IAudioOutManager() = default; + +Result IAudioOutManager::ListAudioOuts( + OutArray out_audio_outs, Out out_count) { + R_RETURN(this->ListAudioOutsAuto(out_audio_outs, out_count)); +} + +Result IAudioOutManager::OpenAudioOut(Out out_parameter_internal, + Out> out_audio_out, + OutArray out_name, + InArray name, + AudioOutParameter parameter, + InCopyHandle process_handle, + ClientAppletResourceUserId aruid) { + R_RETURN(this->OpenAudioOutAuto(out_parameter_internal, out_audio_out, out_name, name, + parameter, process_handle, aruid)); +} + +Result IAudioOutManager::ListAudioOutsAuto( + OutArray out_audio_outs, Out out_count) { + if (!out_audio_outs.empty()) { + out_audio_outs[0] = AudioDeviceName("DeviceOut"); + *out_count = 1; + LOG_DEBUG(Service_Audio, "called. \nName=DeviceOut"); + } else { + *out_count = 0; + LOG_DEBUG(Service_Audio, "called. Empty buffer passed in."); + } + + R_SUCCEED(); +} + +Result IAudioOutManager::OpenAudioOutAuto( + Out out_parameter_internal, + Out> out_audio_out, + OutArray out_name, + InArray name, AudioOutParameter parameter, + InCopyHandle process_handle, ClientAppletResourceUserId aruid) { + if (!process_handle) { + LOG_ERROR(Service_Audio, "Failed to get process handle"); + R_THROW(ResultUnknown); + } + if (name.empty() || out_name.empty()) { + LOG_ERROR(Service_Audio, "Invalid buffers"); + R_THROW(ResultUnknown); + } + + size_t new_session_id{}; + R_TRY(impl->LinkToManager()); + R_TRY(impl->AcquireSessionId(new_session_id)); + + const auto name_buffer = std::span(reinterpret_cast(name[0].name.data()), 0x100); + const auto device_name = Common::StringFromBuffer(name_buffer); + + LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id, + impl->num_free_sessions); + + auto audio_out = std::make_shared(system, *impl, new_session_id, device_name, + parameter, process_handle.Get(), aruid.pid); + R_TRY(audio_out->GetImpl()->GetSystem().Initialize(device_name, parameter, process_handle.Get(), + aruid.pid)); + + *out_audio_out = audio_out; + impl->sessions[new_session_id] = audio_out->GetImpl(); + impl->applet_resource_user_ids[new_session_id] = aruid.pid; + + auto& out_system = impl->sessions[new_session_id]->GetSystem(); + *out_parameter_internal = + AudioOutParameterInternal{.sample_rate = out_system.GetSampleRate(), + .channel_count = out_system.GetChannelCount(), + .sample_format = static_cast(out_system.GetSampleFormat()), + .state = static_cast(out_system.GetState())}; + + R_SUCCEED(); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_out_manager.h b/src/core/hle/service/audio/audio_out_manager.h new file mode 100644 index 000000000..eaa27bc79 --- /dev/null +++ b/src/core/hle/service/audio/audio_out_manager.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/audio_out_manager.h" +#include "audio_core/out/audio_out.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { + +using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName; +class IAudioOut; + +class IAudioOutManager final : public ServiceFramework { +public: + explicit IAudioOutManager(Core::System& system_); + ~IAudioOutManager() override; + +private: + Result ListAudioOuts(OutArray out_audio_outs, + Out out_count); + Result OpenAudioOut(Out out_parameter_internal, + Out> out_audio_out, + OutArray out_name, + InArray name, + AudioCore::AudioOut::AudioOutParameter parameter, + InCopyHandle process_handle, + ClientAppletResourceUserId aruid); + Result ListAudioOutsAuto(OutArray out_audio_outs, + Out out_count); + Result OpenAudioOutAuto( + Out out_parameter_internal, + Out> out_audio_out, + OutArray out_name, + InArray name, + AudioCore::AudioOut::AudioOutParameter parameter, + InCopyHandle process_handle, ClientAppletResourceUserId aruid); + + std::unique_ptr impl; +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp deleted file mode 100644 index 5364177ba..000000000 --- a/src/core/hle/service/audio/audout_u.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/string_util.h" -#include "core/hle/service/audio/audio_out.h" -#include "core/hle/service/audio/audout_u.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/memory.h" - -namespace Service::Audio { -using namespace AudioCore::AudioOut; - -AudOutU::AudOutU(Core::System& system_) - : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, - impl{std::make_unique(system_)} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &AudOutU::ListAudioOuts, "ListAudioOuts"}, - {1, &AudOutU::OpenAudioOut, "OpenAudioOut"}, - {2, &AudOutU::ListAudioOuts, "ListAudioOutsAuto"}, - {3, &AudOutU::OpenAudioOut, "OpenAudioOutAuto"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -AudOutU::~AudOutU() = default; - -void AudOutU::ListAudioOuts(HLERequestContext& ctx) { - using namespace AudioCore::Renderer; - - std::scoped_lock l{impl->mutex}; - - const auto write_count = - static_cast(ctx.GetWriteBufferNumElements()); - std::vector device_names{}; - if (write_count > 0) { - device_names.emplace_back("DeviceOut"); - LOG_DEBUG(Service_Audio, "called. \nName=DeviceOut"); - } else { - LOG_DEBUG(Service_Audio, "called. Empty buffer passed in."); - } - - ctx.WriteBuffer(device_names); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(device_names.size())); -} - -void AudOutU::OpenAudioOut(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto in_params{rp.PopRaw()}; - auto applet_resource_user_id{rp.PopRaw()}; - const auto device_name_data{ctx.ReadBuffer()}; - auto device_name = Common::StringFromBuffer(device_name_data); - auto handle{ctx.GetCopyHandle(0)}; - - auto process{ctx.GetObjectFromHandle(handle)}; - if (process.IsNull()) { - LOG_ERROR(Service_Audio, "Failed to get process handle"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultUnknown); - return; - } - - auto link{impl->LinkToManager()}; - if (link.IsError()) { - LOG_ERROR(Service_Audio, "Failed to link Audio Out to Audio Manager"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(link); - return; - } - - size_t new_session_id{}; - auto result{impl->AcquireSessionId(new_session_id)}; - if (result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id, - impl->num_free_sessions); - - auto audio_out = - std::make_shared(system, *impl, new_session_id, device_name, in_params, - process.GetPointerUnsafe(), applet_resource_user_id); - result = audio_out->GetImpl()->GetSystem().Initialize( - device_name, in_params, process.GetPointerUnsafe(), applet_resource_user_id); - if (result.IsError()) { - LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - impl->sessions[new_session_id] = audio_out->GetImpl(); - impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; - - auto& out_system = impl->sessions[new_session_id]->GetSystem(); - AudioOutParameterInternal out_params{.sample_rate = out_system.GetSampleRate(), - .channel_count = out_system.GetChannelCount(), - .sample_format = - static_cast(out_system.GetSampleFormat()), - .state = static_cast(out_system.GetState())}; - - IPC::ResponseBuilder rb{ctx, 6, 0, 1}; - - ctx.WriteBuffer(out_system.GetName()); - - rb.Push(ResultSuccess); - rb.PushRaw(out_params); - rb.PushIpcInterface(audio_out); -} - -} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h deleted file mode 100644 index 8f288c6e0..000000000 --- a/src/core/hle/service/audio/audout_u.h +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "audio_core/audio_out_manager.h" -#include "audio_core/out/audio_out.h" -#include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace AudioCore::AudioOut { -class Manager; -class Out; -} // namespace AudioCore::AudioOut - -namespace Service::Audio { - -class IAudioOut; - -class AudOutU final : public ServiceFramework { -public: - explicit AudOutU(Core::System& system_); - ~AudOutU() override; - -private: - void ListAudioOuts(HLERequestContext& ctx); - void OpenAudioOut(HLERequestContext& ctx); - - KernelHelpers::ServiceContext service_context; - std::unique_ptr impl; -}; - -} // namespace Service::Audio From 2e5a9cf119703a595c3e1e34aa233a9843f5871c Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 19 Feb 2024 23:43:00 -0500 Subject: [PATCH 05/16] audio: move IFinalOutputRecorderManager{,ForApplet} --- src/core/CMakeLists.txt | 8 ++++---- src/core/hle/service/audio/audio.cpp | 10 ++++++---- ...{audrec_u.cpp => final_output_recorder_manager.cpp} | 7 ++++--- .../{audrec_a.h => final_output_recorder_manager.h} | 6 +++--- ...pp => final_output_recorder_manager_for_applet.cpp} | 7 ++++--- ..._u.h => final_output_recorder_manager_for_applet.h} | 7 ++++--- 6 files changed, 25 insertions(+), 20 deletions(-) rename src/core/hle/service/audio/{audrec_u.cpp => final_output_recorder_manager.cpp} (83%) rename src/core/hle/service/audio/{audrec_a.h => final_output_recorder_manager.h} (56%) rename src/core/hle/service/audio/{audrec_a.cpp => final_output_recorder_manager_for_applet.cpp} (55%) rename src/core/hle/service/audio/{audrec_u.h => final_output_recorder_manager_for_applet.h} (51%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c0f828bce..68b940af3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -501,13 +501,13 @@ add_library(core STATIC hle/service/audio/audio.h hle/service/audio/audio_controller.cpp hle/service/audio/audio_controller.h - hle/service/audio/audrec_a.cpp - hle/service/audio/audrec_a.h - hle/service/audio/audrec_u.cpp - hle/service/audio/audrec_u.h hle/service/audio/audren_u.cpp hle/service/audio/audren_u.h hle/service/audio/errors.h + hle/service/audio/final_output_recorder_manager_for_applet.cpp + hle/service/audio/final_output_recorder_manager_for_applet.h + hle/service/audio/final_output_recorder_manager.cpp + hle/service/audio/final_output_recorder_manager.h hle/service/audio/hwopus.cpp hle/service/audio/hwopus.h hle/service/bcat/backend/backend.cpp diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index aa5b9dbfe..02773aee5 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -6,9 +6,9 @@ #include "core/hle/service/audio/audio_controller.h" #include "core/hle/service/audio/audio_in_manager.h" #include "core/hle/service/audio/audio_out_manager.h" -#include "core/hle/service/audio/audrec_a.h" -#include "core/hle/service/audio/audrec_u.h" #include "core/hle/service/audio/audren_u.h" +#include "core/hle/service/audio/final_output_recorder_manager.h" +#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h" #include "core/hle/service/audio/hwopus.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" @@ -21,8 +21,10 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService("audctl", std::make_shared(system)); server_manager->RegisterNamedService("audin:u", std::make_shared(system)); server_manager->RegisterNamedService("audout:u", std::make_shared(system)); - server_manager->RegisterNamedService("audrec:a", std::make_shared(system)); - server_manager->RegisterNamedService("audrec:u", std::make_shared(system)); + server_manager->RegisterNamedService( + "audrec:a", std::make_shared(system)); + server_manager->RegisterNamedService("audrec:u", + std::make_shared(system)); server_manager->RegisterNamedService("audren:u", std::make_shared(system)); server_manager->RegisterNamedService("hwopus", std::make_shared(system)); ServerManager::RunServer(std::move(server_manager)); diff --git a/src/core/hle/service/audio/audrec_u.cpp b/src/core/hle/service/audio/final_output_recorder_manager.cpp similarity index 83% rename from src/core/hle/service/audio/audrec_u.cpp rename to src/core/hle/service/audio/final_output_recorder_manager.cpp index bc55cec17..f70a0e62d 100644 --- a/src/core/hle/service/audio/audrec_u.cpp +++ b/src/core/hle/service/audio/final_output_recorder_manager.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/audio/audrec_u.h" +#include "core/hle/service/audio/final_output_recorder_manager.h" namespace Service::Audio { @@ -30,13 +30,14 @@ public: } }; -AudRecU::AudRecU(Core::System& system_) : ServiceFramework{system_, "audrec:u"} { +IFinalOutputRecorderManager::IFinalOutputRecorderManager(Core::System& system_) + : ServiceFramework{system_, "audrec:u"} { static const FunctionInfo functions[] = { {0, nullptr, "OpenFinalOutputRecorder"}, }; RegisterHandlers(functions); } -AudRecU::~AudRecU() = default; +IFinalOutputRecorderManager::~IFinalOutputRecorderManager() = default; } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audrec_a.h b/src/core/hle/service/audio/final_output_recorder_manager.h similarity index 56% rename from src/core/hle/service/audio/audrec_a.h rename to src/core/hle/service/audio/final_output_recorder_manager.h index 9edf89f6c..0663b894e 100644 --- a/src/core/hle/service/audio/audrec_a.h +++ b/src/core/hle/service/audio/final_output_recorder_manager.h @@ -11,10 +11,10 @@ class System; namespace Service::Audio { -class AudRecA final : public ServiceFramework { +class IFinalOutputRecorderManager final : public ServiceFramework { public: - explicit AudRecA(Core::System& system_); - ~AudRecA() override; + explicit IFinalOutputRecorderManager(Core::System& system_); + ~IFinalOutputRecorderManager() override; }; } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp similarity index 55% rename from src/core/hle/service/audio/audrec_a.cpp rename to src/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp index fa82e9ac7..7e2e42bbe 100644 --- a/src/core/hle/service/audio/audrec_a.cpp +++ b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.cpp @@ -1,11 +1,12 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/audio/audrec_a.h" +#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h" namespace Service::Audio { -AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} { +IFinalOutputRecorderManagerForApplet::IFinalOutputRecorderManagerForApplet(Core::System& system_) + : ServiceFramework{system_, "audrec:a"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "RequestSuspend"}, @@ -16,6 +17,6 @@ AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} RegisterHandlers(functions); } -AudRecA::~AudRecA() = default; +IFinalOutputRecorderManagerForApplet::~IFinalOutputRecorderManagerForApplet() = default; } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audrec_u.h b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.h similarity index 51% rename from src/core/hle/service/audio/audrec_u.h rename to src/core/hle/service/audio/final_output_recorder_manager_for_applet.h index 8b4817884..27940f7e0 100644 --- a/src/core/hle/service/audio/audrec_u.h +++ b/src/core/hle/service/audio/final_output_recorder_manager_for_applet.h @@ -11,10 +11,11 @@ class System; namespace Service::Audio { -class AudRecU final : public ServiceFramework { +class IFinalOutputRecorderManagerForApplet final + : public ServiceFramework { public: - explicit AudRecU(Core::System& system_); - ~AudRecU() override; + explicit IFinalOutputRecorderManagerForApplet(Core::System& system_); + ~IFinalOutputRecorderManagerForApplet() override; }; } // namespace Service::Audio From 62083fcafd11348e01cf0d99e2693cb608cca71b Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 00:46:35 -0500 Subject: [PATCH 06/16] audio: split IAudioDevice, IAudioRenderer, move IAudioRendererManager --- src/core/CMakeLists.txt | 12 +- src/core/hle/service/audio/audio.cpp | 5 +- src/core/hle/service/audio/audio_device.cpp | 183 ++++++ src/core/hle/service/audio/audio_device.h | 35 ++ src/core/hle/service/audio/audio_renderer.cpp | 210 +++++++ src/core/hle/service/audio/audio_renderer.h | 45 ++ .../service/audio/audio_renderer_manager.cpp | 143 +++++ .../{audren_u.h => audio_renderer_manager.h} | 7 +- src/core/hle/service/audio/audren_u.cpp | 552 ------------------ 9 files changed, 630 insertions(+), 562 deletions(-) create mode 100644 src/core/hle/service/audio/audio_device.cpp create mode 100644 src/core/hle/service/audio/audio_device.h create mode 100644 src/core/hle/service/audio/audio_renderer.cpp create mode 100644 src/core/hle/service/audio/audio_renderer.h create mode 100644 src/core/hle/service/audio/audio_renderer_manager.cpp rename src/core/hle/service/audio/{audren_u.h => audio_renderer_manager.h} (81%) delete mode 100644 src/core/hle/service/audio/audren_u.cpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 68b940af3..5a1fc83bd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -489,6 +489,10 @@ add_library(core STATIC hle/service/apm/apm_controller.h hle/service/apm/apm_interface.cpp hle/service/apm/apm_interface.h + hle/service/audio/audio_controller.cpp + hle/service/audio/audio_controller.h + hle/service/audio/audio_device.cpp + hle/service/audio/audio_device.h hle/service/audio/audio_in_manager.cpp hle/service/audio/audio_in_manager.h hle/service/audio/audio_in.cpp @@ -497,12 +501,12 @@ add_library(core STATIC hle/service/audio/audio_out_manager.h hle/service/audio/audio_out.cpp hle/service/audio/audio_out.h + hle/service/audio/audio_renderer_manager.cpp + hle/service/audio/audio_renderer_manager.h + hle/service/audio/audio_renderer.cpp + hle/service/audio/audio_renderer.h hle/service/audio/audio.cpp hle/service/audio/audio.h - hle/service/audio/audio_controller.cpp - hle/service/audio/audio_controller.h - hle/service/audio/audren_u.cpp - hle/service/audio/audren_u.h hle/service/audio/errors.h hle/service/audio/final_output_recorder_manager_for_applet.cpp hle/service/audio/final_output_recorder_manager_for_applet.h diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index 02773aee5..82a2ae283 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -6,7 +6,7 @@ #include "core/hle/service/audio/audio_controller.h" #include "core/hle/service/audio/audio_in_manager.h" #include "core/hle/service/audio/audio_out_manager.h" -#include "core/hle/service/audio/audren_u.h" +#include "core/hle/service/audio/audio_renderer_manager.h" #include "core/hle/service/audio/final_output_recorder_manager.h" #include "core/hle/service/audio/final_output_recorder_manager_for_applet.h" #include "core/hle/service/audio/hwopus.h" @@ -25,7 +25,8 @@ void LoopProcess(Core::System& system) { "audrec:a", std::make_shared(system)); server_manager->RegisterNamedService("audrec:u", std::make_shared(system)); - server_manager->RegisterNamedService("audren:u", std::make_shared(system)); + server_manager->RegisterNamedService("audren:u", + std::make_shared(system)); server_manager->RegisterNamedService("hwopus", std::make_shared(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp new file mode 100644 index 000000000..3608d08c7 --- /dev/null +++ b/src/core/hle/service/audio/audio_device.cpp @@ -0,0 +1,183 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "audio_core/audio_core.h" +#include "common/string_util.h" +#include "core/hle/service/audio/audio_device.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::Audio { +using namespace AudioCore::Renderer; + +IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, + u32 device_num) + : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"}, + impl{std::make_unique(system_, applet_resource_user_id, revision)}, + event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { + static const FunctionInfo functions[] = { + {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, + {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, + {2, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolume"}, + {3, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceName"}, + {4, &IAudioDevice::QueryAudioDeviceSystemEvent, "QueryAudioDeviceSystemEvent"}, + {5, &IAudioDevice::GetActiveChannelCount, "GetActiveChannelCount"}, + {6, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceNameAuto"}, + {7, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolumeAuto"}, + {8, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolumeAuto"}, + {10, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceNameAuto"}, + {11, &IAudioDevice::QueryAudioDeviceInputEvent, "QueryAudioDeviceInputEvent"}, + {12, &IAudioDevice::QueryAudioDeviceOutputEvent, "QueryAudioDeviceOutputEvent"}, + {13, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioOutputDeviceName"}, + {14, &IAudioDevice::ListAudioOutputDeviceName, "ListAudioOutputDeviceName"}, + }; + RegisterHandlers(functions); + + event->Signal(); +} + +IAudioDevice::~IAudioDevice() { + service_context.CloseEvent(event); +} + +void IAudioDevice::ListAudioDeviceName(HLERequestContext& ctx) { + const size_t in_count = ctx.GetWriteBufferNumElements(); + + std::vector out_names{}; + + const u32 out_count = impl->ListAudioDeviceName(out_names, in_count); + + std::string out{}; + for (u32 i = 0; i < out_count; i++) { + std::string a{}; + u32 j = 0; + while (out_names[i].name[j] != '\0') { + a += out_names[i].name[j]; + j++; + } + out += "\n\t" + a; + } + + LOG_DEBUG(Service_Audio, "called.\nNames={}", out); + + IPC::ResponseBuilder rb{ctx, 3}; + + ctx.WriteBuffer(out_names); + + rb.Push(ResultSuccess); + rb.Push(out_count); +} + +void IAudioDevice::SetAudioDeviceOutputVolume(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const f32 volume = rp.Pop(); + + const auto device_name_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(device_name_buffer); + + LOG_DEBUG(Service_Audio, "called. name={}, volume={}", name, volume); + + if (name == "AudioTvOutput") { + impl->SetDeviceVolumes(volume); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IAudioDevice::GetAudioDeviceOutputVolume(HLERequestContext& ctx) { + const auto device_name_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(device_name_buffer); + + LOG_DEBUG(Service_Audio, "called. Name={}", name); + + f32 volume{1.0f}; + if (name == "AudioTvOutput") { + volume = impl->GetDeviceVolume(name); + } + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(volume); +} + +void IAudioDevice::GetActiveAudioDeviceName(HLERequestContext& ctx) { + const auto write_size = ctx.GetWriteBufferSize(); + std::string out_name{"AudioTvOutput"}; + + LOG_DEBUG(Service_Audio, "(STUBBED) called. Name={}", out_name); + + out_name.resize(write_size); + + ctx.WriteBuffer(out_name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IAudioDevice::QueryAudioDeviceSystemEvent(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "(STUBBED) called"); + + event->Signal(); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(event->GetReadableEvent()); +} + +void IAudioDevice::GetActiveChannelCount(HLERequestContext& ctx) { + const auto& sink{system.AudioCore().GetOutputSink()}; + u32 channel_count{sink.GetSystemChannels()}; + + LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", channel_count); + + IPC::ResponseBuilder rb{ctx, 3}; + + rb.Push(ResultSuccess); + rb.Push(channel_count); +} + +void IAudioDevice::QueryAudioDeviceInputEvent(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(event->GetReadableEvent()); +} + +void IAudioDevice::QueryAudioDeviceOutputEvent(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(event->GetReadableEvent()); +} + +void IAudioDevice::ListAudioOutputDeviceName(HLERequestContext& ctx) { + const size_t in_count = ctx.GetWriteBufferNumElements(); + + std::vector out_names{}; + + const u32 out_count = impl->ListAudioOutputDeviceName(out_names, in_count); + + std::string out{}; + for (u32 i = 0; i < out_count; i++) { + std::string a{}; + u32 j = 0; + while (out_names[i].name[j] != '\0') { + a += out_names[i].name[j]; + j++; + } + out += "\n\t" + a; + } + + LOG_DEBUG(Service_Audio, "called.\nNames={}", out); + + IPC::ResponseBuilder rb{ctx, 3}; + + ctx.WriteBuffer(out_names); + + rb.Push(ResultSuccess); + rb.Push(out_count); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_device.h b/src/core/hle/service/audio/audio_device.h new file mode 100644 index 000000000..850c60051 --- /dev/null +++ b/src/core/hle/service/audio/audio_device.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/renderer/audio_device.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class IAudioDevice final : public ServiceFramework { + +public: + explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, + u32 device_num); + ~IAudioDevice() override; + +private: + void ListAudioDeviceName(HLERequestContext& ctx); + void SetAudioDeviceOutputVolume(HLERequestContext& ctx); + void GetAudioDeviceOutputVolume(HLERequestContext& ctx); + void GetActiveAudioDeviceName(HLERequestContext& ctx); + void QueryAudioDeviceSystemEvent(HLERequestContext& ctx); + void GetActiveChannelCount(HLERequestContext& ctx); + void QueryAudioDeviceInputEvent(HLERequestContext& ctx); + void QueryAudioDeviceOutputEvent(HLERequestContext& ctx); + void ListAudioOutputDeviceName(HLERequestContext& ctx); + + KernelHelpers::ServiceContext service_context; + std::unique_ptr impl; + Kernel::KEvent* event; +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp new file mode 100644 index 000000000..68415eb8f --- /dev/null +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -0,0 +1,210 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/audio/audio_renderer.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::Audio { +using namespace AudioCore::Renderer; + +IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, + AudioCore::AudioRendererParameterInternal& params, + Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, + u32 process_handle, Kernel::KProcess& process_, + u64 applet_resource_user_id, s32 session_id) + : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, + rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, + impl{std::make_unique(system_, manager, rendered_event)}, process{process_} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, + {1, &IAudioRenderer::GetSampleCount, "GetSampleCount"}, + {2, &IAudioRenderer::GetMixBufferCount, "GetMixBufferCount"}, + {3, &IAudioRenderer::GetState, "GetState"}, + {4, &IAudioRenderer::RequestUpdate, "RequestUpdate"}, + {5, &IAudioRenderer::Start, "Start"}, + {6, &IAudioRenderer::Stop, "Stop"}, + {7, &IAudioRenderer::QuerySystemEvent, "QuerySystemEvent"}, + {8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"}, + {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, + {10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"}, + {11, nullptr, "ExecuteAudioRendererRendering"}, + {12, &IAudioRenderer::SetVoiceDropParameter, "SetVoiceDropParameter"}, + {13, &IAudioRenderer::GetVoiceDropParameter, "GetVoiceDropParameter"}, + }; + // clang-format on + RegisterHandlers(functions); + + process.Open(); + impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, + applet_resource_user_id, session_id); +} + +IAudioRenderer::~IAudioRenderer() { + impl->Finalize(); + service_context.CloseEvent(rendered_event); + process.Close(); +} + +void IAudioRenderer::GetSampleRate(HLERequestContext& ctx) { + const auto sample_rate{impl->GetSystem().GetSampleRate()}; + + LOG_DEBUG(Service_Audio, "called. Sample rate {}", sample_rate); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(sample_rate); +} + +void IAudioRenderer::GetSampleCount(HLERequestContext& ctx) { + const auto sample_count{impl->GetSystem().GetSampleCount()}; + + LOG_DEBUG(Service_Audio, "called. Sample count {}", sample_count); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(sample_count); +} + +void IAudioRenderer::GetState(HLERequestContext& ctx) { + const u32 state{!impl->GetSystem().IsActive()}; + + LOG_DEBUG(Service_Audio, "called, state {}", state); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(state); +} + +void IAudioRenderer::GetMixBufferCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + const auto buffer_count{impl->GetSystem().GetMixBufferCount()}; + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(buffer_count); +} + +void IAudioRenderer::RequestUpdate(HLERequestContext& ctx) { + LOG_TRACE(Service_Audio, "called"); + + const auto input{ctx.ReadBuffer(0)}; + + // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for + // checking size 0. Performance size is 0 for most games. + + auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; + if (is_buffer_b) { + const auto buffersB{ctx.BufferDescriptorB()}; + output_buffer.resize_destructive(buffersB[0].Size()); + performance_buffer.resize_destructive(buffersB[1].Size()); + } else { + const auto buffersC{ctx.BufferDescriptorC()}; + output_buffer.resize_destructive(buffersC[0].Size()); + performance_buffer.resize_destructive(buffersC[1].Size()); + } + + auto result = impl->RequestUpdate(input, performance_buffer, output_buffer); + + if (result.IsSuccess()) { + if (is_buffer_b) { + ctx.WriteBufferB(output_buffer.data(), output_buffer.size(), 0); + ctx.WriteBufferB(performance_buffer.data(), performance_buffer.size(), 1); + } else { + ctx.WriteBufferC(output_buffer.data(), output_buffer.size(), 0); + ctx.WriteBufferC(performance_buffer.data(), performance_buffer.size(), 1); + } + } else { + LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.GetDescription()); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IAudioRenderer::Start(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + impl->Start(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IAudioRenderer::Stop(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + impl->Stop(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IAudioRenderer::QuerySystemEvent(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(Audio::ResultNotSupported); + return; + } + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(rendered_event->GetReadableEvent()); +} + +void IAudioRenderer::SetRenderingTimeLimit(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + IPC::RequestParser rp{ctx}; + auto limit = rp.PopRaw(); + + auto& system_ = impl->GetSystem(); + system_.SetRenderingTimeLimit(limit); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IAudioRenderer::GetRenderingTimeLimit(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + auto& system_ = impl->GetSystem(); + auto time = system_.GetRenderingTimeLimit(); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(time); +} + +void IAudioRenderer::ExecuteAudioRendererRendering(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); +} + +void IAudioRenderer::SetVoiceDropParameter(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + IPC::RequestParser rp{ctx}; + auto voice_drop_param{rp.Pop()}; + + auto& system_ = impl->GetSystem(); + system_.SetVoiceDropParameter(voice_drop_param); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IAudioRenderer::GetVoiceDropParameter(HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + + auto& system_ = impl->GetSystem(); + auto voice_drop_param{system_.GetVoiceDropParameter()}; + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(voice_drop_param); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_renderer.h b/src/core/hle/service/audio/audio_renderer.h new file mode 100644 index 000000000..f8c48154b --- /dev/null +++ b/src/core/hle/service/audio/audio_renderer.h @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/renderer/audio_renderer.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class IAudioRenderer final : public ServiceFramework { +public: + explicit IAudioRenderer(Core::System& system_, AudioCore::Renderer::Manager& manager_, + AudioCore::AudioRendererParameterInternal& params, + Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, + u32 process_handle, Kernel::KProcess& process_, + u64 applet_resource_user_id, s32 session_id); + ~IAudioRenderer() override; + +private: + void GetSampleRate(HLERequestContext& ctx); + void GetSampleCount(HLERequestContext& ctx); + void GetState(HLERequestContext& ctx); + void GetMixBufferCount(HLERequestContext& ctx); + void RequestUpdate(HLERequestContext& ctx); + void Start(HLERequestContext& ctx); + void Stop(HLERequestContext& ctx); + void QuerySystemEvent(HLERequestContext& ctx); + void SetRenderingTimeLimit(HLERequestContext& ctx); + void GetRenderingTimeLimit(HLERequestContext& ctx); + void ExecuteAudioRendererRendering(HLERequestContext& ctx); + void SetVoiceDropParameter(HLERequestContext& ctx); + void GetVoiceDropParameter(HLERequestContext& ctx); + + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* rendered_event; + AudioCore::Renderer::Manager& manager; + std::unique_ptr impl; + Kernel::KProcess& process; + Common::ScratchBuffer output_buffer; + Common::ScratchBuffer performance_buffer; +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_renderer_manager.cpp b/src/core/hle/service/audio/audio_renderer_manager.cpp new file mode 100644 index 000000000..7baa9d8cf --- /dev/null +++ b/src/core/hle/service/audio/audio_renderer_manager.cpp @@ -0,0 +1,143 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "audio_core/audio_render_manager.h" +#include "audio_core/common/feature_support.h" +#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/service/audio/audio_device.h" +#include "core/hle/service/audio/audio_renderer.h" +#include "core/hle/service/audio/audio_renderer_manager.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::Audio { + +using namespace AudioCore::Renderer; + +IAudioRendererManager::IAudioRendererManager(Core::System& system_) + : ServiceFramework{system_, "audren:u"}, service_context{system_, "audren:u"}, + impl{std::make_unique(system_)} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IAudioRendererManager::OpenAudioRenderer, "OpenAudioRenderer"}, + {1, &IAudioRendererManager::GetWorkBufferSize, "GetWorkBufferSize"}, + {2, &IAudioRendererManager::GetAudioDeviceService, "GetAudioDeviceService"}, + {3, nullptr, "OpenAudioRendererForManualExecution"}, + {4, &IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IAudioRendererManager::~IAudioRendererManager() = default; + +void IAudioRendererManager::OpenAudioRenderer(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + AudioCore::AudioRendererParameterInternal params; + rp.PopRaw(params); + rp.Skip(1, false); + auto transfer_memory_size = rp.Pop(); + auto applet_resource_user_id = rp.Pop(); + auto transfer_memory_handle = ctx.GetCopyHandle(0); + auto process_handle = ctx.GetCopyHandle(1); + + if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { + LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(Audio::ResultOutOfSessions); + return; + } + + auto process{ctx.GetObjectFromHandle(process_handle).GetPointerUnsafe()}; + auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; + + const auto session_id{impl->GetSessionId()}; + if (session_id == -1) { + LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(Audio::ResultOutOfSessions); + return; + } + + LOG_DEBUG(Service_Audio, "Opened new AudioRenderer session {} sessions open {}", session_id, + impl->GetSessionCount()); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system, *impl, params, transfer_memory.GetPointerUnsafe(), + transfer_memory_size, process_handle, *process, + applet_resource_user_id, session_id); +} + +void IAudioRendererManager::GetWorkBufferSize(HLERequestContext& ctx) { + AudioCore::AudioRendererParameterInternal params; + + IPC::RequestParser rp{ctx}; + rp.PopRaw(params); + + u64 size{0}; + auto result = impl->GetWorkBufferSize(params, size); + + std::string output_info{}; + output_info += fmt::format("\tRevision {}", AudioCore::GetRevisionNum(params.revision)); + output_info += + fmt::format("\n\tSample Rate {}, Sample Count {}", params.sample_rate, params.sample_count); + output_info += fmt::format("\n\tExecution Mode {}, Voice Drop Enabled {}", + static_cast(params.execution_mode), params.voice_drop_enabled); + output_info += fmt::format( + "\n\tSizes: Effects {:04X}, Mixes {:04X}, Sinks {:04X}, Submixes {:04X}, Splitter Infos " + "{:04X}, Splitter Destinations {:04X}, Voices {:04X}, Performance Frames {:04X} External " + "Context {:04X}", + params.effects, params.mixes, params.sinks, params.sub_mixes, params.splitter_infos, + params.splitter_destinations, params.voices, params.perf_frames, + params.external_context_size); + + LOG_DEBUG(Service_Audio, "called.\nInput params:\n{}\nOutput params:\n\tWorkbuffer size {:08X}", + output_info, size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +void IAudioRendererManager::GetAudioDeviceService(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto applet_resource_user_id = rp.Pop(); + + LOG_DEBUG(Service_Audio, "called. Applet resource id {}", applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + + rb.Push(ResultSuccess); + rb.PushIpcInterface(system, applet_resource_user_id, + ::Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++); +} + +void IAudioRendererManager::OpenAudioRendererForManualExecution(HLERequestContext& ctx) { + LOG_ERROR(Service_Audio, "called. Implement me!"); +} + +void IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) { + struct Parameters { + u32 revision; + u64 applet_resource_user_id; + }; + + IPC::RequestParser rp{ctx}; + + const auto [revision, applet_resource_user_id] = rp.PopRaw(); + + LOG_DEBUG(Service_Audio, "called. Revision {} Applet resource id {}", + AudioCore::GetRevisionNum(revision), applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + + rb.Push(ResultSuccess); + rb.PushIpcInterface(system, applet_resource_user_id, revision, + num_audio_devices++); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audio_renderer_manager.h similarity index 81% rename from src/core/hle/service/audio/audren_u.h rename to src/core/hle/service/audio/audio_renderer_manager.h index 3d7993a16..3623f91c6 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audio_renderer_manager.h @@ -4,7 +4,6 @@ #pragma once #include "audio_core/audio_render_manager.h" -#include "common/scratch_buffer.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" @@ -15,10 +14,10 @@ class System; namespace Service::Audio { class IAudioRenderer; -class AudRenU final : public ServiceFramework { +class IAudioRendererManager final : public ServiceFramework { public: - explicit AudRenU(Core::System& system_); - ~AudRenU() override; + explicit IAudioRendererManager(Core::System& system_); + ~IAudioRendererManager() override; private: void OpenAudioRenderer(HLERequestContext& ctx); diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp deleted file mode 100644 index 10108abc0..000000000 --- a/src/core/hle/service/audio/audren_u.cpp +++ /dev/null @@ -1,552 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -#include "audio_core/audio_core.h" -#include "audio_core/common/audio_renderer_parameter.h" -#include "audio_core/common/feature_support.h" -#include "audio_core/renderer/audio_device.h" -#include "audio_core/renderer/audio_renderer.h" -#include "audio_core/renderer/voice/voice_info.h" -#include "common/alignment.h" -#include "common/bit_util.h" -#include "common/common_funcs.h" -#include "common/logging/log.h" -#include "common/polyfill_ranges.h" -#include "common/scratch_buffer.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/kernel/k_transfer_memory.h" -#include "core/hle/service/audio/audren_u.h" -#include "core/hle/service/audio/errors.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/memory.h" - -using namespace AudioCore::Renderer; - -namespace Service::Audio { - -class IAudioRenderer final : public ServiceFramework { -public: - explicit IAudioRenderer(Core::System& system_, Manager& manager_, - AudioCore::AudioRendererParameterInternal& params, - Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, - u32 process_handle, Kernel::KProcess& process_, - u64 applet_resource_user_id, s32 session_id) - : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, - rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, - impl{std::make_unique(system_, manager, rendered_event)}, process{process_} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, - {1, &IAudioRenderer::GetSampleCount, "GetSampleCount"}, - {2, &IAudioRenderer::GetMixBufferCount, "GetMixBufferCount"}, - {3, &IAudioRenderer::GetState, "GetState"}, - {4, &IAudioRenderer::RequestUpdate, "RequestUpdate"}, - {5, &IAudioRenderer::Start, "Start"}, - {6, &IAudioRenderer::Stop, "Stop"}, - {7, &IAudioRenderer::QuerySystemEvent, "QuerySystemEvent"}, - {8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"}, - {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, - {10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"}, - {11, nullptr, "ExecuteAudioRendererRendering"}, - {12, &IAudioRenderer::SetVoiceDropParameter, "SetVoiceDropParameter"}, - {13, &IAudioRenderer::GetVoiceDropParameter, "GetVoiceDropParameter"}, - }; - // clang-format on - RegisterHandlers(functions); - - process.Open(); - impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, - applet_resource_user_id, session_id); - } - - ~IAudioRenderer() override { - impl->Finalize(); - service_context.CloseEvent(rendered_event); - process.Close(); - } - -private: - void GetSampleRate(HLERequestContext& ctx) { - const auto sample_rate{impl->GetSystem().GetSampleRate()}; - - LOG_DEBUG(Service_Audio, "called. Sample rate {}", sample_rate); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(sample_rate); - } - - void GetSampleCount(HLERequestContext& ctx) { - const auto sample_count{impl->GetSystem().GetSampleCount()}; - - LOG_DEBUG(Service_Audio, "called. Sample count {}", sample_count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(sample_count); - } - - void GetState(HLERequestContext& ctx) { - const u32 state{!impl->GetSystem().IsActive()}; - - LOG_DEBUG(Service_Audio, "called, state {}", state); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(state); - } - - void GetMixBufferCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - const auto buffer_count{impl->GetSystem().GetMixBufferCount()}; - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(buffer_count); - } - - void RequestUpdate(HLERequestContext& ctx) { - LOG_TRACE(Service_Audio, "called"); - - const auto input{ctx.ReadBuffer(0)}; - - // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for - // checking size 0. Performance size is 0 for most games. - - auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; - if (is_buffer_b) { - const auto buffersB{ctx.BufferDescriptorB()}; - output_buffer.resize_destructive(buffersB[0].Size()); - performance_buffer.resize_destructive(buffersB[1].Size()); - } else { - const auto buffersC{ctx.BufferDescriptorC()}; - output_buffer.resize_destructive(buffersC[0].Size()); - performance_buffer.resize_destructive(buffersC[1].Size()); - } - - auto result = impl->RequestUpdate(input, performance_buffer, output_buffer); - - if (result.IsSuccess()) { - if (is_buffer_b) { - ctx.WriteBufferB(output_buffer.data(), output_buffer.size(), 0); - ctx.WriteBufferB(performance_buffer.data(), performance_buffer.size(), 1); - } else { - ctx.WriteBufferC(output_buffer.data(), output_buffer.size(), 0); - ctx.WriteBufferC(performance_buffer.data(), performance_buffer.size(), 1); - } - } else { - LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", - result.GetDescription()); - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void Start(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - impl->Start(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void Stop(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - impl->Stop(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void QuerySystemEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Audio::ResultNotSupported); - return; - } - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(rendered_event->GetReadableEvent()); - } - - void SetRenderingTimeLimit(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - IPC::RequestParser rp{ctx}; - auto limit = rp.PopRaw(); - - auto& system_ = impl->GetSystem(); - system_.SetRenderingTimeLimit(limit); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetRenderingTimeLimit(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto& system_ = impl->GetSystem(); - auto time = system_.GetRenderingTimeLimit(); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(time); - } - - void ExecuteAudioRendererRendering(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - } - - void SetVoiceDropParameter(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - IPC::RequestParser rp{ctx}; - auto voice_drop_param{rp.Pop()}; - - auto& system_ = impl->GetSystem(); - system_.SetVoiceDropParameter(voice_drop_param); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetVoiceDropParameter(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto& system_ = impl->GetSystem(); - auto voice_drop_param{system_.GetVoiceDropParameter()}; - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(voice_drop_param); - } - - KernelHelpers::ServiceContext service_context; - Kernel::KEvent* rendered_event; - Manager& manager; - std::unique_ptr impl; - Kernel::KProcess& process; - Common::ScratchBuffer output_buffer; - Common::ScratchBuffer performance_buffer; -}; - -class IAudioDevice final : public ServiceFramework { - -public: - explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, - u32 device_num) - : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"}, - impl{std::make_unique(system_, applet_resource_user_id, revision)}, - event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { - static const FunctionInfo functions[] = { - {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, - {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, - {2, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolume"}, - {3, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceName"}, - {4, &IAudioDevice::QueryAudioDeviceSystemEvent, "QueryAudioDeviceSystemEvent"}, - {5, &IAudioDevice::GetActiveChannelCount, "GetActiveChannelCount"}, - {6, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceNameAuto"}, - {7, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolumeAuto"}, - {8, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolumeAuto"}, - {10, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceNameAuto"}, - {11, &IAudioDevice::QueryAudioDeviceInputEvent, "QueryAudioDeviceInputEvent"}, - {12, &IAudioDevice::QueryAudioDeviceOutputEvent, "QueryAudioDeviceOutputEvent"}, - {13, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioOutputDeviceName"}, - {14, &IAudioDevice::ListAudioOutputDeviceName, "ListAudioOutputDeviceName"}, - }; - RegisterHandlers(functions); - - event->Signal(); - } - - ~IAudioDevice() override { - service_context.CloseEvent(event); - } - -private: - void ListAudioDeviceName(HLERequestContext& ctx) { - const size_t in_count = ctx.GetWriteBufferNumElements(); - - std::vector out_names{}; - - const u32 out_count = impl->ListAudioDeviceName(out_names, in_count); - - std::string out{}; - for (u32 i = 0; i < out_count; i++) { - std::string a{}; - u32 j = 0; - while (out_names[i].name[j] != '\0') { - a += out_names[i].name[j]; - j++; - } - out += "\n\t" + a; - } - - LOG_DEBUG(Service_Audio, "called.\nNames={}", out); - - IPC::ResponseBuilder rb{ctx, 3}; - - ctx.WriteBuffer(out_names); - - rb.Push(ResultSuccess); - rb.Push(out_count); - } - - void SetAudioDeviceOutputVolume(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const f32 volume = rp.Pop(); - - const auto device_name_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(device_name_buffer); - - LOG_DEBUG(Service_Audio, "called. name={}, volume={}", name, volume); - - if (name == "AudioTvOutput") { - impl->SetDeviceVolumes(volume); - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetAudioDeviceOutputVolume(HLERequestContext& ctx) { - const auto device_name_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(device_name_buffer); - - LOG_DEBUG(Service_Audio, "called. Name={}", name); - - f32 volume{1.0f}; - if (name == "AudioTvOutput") { - volume = impl->GetDeviceVolume(name); - } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(volume); - } - - void GetActiveAudioDeviceName(HLERequestContext& ctx) { - const auto write_size = ctx.GetWriteBufferSize(); - std::string out_name{"AudioTvOutput"}; - - LOG_DEBUG(Service_Audio, "(STUBBED) called. Name={}", out_name); - - out_name.resize(write_size); - - ctx.WriteBuffer(out_name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void QueryAudioDeviceSystemEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "(STUBBED) called"); - - event->Signal(); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); - } - - void GetActiveChannelCount(HLERequestContext& ctx) { - const auto& sink{system.AudioCore().GetOutputSink()}; - u32 channel_count{sink.GetSystemChannels()}; - - LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", channel_count); - - IPC::ResponseBuilder rb{ctx, 3}; - - rb.Push(ResultSuccess); - rb.Push(channel_count); - } - - void QueryAudioDeviceInputEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); - } - - void QueryAudioDeviceOutputEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); - } - - void ListAudioOutputDeviceName(HLERequestContext& ctx) { - const size_t in_count = ctx.GetWriteBufferNumElements(); - - std::vector out_names{}; - - const u32 out_count = impl->ListAudioOutputDeviceName(out_names, in_count); - - std::string out{}; - for (u32 i = 0; i < out_count; i++) { - std::string a{}; - u32 j = 0; - while (out_names[i].name[j] != '\0') { - a += out_names[i].name[j]; - j++; - } - out += "\n\t" + a; - } - - LOG_DEBUG(Service_Audio, "called.\nNames={}", out); - - IPC::ResponseBuilder rb{ctx, 3}; - - ctx.WriteBuffer(out_names); - - rb.Push(ResultSuccess); - rb.Push(out_count); - } - - KernelHelpers::ServiceContext service_context; - std::unique_ptr impl; - Kernel::KEvent* event; -}; - -AudRenU::AudRenU(Core::System& system_) - : ServiceFramework{system_, "audren:u"}, - service_context{system_, "audren:u"}, impl{std::make_unique(system_)} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, - {1, &AudRenU::GetWorkBufferSize, "GetWorkBufferSize"}, - {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"}, - {3, nullptr, "OpenAudioRendererForManualExecution"}, - {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -AudRenU::~AudRenU() = default; - -void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - AudioCore::AudioRendererParameterInternal params; - rp.PopRaw(params); - rp.Skip(1, false); - auto transfer_memory_size = rp.Pop(); - auto applet_resource_user_id = rp.Pop(); - auto transfer_memory_handle = ctx.GetCopyHandle(0); - auto process_handle = ctx.GetCopyHandle(1); - - if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { - LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Audio::ResultOutOfSessions); - return; - } - - auto process{ctx.GetObjectFromHandle(process_handle).GetPointerUnsafe()}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - const auto session_id{impl->GetSessionId()}; - if (session_id == -1) { - LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Audio::ResultOutOfSessions); - return; - } - - LOG_DEBUG(Service_Audio, "Opened new AudioRenderer session {} sessions open {}", session_id, - impl->GetSessionCount()); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, *impl, params, transfer_memory.GetPointerUnsafe(), - transfer_memory_size, process_handle, *process, - applet_resource_user_id, session_id); -} - -void AudRenU::GetWorkBufferSize(HLERequestContext& ctx) { - AudioCore::AudioRendererParameterInternal params; - - IPC::RequestParser rp{ctx}; - rp.PopRaw(params); - - u64 size{0}; - auto result = impl->GetWorkBufferSize(params, size); - - std::string output_info{}; - output_info += fmt::format("\tRevision {}", AudioCore::GetRevisionNum(params.revision)); - output_info += - fmt::format("\n\tSample Rate {}, Sample Count {}", params.sample_rate, params.sample_count); - output_info += fmt::format("\n\tExecution Mode {}, Voice Drop Enabled {}", - static_cast(params.execution_mode), params.voice_drop_enabled); - output_info += fmt::format( - "\n\tSizes: Effects {:04X}, Mixes {:04X}, Sinks {:04X}, Submixes {:04X}, Splitter Infos " - "{:04X}, Splitter Destinations {:04X}, Voices {:04X}, Performance Frames {:04X} External " - "Context {:04X}", - params.effects, params.mixes, params.sinks, params.sub_mixes, params.splitter_infos, - params.splitter_destinations, params.voices, params.perf_frames, - params.external_context_size); - - LOG_DEBUG(Service_Audio, "called.\nInput params:\n{}\nOutput params:\n\tWorkbuffer size {:08X}", - output_info, size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void AudRenU::GetAudioDeviceService(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto applet_resource_user_id = rp.Pop(); - - LOG_DEBUG(Service_Audio, "called. Applet resource id {}", applet_resource_user_id); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, applet_resource_user_id, - ::Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++); -} - -void AudRenU::OpenAudioRendererForManualExecution(HLERequestContext& ctx) { - LOG_ERROR(Service_Audio, "called. Implement me!"); -} - -void AudRenU::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) { - struct Parameters { - u32 revision; - u64 applet_resource_user_id; - }; - - IPC::RequestParser rp{ctx}; - - const auto [revision, applet_resource_user_id] = rp.PopRaw(); - - LOG_DEBUG(Service_Audio, "called. Revision {} Applet resource id {}", - AudioCore::GetRevisionNum(revision), applet_resource_user_id); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, applet_resource_user_id, revision, - num_audio_devices++); -} - -} // namespace Service::Audio From f65539504f009bb18409907fef429bf8c70e0508 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 00:55:02 -0500 Subject: [PATCH 07/16] audio: split IHardwarweOpusDecoder, move IHardwareOpusDecoderManager --- src/core/CMakeLists.txt | 6 +- src/core/hle/service/audio/audio.cpp | 5 +- .../service/audio/hardware_opus_decoder.cpp | 265 +++++++++ .../hle/service/audio/hardware_opus_decoder.h | 38 ++ .../audio/hardware_opus_decoder_manager.cpp | 243 +++++++++ ...opus.h => hardware_opus_decoder_manager.h} | 6 +- src/core/hle/service/audio/hwopus.cpp | 502 ------------------ 7 files changed, 556 insertions(+), 509 deletions(-) create mode 100644 src/core/hle/service/audio/hardware_opus_decoder.cpp create mode 100644 src/core/hle/service/audio/hardware_opus_decoder.h create mode 100644 src/core/hle/service/audio/hardware_opus_decoder_manager.cpp rename src/core/hle/service/audio/{hwopus.h => hardware_opus_decoder_manager.h} (83%) delete mode 100644 src/core/hle/service/audio/hwopus.cpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5a1fc83bd..c49560789 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -512,8 +512,10 @@ add_library(core STATIC hle/service/audio/final_output_recorder_manager_for_applet.h hle/service/audio/final_output_recorder_manager.cpp hle/service/audio/final_output_recorder_manager.h - hle/service/audio/hwopus.cpp - hle/service/audio/hwopus.h + hle/service/audio/hardware_opus_decoder_manager.cpp + hle/service/audio/hardware_opus_decoder_manager.h + hle/service/audio/hardware_opus_decoder.cpp + hle/service/audio/hardware_opus_decoder.h hle/service/bcat/backend/backend.cpp hle/service/bcat/backend/backend.h hle/service/bcat/bcat.cpp diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index 82a2ae283..331176bf7 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -9,7 +9,7 @@ #include "core/hle/service/audio/audio_renderer_manager.h" #include "core/hle/service/audio/final_output_recorder_manager.h" #include "core/hle/service/audio/final_output_recorder_manager_for_applet.h" -#include "core/hle/service/audio/hwopus.h" +#include "core/hle/service/audio/hardware_opus_decoder_manager.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" @@ -27,7 +27,8 @@ void LoopProcess(Core::System& system) { std::make_shared(system)); server_manager->RegisterNamedService("audren:u", std::make_shared(system)); - server_manager->RegisterNamedService("hwopus", std::make_shared(system)); + server_manager->RegisterNamedService("hwopus", + std::make_shared(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/audio/hardware_opus_decoder.cpp b/src/core/hle/service/audio/hardware_opus_decoder.cpp new file mode 100644 index 000000000..876bfe334 --- /dev/null +++ b/src/core/hle/service/audio/hardware_opus_decoder.cpp @@ -0,0 +1,265 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/audio/hardware_opus_decoder.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::Audio { + +using namespace AudioCore::OpusDecoder; + +IHardwareOpusDecoder::IHardwareOpusDecoder(Core::System& system_, HardwareOpus& hardware_opus) + : ServiceFramework{system_, "IHardwareOpusDecoder"}, + impl{std::make_unique(system_, hardware_opus)} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IHardwareOpusDecoder::DecodeInterleavedOld, "DecodeInterleavedOld"}, + {1, &IHardwareOpusDecoder::SetContext, "SetContext"}, + {2, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld, "DecodeInterleavedForMultiStreamOld"}, + {3, &IHardwareOpusDecoder::SetContextForMultiStream, "SetContextForMultiStream"}, + {4, &IHardwareOpusDecoder::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"}, + {5, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld, "DecodeInterleavedForMultiStreamWithPerfOld"}, + {6, &IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld, "DecodeInterleavedWithPerfAndResetOld"}, + {7, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, + {8, &IHardwareOpusDecoder::DecodeInterleaved, "DecodeInterleaved"}, + {9, &IHardwareOpusDecoder::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IHardwareOpusDecoder::~IHardwareOpusDecoder() = default; + +Result IHardwareOpusDecoder::Initialize(OpusParametersEx& params, + Kernel::KTransferMemory* transfer_memory, + u64 transfer_memory_size) { + return impl->Initialize(params, transfer_memory, transfer_memory_size); +} + +Result IHardwareOpusDecoder::Initialize(OpusMultiStreamParametersEx& params, + Kernel::KTransferMemory* transfer_memory, + u64 transfer_memory_size) { + return impl->Initialize(params, transfer_memory, transfer_memory_size); +} + +void IHardwareOpusDecoder::DecodeInterleavedOld(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + auto result = + impl->DecodeInterleaved(&size, nullptr, &sample_count, input_data, output_data, false); + + LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); +} + +void IHardwareOpusDecoder::SetContext(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + LOG_DEBUG(Service_Audio, "called"); + + auto input_data{ctx.ReadBuffer(0)}; + auto result = impl->SetContext(input_data); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + auto result = impl->DecodeInterleavedForMultiStream(&size, nullptr, &sample_count, input_data, + output_data, false); + + LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); +} + +void IHardwareOpusDecoder::SetContextForMultiStream(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + LOG_DEBUG(Service_Audio, "called"); + + auto input_data{ctx.ReadBuffer(0)}; + auto result = impl->SetContext(input_data); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHardwareOpusDecoder::DecodeInterleavedWithPerfOld(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + u64 time_taken{}; + auto result = + impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, false); + + LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size, + sample_count, time_taken); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); + rb.Push(time_taken); +} + +void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + u64 time_taken{}; + auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, + input_data, output_data, false); + + LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size, + sample_count, time_taken); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); + rb.Push(time_taken); +} + +void IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto reset{rp.Pop()}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + u64 time_taken{}; + auto result = + impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset); + + LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, + size, sample_count, time_taken); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); + rb.Push(time_taken); +} + +void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld( + HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto reset{rp.Pop()}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + u64 time_taken{}; + auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, + input_data, output_data, reset); + + LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, + size, sample_count, time_taken); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); + rb.Push(time_taken); +} + +void IHardwareOpusDecoder::DecodeInterleaved(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto reset{rp.Pop()}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + u64 time_taken{}; + auto result = + impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset); + + LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, + size, sample_count, time_taken); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); + rb.Push(time_taken); +} + +void IHardwareOpusDecoder::DecodeInterleavedForMultiStream(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto reset{rp.Pop()}; + + auto input_data{ctx.ReadBuffer(0)}; + output_data.resize_destructive(ctx.GetWriteBufferSize()); + + u32 size{}; + u32 sample_count{}; + u64 time_taken{}; + auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, + input_data, output_data, reset); + + LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, + size, sample_count, time_taken); + + ctx.WriteBuffer(output_data); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(result); + rb.Push(size); + rb.Push(sample_count); + rb.Push(time_taken); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/hardware_opus_decoder.h b/src/core/hle/service/audio/hardware_opus_decoder.h new file mode 100644 index 000000000..fe6636ce6 --- /dev/null +++ b/src/core/hle/service/audio/hardware_opus_decoder.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "audio_core/opus/decoder.h" +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class IHardwareOpusDecoder final : public ServiceFramework { +public: + explicit IHardwareOpusDecoder(Core::System& system_, + AudioCore::OpusDecoder::HardwareOpus& hardware_opus); + ~IHardwareOpusDecoder() override; + + Result Initialize(AudioCore::OpusDecoder::OpusParametersEx& params, + Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); + Result Initialize(AudioCore::OpusDecoder::OpusMultiStreamParametersEx& params, + Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); + +private: + void DecodeInterleavedOld(HLERequestContext& ctx); + void SetContext(HLERequestContext& ctx); + void DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx); + void SetContextForMultiStream(HLERequestContext& ctx); + void DecodeInterleavedWithPerfOld(HLERequestContext& ctx); + void DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx); + void DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx); + void DecodeInterleavedForMultiStreamWithPerfAndResetOld(HLERequestContext& ctx); + void DecodeInterleaved(HLERequestContext& ctx); + void DecodeInterleavedForMultiStream(HLERequestContext& ctx); + + std::unique_ptr impl; + Common::ScratchBuffer output_data; +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp b/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp new file mode 100644 index 000000000..6d7205cd2 --- /dev/null +++ b/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp @@ -0,0 +1,243 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/audio/hardware_opus_decoder.h" +#include "core/hle/service/audio/hardware_opus_decoder_manager.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::Audio { + +using namespace AudioCore::OpusDecoder; + +void IHardwareOpusDecoderManager::OpenHardwareOpusDecoder(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto params = rp.PopRaw(); + auto transfer_memory_size{rp.Pop()}; + auto transfer_memory_handle{ctx.GetCopyHandle(0)}; + auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; + + LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}", + params.sample_rate, params.channel_count, transfer_memory_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + + OpusParametersEx ex{ + .sample_rate = params.sample_rate, + .channel_count = params.channel_count, + .use_large_frame_size = false, + }; + auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(result); + rb.PushIpcInterface(decoder); +} + +void IHardwareOpusDecoderManager::GetWorkBufferSize(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto params = rp.PopRaw(); + + u64 size{}; + auto result = impl.GetWorkBufferSize(params, size); + + LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size 0x{:X}", + params.sample_rate, params.channel_count, size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input{ctx.ReadBuffer()}; + OpusMultiStreamParameters params; + std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters)); + + auto transfer_memory_size{rp.Pop()}; + auto transfer_memory_handle{ctx.GetCopyHandle(0)}; + auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; + + LOG_DEBUG(Service_Audio, + "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " + "transfer_memory_size 0x{:X}", + params.sample_rate, params.channel_count, params.total_stream_count, + params.stereo_stream_count, transfer_memory_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + + OpusMultiStreamParametersEx ex{ + .sample_rate = params.sample_rate, + .channel_count = params.channel_count, + .total_stream_count = params.total_stream_count, + .stereo_stream_count = params.stereo_stream_count, + .use_large_frame_size = false, + .mappings{}, + }; + std::memcpy(ex.mappings.data(), params.mappings.data(), sizeof(params.mappings)); + auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(result); + rb.PushIpcInterface(decoder); +} + +void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input{ctx.ReadBuffer()}; + OpusMultiStreamParameters params; + std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters)); + + u64 size{}; + auto result = impl.GetWorkBufferSizeForMultiStream(params, size); + + LOG_DEBUG(Service_Audio, "size 0x{:X}", size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto params = rp.PopRaw(); + auto transfer_memory_size{rp.Pop()}; + auto transfer_memory_handle{ctx.GetCopyHandle(0)}; + auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; + + LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}", + params.sample_rate, params.channel_count, transfer_memory_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + + auto result = + decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(result); + rb.PushIpcInterface(decoder); +} + +void IHardwareOpusDecoderManager::GetWorkBufferSizeEx(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto params = rp.PopRaw(); + + u64 size{}; + auto result = impl.GetWorkBufferSizeEx(params, size); + + LOG_DEBUG(Service_Audio, "size 0x{:X}", size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input{ctx.ReadBuffer()}; + OpusMultiStreamParametersEx params; + std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); + + auto transfer_memory_size{rp.Pop()}; + auto transfer_memory_handle{ctx.GetCopyHandle(0)}; + auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; + + LOG_DEBUG(Service_Audio, + "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " + "use_large_frame_size {}" + "transfer_memory_size 0x{:X}", + params.sample_rate, params.channel_count, params.total_stream_count, + params.stereo_stream_count, params.use_large_frame_size, transfer_memory_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + + auto result = + decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(result); + rb.PushIpcInterface(decoder); +} + +void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input{ctx.ReadBuffer()}; + OpusMultiStreamParametersEx params; + std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); + + u64 size{}; + auto result = impl.GetWorkBufferSizeForMultiStreamEx(params, size); + + LOG_DEBUG(Service_Audio, + "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " + "use_large_frame_size {} -- returned size 0x{:X}", + params.sample_rate, params.channel_count, params.total_stream_count, + params.stereo_stream_count, params.use_large_frame_size, size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +void IHardwareOpusDecoderManager::GetWorkBufferSizeExEx(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto params = rp.PopRaw(); + + u64 size{}; + auto result = impl.GetWorkBufferSizeExEx(params, size); + + LOG_DEBUG(Service_Audio, "size 0x{:X}", size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto input{ctx.ReadBuffer()}; + OpusMultiStreamParametersEx params; + std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); + + u64 size{}; + auto result = impl.GetWorkBufferSizeForMultiStreamExEx(params, size); + + LOG_DEBUG(Service_Audio, "size 0x{:X}", size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(result); + rb.Push(size); +} + +IHardwareOpusDecoderManager::IHardwareOpusDecoderManager(Core::System& system_) + : ServiceFramework{system_, "hwopus"}, system{system_}, impl{system} { + static const FunctionInfo functions[] = { + {0, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"}, + {1, &IHardwareOpusDecoderManager::GetWorkBufferSize, "GetWorkBufferSize"}, + {2, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream, + "OpenOpusDecoderForMultiStream"}, + {3, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream, + "GetWorkBufferSizeForMultiStream"}, + {4, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"}, + {5, &IHardwareOpusDecoderManager::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"}, + {6, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx, + "OpenHardwareOpusDecoderForMultiStreamEx"}, + {7, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx, + "GetWorkBufferSizeForMultiStreamEx"}, + {8, &IHardwareOpusDecoderManager::GetWorkBufferSizeExEx, "GetWorkBufferSizeExEx"}, + {9, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx, + "GetWorkBufferSizeForMultiStreamExEx"}, + }; + RegisterHandlers(functions); +} + +IHardwareOpusDecoderManager::~IHardwareOpusDecoderManager() = default; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hardware_opus_decoder_manager.h similarity index 83% rename from src/core/hle/service/audio/hwopus.h rename to src/core/hle/service/audio/hardware_opus_decoder_manager.h index d3960065e..29b1f16f5 100644 --- a/src/core/hle/service/audio/hwopus.h +++ b/src/core/hle/service/audio/hardware_opus_decoder_manager.h @@ -12,10 +12,10 @@ class System; namespace Service::Audio { -class HwOpus final : public ServiceFramework { +class IHardwareOpusDecoderManager final : public ServiceFramework { public: - explicit HwOpus(Core::System& system_); - ~HwOpus() override; + explicit IHardwareOpusDecoderManager(Core::System& system_); + ~IHardwareOpusDecoderManager() override; private: void OpenHardwareOpusDecoder(HLERequestContext& ctx); diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp deleted file mode 100644 index 91f33aabd..000000000 --- a/src/core/hle/service/audio/hwopus.cpp +++ /dev/null @@ -1,502 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -#include "audio_core/opus/decoder.h" -#include "audio_core/opus/parameters.h" -#include "common/assert.h" -#include "common/logging/log.h" -#include "common/scratch_buffer.h" -#include "core/core.h" -#include "core/hle/service/audio/hwopus.h" -#include "core/hle/service/ipc_helpers.h" - -namespace Service::Audio { -using namespace AudioCore::OpusDecoder; - -class IHardwareOpusDecoder final : public ServiceFramework { -public: - explicit IHardwareOpusDecoder(Core::System& system_, HardwareOpus& hardware_opus) - : ServiceFramework{system_, "IHardwareOpusDecoder"}, - impl{std::make_unique(system_, hardware_opus)} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IHardwareOpusDecoder::DecodeInterleavedOld, "DecodeInterleavedOld"}, - {1, &IHardwareOpusDecoder::SetContext, "SetContext"}, - {2, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld, "DecodeInterleavedForMultiStreamOld"}, - {3, &IHardwareOpusDecoder::SetContextForMultiStream, "SetContextForMultiStream"}, - {4, &IHardwareOpusDecoder::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"}, - {5, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld, "DecodeInterleavedForMultiStreamWithPerfOld"}, - {6, &IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld, "DecodeInterleavedWithPerfAndResetOld"}, - {7, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, - {8, &IHardwareOpusDecoder::DecodeInterleaved, "DecodeInterleaved"}, - {9, &IHardwareOpusDecoder::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - - Result Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, - u64 transfer_memory_size) { - return impl->Initialize(params, transfer_memory, transfer_memory_size); - } - - Result Initialize(OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, - u64 transfer_memory_size) { - return impl->Initialize(params, transfer_memory, transfer_memory_size); - } - -private: - void DecodeInterleavedOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - auto result = - impl->DecodeInterleaved(&size, nullptr, &sample_count, input_data, output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - } - - void SetContext(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - LOG_DEBUG(Service_Audio, "called"); - - auto input_data{ctx.ReadBuffer(0)}; - auto result = impl->SetContext(input_data); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, nullptr, &sample_count, - input_data, output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - } - - void SetContextForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - LOG_DEBUG(Service_Audio, "called"); - - auto input_data{ctx.ReadBuffer(0)}; - auto result = impl->SetContext(input_data); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } - - void DecodeInterleavedWithPerfOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, - output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size, - sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); - } - - void DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, - input_data, output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size, - sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); - } - - void DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, - output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", - reset, size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); - } - - void DecodeInterleavedForMultiStreamWithPerfAndResetOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, - input_data, output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", - reset, size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); - } - - void DecodeInterleaved(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, - output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", - reset, size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); - } - - void DecodeInterleavedForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, - input_data, output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", - reset, size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); - } - - std::unique_ptr impl; - Common::ScratchBuffer output_data; -}; - -void HwOpus::OpenHardwareOpusDecoder(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto params = rp.PopRaw(); - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - OpusParametersEx ex{ - .sample_rate = params.sample_rate, - .channel_count = params.channel_count, - .use_large_frame_size = false, - }; - auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void HwOpus::GetWorkBufferSize(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw(); - - u64 size{}; - auto result = impl.GetWorkBufferSize(params, size); - - LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size 0x{:X}", - params.sample_rate, params.channel_count, size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void HwOpus::OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParameters params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters)); - - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, - "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " - "transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, params.total_stream_count, - params.stereo_stream_count, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - OpusMultiStreamParametersEx ex{ - .sample_rate = params.sample_rate, - .channel_count = params.channel_count, - .total_stream_count = params.total_stream_count, - .stereo_stream_count = params.stereo_stream_count, - .use_large_frame_size = false, - .mappings{}, - }; - std::memcpy(ex.mappings.data(), params.mappings.data(), sizeof(params.mappings)); - auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void HwOpus::GetWorkBufferSizeForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParameters params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters)); - - u64 size{}; - auto result = impl.GetWorkBufferSizeForMultiStream(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto params = rp.PopRaw(); - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - auto result = - decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void HwOpus::GetWorkBufferSizeEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw(); - - u64 size{}; - auto result = impl.GetWorkBufferSizeEx(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParametersEx params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); - - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, - "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " - "use_large_frame_size {}" - "transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, params.total_stream_count, - params.stereo_stream_count, params.use_large_frame_size, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - auto result = - decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void HwOpus::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParametersEx params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); - - u64 size{}; - auto result = impl.GetWorkBufferSizeForMultiStreamEx(params, size); - - LOG_DEBUG(Service_Audio, - "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " - "use_large_frame_size {} -- returned size 0x{:X}", - params.sample_rate, params.channel_count, params.total_stream_count, - params.stereo_stream_count, params.use_large_frame_size, size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void HwOpus::GetWorkBufferSizeExEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw(); - - u64 size{}; - auto result = impl.GetWorkBufferSizeExEx(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void HwOpus::GetWorkBufferSizeForMultiStreamExEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParametersEx params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); - - u64 size{}; - auto result = impl.GetWorkBufferSizeForMultiStreamExEx(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -HwOpus::HwOpus(Core::System& system_) - : ServiceFramework{system_, "hwopus"}, system{system_}, impl{system} { - static const FunctionInfo functions[] = { - {0, &HwOpus::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"}, - {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, - {2, &HwOpus::OpenHardwareOpusDecoderForMultiStream, "OpenOpusDecoderForMultiStream"}, - {3, &HwOpus::GetWorkBufferSizeForMultiStream, "GetWorkBufferSizeForMultiStream"}, - {4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"}, - {5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"}, - {6, &HwOpus::OpenHardwareOpusDecoderForMultiStreamEx, - "OpenHardwareOpusDecoderForMultiStreamEx"}, - {7, &HwOpus::GetWorkBufferSizeForMultiStreamEx, "GetWorkBufferSizeForMultiStreamEx"}, - {8, &HwOpus::GetWorkBufferSizeExEx, "GetWorkBufferSizeExEx"}, - {9, &HwOpus::GetWorkBufferSizeForMultiStreamExEx, "GetWorkBufferSizeForMultiStreamExEx"}, - }; - RegisterHandlers(functions); -} - -HwOpus::~HwOpus() = default; - -} // namespace Service::Audio From 6012c9fe3af1c649e5ac6392dc4b74bd3cfd0c4f Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 20:02:36 -0500 Subject: [PATCH 08/16] audio: rewrite IAudioRendererManager --- src/audio_core/renderer/audio_renderer.cpp | 7 +- src/audio_core/renderer/audio_renderer.h | 4 +- .../renderer/behavior/info_updater.cpp | 9 +- .../renderer/behavior/info_updater.h | 10 +- .../renderer/memory/pool_mapper.cpp | 22 ++-- src/audio_core/renderer/memory/pool_mapper.h | 14 ++- src/audio_core/renderer/system.cpp | 10 +- src/audio_core/renderer/system.h | 8 +- src/core/hle/service/audio/audio_renderer.cpp | 13 +- src/core/hle/service/audio/audio_renderer.h | 6 +- .../service/audio/audio_renderer_manager.cpp | 115 ++++++------------ .../service/audio/audio_renderer_manager.h | 25 ++-- 12 files changed, 107 insertions(+), 136 deletions(-) diff --git a/src/audio_core/renderer/audio_renderer.cpp b/src/audio_core/renderer/audio_renderer.cpp index df03d03aa..7c728cb86 100644 --- a/src/audio_core/renderer/audio_renderer.cpp +++ b/src/audio_core/renderer/audio_renderer.cpp @@ -17,9 +17,8 @@ Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* ren Result Renderer::Initialize(const AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, - const u64 transfer_memory_size, const u32 process_handle, - Kernel::KProcess& process, const u64 applet_resource_user_id, - const s32 session_id) { + const u64 transfer_memory_size, Kernel::KProcess* process_handle, + const u64 applet_resource_user_id, const s32 session_id) { if (params.execution_mode == ExecutionMode::Auto) { if (!manager.AddSystem(system)) { LOG_ERROR(Service_Audio, @@ -30,7 +29,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params, } initialized = true; - system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, + system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, applet_resource_user_id, session_id); return ResultSuccess; diff --git a/src/audio_core/renderer/audio_renderer.h b/src/audio_core/renderer/audio_renderer.h index 1219f74ca..f16adeda7 100644 --- a/src/audio_core/renderer/audio_renderer.h +++ b/src/audio_core/renderer/audio_renderer.h @@ -38,14 +38,14 @@ public: * @param params - Input parameters to initialize the system with. * @param transfer_memory - Game-supplied memory for all workbuffers. Unused. * @param transfer_memory_size - Size of the transfer memory. Unused. - * @param process_handle - Process handle, also used for memory. Unused. + * @param process_handle - Process handle, also used for memory. * @param applet_resource_user_id - Applet id for this renderer. Unused. * @param session_id - Session id of this renderer. * @return Result code. */ Result Initialize(const AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, - u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id, + Kernel::KProcess* process_handle, u64 applet_resource_user_id, s32 session_id); /** diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 667711e17..163127789 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -18,11 +18,10 @@ namespace AudioCore::Renderer { InfoUpdater::InfoUpdater(std::span input_, std::span output_, - const u32 process_handle_, BehaviorInfo& behaviour_) - : input{input_.data() + sizeof(UpdateDataHeader)}, - input_origin{input_}, output{output_.data() + sizeof(UpdateDataHeader)}, - output_origin{output_}, in_header{reinterpret_cast( - input_origin.data())}, + Kernel::KProcess* process_handle_, BehaviorInfo& behaviour_) + : input{input_.data() + sizeof(UpdateDataHeader)}, input_origin{input_}, + output{output_.data() + sizeof(UpdateDataHeader)}, output_origin{output_}, + in_header{reinterpret_cast(input_origin.data())}, out_header{reinterpret_cast(output_origin.data())}, expected_input_size{input_.size()}, expected_output_size{output_.size()}, process_handle{process_handle_}, behaviour{behaviour_} { diff --git a/src/audio_core/renderer/behavior/info_updater.h b/src/audio_core/renderer/behavior/info_updater.h index fb4b7d25a..4f27a817e 100644 --- a/src/audio_core/renderer/behavior/info_updater.h +++ b/src/audio_core/renderer/behavior/info_updater.h @@ -8,6 +8,10 @@ #include "common/common_types.h" #include "core/hle/service/audio/errors.h" +namespace Kernel { +class KProcess; +} + namespace AudioCore::Renderer { class BehaviorInfo; class VoiceContext; @@ -39,8 +43,8 @@ class InfoUpdater { static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has the wrong size!"); public: - explicit InfoUpdater(std::span input, std::span output, u32 process_handle, - BehaviorInfo& behaviour); + explicit InfoUpdater(std::span input, std::span output, + Kernel::KProcess* process_handle, BehaviorInfo& behaviour); /** * Update the voice channel resources. @@ -197,7 +201,7 @@ private: /// Expected output size, see CheckConsumedSize u64 expected_output_size; /// Unused - u32 process_handle; + Kernel::KProcess* process_handle; /// Behaviour BehaviorInfo& behaviour; }; diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp index 999bb746b..1df786feb 100644 --- a/src/audio_core/renderer/memory/pool_mapper.cpp +++ b/src/audio_core/renderer/memory/pool_mapper.cpp @@ -8,13 +8,13 @@ namespace AudioCore::Renderer { -PoolMapper::PoolMapper(u32 process_handle_, bool force_map_) +PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, bool force_map_) : process_handle{process_handle_}, force_map{force_map_} {} -PoolMapper::PoolMapper(u32 process_handle_, std::span pool_infos_, u32 pool_count_, - bool force_map_) - : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, - pool_count{pool_count_}, force_map{force_map_} {} +PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, std::span pool_infos_, + u32 pool_count_, bool force_map_) + : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, pool_count{pool_count_}, + force_map{force_map_} {} void PoolMapper::ClearUseState(std::span pools, const u32 count) { for (u32 i = 0; i < count; i++) { @@ -106,15 +106,17 @@ bool PoolMapper::IsForceMapEnabled() const { return force_map; } -u32 PoolMapper::GetProcessHandle(const MemoryPoolInfo* pool) const { +Kernel::KProcess* PoolMapper::GetProcessHandle(const MemoryPoolInfo* pool) const { switch (pool->GetLocation()) { case MemoryPoolInfo::Location::CPU: return process_handle; case MemoryPoolInfo::Location::DSP: - return Kernel::Svc::CurrentProcess; + // return Kernel::Svc::CurrentProcess; + return nullptr; } LOG_WARNING(Service_Audio, "Invalid MemoryPoolInfo location!"); - return Kernel::Svc::CurrentProcess; + // return Kernel::Svc::CurrentProcess; + return nullptr; } bool PoolMapper::Map([[maybe_unused]] const u32 handle, [[maybe_unused]] const CpuAddr cpu_addr, @@ -147,14 +149,14 @@ bool PoolMapper::Unmap([[maybe_unused]] const u32 handle, [[maybe_unused]] const } bool PoolMapper::Unmap(MemoryPoolInfo& pool) const { - [[maybe_unused]] u32 handle{0}; + [[maybe_unused]] Kernel::KProcess* handle{}; switch (pool.GetLocation()) { case MemoryPoolInfo::Location::CPU: handle = process_handle; break; case MemoryPoolInfo::Location::DSP: - handle = Kernel::Svc::CurrentProcess; + // handle = Kernel::Svc::CurrentProcess; break; } // nn::audio::dsp::UnmapUserPointer(handle, pool->cpu_address, pool->size); diff --git a/src/audio_core/renderer/memory/pool_mapper.h b/src/audio_core/renderer/memory/pool_mapper.h index 95ae5d8ea..fb5122b73 100644 --- a/src/audio_core/renderer/memory/pool_mapper.h +++ b/src/audio_core/renderer/memory/pool_mapper.h @@ -10,6 +10,10 @@ #include "common/common_types.h" #include "core/hle/service/audio/errors.h" +namespace Kernel { +class KProcess; +} + namespace AudioCore::Renderer { class AddressInfo; @@ -18,9 +22,9 @@ class AddressInfo; */ class PoolMapper { public: - explicit PoolMapper(u32 process_handle, bool force_map); - explicit PoolMapper(u32 process_handle, std::span pool_infos, u32 pool_count, - bool force_map); + explicit PoolMapper(Kernel::KProcess* process_handle, bool force_map); + explicit PoolMapper(Kernel::KProcess* process_handle, std::span pool_infos, + u32 pool_count, bool force_map); /** * Clear the usage state for all given pools. @@ -98,7 +102,7 @@ public: * @return CurrentProcessHandle if location == DSP, * the PoolMapper's process_handle if location == CPU */ - u32 GetProcessHandle(const MemoryPoolInfo* pool) const; + Kernel::KProcess* GetProcessHandle(const MemoryPoolInfo* pool) const; /** * Map the given region with the given handle. This is a no-op. @@ -167,7 +171,7 @@ public: private: /// Process handle for this mapper, used when location == CPU - u32 process_handle; + Kernel::KProcess* process_handle{}; /// List of memory pools assigned to this mapper MemoryPoolInfo* pool_infos{}; /// The number of pools diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index ca656edae..c30d68426 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp @@ -102,8 +102,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_) Result System::Initialize(const AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, - u32 process_handle_, Kernel::KProcess& process_, - u64 applet_resource_user_id_, s32 session_id_) { + Kernel::KProcess* process_handle_, u64 applet_resource_user_id_, + s32 session_id_) { if (!CheckValidRevision(params.revision)) { return Service::Audio::ResultInvalidRevision; } @@ -119,7 +119,6 @@ Result System::Initialize(const AudioRendererParameterInternal& params, behavior.SetUserLibRevision(params.revision); process_handle = process_handle_; - process = &process_; applet_resource_user_id = applet_resource_user_id_; session_id = session_id_; @@ -132,7 +131,8 @@ Result System::Initialize(const AudioRendererParameterInternal& params, render_device = params.rendering_device; execution_mode = params.execution_mode; - process->GetMemory().ZeroBlock(transfer_memory->GetSourceAddress(), transfer_memory_size); + process_handle->GetMemory().ZeroBlock(transfer_memory->GetSourceAddress(), + transfer_memory_size); // Note: We're not actually using the transfer memory because it's a pain to code for. // Allocate the memory normally instead and hope the game doesn't try to read anything back @@ -616,7 +616,7 @@ void System::SendCommandToDsp() { static_cast((time_limit_percent / 100) * 2'880'000.0 * (static_cast(render_time_limit_percent) / 100.0f))}; audio_renderer.SetCommandBuffer(session_id, translated_addr, command_size, time_limit, - applet_resource_user_id, process, + applet_resource_user_id, process_handle, reset_command_buffers); reset_command_buffers = false; command_buffer_size = command_size; diff --git a/src/audio_core/renderer/system.h b/src/audio_core/renderer/system.h index 753a0b796..3533a74ef 100644 --- a/src/audio_core/renderer/system.h +++ b/src/audio_core/renderer/system.h @@ -74,14 +74,14 @@ public: * @param params - Input parameters to initialize the system with. * @param transfer_memory - Game-supplied memory for all workbuffers. Unused. * @param transfer_memory_size - Size of the transfer memory. Unused. - * @param process_handle - Process handle, also used for memory. Unused. + * @param process_handle - Process handle, also used for memory. * @param applet_resource_user_id - Applet id for this renderer. Unused. * @param session_id - Session id of this renderer. * @return Result code. */ Result Initialize(const AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, - u32 process_handle, Kernel::KProcess& process, u64 applet_resource_user_id, + Kernel::KProcess* process_handle, u64 applet_resource_user_id, s32 session_id); /** @@ -278,9 +278,7 @@ private: /// Does what locks do std::mutex lock{}; /// Process this audio render is operating within, used for memory reads/writes. - Kernel::KProcess* process{}; - /// Handle for the process for this system, unused - u32 process_handle{}; + Kernel::KProcess* process_handle{}; /// Applet resource id for this system, unused u64 applet_resource_user_id{}; /// Controls performance input and output diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index 68415eb8f..a408fc3cf 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -10,11 +10,12 @@ using namespace AudioCore::Renderer; IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, AudioCore::AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, - u32 process_handle, Kernel::KProcess& process_, - u64 applet_resource_user_id, s32 session_id) + Kernel::KProcess* process_handle_, u64 applet_resource_user_id, + s32 session_id) : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, - impl{std::make_unique(system_, manager, rendered_event)}, process{process_} { + impl{std::make_unique(system_, manager, rendered_event)}, + process_handle{process_handle_} { // clang-format off static const FunctionInfo functions[] = { {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, @@ -35,15 +36,15 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, // clang-format on RegisterHandlers(functions); - process.Open(); - impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, process, + process_handle->Open(); + impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, applet_resource_user_id, session_id); } IAudioRenderer::~IAudioRenderer() { impl->Finalize(); service_context.CloseEvent(rendered_event); - process.Close(); + process_handle->Close(); } void IAudioRenderer::GetSampleRate(HLERequestContext& ctx) { diff --git a/src/core/hle/service/audio/audio_renderer.h b/src/core/hle/service/audio/audio_renderer.h index f8c48154b..d3e7461ef 100644 --- a/src/core/hle/service/audio/audio_renderer.h +++ b/src/core/hle/service/audio/audio_renderer.h @@ -14,8 +14,8 @@ public: explicit IAudioRenderer(Core::System& system_, AudioCore::Renderer::Manager& manager_, AudioCore::AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, - u32 process_handle, Kernel::KProcess& process_, - u64 applet_resource_user_id, s32 session_id); + Kernel::KProcess* process_handle_, u64 applet_resource_user_id, + s32 session_id); ~IAudioRenderer() override; private: @@ -37,7 +37,7 @@ private: Kernel::KEvent* rendered_event; AudioCore::Renderer::Manager& manager; std::unique_ptr impl; - Kernel::KProcess& process; + Kernel::KProcess* process_handle; Common::ScratchBuffer output_buffer; Common::ScratchBuffer performance_buffer; }; diff --git a/src/core/hle/service/audio/audio_renderer_manager.cpp b/src/core/hle/service/audio/audio_renderer_manager.cpp index 7baa9d8cf..3129169a4 100644 --- a/src/core/hle/service/audio/audio_renderer_manager.cpp +++ b/src/core/hle/service/audio/audio_renderer_manager.cpp @@ -8,22 +8,21 @@ #include "core/hle/service/audio/audio_device.h" #include "core/hle/service/audio/audio_renderer.h" #include "core/hle/service/audio/audio_renderer_manager.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::Audio { using namespace AudioCore::Renderer; IAudioRendererManager::IAudioRendererManager(Core::System& system_) - : ServiceFramework{system_, "audren:u"}, service_context{system_, "audren:u"}, - impl{std::make_unique(system_)} { + : ServiceFramework{system_, "audren:u"}, impl{std::make_unique(system_)} { // clang-format off static const FunctionInfo functions[] = { - {0, &IAudioRendererManager::OpenAudioRenderer, "OpenAudioRenderer"}, - {1, &IAudioRendererManager::GetWorkBufferSize, "GetWorkBufferSize"}, - {2, &IAudioRendererManager::GetAudioDeviceService, "GetAudioDeviceService"}, + {0, C<&IAudioRendererManager::OpenAudioRenderer>, "OpenAudioRenderer"}, + {1, C<&IAudioRendererManager::GetWorkBufferSize>, "GetWorkBufferSize"}, + {2, C<&IAudioRendererManager::GetAudioDeviceService>, "GetAudioDeviceService"}, {3, nullptr, "OpenAudioRendererForManualExecution"}, - {4, &IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, + {4, C<&IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo>, "GetAudioDeviceServiceWithRevisionInfo"}, }; // clang-format on @@ -32,53 +31,38 @@ IAudioRendererManager::IAudioRendererManager(Core::System& system_) IAudioRendererManager::~IAudioRendererManager() = default; -void IAudioRendererManager::OpenAudioRenderer(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - AudioCore::AudioRendererParameterInternal params; - rp.PopRaw(params); - rp.Skip(1, false); - auto transfer_memory_size = rp.Pop(); - auto applet_resource_user_id = rp.Pop(); - auto transfer_memory_handle = ctx.GetCopyHandle(0); - auto process_handle = ctx.GetCopyHandle(1); +Result IAudioRendererManager::OpenAudioRenderer( + Out> out_audio_renderer, + AudioCore::AudioRendererParameterInternal parameter, + InCopyHandle tmem_handle, u64 tmem_size, + InCopyHandle process_handle, ClientAppletResourceUserId aruid) { + LOG_DEBUG(Service_Audio, "called"); if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Audio::ResultOutOfSessions); - return; + R_THROW(Audio::ResultOutOfSessions); } - auto process{ctx.GetObjectFromHandle(process_handle).GetPointerUnsafe()}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - const auto session_id{impl->GetSessionId()}; if (session_id == -1) { LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Audio::ResultOutOfSessions); - return; + R_THROW(Audio::ResultOutOfSessions); } LOG_DEBUG(Service_Audio, "Opened new AudioRenderer session {} sessions open {}", session_id, impl->GetSessionCount()); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, *impl, params, transfer_memory.GetPointerUnsafe(), - transfer_memory_size, process_handle, *process, - applet_resource_user_id, session_id); + *out_audio_renderer = + std::make_shared(system, *impl, parameter, tmem_handle.Get(), tmem_size, + process_handle.Get(), aruid.pid, session_id); + R_SUCCEED(); } -void IAudioRendererManager::GetWorkBufferSize(HLERequestContext& ctx) { - AudioCore::AudioRendererParameterInternal params; +Result IAudioRendererManager::GetWorkBufferSize(Out out_size, + AudioCore::AudioRendererParameterInternal params) { + LOG_DEBUG(Service_Audio, "called"); - IPC::RequestParser rp{ctx}; - rp.PopRaw(params); - - u64 size{0}; - auto result = impl->GetWorkBufferSize(params, size); + R_TRY(impl->GetWorkBufferSize(params, *out_size)) std::string output_info{}; output_info += fmt::format("\tRevision {}", AudioCore::GetRevisionNum(params.revision)); @@ -95,49 +79,26 @@ void IAudioRendererManager::GetWorkBufferSize(HLERequestContext& ctx) { params.external_context_size); LOG_DEBUG(Service_Audio, "called.\nInput params:\n{}\nOutput params:\n\tWorkbuffer size {:08X}", - output_info, size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); + output_info, *out_size); + R_SUCCEED(); } -void IAudioRendererManager::GetAudioDeviceService(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto applet_resource_user_id = rp.Pop(); - - LOG_DEBUG(Service_Audio, "called. Applet resource id {}", applet_resource_user_id); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, applet_resource_user_id, - ::Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++); +Result IAudioRendererManager::GetAudioDeviceService( + Out> out_audio_device, ClientAppletResourceUserId aruid) { + LOG_DEBUG(Service_Audio, "called, aruid={:#x}", aruid.pid); + *out_audio_device = std::make_shared( + system, aruid.pid, Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++); + R_SUCCEED(); } -void IAudioRendererManager::OpenAudioRendererForManualExecution(HLERequestContext& ctx) { - LOG_ERROR(Service_Audio, "called. Implement me!"); -} - -void IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) { - struct Parameters { - u32 revision; - u64 applet_resource_user_id; - }; - - IPC::RequestParser rp{ctx}; - - const auto [revision, applet_resource_user_id] = rp.PopRaw(); - - LOG_DEBUG(Service_Audio, "called. Revision {} Applet resource id {}", - AudioCore::GetRevisionNum(revision), applet_resource_user_id); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, applet_resource_user_id, revision, - num_audio_devices++); +Result IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo( + Out> out_audio_device, u32 revision, + ClientAppletResourceUserId aruid) { + LOG_DEBUG(Service_Audio, "called, revision={} aruid={:#x}", AudioCore::GetRevisionNum(revision), + aruid.pid); + *out_audio_device = + std::make_shared(system, aruid.pid, revision, num_audio_devices++); + R_SUCCEED(); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_renderer_manager.h b/src/core/hle/service/audio/audio_renderer_manager.h index 3623f91c6..69eee664c 100644 --- a/src/core/hle/service/audio/audio_renderer_manager.h +++ b/src/core/hle/service/audio/audio_renderer_manager.h @@ -4,14 +4,12 @@ #pragma once #include "audio_core/audio_render_manager.h" -#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" -namespace Core { -class System; -} - namespace Service::Audio { + +class IAudioDevice; class IAudioRenderer; class IAudioRendererManager final : public ServiceFramework { @@ -20,13 +18,18 @@ public: ~IAudioRendererManager() override; private: - void OpenAudioRenderer(HLERequestContext& ctx); - void GetWorkBufferSize(HLERequestContext& ctx); - void GetAudioDeviceService(HLERequestContext& ctx); - void OpenAudioRendererForManualExecution(HLERequestContext& ctx); - void GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx); + Result OpenAudioRenderer(Out> out_audio_renderer, + AudioCore::AudioRendererParameterInternal parameter, + InCopyHandle tmem_handle, u64 tmem_size, + InCopyHandle process_handle, + ClientAppletResourceUserId aruid); + Result GetWorkBufferSize(Out out_size, + AudioCore::AudioRendererParameterInternal parameter); + Result GetAudioDeviceService(Out> out_audio_device, + ClientAppletResourceUserId aruid); + Result GetAudioDeviceServiceWithRevisionInfo(Out> out_audio_device, + u32 revision, ClientAppletResourceUserId aruid); - KernelHelpers::ServiceContext service_context; std::unique_ptr impl; u32 num_audio_devices{0}; }; From 0471e54e5a74e3171da77ca95f0420142d675947 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 20:16:41 -0500 Subject: [PATCH 09/16] audio: rewrite IAudioRenderer --- src/core/hle/service/audio/audio_renderer.cpp | 200 ++++++------------ src/core/hle/service/audio/audio_renderer.h | 35 +-- src/core/hle/service/cmif_serialization.h | 2 +- 3 files changed, 87 insertions(+), 150 deletions(-) diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index a408fc3cf..fc20054b4 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/audio/audio_renderer.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::Audio { using namespace AudioCore::Renderer; @@ -18,20 +18,20 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, process_handle{process_handle_} { // clang-format off static const FunctionInfo functions[] = { - {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, - {1, &IAudioRenderer::GetSampleCount, "GetSampleCount"}, - {2, &IAudioRenderer::GetMixBufferCount, "GetMixBufferCount"}, - {3, &IAudioRenderer::GetState, "GetState"}, - {4, &IAudioRenderer::RequestUpdate, "RequestUpdate"}, - {5, &IAudioRenderer::Start, "Start"}, - {6, &IAudioRenderer::Stop, "Stop"}, - {7, &IAudioRenderer::QuerySystemEvent, "QuerySystemEvent"}, - {8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"}, - {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, - {10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"}, + {0, C<&IAudioRenderer::GetSampleRate>, "GetSampleRate"}, + {1, C<&IAudioRenderer::GetSampleCount>, "GetSampleCount"}, + {2, C<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"}, + {3, C<&IAudioRenderer::GetState>, "GetState"}, + {4, C<&IAudioRenderer::RequestUpdate>, "RequestUpdate"}, + {5, C<&IAudioRenderer::Start>, "Start"}, + {6, C<&IAudioRenderer::Stop>, "Stop"}, + {7, C<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"}, + {8, C<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"}, + {9, C<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"}, + {10, C<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto"}, {11, nullptr, "ExecuteAudioRendererRendering"}, - {12, &IAudioRenderer::SetVoiceDropParameter, "SetVoiceDropParameter"}, - {13, &IAudioRenderer::GetVoiceDropParameter, "GetVoiceDropParameter"}, + {12, C<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter"}, + {13, C<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter"}, }; // clang-format on RegisterHandlers(functions); @@ -47,165 +47,93 @@ IAudioRenderer::~IAudioRenderer() { process_handle->Close(); } -void IAudioRenderer::GetSampleRate(HLERequestContext& ctx) { - const auto sample_rate{impl->GetSystem().GetSampleRate()}; - - LOG_DEBUG(Service_Audio, "called. Sample rate {}", sample_rate); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(sample_rate); +Result IAudioRenderer::GetSampleRate(Out out_sample_rate) { + *out_sample_rate = impl->GetSystem().GetSampleRate(); + LOG_DEBUG(Service_Audio, "called. Sample rate {}", *out_sample_rate); + R_SUCCEED(); } -void IAudioRenderer::GetSampleCount(HLERequestContext& ctx) { - const auto sample_count{impl->GetSystem().GetSampleCount()}; - - LOG_DEBUG(Service_Audio, "called. Sample count {}", sample_count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(sample_count); +Result IAudioRenderer::GetSampleCount(Out out_sample_count) { + *out_sample_count = impl->GetSystem().GetSampleCount(); + LOG_DEBUG(Service_Audio, "called. Sample count {}", *out_sample_count); + R_SUCCEED(); } -void IAudioRenderer::GetState(HLERequestContext& ctx) { - const u32 state{!impl->GetSystem().IsActive()}; - - LOG_DEBUG(Service_Audio, "called, state {}", state); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(state); +Result IAudioRenderer::GetState(Out out_state) { + *out_state = !impl->GetSystem().IsActive(); + LOG_DEBUG(Service_Audio, "called, state {}", *out_state); + R_SUCCEED(); } -void IAudioRenderer::GetMixBufferCount(HLERequestContext& ctx) { +Result IAudioRenderer::GetMixBufferCount(Out out_mix_buffer_count) { LOG_DEBUG(Service_Audio, "called"); - - const auto buffer_count{impl->GetSystem().GetMixBufferCount()}; - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(buffer_count); + *out_mix_buffer_count = impl->GetSystem().GetMixBufferCount(); + R_SUCCEED(); } -void IAudioRenderer::RequestUpdate(HLERequestContext& ctx) { +Result IAudioRenderer::RequestUpdate(OutBuffer out_buffer, + OutBuffer out_performance_buffer, + InBuffer input) { + R_RETURN(this->RequestUpdateAuto(out_buffer, out_performance_buffer, input)); +} + +Result IAudioRenderer::RequestUpdateAuto( + OutBuffer out_buffer, + OutBuffer out_performance_buffer, + InBuffer input) { LOG_TRACE(Service_Audio, "called"); - const auto input{ctx.ReadBuffer(0)}; - - // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for - // checking size 0. Performance size is 0 for most games. - - auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; - if (is_buffer_b) { - const auto buffersB{ctx.BufferDescriptorB()}; - output_buffer.resize_destructive(buffersB[0].Size()); - performance_buffer.resize_destructive(buffersB[1].Size()); - } else { - const auto buffersC{ctx.BufferDescriptorC()}; - output_buffer.resize_destructive(buffersC[0].Size()); - performance_buffer.resize_destructive(buffersC[1].Size()); - } - - auto result = impl->RequestUpdate(input, performance_buffer, output_buffer); - - if (result.IsSuccess()) { - if (is_buffer_b) { - ctx.WriteBufferB(output_buffer.data(), output_buffer.size(), 0); - ctx.WriteBufferB(performance_buffer.data(), performance_buffer.size(), 1); - } else { - ctx.WriteBufferC(output_buffer.data(), output_buffer.size(), 0); - ctx.WriteBufferC(performance_buffer.data(), performance_buffer.size(), 1); - } - } else { + const auto result = impl->RequestUpdate(input, out_performance_buffer, out_buffer); + if (result.IsFailure()) { LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.GetDescription()); } - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); + R_RETURN(result); } -void IAudioRenderer::Start(HLERequestContext& ctx) { +Result IAudioRenderer::Start() { LOG_DEBUG(Service_Audio, "called"); - impl->Start(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_SUCCEED(); } -void IAudioRenderer::Stop(HLERequestContext& ctx) { +Result IAudioRenderer::Stop() { LOG_DEBUG(Service_Audio, "called"); - impl->Stop(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_SUCCEED(); } -void IAudioRenderer::QuerySystemEvent(HLERequestContext& ctx) { +Result IAudioRenderer::QuerySystemEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "called"); - - if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Audio::ResultNotSupported); - return; - } - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(rendered_event->GetReadableEvent()); + R_UNLESS(impl->GetSystem().GetExecutionMode() != AudioCore::ExecutionMode::Manual, + Audio::ResultNotSupported); + *out_event = &rendered_event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioRenderer::SetRenderingTimeLimit(HLERequestContext& ctx) { +Result IAudioRenderer::SetRenderingTimeLimit(u32 rendering_time_limit) { LOG_DEBUG(Service_Audio, "called"); - - IPC::RequestParser rp{ctx}; - auto limit = rp.PopRaw(); - - auto& system_ = impl->GetSystem(); - system_.SetRenderingTimeLimit(limit); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + impl->GetSystem().SetRenderingTimeLimit(rendering_time_limit); + ; + R_SUCCEED(); } -void IAudioRenderer::GetRenderingTimeLimit(HLERequestContext& ctx) { +Result IAudioRenderer::GetRenderingTimeLimit(Out out_rendering_time_limit) { LOG_DEBUG(Service_Audio, "called"); - - auto& system_ = impl->GetSystem(); - auto time = system_.GetRenderingTimeLimit(); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(time); + *out_rendering_time_limit = impl->GetSystem().GetRenderingTimeLimit(); + R_SUCCEED(); } -void IAudioRenderer::ExecuteAudioRendererRendering(HLERequestContext& ctx) { +Result IAudioRenderer::SetVoiceDropParameter(f32 voice_drop_parameter) { LOG_DEBUG(Service_Audio, "called"); + impl->GetSystem().SetVoiceDropParameter(voice_drop_parameter); + R_SUCCEED(); } -void IAudioRenderer::SetVoiceDropParameter(HLERequestContext& ctx) { +Result IAudioRenderer::GetVoiceDropParameter(Out out_voice_drop_parameter) { LOG_DEBUG(Service_Audio, "called"); - - IPC::RequestParser rp{ctx}; - auto voice_drop_param{rp.Pop()}; - - auto& system_ = impl->GetSystem(); - system_.SetVoiceDropParameter(voice_drop_param); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IAudioRenderer::GetVoiceDropParameter(HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); - - auto& system_ = impl->GetSystem(); - auto voice_drop_param{system_.GetVoiceDropParameter()}; - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(voice_drop_param); + *out_voice_drop_parameter = impl->GetSystem().GetVoiceDropParameter(); + R_SUCCEED(); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_renderer.h b/src/core/hle/service/audio/audio_renderer.h index d3e7461ef..f25c50ce8 100644 --- a/src/core/hle/service/audio/audio_renderer.h +++ b/src/core/hle/service/audio/audio_renderer.h @@ -4,9 +4,14 @@ #pragma once #include "audio_core/renderer/audio_renderer.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" +namespace Kernel { +class KReadableEvent; +} + namespace Service::Audio { class IAudioRenderer final : public ServiceFramework { @@ -19,19 +24,23 @@ public: ~IAudioRenderer() override; private: - void GetSampleRate(HLERequestContext& ctx); - void GetSampleCount(HLERequestContext& ctx); - void GetState(HLERequestContext& ctx); - void GetMixBufferCount(HLERequestContext& ctx); - void RequestUpdate(HLERequestContext& ctx); - void Start(HLERequestContext& ctx); - void Stop(HLERequestContext& ctx); - void QuerySystemEvent(HLERequestContext& ctx); - void SetRenderingTimeLimit(HLERequestContext& ctx); - void GetRenderingTimeLimit(HLERequestContext& ctx); - void ExecuteAudioRendererRendering(HLERequestContext& ctx); - void SetVoiceDropParameter(HLERequestContext& ctx); - void GetVoiceDropParameter(HLERequestContext& ctx); + Result GetSampleRate(Out out_sample_rate); + Result GetSampleCount(Out out_sample_count); + Result GetState(Out out_state); + Result GetMixBufferCount(Out out_mix_buffer_count); + Result RequestUpdate(OutBuffer out_buffer, + OutBuffer out_performance_buffer, + InBuffer input); + Result RequestUpdateAuto(OutBuffer out_buffer, + OutBuffer out_performance_buffer, + InBuffer input); + Result Start(); + Result Stop(); + Result QuerySystemEvent(OutCopyHandle out_event); + Result SetRenderingTimeLimit(u32 rendering_time_limit); + Result GetRenderingTimeLimit(Out out_rendering_time_limit); + Result SetVoiceDropParameter(f32 voice_drop_parameter); + Result GetVoiceDropParameter(Out out_voice_drop_parameter); KernelHelpers::ServiceContext service_context; Kernel::KEvent* rendered_event; diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h index f24682c34..5a5f610f3 100644 --- a/src/core/hle/service/cmif_serialization.h +++ b/src/core/hle/service/cmif_serialization.h @@ -415,7 +415,7 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ auto& buffer = temp[OutBufferIndex]; const size_t size = buffer.size(); - if (ctx.CanWriteBuffer(OutBufferIndex)) { + if (size > 0 && ctx.CanWriteBuffer(OutBufferIndex)) { if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) { ctx.WriteBuffer(buffer.data(), size, OutBufferIndex); } else if constexpr (ArgType::Attr & BufferAttr_HipcMapAlias) { From ea4703cb3111a21bc65588e3e01712b006f4d367 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 20:42:28 -0500 Subject: [PATCH 10/16] audio: rewrite IHardwareOpusDecoderManager --- src/audio_core/opus/decoder.cpp | 6 +- src/audio_core/opus/decoder.h | 6 +- src/audio_core/opus/decoder_manager.cpp | 18 +- src/audio_core/opus/decoder_manager.h | 16 +- src/audio_core/opus/hardware_opus.cpp | 13 +- src/audio_core/opus/hardware_opus.h | 6 +- .../hle/service/audio/audio_controller.cpp | 24 +- src/core/hle/service/audio/audio_in.cpp | 30 +- .../hle/service/audio/audio_in_manager.cpp | 12 +- src/core/hle/service/audio/audio_out.cpp | 28 +- .../hle/service/audio/audio_out_manager.cpp | 8 +- src/core/hle/service/audio/audio_renderer.cpp | 26 +- .../service/audio/audio_renderer_manager.cpp | 8 +- .../service/audio/hardware_opus_decoder.cpp | 4 +- .../hle/service/audio/hardware_opus_decoder.h | 4 +- .../audio/hardware_opus_decoder_manager.cpp | 359 +++++++----------- .../audio/hardware_opus_decoder_manager.h | 45 ++- 17 files changed, 273 insertions(+), 340 deletions(-) diff --git a/src/audio_core/opus/decoder.cpp b/src/audio_core/opus/decoder.cpp index b7fed5304..0c110cbeb 100644 --- a/src/audio_core/opus/decoder.cpp +++ b/src/audio_core/opus/decoder.cpp @@ -28,8 +28,8 @@ OpusDecoder::~OpusDecoder() { } } -Result OpusDecoder::Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, - u64 transfer_memory_size) { +Result OpusDecoder::Initialize(const OpusParametersEx& params, + Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { auto frame_size{params.use_large_frame_size ? 5760 : 1920}; shared_buffer_size = transfer_memory_size; shared_buffer = std::make_unique(shared_buffer_size); @@ -59,7 +59,7 @@ Result OpusDecoder::Initialize(OpusParametersEx& params, Kernel::KTransferMemory R_SUCCEED(); } -Result OpusDecoder::Initialize(OpusMultiStreamParametersEx& params, +Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { auto frame_size{params.use_large_frame_size ? 5760 : 1920}; shared_buffer_size = transfer_memory_size; diff --git a/src/audio_core/opus/decoder.h b/src/audio_core/opus/decoder.h index fd728958a..1b8c257d4 100644 --- a/src/audio_core/opus/decoder.h +++ b/src/audio_core/opus/decoder.h @@ -22,10 +22,10 @@ public: explicit OpusDecoder(Core::System& system, HardwareOpus& hardware_opus_); ~OpusDecoder(); - Result Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, - u64 transfer_memory_size); - Result Initialize(OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, + Result Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); + Result Initialize(const OpusMultiStreamParametersEx& params, + Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); Result DecodeInterleaved(u32* out_data_size, u64* out_time_taken, u32* out_sample_count, std::span input_data, std::span output_data, bool reset); Result SetContext([[maybe_unused]] std::span context); diff --git a/src/audio_core/opus/decoder_manager.cpp b/src/audio_core/opus/decoder_manager.cpp index 1464880a1..89eec1298 100644 --- a/src/audio_core/opus/decoder_manager.cpp +++ b/src/audio_core/opus/decoder_manager.cpp @@ -38,7 +38,7 @@ OpusDecoderManager::OpusDecoderManager(Core::System& system_) } } -Result OpusDecoderManager::GetWorkBufferSize(OpusParameters& params, u64& out_size) { +Result OpusDecoderManager::GetWorkBufferSize(const OpusParameters& params, u32& out_size) { OpusParametersEx ex{ .sample_rate = params.sample_rate, .channel_count = params.channel_count, @@ -47,11 +47,11 @@ Result OpusDecoderManager::GetWorkBufferSize(OpusParameters& params, u64& out_si R_RETURN(GetWorkBufferSizeExEx(ex, out_size)); } -Result OpusDecoderManager::GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size) { +Result OpusDecoderManager::GetWorkBufferSizeEx(const OpusParametersEx& params, u32& out_size) { R_RETURN(GetWorkBufferSizeExEx(params, out_size)); } -Result OpusDecoderManager::GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size) { +Result OpusDecoderManager::GetWorkBufferSizeExEx(const OpusParametersEx& params, u32& out_size) { R_UNLESS(IsValidChannelCount(params.channel_count), ResultInvalidOpusChannelCount); R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate); @@ -63,8 +63,8 @@ Result OpusDecoderManager::GetWorkBufferSizeExEx(OpusParametersEx& params, u64& R_SUCCEED(); } -Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params, - u64& out_size) { +Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(const OpusMultiStreamParameters& params, + u32& out_size) { OpusMultiStreamParametersEx ex{ .sample_rate = params.sample_rate, .channel_count = params.channel_count, @@ -76,13 +76,13 @@ Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(OpusMultiStreamParame R_RETURN(GetWorkBufferSizeForMultiStreamExEx(ex, out_size)); } -Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params, - u64& out_size) { +Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamEx( + const OpusMultiStreamParametersEx& params, u32& out_size) { R_RETURN(GetWorkBufferSizeForMultiStreamExEx(params, out_size)); } -Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params, - u64& out_size) { +Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx( + const OpusMultiStreamParametersEx& params, u32& out_size) { R_UNLESS(IsValidMultiStreamChannelCount(params.channel_count), ResultInvalidOpusChannelCount); R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate); R_UNLESS(IsValidStreamCount(params.channel_count, params.total_stream_count, diff --git a/src/audio_core/opus/decoder_manager.h b/src/audio_core/opus/decoder_manager.h index 70ebc4bab..8f6876d5c 100644 --- a/src/audio_core/opus/decoder_manager.h +++ b/src/audio_core/opus/decoder_manager.h @@ -22,17 +22,19 @@ public: return hardware_opus; } - Result GetWorkBufferSize(OpusParameters& params, u64& out_size); - Result GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size); - Result GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size); - Result GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params, u64& out_size); - Result GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params, u64& out_size); - Result GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params, u64& out_size); + Result GetWorkBufferSize(const OpusParameters& params, u32& out_size); + Result GetWorkBufferSizeEx(const OpusParametersEx& params, u32& out_size); + Result GetWorkBufferSizeExEx(const OpusParametersEx& params, u32& out_size); + Result GetWorkBufferSizeForMultiStream(const OpusMultiStreamParameters& params, u32& out_size); + Result GetWorkBufferSizeForMultiStreamEx(const OpusMultiStreamParametersEx& params, + u32& out_size); + Result GetWorkBufferSizeForMultiStreamExEx(const OpusMultiStreamParametersEx& params, + u32& out_size); private: Core::System& system; HardwareOpus hardware_opus; - std::array required_workbuffer_sizes{}; + std::array required_workbuffer_sizes{}; }; } // namespace AudioCore::OpusDecoder diff --git a/src/audio_core/opus/hardware_opus.cpp b/src/audio_core/opus/hardware_opus.cpp index 5ff71ab2d..30805f4a3 100644 --- a/src/audio_core/opus/hardware_opus.cpp +++ b/src/audio_core/opus/hardware_opus.cpp @@ -42,7 +42,7 @@ HardwareOpus::HardwareOpus(Core::System& system_) opus_decoder.SetSharedMemory(shared_memory); } -u64 HardwareOpus::GetWorkBufferSize(u32 channel) { +u32 HardwareOpus::GetWorkBufferSize(u32 channel) { if (!opus_decoder.IsRunning()) { return 0; } @@ -55,10 +55,10 @@ u64 HardwareOpus::GetWorkBufferSize(u32 channel) { ADSP::OpusDecoder::Message::GetWorkBufferSizeOK, msg); return 0; } - return shared_memory.dsp_return_data[0]; + return static_cast(shared_memory.dsp_return_data[0]); } -u64 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count) { +u32 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count) { std::scoped_lock l{mutex}; shared_memory.host_send_data[0] = total_stream_count; shared_memory.host_send_data[1] = stereo_stream_count; @@ -70,7 +70,7 @@ u64 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 st ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK, msg); return 0; } - return shared_memory.dsp_return_data[0]; + return static_cast(shared_memory.dsp_return_data[0]); } Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer, @@ -94,8 +94,9 @@ Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count, Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count, u32 total_stream_count, - u32 stereo_stream_count, void* mappings, - void* buffer, u64 buffer_size) { + u32 stereo_stream_count, + const void* mappings, void* buffer, + u64 buffer_size) { std::scoped_lock l{mutex}; shared_memory.host_send_data[0] = (u64)buffer; shared_memory.host_send_data[1] = buffer_size; diff --git a/src/audio_core/opus/hardware_opus.h b/src/audio_core/opus/hardware_opus.h index b10184baa..caa746840 100644 --- a/src/audio_core/opus/hardware_opus.h +++ b/src/audio_core/opus/hardware_opus.h @@ -16,14 +16,14 @@ class HardwareOpus { public: HardwareOpus(Core::System& system); - u64 GetWorkBufferSize(u32 channel); - u64 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count); + u32 GetWorkBufferSize(u32 channel); + u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count); Result InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer, u64 buffer_size); Result InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count, u32 totaL_stream_count, u32 stereo_stream_count, - void* mappings, void* buffer, u64 buffer_size); + const void* mappings, void* buffer, u64 buffer_size); Result ShutdownDecodeObject(void* buffer, u64 buffer_size); Result ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size); Result DecodeInterleaved(u32& out_sample_count, void* output_data, u64 output_data_size, diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index a6da66d0f..d51c89118 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp @@ -16,23 +16,23 @@ IAudioController::IAudioController(Core::System& system_) static const FunctionInfo functions[] = { {0, nullptr, "GetTargetVolume"}, {1, nullptr, "SetTargetVolume"}, - {2, C<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"}, - {3, C<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"}, + {2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"}, + {3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"}, {4, nullptr, "IsTargetMute"}, {5, nullptr, "SetTargetMute"}, {6, nullptr, "IsTargetConnected"}, {7, nullptr, "SetDefaultTarget"}, {8, nullptr, "GetDefaultTarget"}, - {9, C<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"}, - {10, C<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"}, + {9, D<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"}, + {10, D<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"}, {11, nullptr, "SetForceMutePolicy"}, - {12, C<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"}, - {13, C<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"}, - {14, C<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"}, + {12, D<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"}, + {13, D<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"}, + {14, D<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"}, {15, nullptr, "SetOutputTarget"}, {16, nullptr, "SetInputTargetForceEnabled"}, - {17, C<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"}, - {18, C<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"}, + {17, D<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"}, + {18, D<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"}, {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, {21, nullptr, "GetAudioOutputTargetForPlayReport"}, @@ -44,11 +44,11 @@ IAudioController::IAudioController(Core::System& system_) {27, nullptr, "SetVolumeMappingTableForDev"}, {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, - {30, C<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"}, - {31, C<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"}, + {30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"}, + {31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"}, {32, nullptr, "GetActiveOutputTarget"}, {33, nullptr, "GetTargetDeviceInfo"}, - {34, C<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"}, + {34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"}, {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, {37, nullptr, "SetHearingProtectionSafeguardEnabled"}, diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp index 31d136077..9240cc336 100644 --- a/src/core/hle/service/audio/audio_in.cpp +++ b/src/core/hle/service/audio/audio_in.cpp @@ -16,21 +16,21 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, impl{std::make_shared(system_, manager, event, session_id)} { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IAudioIn::GetAudioInState>, "GetAudioInState"}, - {1, C<&IAudioIn::Start>, "Start"}, - {2, C<&IAudioIn::Stop>, "Stop"}, - {3, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"}, - {4, C<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"}, - {5, C<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"}, - {6, C<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"}, - {7, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"}, - {8, C<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"}, - {9, C<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"}, - {10, C<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"}, - {11, C<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"}, - {12, C<&IAudioIn::SetDeviceGain>, "SetDeviceGain"}, - {13, C<&IAudioIn::GetDeviceGain>, "GetDeviceGain"}, - {14, C<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"}, + {0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"}, + {1, D<&IAudioIn::Start>, "Start"}, + {2, D<&IAudioIn::Stop>, "Stop"}, + {3, D<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"}, + {4, D<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"}, + {5, D<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"}, + {6, D<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"}, + {7, D<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"}, + {8, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"}, + {9, D<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"}, + {10, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"}, + {11, D<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"}, + {12, D<&IAudioIn::SetDeviceGain>, "SetDeviceGain"}, + {13, D<&IAudioIn::GetDeviceGain>, "GetDeviceGain"}, + {14, D<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"}, }; // clang-format on diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp index 0379a2f68..9b67af367 100644 --- a/src/core/hle/service/audio/audio_in_manager.cpp +++ b/src/core/hle/service/audio/audio_in_manager.cpp @@ -14,12 +14,12 @@ IAudioInManager::IAudioInManager(Core::System& system_) impl{std::make_unique(system_)} { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IAudioInManager::ListAudioIns>, "ListAudioIns"}, - {1, C<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"}, - {2, C<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"}, - {3, C<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"}, - {4, C<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"}, - {5, C<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"}, + {0, D<&IAudioInManager::ListAudioIns>, "ListAudioIns"}, + {1, D<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"}, + {2, D<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"}, + {3, D<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"}, + {4, D<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"}, + {5, D<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"}, }; // clang-format on diff --git a/src/core/hle/service/audio/audio_out.cpp b/src/core/hle/service/audio/audio_out.cpp index cd2dc1f6f..53009d5d7 100644 --- a/src/core/hle/service/audio/audio_out.cpp +++ b/src/core/hle/service/audio/audio_out.cpp @@ -21,20 +21,20 @@ IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id, // clang-format off static const FunctionInfo functions[] = { - {0, C<&IAudioOut::GetAudioOutState>, "GetAudioOutState"}, - {1, C<&IAudioOut::Start>, "Start"}, - {2, C<&IAudioOut::Stop>, "Stop"}, - {3, C<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"}, - {4, C<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"}, - {5, C<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"}, - {6, C<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"}, - {7, C<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"}, - {8, C<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"}, - {9, C<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"}, - {10, C<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"}, - {11, C<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"}, - {12, C<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"}, - {13, C<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"}, + {0, D<&IAudioOut::GetAudioOutState>, "GetAudioOutState"}, + {1, D<&IAudioOut::Start>, "Start"}, + {2, D<&IAudioOut::Stop>, "Stop"}, + {3, D<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"}, + {4, D<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"}, + {5, D<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"}, + {6, D<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"}, + {7, D<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"}, + {8, D<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"}, + {9, D<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"}, + {10, D<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"}, + {11, D<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"}, + {12, D<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"}, + {13, D<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"}, }; // clang-format on RegisterHandlers(functions); diff --git a/src/core/hle/service/audio/audio_out_manager.cpp b/src/core/hle/service/audio/audio_out_manager.cpp index 89cd6df94..780e1dcda 100644 --- a/src/core/hle/service/audio/audio_out_manager.cpp +++ b/src/core/hle/service/audio/audio_out_manager.cpp @@ -14,10 +14,10 @@ IAudioOutManager::IAudioOutManager(Core::System& system_) : ServiceFramework{system_, "audout:u"}, impl{std::make_unique(system_)} { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"}, - {1, C<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"}, - {2, C<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"}, - {3, C<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"}, + {0, D<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"}, + {1, D<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"}, + {2, D<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"}, + {3, D<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"}, }; // clang-format on diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index fc20054b4..b78660cea 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -18,20 +18,20 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, process_handle{process_handle_} { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IAudioRenderer::GetSampleRate>, "GetSampleRate"}, - {1, C<&IAudioRenderer::GetSampleCount>, "GetSampleCount"}, - {2, C<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"}, - {3, C<&IAudioRenderer::GetState>, "GetState"}, - {4, C<&IAudioRenderer::RequestUpdate>, "RequestUpdate"}, - {5, C<&IAudioRenderer::Start>, "Start"}, - {6, C<&IAudioRenderer::Stop>, "Stop"}, - {7, C<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"}, - {8, C<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"}, - {9, C<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"}, - {10, C<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto"}, + {0, D<&IAudioRenderer::GetSampleRate>, "GetSampleRate"}, + {1, D<&IAudioRenderer::GetSampleCount>, "GetSampleCount"}, + {2, D<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"}, + {3, D<&IAudioRenderer::GetState>, "GetState"}, + {4, D<&IAudioRenderer::RequestUpdate>, "RequestUpdate"}, + {5, D<&IAudioRenderer::Start>, "Start"}, + {6, D<&IAudioRenderer::Stop>, "Stop"}, + {7, D<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"}, + {8, D<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"}, + {9, D<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"}, + {10, D<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto"}, {11, nullptr, "ExecuteAudioRendererRendering"}, - {12, C<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter"}, - {13, C<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter"}, + {12, D<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter"}, + {13, D<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter"}, }; // clang-format on RegisterHandlers(functions); diff --git a/src/core/hle/service/audio/audio_renderer_manager.cpp b/src/core/hle/service/audio/audio_renderer_manager.cpp index 3129169a4..6a1345c07 100644 --- a/src/core/hle/service/audio/audio_renderer_manager.cpp +++ b/src/core/hle/service/audio/audio_renderer_manager.cpp @@ -18,11 +18,11 @@ IAudioRendererManager::IAudioRendererManager(Core::System& system_) : ServiceFramework{system_, "audren:u"}, impl{std::make_unique(system_)} { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IAudioRendererManager::OpenAudioRenderer>, "OpenAudioRenderer"}, - {1, C<&IAudioRendererManager::GetWorkBufferSize>, "GetWorkBufferSize"}, - {2, C<&IAudioRendererManager::GetAudioDeviceService>, "GetAudioDeviceService"}, + {0, D<&IAudioRendererManager::OpenAudioRenderer>, "OpenAudioRenderer"}, + {1, D<&IAudioRendererManager::GetWorkBufferSize>, "GetWorkBufferSize"}, + {2, D<&IAudioRendererManager::GetAudioDeviceService>, "GetAudioDeviceService"}, {3, nullptr, "OpenAudioRendererForManualExecution"}, - {4, C<&IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo>, "GetAudioDeviceServiceWithRevisionInfo"}, + {4, D<&IAudioRendererManager::GetAudioDeviceServiceWithRevisionInfo>, "GetAudioDeviceServiceWithRevisionInfo"}, }; // clang-format on diff --git a/src/core/hle/service/audio/hardware_opus_decoder.cpp b/src/core/hle/service/audio/hardware_opus_decoder.cpp index 876bfe334..e398511a6 100644 --- a/src/core/hle/service/audio/hardware_opus_decoder.cpp +++ b/src/core/hle/service/audio/hardware_opus_decoder.cpp @@ -31,13 +31,13 @@ IHardwareOpusDecoder::IHardwareOpusDecoder(Core::System& system_, HardwareOpus& IHardwareOpusDecoder::~IHardwareOpusDecoder() = default; -Result IHardwareOpusDecoder::Initialize(OpusParametersEx& params, +Result IHardwareOpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { return impl->Initialize(params, transfer_memory, transfer_memory_size); } -Result IHardwareOpusDecoder::Initialize(OpusMultiStreamParametersEx& params, +Result IHardwareOpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) { return impl->Initialize(params, transfer_memory, transfer_memory_size); diff --git a/src/core/hle/service/audio/hardware_opus_decoder.h b/src/core/hle/service/audio/hardware_opus_decoder.h index fe6636ce6..121858a6f 100644 --- a/src/core/hle/service/audio/hardware_opus_decoder.h +++ b/src/core/hle/service/audio/hardware_opus_decoder.h @@ -14,9 +14,9 @@ public: AudioCore::OpusDecoder::HardwareOpus& hardware_opus); ~IHardwareOpusDecoder() override; - Result Initialize(AudioCore::OpusDecoder::OpusParametersEx& params, + Result Initialize(const AudioCore::OpusDecoder::OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); - Result Initialize(AudioCore::OpusDecoder::OpusMultiStreamParametersEx& params, + Result Initialize(const AudioCore::OpusDecoder::OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); private: diff --git a/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp b/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp index 6d7205cd2..9de72e30f 100644 --- a/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp +++ b/src/core/hle/service/audio/hardware_opus_decoder_manager.cpp @@ -3,241 +3,154 @@ #include "core/hle/service/audio/hardware_opus_decoder.h" #include "core/hle/service/audio/hardware_opus_decoder_manager.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::Audio { using namespace AudioCore::OpusDecoder; -void IHardwareOpusDecoderManager::OpenHardwareOpusDecoder(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto params = rp.PopRaw(); - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - OpusParametersEx ex{ - .sample_rate = params.sample_rate, - .channel_count = params.channel_count, - .use_large_frame_size = false, - }; - auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void IHardwareOpusDecoderManager::GetWorkBufferSize(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw(); - - u64 size{}; - auto result = impl.GetWorkBufferSize(params, size); - - LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size 0x{:X}", - params.sample_rate, params.channel_count, size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParameters params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters)); - - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, - "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " - "transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, params.total_stream_count, - params.stereo_stream_count, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - OpusMultiStreamParametersEx ex{ - .sample_rate = params.sample_rate, - .channel_count = params.channel_count, - .total_stream_count = params.total_stream_count, - .stereo_stream_count = params.stereo_stream_count, - .use_large_frame_size = false, - .mappings{}, - }; - std::memcpy(ex.mappings.data(), params.mappings.data(), sizeof(params.mappings)); - auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParameters params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters)); - - u64 size{}; - auto result = impl.GetWorkBufferSizeForMultiStream(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto params = rp.PopRaw(); - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - auto result = - decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void IHardwareOpusDecoderManager::GetWorkBufferSizeEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw(); - - u64 size{}; - auto result = impl.GetWorkBufferSizeEx(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParametersEx params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); - - auto transfer_memory_size{rp.Pop()}; - auto transfer_memory_handle{ctx.GetCopyHandle(0)}; - auto transfer_memory{ctx.GetObjectFromHandle(transfer_memory_handle)}; - - LOG_DEBUG(Service_Audio, - "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " - "use_large_frame_size {}" - "transfer_memory_size 0x{:X}", - params.sample_rate, params.channel_count, params.total_stream_count, - params.stereo_stream_count, params.use_large_frame_size, transfer_memory_size); - - auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; - - auto result = - decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(result); - rb.PushIpcInterface(decoder); -} - -void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParametersEx params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); - - u64 size{}; - auto result = impl.GetWorkBufferSizeForMultiStreamEx(params, size); - - LOG_DEBUG(Service_Audio, - "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " - "use_large_frame_size {} -- returned size 0x{:X}", - params.sample_rate, params.channel_count, params.total_stream_count, - params.stereo_stream_count, params.use_large_frame_size, size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void IHardwareOpusDecoderManager::GetWorkBufferSizeExEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw(); - - u64 size{}; - auto result = impl.GetWorkBufferSizeExEx(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - -void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input{ctx.ReadBuffer()}; - OpusMultiStreamParametersEx params; - std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx)); - - u64 size{}; - auto result = impl.GetWorkBufferSizeForMultiStreamExEx(params, size); - - LOG_DEBUG(Service_Audio, "size 0x{:X}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); -} - IHardwareOpusDecoderManager::IHardwareOpusDecoderManager(Core::System& system_) : ServiceFramework{system_, "hwopus"}, system{system_}, impl{system} { + // clang-format off static const FunctionInfo functions[] = { - {0, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"}, - {1, &IHardwareOpusDecoderManager::GetWorkBufferSize, "GetWorkBufferSize"}, - {2, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream, - "OpenOpusDecoderForMultiStream"}, - {3, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream, - "GetWorkBufferSizeForMultiStream"}, - {4, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"}, - {5, &IHardwareOpusDecoderManager::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"}, - {6, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx, - "OpenHardwareOpusDecoderForMultiStreamEx"}, - {7, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx, - "GetWorkBufferSizeForMultiStreamEx"}, - {8, &IHardwareOpusDecoderManager::GetWorkBufferSizeExEx, "GetWorkBufferSizeExEx"}, - {9, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx, - "GetWorkBufferSizeForMultiStreamExEx"}, + {0, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoder>, "OpenHardwareOpusDecoder"}, + {1, D<&IHardwareOpusDecoderManager::GetWorkBufferSize>, "GetWorkBufferSize"}, + {2, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream>, "OpenOpusDecoderForMultiStream"}, + {3, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream>, "GetWorkBufferSizeForMultiStream"}, + {4, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx>, "OpenHardwareOpusDecoderEx"}, + {5, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeEx>, "GetWorkBufferSizeEx"}, + {6, D<&IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx>, "OpenHardwareOpusDecoderForMultiStreamEx"}, + {7, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx>, "GetWorkBufferSizeForMultiStreamEx"}, + {8, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeExEx>, "GetWorkBufferSizeExEx"}, + {9, D<&IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx>, "GetWorkBufferSizeForMultiStreamExEx"}, }; + // clang-format on RegisterHandlers(functions); } IHardwareOpusDecoderManager::~IHardwareOpusDecoderManager() = default; +Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoder( + Out> out_decoder, OpusParameters params, u32 tmem_size, + InCopyHandle tmem_handle) { + LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size {:#x}", + params.sample_rate, params.channel_count, tmem_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + OpusParametersEx ex{ + .sample_rate = params.sample_rate, + .channel_count = params.channel_count, + .use_large_frame_size = false, + }; + R_TRY(decoder->Initialize(ex, tmem_handle.Get(), tmem_size)); + + *out_decoder = decoder; + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::GetWorkBufferSize(Out out_size, OpusParameters params) { + R_TRY(impl.GetWorkBufferSize(params, *out_size)); + LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size {:#x}", + params.sample_rate, params.channel_count, *out_size); + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream( + Out> out_decoder, + InLargeData params, u32 tmem_size, + InCopyHandle tmem_handle) { + LOG_DEBUG(Service_Audio, + "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " + "transfer_memory_size {:#x}", + params->sample_rate, params->channel_count, params->total_stream_count, + params->stereo_stream_count, tmem_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + + OpusMultiStreamParametersEx ex{ + .sample_rate = params->sample_rate, + .channel_count = params->channel_count, + .total_stream_count = params->total_stream_count, + .stereo_stream_count = params->stereo_stream_count, + .use_large_frame_size = false, + .mappings{}, + }; + std::memcpy(ex.mappings.data(), params->mappings.data(), sizeof(params->mappings)); + R_TRY(decoder->Initialize(ex, tmem_handle.Get(), tmem_size)); + + *out_decoder = decoder; + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream( + Out out_size, InLargeData params) { + R_TRY(impl.GetWorkBufferSizeForMultiStream(*params, *out_size)); + LOG_DEBUG(Service_Audio, "size {:#x}", *out_size); + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx( + Out> out_decoder, OpusParametersEx params, u32 tmem_size, + InCopyHandle tmem_handle) { + LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size {:#x}", + params.sample_rate, params.channel_count, tmem_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + R_TRY(decoder->Initialize(params, tmem_handle.Get(), tmem_size)); + + *out_decoder = decoder; + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::GetWorkBufferSizeEx(Out out_size, + OpusParametersEx params) { + R_TRY(impl.GetWorkBufferSizeEx(params, *out_size)); + LOG_DEBUG(Service_Audio, "size {:#x}", *out_size); + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx( + Out> out_decoder, + InLargeData params, u32 tmem_size, + InCopyHandle tmem_handle) { + LOG_DEBUG(Service_Audio, + "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " + "use_large_frame_size {}" + "transfer_memory_size {:#x}", + params->sample_rate, params->channel_count, params->total_stream_count, + params->stereo_stream_count, params->use_large_frame_size, tmem_size); + + auto decoder{std::make_shared(system, impl.GetHardwareOpus())}; + + R_TRY(decoder->Initialize(*params, tmem_handle.Get(), tmem_size)); + + *out_decoder = decoder; + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx( + Out out_size, InLargeData params) { + R_TRY(impl.GetWorkBufferSizeForMultiStreamEx(*params, *out_size)); + LOG_DEBUG(Service_Audio, + "sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} " + "use_large_frame_size {} -- returned size {:#x}", + params->sample_rate, params->channel_count, params->total_stream_count, + params->stereo_stream_count, params->use_large_frame_size, *out_size); + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::GetWorkBufferSizeExEx(Out out_size, + OpusParametersEx params) { + R_TRY(impl.GetWorkBufferSizeExEx(params, *out_size)); + LOG_DEBUG(Service_Audio, "size {:#x}", *out_size); + R_SUCCEED(); +} + +Result IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx( + Out out_size, InLargeData params) { + R_TRY(impl.GetWorkBufferSizeForMultiStreamExEx(*params, *out_size)); + LOG_DEBUG(Service_Audio, "size {:#x}", *out_size); + R_SUCCEED(); +} + } // namespace Service::Audio diff --git a/src/core/hle/service/audio/hardware_opus_decoder_manager.h b/src/core/hle/service/audio/hardware_opus_decoder_manager.h index 29b1f16f5..4f869c517 100644 --- a/src/core/hle/service/audio/hardware_opus_decoder_manager.h +++ b/src/core/hle/service/audio/hardware_opus_decoder_manager.h @@ -4,30 +4,47 @@ #pragma once #include "audio_core/opus/decoder_manager.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" -namespace Core { -class System; -} - namespace Service::Audio { +class IHardwareOpusDecoder; + +using AudioCore::OpusDecoder::OpusMultiStreamParameters; +using AudioCore::OpusDecoder::OpusMultiStreamParametersEx; +using AudioCore::OpusDecoder::OpusParameters; +using AudioCore::OpusDecoder::OpusParametersEx; + class IHardwareOpusDecoderManager final : public ServiceFramework { public: explicit IHardwareOpusDecoderManager(Core::System& system_); ~IHardwareOpusDecoderManager() override; private: - void OpenHardwareOpusDecoder(HLERequestContext& ctx); - void GetWorkBufferSize(HLERequestContext& ctx); - void OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx); - void GetWorkBufferSizeForMultiStream(HLERequestContext& ctx); - void OpenHardwareOpusDecoderEx(HLERequestContext& ctx); - void GetWorkBufferSizeEx(HLERequestContext& ctx); - void OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx); - void GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx); - void GetWorkBufferSizeExEx(HLERequestContext& ctx); - void GetWorkBufferSizeForMultiStreamExEx(HLERequestContext& ctx); + Result OpenHardwareOpusDecoder(Out> out_decoder, + OpusParameters params, u32 tmem_size, + InCopyHandle tmem_handle); + Result GetWorkBufferSize(Out out_size, OpusParameters params); + Result OpenHardwareOpusDecoderForMultiStream( + Out> out_decoder, + InLargeData params, u32 tmem_size, + InCopyHandle tmem_handle); + Result GetWorkBufferSizeForMultiStream( + Out out_size, InLargeData params); + Result OpenHardwareOpusDecoderEx(Out> out_decoder, + OpusParametersEx params, u32 tmem_size, + InCopyHandle tmem_handle); + Result GetWorkBufferSizeEx(Out out_size, OpusParametersEx params); + Result OpenHardwareOpusDecoderForMultiStreamEx( + Out> out_decoder, + InLargeData params, u32 tmem_size, + InCopyHandle tmem_handle); + Result GetWorkBufferSizeForMultiStreamEx( + Out out_size, InLargeData params); + Result GetWorkBufferSizeExEx(Out out_size, OpusParametersEx params); + Result GetWorkBufferSizeForMultiStreamExEx( + Out out_size, InLargeData params); Core::System& system; AudioCore::OpusDecoder::OpusDecoderManager impl; From c575a85233cfea2e0935a5609e4e13d980a8c28f Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 21:17:59 -0500 Subject: [PATCH 11/16] audio: rewrite IAudioDevice --- src/audio_core/renderer/audio_device.cpp | 14 +- src/audio_core/renderer/audio_device.h | 6 +- src/common/string_util.cpp | 4 + src/common/string_util.h | 1 + src/core/hle/service/audio/audio_device.cpp | 182 ++++++++---------- src/core/hle/service/audio/audio_device.h | 41 +++- .../hle/service/audio/audio_in_manager.cpp | 3 +- .../hle/service/audio/audio_out_manager.cpp | 4 +- 8 files changed, 128 insertions(+), 127 deletions(-) diff --git a/src/audio_core/renderer/audio_device.cpp b/src/audio_core/renderer/audio_device.cpp index 2d9bf82bb..5be5594f6 100644 --- a/src/audio_core/renderer/audio_device.cpp +++ b/src/audio_core/renderer/audio_device.cpp @@ -36,8 +36,7 @@ AudioDevice::AudioDevice(Core::System& system, const u64 applet_resource_user_id : output_sink{system.AudioCore().GetOutputSink()}, applet_resource_user_id{applet_resource_user_id_}, user_revision{revision} {} -u32 AudioDevice::ListAudioDeviceName(std::vector& out_buffer, - const size_t max_count) const { +u32 AudioDevice::ListAudioDeviceName(std::span out_buffer) const { std::span names{}; if (CheckFeatureSupported(SupportTags::AudioUsbDeviceOutput, user_revision)) { @@ -46,19 +45,18 @@ u32 AudioDevice::ListAudioDeviceName(std::vector& out_buffer, names = device_names; } - const u32 out_count{static_cast(std::min(max_count, names.size()))}; + const u32 out_count{static_cast(std::min(out_buffer.size(), names.size()))}; for (u32 i = 0; i < out_count; i++) { - out_buffer.push_back(names[i]); + out_buffer[i] = names[i]; } return out_count; } -u32 AudioDevice::ListAudioOutputDeviceName(std::vector& out_buffer, - const size_t max_count) const { - const u32 out_count{static_cast(std::min(max_count, output_device_names.size()))}; +u32 AudioDevice::ListAudioOutputDeviceName(std::span out_buffer) const { + const u32 out_count{static_cast(std::min(out_buffer.size(), output_device_names.size()))}; for (u32 i = 0; i < out_count; i++) { - out_buffer.push_back(output_device_names[i]); + out_buffer[i] = output_device_names[i]; } return out_count; } diff --git a/src/audio_core/renderer/audio_device.h b/src/audio_core/renderer/audio_device.h index ca4040add..4242dad30 100644 --- a/src/audio_core/renderer/audio_device.h +++ b/src/audio_core/renderer/audio_device.h @@ -36,20 +36,18 @@ public: * Get a list of the available output devices. * * @param out_buffer - Output buffer to write the available device names. - * @param max_count - Maximum number of devices to write (count of out_buffer). * @return Number of device names written. */ - u32 ListAudioDeviceName(std::vector& out_buffer, size_t max_count) const; + u32 ListAudioDeviceName(std::span out_buffer) const; /** * Get a list of the available output devices. * Different to above somehow... * * @param out_buffer - Output buffer to write the available device names. - * @param max_count - Maximum number of devices to write (count of out_buffer). * @return Number of device names written. */ - u32 ListAudioOutputDeviceName(std::vector& out_buffer, size_t max_count) const; + u32 ListAudioOutputDeviceName(std::span out_buffer) const; /** * Set the volume of all streams in the backend sink. diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 72c481798..1909aced5 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -38,6 +38,10 @@ std::string StringFromBuffer(std::span data) { return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); } +std::string StringFromBuffer(std::span data) { + return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); +} + // Turns " hej " into "hej". Also handles tabs. std::string StripSpaces(const std::string& str) { const std::size_t s = str.find_first_not_of(" \t\r\n"); diff --git a/src/common/string_util.h b/src/common/string_util.h index 9da1ca4e9..53d0549ca 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -19,6 +19,7 @@ namespace Common { [[nodiscard]] std::string ToUpper(std::string str); [[nodiscard]] std::string StringFromBuffer(std::span data); +[[nodiscard]] std::string StringFromBuffer(std::span data); [[nodiscard]] std::string StripSpaces(const std::string& s); [[nodiscard]] std::string StripQuotes(const std::string& s); diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp index 3608d08c7..438f3cccd 100644 --- a/src/core/hle/service/audio/audio_device.cpp +++ b/src/core/hle/service/audio/audio_device.cpp @@ -4,7 +4,7 @@ #include "audio_core/audio_core.h" #include "common/string_util.h" #include "core/hle/service/audio/audio_device.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::Audio { using namespace AudioCore::Renderer; @@ -15,20 +15,20 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u impl{std::make_unique(system_, applet_resource_user_id, revision)}, event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { static const FunctionInfo functions[] = { - {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, - {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, - {2, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolume"}, - {3, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceName"}, - {4, &IAudioDevice::QueryAudioDeviceSystemEvent, "QueryAudioDeviceSystemEvent"}, - {5, &IAudioDevice::GetActiveChannelCount, "GetActiveChannelCount"}, - {6, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceNameAuto"}, - {7, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolumeAuto"}, - {8, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolumeAuto"}, - {10, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceNameAuto"}, - {11, &IAudioDevice::QueryAudioDeviceInputEvent, "QueryAudioDeviceInputEvent"}, - {12, &IAudioDevice::QueryAudioDeviceOutputEvent, "QueryAudioDeviceOutputEvent"}, - {13, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioOutputDeviceName"}, - {14, &IAudioDevice::ListAudioOutputDeviceName, "ListAudioOutputDeviceName"}, + {0, D<&IAudioDevice::ListAudioDeviceName>, "ListAudioDeviceName"}, + {1, D<&IAudioDevice::SetAudioDeviceOutputVolume>, "SetAudioDeviceOutputVolume"}, + {2, D<&IAudioDevice::GetAudioDeviceOutputVolume>, "GetAudioDeviceOutputVolume"}, + {3, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioDeviceName"}, + {4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"}, + {5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"}, + {6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"}, + {7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"}, + {8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"}, + {10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"}, + {11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"}, + {12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"}, + {13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"}, + {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"}, }; RegisterHandlers(functions); @@ -39,15 +39,33 @@ IAudioDevice::~IAudioDevice() { service_context.CloseEvent(event); } -void IAudioDevice::ListAudioDeviceName(HLERequestContext& ctx) { - const size_t in_count = ctx.GetWriteBufferNumElements(); +Result IAudioDevice::ListAudioDeviceName( + OutArray out_names, Out out_count) { + R_RETURN(this->ListAudioDeviceNameAuto(out_names, out_count)); +} - std::vector out_names{}; +Result IAudioDevice::SetAudioDeviceOutputVolume( + InArray name, f32 volume) { + R_RETURN(this->SetAudioDeviceOutputVolumeAuto(name, volume)); +} - const u32 out_count = impl->ListAudioDeviceName(out_names, in_count); +Result IAudioDevice::GetAudioDeviceOutputVolume( + Out out_volume, InArray name) { + R_RETURN(this->GetAudioDeviceOutputVolumeAuto(out_volume, name)); +} + +Result IAudioDevice::GetActiveAudioDeviceName( + OutArray out_name) { + R_RETURN(this->GetActiveAudioDeviceNameAuto(out_name)); +} + +Result IAudioDevice::ListAudioDeviceNameAuto( + OutArray out_names, + Out out_count) { + *out_count = impl->ListAudioDeviceName(out_names); std::string out{}; - for (u32 i = 0; i < out_count; i++) { + for (s32 i = 0; i < *out_count; i++) { std::string a{}; u32 j = 0; while (out_names[i].name[j] != '\0') { @@ -58,109 +76,77 @@ void IAudioDevice::ListAudioDeviceName(HLERequestContext& ctx) { } LOG_DEBUG(Service_Audio, "called.\nNames={}", out); - - IPC::ResponseBuilder rb{ctx, 3}; - - ctx.WriteBuffer(out_names); - - rb.Push(ResultSuccess); - rb.Push(out_count); + R_SUCCEED(); } -void IAudioDevice::SetAudioDeviceOutputVolume(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const f32 volume = rp.Pop(); +Result IAudioDevice::SetAudioDeviceOutputVolumeAuto( + InArray name, f32 volume) { + R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer); - const auto device_name_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(device_name_buffer); + const std::string device_name = Common::StringFromBuffer(name[0].name); + LOG_DEBUG(Service_Audio, "called. name={}, volume={}", device_name, volume); - LOG_DEBUG(Service_Audio, "called. name={}, volume={}", name, volume); - - if (name == "AudioTvOutput") { + if (device_name == "AudioTvOutput") { impl->SetDeviceVolumes(volume); } - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_SUCCEED(); } -void IAudioDevice::GetAudioDeviceOutputVolume(HLERequestContext& ctx) { - const auto device_name_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(device_name_buffer); +Result IAudioDevice::GetAudioDeviceOutputVolumeAuto( + Out out_volume, InArray name) { + R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer); - LOG_DEBUG(Service_Audio, "called. Name={}", name); + const std::string device_name = Common::StringFromBuffer(name[0].name); + LOG_DEBUG(Service_Audio, "called. Name={}", device_name); - f32 volume{1.0f}; - if (name == "AudioTvOutput") { - volume = impl->GetDeviceVolume(name); + *out_volume = 1.0f; + if (device_name == "AudioTvOutput") { + *out_volume = impl->GetDeviceVolume(device_name); } - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(volume); + R_SUCCEED(); } -void IAudioDevice::GetActiveAudioDeviceName(HLERequestContext& ctx) { - const auto write_size = ctx.GetWriteBufferSize(); - std::string out_name{"AudioTvOutput"}; - - LOG_DEBUG(Service_Audio, "(STUBBED) called. Name={}", out_name); - - out_name.resize(write_size); - - ctx.WriteBuffer(out_name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IAudioDevice::QueryAudioDeviceSystemEvent(HLERequestContext& ctx) { +Result IAudioDevice::GetActiveAudioDeviceNameAuto( + OutArray out_name) { + R_UNLESS(!out_name.empty(), Audio::ResultInsufficientBuffer); + out_name[0] = AudioDevice::AudioDeviceName("AudioTvOutput"); LOG_DEBUG(Service_Audio, "(STUBBED) called"); + R_SUCCEED(); +} +Result IAudioDevice::QueryAudioDeviceSystemEvent(OutCopyHandle out_event) { + LOG_DEBUG(Service_Audio, "(STUBBED) called"); event->Signal(); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); + *out_event = &event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioDevice::GetActiveChannelCount(HLERequestContext& ctx) { - const auto& sink{system.AudioCore().GetOutputSink()}; - u32 channel_count{sink.GetSystemChannels()}; - - LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", channel_count); - - IPC::ResponseBuilder rb{ctx, 3}; - - rb.Push(ResultSuccess); - rb.Push(channel_count); -} - -void IAudioDevice::QueryAudioDeviceInputEvent(HLERequestContext& ctx) { +Result IAudioDevice::QueryAudioDeviceInputEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); + *out_event = &event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioDevice::QueryAudioDeviceOutputEvent(HLERequestContext& ctx) { +Result IAudioDevice::QueryAudioDeviceOutputEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); + *out_event = &event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioDevice::ListAudioOutputDeviceName(HLERequestContext& ctx) { - const size_t in_count = ctx.GetWriteBufferNumElements(); +Result IAudioDevice::GetActiveChannelCount(Out out_active_channel_count) { + *out_active_channel_count = system.AudioCore().GetOutputSink().GetSystemChannels(); + LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", *out_active_channel_count); + R_SUCCEED(); +} - std::vector out_names{}; - - const u32 out_count = impl->ListAudioOutputDeviceName(out_names, in_count); +Result IAudioDevice::ListAudioOutputDeviceName( + OutArray out_names, Out out_count) { + *out_count = impl->ListAudioOutputDeviceName(out_names); std::string out{}; - for (u32 i = 0; i < out_count; i++) { + for (s32 i = 0; i < *out_count; i++) { std::string a{}; u32 j = 0; while (out_names[i].name[j] != '\0') { @@ -171,13 +157,7 @@ void IAudioDevice::ListAudioOutputDeviceName(HLERequestContext& ctx) { } LOG_DEBUG(Service_Audio, "called.\nNames={}", out); - - IPC::ResponseBuilder rb{ctx, 3}; - - ctx.WriteBuffer(out_names); - - rb.Push(ResultSuccess); - rb.Push(out_count); + R_SUCCEED(); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_device.h b/src/core/hle/service/audio/audio_device.h index 850c60051..752157272 100644 --- a/src/core/hle/service/audio/audio_device.h +++ b/src/core/hle/service/audio/audio_device.h @@ -4,11 +4,18 @@ #pragma once #include "audio_core/renderer/audio_device.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" +namespace Kernel { +class KReadableEvent; +} + namespace Service::Audio { +using AudioCore::Renderer::AudioDevice; + class IAudioDevice final : public ServiceFramework { public: @@ -17,15 +24,31 @@ public: ~IAudioDevice() override; private: - void ListAudioDeviceName(HLERequestContext& ctx); - void SetAudioDeviceOutputVolume(HLERequestContext& ctx); - void GetAudioDeviceOutputVolume(HLERequestContext& ctx); - void GetActiveAudioDeviceName(HLERequestContext& ctx); - void QueryAudioDeviceSystemEvent(HLERequestContext& ctx); - void GetActiveChannelCount(HLERequestContext& ctx); - void QueryAudioDeviceInputEvent(HLERequestContext& ctx); - void QueryAudioDeviceOutputEvent(HLERequestContext& ctx); - void ListAudioOutputDeviceName(HLERequestContext& ctx); + Result ListAudioDeviceName( + OutArray out_names, + Out out_count); + Result SetAudioDeviceOutputVolume( + InArray name, f32 volume); + Result GetAudioDeviceOutputVolume( + Out out_volume, InArray name); + Result GetActiveAudioDeviceName( + OutArray out_name); + Result ListAudioDeviceNameAuto( + OutArray out_names, + Out out_count); + Result SetAudioDeviceOutputVolumeAuto( + InArray name, f32 volume); + Result GetAudioDeviceOutputVolumeAuto( + Out out_volume, InArray name); + Result GetActiveAudioDeviceNameAuto( + OutArray out_name); + Result QueryAudioDeviceSystemEvent(OutCopyHandle out_event); + Result QueryAudioDeviceInputEvent(OutCopyHandle out_event); + Result QueryAudioDeviceOutputEvent(OutCopyHandle out_event); + Result GetActiveChannelCount(Out out_active_channel_count); + Result ListAudioOutputDeviceName( + OutArray out_names, + Out out_count); KernelHelpers::ServiceContext service_context; std::unique_ptr impl; diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp index 9b67af367..d55da17c8 100644 --- a/src/core/hle/service/audio/audio_in_manager.cpp +++ b/src/core/hle/service/audio/audio_in_manager.cpp @@ -96,8 +96,7 @@ Result IAudioInManager::OpenAudioInProtocolSpecified( LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id, impl->num_free_sessions); - const auto name_buffer = std::span(reinterpret_cast(name[0].name.data()), 0x100); - const auto device_name = Common::StringFromBuffer(name_buffer); + const auto device_name = Common::StringFromBuffer(name[0].name); *out_audio_in = std::make_shared(system, *impl, new_session_id, device_name, parameter, process_handle.Get(), aruid.pid); impl->sessions[new_session_id] = (*out_audio_in)->GetImpl(); diff --git a/src/core/hle/service/audio/audio_out_manager.cpp b/src/core/hle/service/audio/audio_out_manager.cpp index 780e1dcda..153445097 100644 --- a/src/core/hle/service/audio/audio_out_manager.cpp +++ b/src/core/hle/service/audio/audio_out_manager.cpp @@ -75,9 +75,7 @@ Result IAudioOutManager::OpenAudioOutAuto( R_TRY(impl->LinkToManager()); R_TRY(impl->AcquireSessionId(new_session_id)); - const auto name_buffer = std::span(reinterpret_cast(name[0].name.data()), 0x100); - const auto device_name = Common::StringFromBuffer(name_buffer); - + const auto device_name = Common::StringFromBuffer(name[0].name); LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id, impl->num_free_sessions); From 5f90bd88daf997f9da1f97c1ffe97d3be46e3d0c Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 22:15:28 -0500 Subject: [PATCH 12/16] audio: rewrite IHardwareOpusDecoder --- .../service/audio/hardware_opus_decoder.cpp | 296 ++++++------------ .../hle/service/audio/hardware_opus_decoder.h | 45 ++- 2 files changed, 123 insertions(+), 218 deletions(-) diff --git a/src/core/hle/service/audio/hardware_opus_decoder.cpp b/src/core/hle/service/audio/hardware_opus_decoder.cpp index e398511a6..03d3374c1 100644 --- a/src/core/hle/service/audio/hardware_opus_decoder.cpp +++ b/src/core/hle/service/audio/hardware_opus_decoder.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/audio/hardware_opus_decoder.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::Audio { @@ -13,16 +13,16 @@ IHardwareOpusDecoder::IHardwareOpusDecoder(Core::System& system_, HardwareOpus& impl{std::make_unique(system_, hardware_opus)} { // clang-format off static const FunctionInfo functions[] = { - {0, &IHardwareOpusDecoder::DecodeInterleavedOld, "DecodeInterleavedOld"}, - {1, &IHardwareOpusDecoder::SetContext, "SetContext"}, - {2, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld, "DecodeInterleavedForMultiStreamOld"}, - {3, &IHardwareOpusDecoder::SetContextForMultiStream, "SetContextForMultiStream"}, - {4, &IHardwareOpusDecoder::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"}, - {5, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld, "DecodeInterleavedForMultiStreamWithPerfOld"}, - {6, &IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld, "DecodeInterleavedWithPerfAndResetOld"}, - {7, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, - {8, &IHardwareOpusDecoder::DecodeInterleaved, "DecodeInterleaved"}, - {9, &IHardwareOpusDecoder::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"}, + {0, D<&IHardwareOpusDecoder::DecodeInterleavedOld>, "DecodeInterleavedOld"}, + {1, D<&IHardwareOpusDecoder::SetContext>, "SetContext"}, + {2, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld>, "DecodeInterleavedForMultiStreamOld"}, + {3, D<&IHardwareOpusDecoder::SetContextForMultiStream>, "SetContextForMultiStream"}, + {4, D<&IHardwareOpusDecoder::DecodeInterleavedWithPerfOld>, "DecodeInterleavedWithPerfOld"}, + {5, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld>, "DecodeInterleavedForMultiStreamWithPerfOld"}, + {6, D<&IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld>, "DecodeInterleavedWithPerfAndResetOld"}, + {7, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld>, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, + {8, D<&IHardwareOpusDecoder::DecodeInterleaved>, "DecodeInterleaved"}, + {9, D<&IHardwareOpusDecoder::DecodeInterleavedForMultiStream>, "DecodeInterleavedForMultiStream"}, }; // clang-format on @@ -43,223 +43,103 @@ Result IHardwareOpusDecoder::Initialize(const OpusMultiStreamParametersEx& param return impl->Initialize(params, transfer_memory, transfer_memory_size); } -void IHardwareOpusDecoder::DecodeInterleavedOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - auto result = - impl->DecodeInterleaved(&size, nullptr, &sample_count, input_data, output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); +Result IHardwareOpusDecoder::DecodeInterleavedOld(OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, + InBuffer opus_data) { + R_TRY(impl->DecodeInterleaved(out_data_size, nullptr, out_sample_count, opus_data, out_pcm_data, + false)); + LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {}", *out_data_size, + *out_sample_count); + R_SUCCEED(); } -void IHardwareOpusDecoder::SetContext(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - +Result IHardwareOpusDecoder::SetContext(InBuffer decoder_context) { LOG_DEBUG(Service_Audio, "called"); - - auto input_data{ctx.ReadBuffer(0)}; - auto result = impl->SetContext(input_data); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); + R_RETURN(impl->SetContext(decoder_context)); } -void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, nullptr, &sample_count, input_data, - output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); +Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld( + OutBuffer out_pcm_data, Out out_data_size, + Out out_sample_count, InBuffer opus_data) { + R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, nullptr, out_sample_count, opus_data, + out_pcm_data, false)); + LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {}", *out_data_size, + *out_sample_count); + R_SUCCEED(); } -void IHardwareOpusDecoder::SetContextForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - +Result IHardwareOpusDecoder::SetContextForMultiStream( + InBuffer decoder_context) { LOG_DEBUG(Service_Audio, "called"); - - auto input_data{ctx.ReadBuffer(0)}; - auto result = impl->SetContext(input_data); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); + R_RETURN(impl->SetContext(decoder_context)); } -void IHardwareOpusDecoder::DecodeInterleavedWithPerfOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = - impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size, - sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); +Result IHardwareOpusDecoder::DecodeInterleavedWithPerfOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data) { + R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data, + out_pcm_data, false)); + LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {} time taken {}", *out_data_size, + *out_sample_count, *out_time_taken); + R_SUCCEED(); } -void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, - input_data, output_data, false); - - LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size, - sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); +Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data) { + R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count, + opus_data, out_pcm_data, false)); + LOG_DEBUG(Service_Audio, "bytes read {:#x} samples generated {} time taken {}", *out_data_size, + *out_sample_count, *out_time_taken); + R_SUCCEED(); } -void IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = - impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, - size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); +Result IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, bool reset) { + R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data, + out_pcm_data, reset)); + LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset, + *out_data_size, *out_sample_count, *out_time_taken); + R_SUCCEED(); } -void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld( - HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, - input_data, output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, - size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); +Result IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, bool reset) { + R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count, + opus_data, out_pcm_data, reset)); + LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset, + *out_data_size, *out_sample_count, *out_time_taken); + R_SUCCEED(); } -void IHardwareOpusDecoder::DecodeInterleaved(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = - impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, - size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); +Result IHardwareOpusDecoder::DecodeInterleaved( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, + bool reset) { + R_TRY(impl->DecodeInterleaved(out_data_size, out_time_taken, out_sample_count, opus_data, + out_pcm_data, reset)); + LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset, + *out_data_size, *out_sample_count, *out_time_taken); + R_SUCCEED(); } -void IHardwareOpusDecoder::DecodeInterleavedForMultiStream(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto reset{rp.Pop()}; - - auto input_data{ctx.ReadBuffer(0)}; - output_data.resize_destructive(ctx.GetWriteBufferSize()); - - u32 size{}; - u32 sample_count{}; - u64 time_taken{}; - auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count, - input_data, output_data, reset); - - LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset, - size, sample_count, time_taken); - - ctx.WriteBuffer(output_data); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(result); - rb.Push(size); - rb.Push(sample_count); - rb.Push(time_taken); +Result IHardwareOpusDecoder::DecodeInterleavedForMultiStream( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, + bool reset) { + R_TRY(impl->DecodeInterleavedForMultiStream(out_data_size, out_time_taken, out_sample_count, + opus_data, out_pcm_data, reset)); + LOG_DEBUG(Service_Audio, "reset {} bytes read {:#x} samples generated {} time taken {}", reset, + *out_data_size, *out_sample_count, *out_time_taken); + R_SUCCEED(); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/hardware_opus_decoder.h b/src/core/hle/service/audio/hardware_opus_decoder.h index 121858a6f..511bf46bd 100644 --- a/src/core/hle/service/audio/hardware_opus_decoder.h +++ b/src/core/hle/service/audio/hardware_opus_decoder.h @@ -4,6 +4,7 @@ #pragma once #include "audio_core/opus/decoder.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" namespace Service::Audio { @@ -20,16 +21,40 @@ public: Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size); private: - void DecodeInterleavedOld(HLERequestContext& ctx); - void SetContext(HLERequestContext& ctx); - void DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx); - void SetContextForMultiStream(HLERequestContext& ctx); - void DecodeInterleavedWithPerfOld(HLERequestContext& ctx); - void DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx); - void DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx); - void DecodeInterleavedForMultiStreamWithPerfAndResetOld(HLERequestContext& ctx); - void DecodeInterleaved(HLERequestContext& ctx); - void DecodeInterleavedForMultiStream(HLERequestContext& ctx); + Result DecodeInterleavedOld(OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, + InBuffer opus_data); + Result SetContext(InBuffer decoder_context); + Result DecodeInterleavedForMultiStreamOld(OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, + InBuffer opus_data); + Result SetContextForMultiStream(InBuffer decoder_context); + Result DecodeInterleavedWithPerfOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data); + Result DecodeInterleavedForMultiStreamWithPerfOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data); + Result DecodeInterleavedWithPerfAndResetOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, bool reset); + Result DecodeInterleavedForMultiStreamWithPerfAndResetOld( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, bool reset); + Result DecodeInterleaved( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, + bool reset); + Result DecodeInterleavedForMultiStream( + OutBuffer out_pcm_data, + Out out_data_size, Out out_sample_count, Out out_time_taken, + InBuffer opus_data, + bool reset); std::unique_ptr impl; Common::ScratchBuffer output_data; From 2e4a6b7f92fbf73eb5173c9bda5c9b5b61f5458c Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 22:18:57 -0500 Subject: [PATCH 13/16] audio: format --- src/CMakeLists.txt | 1 + src/audio_core/opus/parameters.h | 4 ++-- src/audio_core/renderer/behavior/info_updater.cpp | 7 ++++--- src/audio_core/renderer/memory/pool_mapper.cpp | 4 ++-- src/core/hle/service/audio/audio_in.cpp | 5 +++-- src/core/hle/service/audio/audio_in_manager.cpp | 4 ++-- src/core/hle/service/audio/audio_renderer.cpp | 4 ++-- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index edca221b1..cf05a3fe3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -121,6 +121,7 @@ else() -Wno-attributes -Wno-invalid-offsetof -Wno-unused-parameter + -Wno-missing-field-initializers ) if (CMAKE_CXX_COMPILER_ID MATCHES Clang) # Clang or AppleClang diff --git a/src/audio_core/opus/parameters.h b/src/audio_core/opus/parameters.h index 4c54b2825..47c418b9f 100644 --- a/src/audio_core/opus/parameters.h +++ b/src/audio_core/opus/parameters.h @@ -20,7 +20,7 @@ struct OpusParametersEx { /* 0x00 */ u32 sample_rate; /* 0x04 */ u32 channel_count; /* 0x08 */ bool use_large_frame_size; - /* 0x09 */ INSERT_PADDING_BYTES(7); + /* 0x09 */ INSERT_PADDING_BYTES_NOINIT(7); }; // size = 0x10 static_assert(sizeof(OpusParametersEx) == 0x10, "OpusParametersEx has the wrong size!"); @@ -40,7 +40,7 @@ struct OpusMultiStreamParametersEx { /* 0x08 */ u32 total_stream_count; /* 0x0C */ u32 stereo_stream_count; /* 0x10 */ bool use_large_frame_size; - /* 0x11 */ INSERT_PADDING_BYTES(7); + /* 0x11 */ INSERT_PADDING_BYTES_NOINIT(7); /* 0x18 */ std::array mappings; }; // size = 0x118 static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118, diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 163127789..3dae6069f 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -19,9 +19,10 @@ namespace AudioCore::Renderer { InfoUpdater::InfoUpdater(std::span input_, std::span output_, Kernel::KProcess* process_handle_, BehaviorInfo& behaviour_) - : input{input_.data() + sizeof(UpdateDataHeader)}, input_origin{input_}, - output{output_.data() + sizeof(UpdateDataHeader)}, output_origin{output_}, - in_header{reinterpret_cast(input_origin.data())}, + : input{input_.data() + sizeof(UpdateDataHeader)}, + input_origin{input_}, output{output_.data() + sizeof(UpdateDataHeader)}, + output_origin{output_}, in_header{reinterpret_cast( + input_origin.data())}, out_header{reinterpret_cast(output_origin.data())}, expected_input_size{input_.size()}, expected_output_size{output_.size()}, process_handle{process_handle_}, behaviour{behaviour_} { diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp index 1df786feb..e47eb66d5 100644 --- a/src/audio_core/renderer/memory/pool_mapper.cpp +++ b/src/audio_core/renderer/memory/pool_mapper.cpp @@ -13,8 +13,8 @@ PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, bool force_map_) PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, std::span pool_infos_, u32 pool_count_, bool force_map_) - : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, pool_count{pool_count_}, - force_map{force_map_} {} + : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, + pool_count{pool_count_}, force_map{force_map_} {} void PoolMapper::ClearUseState(std::span pools, const u32 count) { for (u32 i = 0; i < count; i++) { diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp index 9240cc336..416803acc 100644 --- a/src/core/hle/service/audio/audio_in.cpp +++ b/src/core/hle/service/audio/audio_in.cpp @@ -12,8 +12,9 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, const std::string& device_name, const AudioInParameter& in_params, Kernel::KProcess* handle, u64 applet_resource_user_id) : ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"}, - event{service_context.CreateEvent("AudioInEvent")}, - impl{std::make_shared(system_, manager, event, session_id)} { + event{service_context.CreateEvent("AudioInEvent")}, impl{std::make_shared(system_, + manager, event, + session_id)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"}, diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp index d55da17c8..2675a5773 100644 --- a/src/core/hle/service/audio/audio_in_manager.cpp +++ b/src/core/hle/service/audio/audio_in_manager.cpp @@ -10,8 +10,8 @@ namespace Service::Audio { using namespace AudioCore::AudioIn; IAudioInManager::IAudioInManager(Core::System& system_) - : ServiceFramework{system_, "audin:u"}, - impl{std::make_unique(system_)} { + : ServiceFramework{system_, "audin:u"}, impl{std::make_unique( + system_)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IAudioInManager::ListAudioIns>, "ListAudioIns"}, diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index b78660cea..fc4aad233 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -14,8 +14,8 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, s32 session_id) : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, - impl{std::make_unique(system_, manager, rendered_event)}, - process_handle{process_handle_} { + impl{std::make_unique(system_, manager, rendered_event)}, process_handle{ + process_handle_} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IAudioRenderer::GetSampleRate>, "GetSampleRate"}, From c04567fad4825d08a169efb2f6b118fafe988a31 Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 21 Feb 2024 23:54:10 -0500 Subject: [PATCH 14/16] audio: add NotifyHeadphoneVolumeWarningDisplayedEvent --- src/core/hle/service/audio/audio_controller.cpp | 7 ++++++- src/core/hle/service/audio/audio_controller.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index d51c89118..c9804cf9c 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp @@ -36,7 +36,7 @@ IAudioController::IAudioController(Core::System& system_) {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, {21, nullptr, "GetAudioOutputTargetForPlayReport"}, - {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, + {22, D<&IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent>, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, {23, nullptr, "SetSystemOutputMasterVolume"}, {24, nullptr, "GetSystemOutputMasterVolume"}, {25, nullptr, "GetAudioVolumeDataForPlayReport"}, @@ -150,6 +150,11 @@ Result IAudioController::GetHeadphoneOutputLevelMode( R_SUCCEED(); } +Result IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent() { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + R_SUCCEED(); +} + Result IAudioController::SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled) { LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", is_speaker_auto_mute_enabled); diff --git a/src/core/hle/service/audio/audio_controller.h b/src/core/hle/service/audio/audio_controller.h index 9e8514373..d37c4843e 100644 --- a/src/core/hle/service/audio/audio_controller.h +++ b/src/core/hle/service/audio/audio_controller.h @@ -45,6 +45,7 @@ private: Set::AudioOutputMode output_mode); Result SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode); Result GetHeadphoneOutputLevelMode(Out out_output_level_mode); + Result NotifyHeadphoneVolumeWarningDisplayedEvent(); Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled); Result IsSpeakerAutoMuteEnabled(Out out_is_speaker_auto_mute_enabled); Result AcquireTargetNotification(OutCopyHandle out_notification_event); From 2c00599a539765469c41401adbd038e75228bc3b Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 22 Feb 2024 20:20:31 -0500 Subject: [PATCH 15/16] audio: fix released buffer bounds check --- src/audio_core/device/audio_buffers.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h index 25da4c8a2..9e84a9c05 100644 --- a/src/audio_core/device/audio_buffers.h +++ b/src/audio_core/device/audio_buffers.h @@ -146,11 +146,15 @@ public: break; } + if (released < tags.size()) { + tags[released] = tag; + } + + released++; + if (released >= tags.size()) { break; } - - tags[released++] = tag; } return released; From 964e19ab56385117ee77b12311eb4a959e3abf4a Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 23 Feb 2024 10:30:52 -0500 Subject: [PATCH 16/16] oboe_sink: handle temporary stream creation failure --- src/audio_core/sink/oboe_sink.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/audio_core/sink/oboe_sink.cpp b/src/audio_core/sink/oboe_sink.cpp index e61841172..466a9cc8e 100644 --- a/src/audio_core/sink/oboe_sink.cpp +++ b/src/audio_core/sink/oboe_sink.cpp @@ -67,9 +67,13 @@ public: oboe::AudioStreamBuilder builder; const auto result = ConfigureBuilder(builder, direction)->openStream(temp_stream); - ASSERT(result == oboe::Result::OK); + if (result == oboe::Result::OK) { + return temp_stream->getChannelCount() >= 6 ? 6 : 2; + } - return temp_stream->getChannelCount() >= 6 ? 6 : 2; + LOG_ERROR(Audio_Sink, "Failed to open {} stream. Using default channel count 2", + direction == oboe::Direction::Output ? "output" : "input"); + return 2; } protected: