summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2024-02-19 23:38:09 -0500
committerGravatar Liam2024-02-20 22:15:37 -0500
commita45b8bc9bc64c9a86dd7c5a3e20e0996503754ae (patch)
tree3d01c84b8c9eed1de9fc78e7ffc55b19d15f366d
parentaudio: rewrite IAudioOut (diff)
downloadyuzu-a45b8bc9bc64c9a86dd7c5a3e20e0996503754ae.tar.gz
yuzu-a45b8bc9bc64c9a86dd7c5a3e20e0996503754ae.tar.xz
yuzu-a45b8bc9bc64c9a86dd7c5a3e20e0996503754ae.zip
audio: rewrite IAudioOutManager
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/hle/service/audio/audio.cpp4
-rw-r--r--src/core/hle/service/audio/audio_out_manager.cpp103
-rw-r--r--src/core/hle/service/audio/audio_out_manager.h44
-rw-r--r--src/core/hle/service/audio/audout_u.cpp118
-rw-r--r--src/core/hle/service/audio/audout_u.h37
6 files changed, 151 insertions, 159 deletions
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
493 hle/service/audio/audio_in_manager.h 493 hle/service/audio/audio_in_manager.h
494 hle/service/audio/audio_in.cpp 494 hle/service/audio/audio_in.cpp
495 hle/service/audio/audio_in.h 495 hle/service/audio/audio_in.h
496 hle/service/audio/audio_out_manager.cpp
497 hle/service/audio/audio_out_manager.h
496 hle/service/audio/audio_out.cpp 498 hle/service/audio/audio_out.cpp
497 hle/service/audio/audio_out.h 499 hle/service/audio/audio_out.h
498 hle/service/audio/audio.cpp 500 hle/service/audio/audio.cpp
499 hle/service/audio/audio.h 501 hle/service/audio/audio.h
500 hle/service/audio/audio_controller.cpp 502 hle/service/audio/audio_controller.cpp
501 hle/service/audio/audio_controller.h 503 hle/service/audio/audio_controller.h
502 hle/service/audio/audout_u.cpp
503 hle/service/audio/audout_u.h
504 hle/service/audio/audrec_a.cpp 504 hle/service/audio/audrec_a.cpp
505 hle/service/audio/audrec_a.h 505 hle/service/audio/audrec_a.h
506 hle/service/audio/audrec_u.cpp 506 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 @@
5#include "core/hle/service/audio/audio.h" 5#include "core/hle/service/audio/audio.h"
6#include "core/hle/service/audio/audio_controller.h" 6#include "core/hle/service/audio/audio_controller.h"
7#include "core/hle/service/audio/audio_in_manager.h" 7#include "core/hle/service/audio/audio_in_manager.h"
8#include "core/hle/service/audio/audout_u.h" 8#include "core/hle/service/audio/audio_out_manager.h"
9#include "core/hle/service/audio/audrec_a.h" 9#include "core/hle/service/audio/audrec_a.h"
10#include "core/hle/service/audio/audrec_u.h" 10#include "core/hle/service/audio/audrec_u.h"
11#include "core/hle/service/audio/audren_u.h" 11#include "core/hle/service/audio/audren_u.h"
@@ -20,7 +20,7 @@ void LoopProcess(Core::System& system) {
20 20
21 server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system)); 21 server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
22 server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system)); 22 server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system));
23 server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); 23 server_manager->RegisterNamedService("audout:u", std::make_shared<IAudioOutManager>(system));
24 server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system)); 24 server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system));
25 server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system)); 25 server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system));
26 server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(system)); 26 server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/string_util.h"
5#include "core/hle/service/audio/audio_out.h"
6#include "core/hle/service/audio/audio_out_manager.h"
7#include "core/hle/service/cmif_serialization.h"
8#include "core/memory.h"
9
10namespace Service::Audio {
11using namespace AudioCore::AudioOut;
12
13IAudioOutManager::IAudioOutManager(Core::System& system_)
14 : ServiceFramework{system_, "audout:u"}, impl{std::make_unique<Manager>(system_)} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, C<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"},
18 {1, C<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"},
19 {2, C<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"},
20 {3, C<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"},
21 };
22 // clang-format on
23
24 RegisterHandlers(functions);
25}
26
27IAudioOutManager::~IAudioOutManager() = default;
28
29Result IAudioOutManager::ListAudioOuts(
30 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_outs, Out<u32> out_count) {
31 R_RETURN(this->ListAudioOutsAuto(out_audio_outs, out_count));
32}
33
34Result IAudioOutManager::OpenAudioOut(Out<AudioOutParameterInternal> out_parameter_internal,
35 Out<SharedPointer<IAudioOut>> out_audio_out,
36 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
37 InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
38 AudioOutParameter parameter,
39 InCopyHandle<Kernel::KProcess> process_handle,
40 ClientAppletResourceUserId aruid) {
41 R_RETURN(this->OpenAudioOutAuto(out_parameter_internal, out_audio_out, out_name, name,
42 parameter, process_handle, aruid));
43}
44
45Result IAudioOutManager::ListAudioOutsAuto(
46 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_outs, Out<u32> out_count) {
47 if (!out_audio_outs.empty()) {
48 out_audio_outs[0] = AudioDeviceName("DeviceOut");
49 *out_count = 1;
50 LOG_DEBUG(Service_Audio, "called. \nName=DeviceOut");
51 } else {
52 *out_count = 0;
53 LOG_DEBUG(Service_Audio, "called. Empty buffer passed in.");
54 }
55
56 R_SUCCEED();
57}
58
59Result IAudioOutManager::OpenAudioOutAuto(
60 Out<AudioOutParameterInternal> out_parameter_internal,
61 Out<SharedPointer<IAudioOut>> out_audio_out,
62 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
63 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, AudioOutParameter parameter,
64 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid) {
65 if (!process_handle) {
66 LOG_ERROR(Service_Audio, "Failed to get process handle");
67 R_THROW(ResultUnknown);
68 }
69 if (name.empty() || out_name.empty()) {
70 LOG_ERROR(Service_Audio, "Invalid buffers");
71 R_THROW(ResultUnknown);
72 }
73
74 size_t new_session_id{};
75 R_TRY(impl->LinkToManager());
76 R_TRY(impl->AcquireSessionId(new_session_id));
77
78 const auto name_buffer = std::span(reinterpret_cast<const u8*>(name[0].name.data()), 0x100);
79 const auto device_name = Common::StringFromBuffer(name_buffer);
80
81 LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
82 impl->num_free_sessions);
83
84 auto audio_out = std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name,
85 parameter, process_handle.Get(), aruid.pid);
86 R_TRY(audio_out->GetImpl()->GetSystem().Initialize(device_name, parameter, process_handle.Get(),
87 aruid.pid));
88
89 *out_audio_out = audio_out;
90 impl->sessions[new_session_id] = audio_out->GetImpl();
91 impl->applet_resource_user_ids[new_session_id] = aruid.pid;
92
93 auto& out_system = impl->sessions[new_session_id]->GetSystem();
94 *out_parameter_internal =
95 AudioOutParameterInternal{.sample_rate = out_system.GetSampleRate(),
96 .channel_count = out_system.GetChannelCount(),
97 .sample_format = static_cast<u32>(out_system.GetSampleFormat()),
98 .state = static_cast<u32>(out_system.GetState())};
99
100 R_SUCCEED();
101}
102
103} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/audio_out_manager.h"
7#include "audio_core/out/audio_out.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace Service::Audio {
12
13using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName;
14class IAudioOut;
15
16class IAudioOutManager final : public ServiceFramework<IAudioOutManager> {
17public:
18 explicit IAudioOutManager(Core::System& system_);
19 ~IAudioOutManager() override;
20
21private:
22 Result ListAudioOuts(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_outs,
23 Out<u32> out_count);
24 Result OpenAudioOut(Out<AudioCore::AudioOut::AudioOutParameterInternal> out_parameter_internal,
25 Out<SharedPointer<IAudioOut>> out_audio_out,
26 OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
27 InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
28 AudioCore::AudioOut::AudioOutParameter parameter,
29 InCopyHandle<Kernel::KProcess> process_handle,
30 ClientAppletResourceUserId aruid);
31 Result ListAudioOutsAuto(OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_outs,
32 Out<u32> out_count);
33 Result OpenAudioOutAuto(
34 Out<AudioCore::AudioOut::AudioOutParameterInternal> out_parameter_internal,
35 Out<SharedPointer<IAudioOut>> out_audio_out,
36 OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
37 InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name,
38 AudioCore::AudioOut::AudioOutParameter parameter,
39 InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid);
40
41 std::unique_ptr<AudioCore::AudioOut::Manager> impl;
42};
43
44} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/string_util.h"
5#include "core/hle/service/audio/audio_out.h"
6#include "core/hle/service/audio/audout_u.h"
7#include "core/hle/service/ipc_helpers.h"
8#include "core/memory.h"
9
10namespace Service::Audio {
11using namespace AudioCore::AudioOut;
12
13AudOutU::AudOutU(Core::System& system_)
14 : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"},
15 impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, &AudOutU::ListAudioOuts, "ListAudioOuts"},
19 {1, &AudOutU::OpenAudioOut, "OpenAudioOut"},
20 {2, &AudOutU::ListAudioOuts, "ListAudioOutsAuto"},
21 {3, &AudOutU::OpenAudioOut, "OpenAudioOutAuto"},
22 };
23 // clang-format on
24
25 RegisterHandlers(functions);
26}
27
28AudOutU::~AudOutU() = default;
29
30void AudOutU::ListAudioOuts(HLERequestContext& ctx) {
31 using namespace AudioCore::Renderer;
32
33 std::scoped_lock l{impl->mutex};
34
35 const auto write_count =
36 static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>());
37 std::vector<AudioDevice::AudioDeviceName> device_names{};
38 if (write_count > 0) {
39 device_names.emplace_back("DeviceOut");
40 LOG_DEBUG(Service_Audio, "called. \nName=DeviceOut");
41 } else {
42 LOG_DEBUG(Service_Audio, "called. Empty buffer passed in.");
43 }
44
45 ctx.WriteBuffer(device_names);
46
47 IPC::ResponseBuilder rb{ctx, 3};
48 rb.Push(ResultSuccess);
49 rb.Push<u32>(static_cast<u32>(device_names.size()));
50}
51
52void AudOutU::OpenAudioOut(HLERequestContext& ctx) {
53 IPC::RequestParser rp{ctx};
54 auto in_params{rp.PopRaw<AudioOutParameter>()};
55 auto applet_resource_user_id{rp.PopRaw<u64>()};
56 const auto device_name_data{ctx.ReadBuffer()};
57 auto device_name = Common::StringFromBuffer(device_name_data);
58 auto handle{ctx.GetCopyHandle(0)};
59
60 auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)};
61 if (process.IsNull()) {
62 LOG_ERROR(Service_Audio, "Failed to get process handle");
63 IPC::ResponseBuilder rb{ctx, 2};
64 rb.Push(ResultUnknown);
65 return;
66 }
67
68 auto link{impl->LinkToManager()};
69 if (link.IsError()) {
70 LOG_ERROR(Service_Audio, "Failed to link Audio Out to Audio Manager");
71 IPC::ResponseBuilder rb{ctx, 2};
72 rb.Push(link);
73 return;
74 }
75
76 size_t new_session_id{};
77 auto result{impl->AcquireSessionId(new_session_id)};
78 if (result.IsError()) {
79 IPC::ResponseBuilder rb{ctx, 2};
80 rb.Push(result);
81 return;
82 }
83
84 LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
85 impl->num_free_sessions);
86
87 auto audio_out =
88 std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name, in_params,
89 process.GetPointerUnsafe(), applet_resource_user_id);
90 result = audio_out->GetImpl()->GetSystem().Initialize(
91 device_name, in_params, process.GetPointerUnsafe(), applet_resource_user_id);
92 if (result.IsError()) {
93 LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!");
94 IPC::ResponseBuilder rb{ctx, 2};
95 rb.Push(result);
96 return;
97 }
98
99 impl->sessions[new_session_id] = audio_out->GetImpl();
100 impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
101
102 auto& out_system = impl->sessions[new_session_id]->GetSystem();
103 AudioOutParameterInternal out_params{.sample_rate = out_system.GetSampleRate(),
104 .channel_count = out_system.GetChannelCount(),
105 .sample_format =
106 static_cast<u32>(out_system.GetSampleFormat()),
107 .state = static_cast<u32>(out_system.GetState())};
108
109 IPC::ResponseBuilder rb{ctx, 6, 0, 1};
110
111 ctx.WriteBuffer(out_system.GetName());
112
113 rb.Push(ResultSuccess);
114 rb.PushRaw<AudioOutParameterInternal>(out_params);
115 rb.PushIpcInterface<IAudioOut>(audio_out);
116}
117
118} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "audio_core/audio_out_manager.h"
7#include "audio_core/out/audio_out.h"
8#include "core/hle/service/kernel_helpers.h"
9#include "core/hle/service/service.h"
10
11namespace Core {
12class System;
13}
14
15namespace AudioCore::AudioOut {
16class Manager;
17class Out;
18} // namespace AudioCore::AudioOut
19
20namespace Service::Audio {
21
22class IAudioOut;
23
24class AudOutU final : public ServiceFramework<AudOutU> {
25public:
26 explicit AudOutU(Core::System& system_);
27 ~AudOutU() override;
28
29private:
30 void ListAudioOuts(HLERequestContext& ctx);
31 void OpenAudioOut(HLERequestContext& ctx);
32
33 KernelHelpers::ServiceContext service_context;
34 std::unique_ptr<AudioCore::AudioOut::Manager> impl;
35};
36
37} // namespace Service::Audio