From 62083fcafd11348e01cf0d99e2693cb608cca71b Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 00:46:35 -0500 Subject: audio: split IAudioDevice, IAudioRenderer, move IAudioRendererManager --- src/core/hle/service/audio/audio_device.cpp | 183 ++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/core/hle/service/audio/audio_device.cpp (limited to 'src/core/hle/service/audio/audio_device.cpp') 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 -- cgit v1.2.3