diff options
| author | 2024-02-19 21:45:48 -0500 | |
|---|---|---|
| committer | 2024-02-20 22:15:37 -0500 | |
| commit | 2a2c92f1819f44a86f452654398d0fc16806c438 (patch) | |
| tree | 32607c7d8bbb0232fd496bf8e621e29a3abd0fcb /src/core | |
| parent | audio: rewrite IAudioIn (diff) | |
| download | yuzu-2a2c92f1819f44a86f452654398d0fc16806c438.tar.gz yuzu-2a2c92f1819f44a86f452654398d0fc16806c438.tar.xz yuzu-2a2c92f1819f44a86f452654398d0fc16806c438.zip | |
audio: rewrite IAudioInManager
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audin_u.cpp | 198 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audin_u.h | 38 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio_in_manager.cpp | 126 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio_in_manager.h | 57 |
6 files changed, 187 insertions, 240 deletions
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 | |||
| 489 | hle/service/apm/apm_controller.h | 489 | hle/service/apm/apm_controller.h |
| 490 | hle/service/apm/apm_interface.cpp | 490 | hle/service/apm/apm_interface.cpp |
| 491 | hle/service/apm/apm_interface.h | 491 | hle/service/apm/apm_interface.h |
| 492 | hle/service/audio/audin_u.cpp | 492 | hle/service/audio/audio_in_manager.cpp |
| 493 | hle/service/audio/audin_u.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.cpp | 496 | 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 @@ | |||
| 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/audin_u.h" | ||
| 6 | #include "core/hle/service/audio/audio_in.h" | ||
| 7 | #include "core/hle/service/ipc_helpers.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | using namespace AudioCore::AudioIn; | ||
| 11 | |||
| 12 | AudInU::AudInU(Core::System& system_) | ||
| 13 | : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, | ||
| 14 | impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} { | ||
| 15 | // clang-format off | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {0, &AudInU::ListAudioIns, "ListAudioIns"}, | ||
| 18 | {1, &AudInU::OpenAudioIn, "OpenAudioIn"}, | ||
| 19 | {2, &AudInU::ListAudioIns, "ListAudioInsAuto"}, | ||
| 20 | {3, &AudInU::OpenAudioIn, "OpenAudioInAuto"}, | ||
| 21 | {4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"}, | ||
| 22 | {5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"}, | ||
| 23 | }; | ||
| 24 | // clang-format on | ||
| 25 | |||
| 26 | RegisterHandlers(functions); | ||
| 27 | } | ||
| 28 | |||
| 29 | AudInU::~AudInU() = default; | ||
| 30 | |||
| 31 | void AudInU::ListAudioIns(HLERequestContext& ctx) { | ||
| 32 | using namespace AudioCore::Renderer; | ||
| 33 | |||
| 34 | LOG_DEBUG(Service_Audio, "called"); | ||
| 35 | |||
| 36 | const auto write_count = | ||
| 37 | static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>()); | ||
| 38 | std::vector<AudioDevice::AudioDeviceName> device_names{}; | ||
| 39 | |||
| 40 | u32 out_count{0}; | ||
| 41 | if (write_count > 0) { | ||
| 42 | out_count = impl->GetDeviceNames(device_names, write_count, false); | ||
| 43 | ctx.WriteBuffer(device_names); | ||
| 44 | } | ||
| 45 | |||
| 46 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 47 | rb.Push(ResultSuccess); | ||
| 48 | rb.Push(out_count); | ||
| 49 | } | ||
| 50 | |||
| 51 | void AudInU::ListAudioInsAutoFiltered(HLERequestContext& ctx) { | ||
| 52 | using namespace AudioCore::Renderer; | ||
| 53 | |||
| 54 | LOG_DEBUG(Service_Audio, "called"); | ||
| 55 | |||
| 56 | const auto write_count = | ||
| 57 | static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>()); | ||
| 58 | std::vector<AudioDevice::AudioDeviceName> device_names{}; | ||
| 59 | |||
| 60 | u32 out_count{0}; | ||
| 61 | if (write_count > 0) { | ||
| 62 | out_count = impl->GetDeviceNames(device_names, write_count, true); | ||
| 63 | ctx.WriteBuffer(device_names); | ||
| 64 | } | ||
| 65 | |||
| 66 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 67 | rb.Push(ResultSuccess); | ||
| 68 | rb.Push(out_count); | ||
| 69 | } | ||
| 70 | |||
| 71 | void AudInU::OpenAudioIn(HLERequestContext& ctx) { | ||
| 72 | IPC::RequestParser rp{ctx}; | ||
| 73 | auto in_params{rp.PopRaw<AudioInParameter>()}; | ||
| 74 | auto applet_resource_user_id{rp.PopRaw<u64>()}; | ||
| 75 | const auto device_name_data{ctx.ReadBuffer()}; | ||
| 76 | auto device_name = Common::StringFromBuffer(device_name_data); | ||
| 77 | auto handle{ctx.GetCopyHandle(0)}; | ||
| 78 | |||
| 79 | auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)}; | ||
| 80 | if (process.IsNull()) { | ||
| 81 | LOG_ERROR(Service_Audio, "Failed to get process handle"); | ||
| 82 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 83 | rb.Push(ResultUnknown); | ||
| 84 | return; | ||
| 85 | } | ||
| 86 | |||
| 87 | std::scoped_lock l{impl->mutex}; | ||
| 88 | auto link{impl->LinkToManager()}; | ||
| 89 | if (link.IsError()) { | ||
| 90 | LOG_ERROR(Service_Audio, "Failed to link Audio In to Audio Manager"); | ||
| 91 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 92 | rb.Push(link); | ||
| 93 | return; | ||
| 94 | } | ||
| 95 | |||
| 96 | size_t new_session_id{}; | ||
| 97 | auto result{impl->AcquireSessionId(new_session_id)}; | ||
| 98 | if (result.IsError()) { | ||
| 99 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 100 | rb.Push(result); | ||
| 101 | return; | ||
| 102 | } | ||
| 103 | |||
| 104 | LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id, | ||
| 105 | impl->num_free_sessions); | ||
| 106 | |||
| 107 | auto audio_in = | ||
| 108 | std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params, | ||
| 109 | process.GetPointerUnsafe(), applet_resource_user_id); | ||
| 110 | impl->sessions[new_session_id] = audio_in->GetImpl(); | ||
| 111 | impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; | ||
| 112 | |||
| 113 | auto& out_system = impl->sessions[new_session_id]->GetSystem(); | ||
| 114 | AudioInParameterInternal out_params{.sample_rate = out_system.GetSampleRate(), | ||
| 115 | .channel_count = out_system.GetChannelCount(), | ||
| 116 | .sample_format = | ||
| 117 | static_cast<u32>(out_system.GetSampleFormat()), | ||
| 118 | .state = static_cast<u32>(out_system.GetState())}; | ||
| 119 | |||
| 120 | IPC::ResponseBuilder rb{ctx, 6, 0, 1}; | ||
| 121 | |||
| 122 | std::string out_name{out_system.GetName()}; | ||
| 123 | ctx.WriteBuffer(out_name); | ||
| 124 | |||
| 125 | rb.Push(ResultSuccess); | ||
| 126 | rb.PushRaw<AudioInParameterInternal>(out_params); | ||
| 127 | rb.PushIpcInterface<IAudioIn>(audio_in); | ||
| 128 | } | ||
| 129 | |||
| 130 | void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) { | ||
| 131 | IPC::RequestParser rp{ctx}; | ||
| 132 | auto protocol_specified{rp.PopRaw<u64>()}; | ||
| 133 | auto in_params{rp.PopRaw<AudioInParameter>()}; | ||
| 134 | auto applet_resource_user_id{rp.PopRaw<u64>()}; | ||
| 135 | const auto device_name_data{ctx.ReadBuffer()}; | ||
| 136 | auto device_name = Common::StringFromBuffer(device_name_data); | ||
| 137 | auto handle{ctx.GetCopyHandle(0)}; | ||
| 138 | |||
| 139 | auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)}; | ||
| 140 | if (process.IsNull()) { | ||
| 141 | LOG_ERROR(Service_Audio, "Failed to get process handle"); | ||
| 142 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 143 | rb.Push(ResultUnknown); | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | |||
| 147 | std::scoped_lock l{impl->mutex}; | ||
| 148 | auto link{impl->LinkToManager()}; | ||
| 149 | if (link.IsError()) { | ||
| 150 | LOG_ERROR(Service_Audio, "Failed to link Audio In to Audio Manager"); | ||
| 151 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 152 | rb.Push(link); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | |||
| 156 | size_t new_session_id{}; | ||
| 157 | auto result{impl->AcquireSessionId(new_session_id)}; | ||
| 158 | if (result.IsError()) { | ||
| 159 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 160 | rb.Push(result); | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id, | ||
| 165 | impl->num_free_sessions); | ||
| 166 | |||
| 167 | auto audio_in = | ||
| 168 | std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params, | ||
| 169 | process.GetPointerUnsafe(), applet_resource_user_id); | ||
| 170 | impl->sessions[new_session_id] = audio_in->GetImpl(); | ||
| 171 | impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; | ||
| 172 | |||
| 173 | auto& out_system = impl->sessions[new_session_id]->GetSystem(); | ||
| 174 | AudioInParameterInternal out_params{.sample_rate = out_system.GetSampleRate(), | ||
| 175 | .channel_count = out_system.GetChannelCount(), | ||
| 176 | .sample_format = | ||
| 177 | static_cast<u32>(out_system.GetSampleFormat()), | ||
| 178 | .state = static_cast<u32>(out_system.GetState())}; | ||
| 179 | |||
| 180 | IPC::ResponseBuilder rb{ctx, 6, 0, 1}; | ||
| 181 | |||
| 182 | std::string out_name{out_system.GetName()}; | ||
| 183 | if (protocol_specified == 0) { | ||
| 184 | if (out_system.IsUac()) { | ||
| 185 | out_name = "UacIn"; | ||
| 186 | } else { | ||
| 187 | out_name = "DeviceIn"; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | ctx.WriteBuffer(out_name); | ||
| 192 | |||
| 193 | rb.Push(ResultSuccess); | ||
| 194 | rb.PushRaw<AudioInParameterInternal>(out_params); | ||
| 195 | rb.PushIpcInterface<IAudioIn>(audio_in); | ||
| 196 | } | ||
| 197 | |||
| 198 | } // 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 @@ | |||
| 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_in_manager.h" | ||
| 7 | #include "audio_core/in/audio_in.h" | ||
| 8 | #include "core/hle/service/kernel_helpers.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Core { | ||
| 12 | class System; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace AudioCore::AudioOut { | ||
| 16 | class Manager; | ||
| 17 | class In; | ||
| 18 | } // namespace AudioCore::AudioOut | ||
| 19 | |||
| 20 | namespace Service::Audio { | ||
| 21 | |||
| 22 | class AudInU final : public ServiceFramework<AudInU> { | ||
| 23 | public: | ||
| 24 | explicit AudInU(Core::System& system_); | ||
| 25 | ~AudInU() override; | ||
| 26 | |||
| 27 | private: | ||
| 28 | void ListAudioIns(HLERequestContext& ctx); | ||
| 29 | void ListAudioInsAutoFiltered(HLERequestContext& ctx); | ||
| 30 | void OpenInOutImpl(HLERequestContext& ctx); | ||
| 31 | void OpenAudioIn(HLERequestContext& ctx); | ||
| 32 | void OpenAudioInProtocolSpecified(HLERequestContext& ctx); | ||
| 33 | |||
| 34 | KernelHelpers::ServiceContext service_context; | ||
| 35 | std::unique_ptr<AudioCore::AudioIn::Manager> impl; | ||
| 36 | }; | ||
| 37 | |||
| 38 | } // 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 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/service/audio/audin_u.h" | ||
| 6 | #include "core/hle/service/audio/audio.h" | 5 | #include "core/hle/service/audio/audio.h" |
| 7 | #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" | ||
| 8 | #include "core/hle/service/audio/audout_u.h" | 8 | #include "core/hle/service/audio/audout_u.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" |
| @@ -19,8 +19,8 @@ void LoopProcess(Core::System& system) { | |||
| 19 | auto server_manager = std::make_unique<ServerManager>(system); | 19 | auto server_manager = std::make_unique<ServerManager>(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("audout:u", std::make_shared<AudOutU>(system)); | 23 | server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); |
| 23 | server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(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_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 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 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_in.h" | ||
| 6 | #include "core/hle/service/audio/audio_in_manager.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | using namespace AudioCore::AudioIn; | ||
| 11 | |||
| 12 | IAudioInManager::IAudioInManager(Core::System& system_) | ||
| 13 | : ServiceFramework{system_, "audin:u"}, | ||
| 14 | impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} { | ||
| 15 | // clang-format off | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {0, C<&IAudioInManager::ListAudioIns>, "ListAudioIns"}, | ||
| 18 | {1, C<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"}, | ||
| 19 | {2, C<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"}, | ||
| 20 | {3, C<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"}, | ||
| 21 | {4, C<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"}, | ||
| 22 | {5, C<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"}, | ||
| 23 | }; | ||
| 24 | // clang-format on | ||
| 25 | |||
| 26 | RegisterHandlers(functions); | ||
| 27 | } | ||
| 28 | |||
| 29 | IAudioInManager::~IAudioInManager() = default; | ||
| 30 | |||
| 31 | Result IAudioInManager::ListAudioIns( | ||
| 32 | OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_ins, Out<u32> out_count) { | ||
| 33 | LOG_DEBUG(Service_Audio, "called"); | ||
| 34 | R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count)); | ||
| 35 | } | ||
| 36 | |||
| 37 | Result IAudioInManager::OpenAudioIn(Out<AudioInParameterInternal> out_parameter_internal, | ||
| 38 | Out<SharedPointer<IAudioIn>> out_audio_in, | ||
| 39 | OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name, | ||
| 40 | InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name, | ||
| 41 | AudioInParameter parameter, | ||
| 42 | InCopyHandle<Kernel::KProcess> process_handle, | ||
| 43 | ClientAppletResourceUserId aruid) { | ||
| 44 | LOG_DEBUG(Service_Audio, "called"); | ||
| 45 | R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name, | ||
| 46 | name, {}, parameter, process_handle, aruid)); | ||
| 47 | } | ||
| 48 | |||
| 49 | Result IAudioInManager::ListAudioInsAuto( | ||
| 50 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) { | ||
| 51 | LOG_DEBUG(Service_Audio, "called"); | ||
| 52 | R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count)); | ||
| 53 | } | ||
| 54 | |||
| 55 | Result IAudioInManager::OpenAudioInAuto( | ||
| 56 | Out<AudioInParameterInternal> out_parameter_internal, Out<SharedPointer<IAudioIn>> out_audio_in, | ||
| 57 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name, | ||
| 58 | InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, AudioInParameter parameter, | ||
| 59 | InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid) { | ||
| 60 | LOG_DEBUG(Service_Audio, "called"); | ||
| 61 | R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name, | ||
| 62 | name, {}, parameter, process_handle, aruid)); | ||
| 63 | } | ||
| 64 | |||
| 65 | Result IAudioInManager::ListAudioInsAutoFiltered( | ||
| 66 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) { | ||
| 67 | LOG_DEBUG(Service_Audio, "called"); | ||
| 68 | *out_count = impl->GetDeviceNames(out_audio_ins, true); | ||
| 69 | R_SUCCEED(); | ||
| 70 | } | ||
| 71 | |||
| 72 | Result IAudioInManager::OpenAudioInProtocolSpecified( | ||
| 73 | Out<AudioInParameterInternal> out_parameter_internal, Out<SharedPointer<IAudioIn>> out_audio_in, | ||
| 74 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name, | ||
| 75 | InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, Protocol protocol, | ||
| 76 | AudioInParameter parameter, InCopyHandle<Kernel::KProcess> process_handle, | ||
| 77 | ClientAppletResourceUserId aruid) { | ||
| 78 | LOG_DEBUG(Service_Audio, "called"); | ||
| 79 | |||
| 80 | if (!process_handle) { | ||
| 81 | LOG_ERROR(Service_Audio, "Failed to get process handle"); | ||
| 82 | R_THROW(ResultUnknown); | ||
| 83 | } | ||
| 84 | if (name.empty() || out_name.empty()) { | ||
| 85 | LOG_ERROR(Service_Audio, "Invalid buffers"); | ||
| 86 | R_THROW(ResultUnknown); | ||
| 87 | } | ||
| 88 | |||
| 89 | std::scoped_lock l{impl->mutex}; | ||
| 90 | |||
| 91 | size_t new_session_id{}; | ||
| 92 | |||
| 93 | R_TRY(impl->LinkToManager()); | ||
| 94 | R_TRY(impl->AcquireSessionId(new_session_id)); | ||
| 95 | |||
| 96 | LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id, | ||
| 97 | impl->num_free_sessions); | ||
| 98 | |||
| 99 | const auto name_buffer = std::span(reinterpret_cast<const u8*>(name[0].name.data()), 0x100); | ||
| 100 | const auto device_name = Common::StringFromBuffer(name_buffer); | ||
| 101 | *out_audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, | ||
| 102 | parameter, process_handle.Get(), aruid.pid); | ||
| 103 | impl->sessions[new_session_id] = (*out_audio_in)->GetImpl(); | ||
| 104 | impl->applet_resource_user_ids[new_session_id] = aruid.pid; | ||
| 105 | |||
| 106 | auto& out_system = impl->sessions[new_session_id]->GetSystem(); | ||
| 107 | *out_parameter_internal = | ||
| 108 | AudioInParameterInternal{.sample_rate = out_system.GetSampleRate(), | ||
| 109 | .channel_count = out_system.GetChannelCount(), | ||
| 110 | .sample_format = static_cast<u32>(out_system.GetSampleFormat()), | ||
| 111 | .state = static_cast<u32>(out_system.GetState())}; | ||
| 112 | |||
| 113 | out_name[0] = AudioDeviceName(out_system.GetName()); | ||
| 114 | |||
| 115 | if (protocol == Protocol{}) { | ||
| 116 | if (out_system.IsUac()) { | ||
| 117 | out_name[0] = AudioDeviceName("UacIn"); | ||
| 118 | } else { | ||
| 119 | out_name[0] = AudioDeviceName("DeviceIn"); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | R_SUCCEED(); | ||
| 124 | } | ||
| 125 | |||
| 126 | } // 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 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "audio_core/audio_in_manager.h" | ||
| 7 | #include "audio_core/in/audio_in_system.h" | ||
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::Audio { | ||
| 12 | |||
| 13 | using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName; | ||
| 14 | using Protocol = std::array<u32, 2>; | ||
| 15 | |||
| 16 | class IAudioIn; | ||
| 17 | |||
| 18 | class IAudioInManager final : public ServiceFramework<IAudioInManager> { | ||
| 19 | public: | ||
| 20 | explicit IAudioInManager(Core::System& system_); | ||
| 21 | ~IAudioInManager() override; | ||
| 22 | |||
| 23 | private: | ||
| 24 | Result ListAudioIns(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_ins, | ||
| 25 | Out<u32> out_count); | ||
| 26 | Result OpenAudioIn(Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal, | ||
| 27 | Out<SharedPointer<IAudioIn>> out_audio_in, | ||
| 28 | OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name, | ||
| 29 | InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name, | ||
| 30 | AudioCore::AudioIn::AudioInParameter parameter, | ||
| 31 | InCopyHandle<Kernel::KProcess> process_handle, | ||
| 32 | ClientAppletResourceUserId aruid); | ||
| 33 | |||
| 34 | Result ListAudioInsAuto(OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, | ||
| 35 | Out<u32> out_count); | ||
| 36 | Result OpenAudioInAuto(Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal, | ||
| 37 | Out<SharedPointer<IAudioIn>> out_audio_in, | ||
| 38 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name, | ||
| 39 | InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, | ||
| 40 | AudioCore::AudioIn::AudioInParameter parameter, | ||
| 41 | InCopyHandle<Kernel::KProcess> process_handle, | ||
| 42 | ClientAppletResourceUserId aruid); | ||
| 43 | |||
| 44 | Result ListAudioInsAutoFiltered( | ||
| 45 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count); | ||
| 46 | Result OpenAudioInProtocolSpecified( | ||
| 47 | Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal, | ||
| 48 | Out<SharedPointer<IAudioIn>> out_audio_in, | ||
| 49 | OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name, | ||
| 50 | InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, Protocol protocol, | ||
| 51 | AudioCore::AudioIn::AudioInParameter parameter, | ||
| 52 | InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid); | ||
| 53 | |||
| 54 | std::unique_ptr<AudioCore::AudioIn::Manager> impl; | ||
| 55 | }; | ||
| 56 | |||
| 57 | } // namespace Service::Audio | ||