summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/audio/audio_device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/audio/audio_device.cpp')
-rw-r--r--src/core/hle/service/audio/audio_device.cpp183
1 files changed, 183 insertions, 0 deletions
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<AudioDevice>(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<AudioDevice::AudioDeviceName>();
+
+ std::vector<AudioDevice::AudioDeviceName> 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<f32>();
+
+ 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<u32>(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<AudioDevice::AudioDeviceName>();
+
+ std::vector<AudioDevice::AudioDeviceName> 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