summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/audio/audin_u.cpp197
-rw-r--r--src/core/hle/service/audio/audio_in.cpp131
-rw-r--r--src/core/hle/service/audio/audio_in.h48
4 files changed, 182 insertions, 196 deletions
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
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/audin_u.cpp
493 hle/service/audio/audin_u.h 493 hle/service/audio/audin_u.h
494 hle/service/audio/audio_in.cpp
495 hle/service/audio/audio_in.h
494 hle/service/audio/audio.cpp 496 hle/service/audio/audio.cpp
495 hle/service/audio/audio.h 497 hle/service/audio/audio.h
496 hle/service/audio/audio_controller.cpp 498 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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "audio_core/in/audio_in_system.h"
5#include "audio_core/renderer/audio_device.h"
6#include "common/common_funcs.h"
7#include "common/logging/log.h"
8#include "common/scratch_buffer.h"
9#include "common/string_util.h" 4#include "common/string_util.h"
10#include "core/core.h"
11#include "core/hle/kernel/k_event.h"
12#include "core/hle/service/audio/audin_u.h" 5#include "core/hle/service/audio/audin_u.h"
6#include "core/hle/service/audio/audio_in.h"
13#include "core/hle/service/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
14 8
15namespace Service::Audio { 9namespace Service::Audio {
16using namespace AudioCore::AudioIn; 10using namespace AudioCore::AudioIn;
17 11
18class IAudioIn final : public ServiceFramework<IAudioIn> {
19public:
20 explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
21 const std::string& device_name, const AudioInParameter& in_params,
22 Kernel::KProcess* handle, u64 applet_resource_user_id)
23 : ServiceFramework{system_, "IAudioIn"},
24 service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")},
25 process{handle}, impl{std::make_shared<In>(system_, manager, event, session_id)} {
26 // clang-format off
27 static const FunctionInfo functions[] = {
28 {0, &IAudioIn::GetAudioInState, "GetAudioInState"},
29 {1, &IAudioIn::Start, "Start"},
30 {2, &IAudioIn::Stop, "Stop"},
31 {3, &IAudioIn::AppendAudioInBuffer, "AppendAudioInBuffer"},
32 {4, &IAudioIn::RegisterBufferEvent, "RegisterBufferEvent"},
33 {5, &IAudioIn::GetReleasedAudioInBuffer, "GetReleasedAudioInBuffer"},
34 {6, &IAudioIn::ContainsAudioInBuffer, "ContainsAudioInBuffer"},
35 {7, &IAudioIn::AppendAudioInBuffer, "AppendUacInBuffer"},
36 {8, &IAudioIn::AppendAudioInBuffer, "AppendAudioInBufferAuto"},
37 {9, &IAudioIn::GetReleasedAudioInBuffer, "GetReleasedAudioInBuffersAuto"},
38 {10, &IAudioIn::AppendAudioInBuffer, "AppendUacInBufferAuto"},
39 {11, &IAudioIn::GetAudioInBufferCount, "GetAudioInBufferCount"},
40 {12, &IAudioIn::SetDeviceGain, "SetDeviceGain"},
41 {13, &IAudioIn::GetDeviceGain, "GetDeviceGain"},
42 {14, &IAudioIn::FlushAudioInBuffers, "FlushAudioInBuffers"},
43 };
44 // clang-format on
45
46 RegisterHandlers(functions);
47
48 process->Open();
49
50 if (impl->GetSystem()
51 .Initialize(device_name, in_params, handle, applet_resource_user_id)
52 .IsError()) {
53 LOG_ERROR(Service_Audio, "Failed to initialize the AudioIn System!");
54 }
55 }
56
57 ~IAudioIn() override {
58 impl->Free();
59 service_context.CloseEvent(event);
60 process->Close();
61 }
62
63 [[nodiscard]] std::shared_ptr<In> GetImpl() {
64 return impl;
65 }
66
67private:
68 void GetAudioInState(HLERequestContext& ctx) {
69 const auto state = static_cast<u32>(impl->GetState());
70
71 LOG_DEBUG(Service_Audio, "called. State={}", state);
72
73 IPC::ResponseBuilder rb{ctx, 3};
74 rb.Push(ResultSuccess);
75 rb.Push(state);
76 }
77
78 void Start(HLERequestContext& ctx) {
79 LOG_DEBUG(Service_Audio, "called");
80
81 auto result = impl->StartSystem();
82
83 IPC::ResponseBuilder rb{ctx, 2};
84 rb.Push(result);
85 }
86
87 void Stop(HLERequestContext& ctx) {
88 LOG_DEBUG(Service_Audio, "called");
89
90 auto result = impl->StopSystem();
91
92 IPC::ResponseBuilder rb{ctx, 2};
93 rb.Push(result);
94 }
95
96 void AppendAudioInBuffer(HLERequestContext& ctx) {
97 IPC::RequestParser rp{ctx};
98 u64 tag = rp.PopRaw<u64>();
99
100 const auto in_buffer_size{ctx.GetReadBufferSize()};
101 if (in_buffer_size < sizeof(AudioInBuffer)) {
102 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!");
103 }
104
105 const auto& in_buffer = ctx.ReadBuffer();
106 AudioInBuffer buffer{};
107 std::memcpy(&buffer, in_buffer.data(), sizeof(AudioInBuffer));
108
109 [[maybe_unused]] auto sessionid{impl->GetSystem().GetSessionId()};
110 LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", sessionid, tag);
111
112 auto result = impl->AppendBuffer(buffer, tag);
113
114 IPC::ResponseBuilder rb{ctx, 2};
115 rb.Push(result);
116 }
117
118 void RegisterBufferEvent(HLERequestContext& ctx) {
119 LOG_DEBUG(Service_Audio, "called");
120
121 auto& buffer_event = impl->GetBufferEvent();
122
123 IPC::ResponseBuilder rb{ctx, 2, 1};
124 rb.Push(ResultSuccess);
125 rb.PushCopyObjects(buffer_event);
126 }
127
128 void GetReleasedAudioInBuffer(HLERequestContext& ctx) {
129 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
130 released_buffer.resize_destructive(write_buffer_size);
131 released_buffer[0] = 0;
132
133 const auto count = impl->GetReleasedBuffers(released_buffer);
134
135 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
136 impl->GetSystem().GetSessionId(), count);
137
138 ctx.WriteBuffer(released_buffer);
139
140 IPC::ResponseBuilder rb{ctx, 3};
141 rb.Push(ResultSuccess);
142 rb.Push(count);
143 }
144
145 void ContainsAudioInBuffer(HLERequestContext& ctx) {
146 IPC::RequestParser rp{ctx};
147
148 const u64 tag{rp.Pop<u64>()};
149 const auto buffer_queued{impl->ContainsAudioBuffer(tag)};
150
151 LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", tag, buffer_queued);
152
153 IPC::ResponseBuilder rb{ctx, 3};
154 rb.Push(ResultSuccess);
155 rb.Push(buffer_queued);
156 }
157
158 void GetAudioInBufferCount(HLERequestContext& ctx) {
159 const auto buffer_count = impl->GetBufferCount();
160
161 LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count);
162
163 IPC::ResponseBuilder rb{ctx, 3};
164 rb.Push(ResultSuccess);
165 rb.Push(buffer_count);
166 }
167
168 void SetDeviceGain(HLERequestContext& ctx) {
169 IPC::RequestParser rp{ctx};
170
171 const auto volume{rp.Pop<f32>()};
172 LOG_DEBUG(Service_Audio, "called. Gain {}", volume);
173
174 impl->SetVolume(volume);
175
176 IPC::ResponseBuilder rb{ctx, 2};
177 rb.Push(ResultSuccess);
178 }
179
180 void GetDeviceGain(HLERequestContext& ctx) {
181 auto volume{impl->GetVolume()};
182
183 LOG_DEBUG(Service_Audio, "called. Gain {}", volume);
184
185 IPC::ResponseBuilder rb{ctx, 3};
186 rb.Push(ResultSuccess);
187 rb.Push(volume);
188 }
189
190 void FlushAudioInBuffers(HLERequestContext& ctx) {
191 bool flushed{impl->FlushAudioInBuffers()};
192
193 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed);
194
195 IPC::ResponseBuilder rb{ctx, 3};
196 rb.Push(ResultSuccess);
197 rb.Push(flushed);
198 }
199
200 KernelHelpers::ServiceContext service_context;
201 Kernel::KEvent* event;
202 Kernel::KProcess* process;
203 std::shared_ptr<AudioCore::AudioIn::In> impl;
204 Common::ScratchBuffer<u64> released_buffer;
205};
206
207AudInU::AudInU(Core::System& system_) 12AudInU::AudInU(Core::System& system_)
208 : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, 13 : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"},
209 impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} { 14 impl{std::make_unique<AudioCore::AudioIn::Manager>(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 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/audio_in.h"
5#include "core/hle/service/cmif_serialization.h"
6#include "core/hle/service/ipc_helpers.h"
7
8namespace Service::Audio {
9using namespace AudioCore::AudioIn;
10
11IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
12 const std::string& device_name, const AudioInParameter& in_params,
13 Kernel::KProcess* handle, u64 applet_resource_user_id)
14 : ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"},
15 event{service_context.CreateEvent("AudioInEvent")},
16 impl{std::make_shared<In>(system_, manager, event, session_id)} {
17 // clang-format off
18 static const FunctionInfo functions[] = {
19 {0, C<&IAudioIn::GetAudioInState>, "GetAudioInState"},
20 {1, C<&IAudioIn::Start>, "Start"},
21 {2, C<&IAudioIn::Stop>, "Stop"},
22 {3, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"},
23 {4, C<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"},
24 {5, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffer"},
25 {6, C<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"},
26 {7, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"},
27 {8, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBufferAuto"},
28 {9, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffersAuto"},
29 {10, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBufferAuto"},
30 {11, C<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"},
31 {12, C<&IAudioIn::SetDeviceGain>, "SetDeviceGain"},
32 {13, C<&IAudioIn::GetDeviceGain>, "GetDeviceGain"},
33 {14, C<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"},
34 };
35 // clang-format on
36
37 RegisterHandlers(functions);
38
39 process->Open();
40
41 if (impl->GetSystem()
42 .Initialize(device_name, in_params, handle, applet_resource_user_id)
43 .IsError()) {
44 LOG_ERROR(Service_Audio, "Failed to initialize the AudioIn System!");
45 }
46}
47
48IAudioIn::~IAudioIn() {
49 impl->Free();
50 service_context.CloseEvent(event);
51 process->Close();
52}
53
54Result IAudioIn::GetAudioInState(Out<u32> out_state) {
55 *out_state = static_cast<u32>(impl->GetState());
56 LOG_DEBUG(Service_Audio, "called. state={}", *out_state);
57 R_SUCCEED();
58}
59
60Result IAudioIn::Start() {
61 LOG_DEBUG(Service_Audio, "called");
62 R_RETURN(impl->StartSystem());
63}
64
65Result IAudioIn::Stop() {
66 LOG_DEBUG(Service_Audio, "called");
67 R_RETURN(impl->StopSystem());
68}
69
70Result IAudioIn::AppendAudioInBuffer(InArray<AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
71 u64 buffer_client_ptr) {
72 if (buffer.empty()) {
73 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!");
74 R_THROW(Audio::ResultInsufficientBuffer);
75 }
76
77 [[maybe_unused]] const auto session_id{impl->GetSystem().GetSessionId()};
78 LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", session_id,
79 buffer_client_ptr);
80
81 R_RETURN(impl->AppendBuffer(buffer[0], buffer_client_ptr));
82}
83
84Result IAudioIn::RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
85 LOG_DEBUG(Service_Audio, "called");
86 *out_event = &impl->GetBufferEvent();
87 R_SUCCEED();
88}
89
90Result IAudioIn::GetReleasedAudioInBuffer(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
91 Out<u32> out_count) {
92 *out_count = impl->GetReleasedBuffers(out_audio_buffer);
93
94 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
95 impl->GetSystem().GetSessionId(), *out_count);
96 R_SUCCEED();
97}
98
99Result IAudioIn::ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr) {
100 *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr);
101
102 LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr,
103 *out_contains_buffer);
104 R_SUCCEED();
105}
106
107Result IAudioIn::GetAudioInBufferCount(Out<u32> out_buffer_count) {
108 *out_buffer_count = impl->GetBufferCount();
109 LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count);
110 R_SUCCEED();
111}
112
113Result IAudioIn::SetDeviceGain(f32 device_gain) {
114 impl->SetVolume(device_gain);
115 LOG_DEBUG(Service_Audio, "called. Gain {}", device_gain);
116 R_SUCCEED();
117}
118
119Result IAudioIn::GetDeviceGain(Out<f32> out_device_gain) {
120 *out_device_gain = impl->GetVolume();
121 LOG_DEBUG(Service_Audio, "called. Gain {}", *out_device_gain);
122 R_SUCCEED();
123}
124
125Result IAudioIn::FlushAudioInBuffers(Out<bool> out_flushed) {
126 *out_flushed = impl->FlushAudioInBuffers();
127 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed);
128 R_SUCCEED();
129}
130
131} // 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 @@
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/in/audio_in.h"
7#include "core/hle/service/cmif_types.h"
8#include "core/hle/service/kernel_helpers.h"
9#include "core/hle/service/service.h"
10
11namespace Service::Audio {
12
13class IAudioIn final : public ServiceFramework<IAudioIn> {
14public:
15 explicit IAudioIn(Core::System& system_, AudioCore::AudioIn::Manager& manager,
16 size_t session_id, const std::string& device_name,
17 const AudioCore::AudioIn::AudioInParameter& in_params,
18 Kernel::KProcess* handle, u64 applet_resource_user_id);
19 ~IAudioIn() override;
20
21 std::shared_ptr<AudioCore::AudioIn::In> GetImpl() {
22 return impl;
23 }
24
25 Result GetAudioInState(Out<u32> out_state);
26 Result Start();
27 Result Stop();
28 Result AppendAudioInBuffer(
29 InArray<AudioCore::AudioIn::AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
30 u64 buffer_client_ptr);
31 Result RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
32 Result GetReleasedAudioInBuffer(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
33 Out<u32> out_count);
34 Result ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr);
35 Result GetAudioInBufferCount(Out<u32> out_buffer_count);
36 Result SetDeviceGain(f32 device_gain);
37 Result GetDeviceGain(Out<f32> out_device_gain);
38 Result FlushAudioInBuffers(Out<bool> out_flushed);
39
40private:
41 Kernel::KProcess* process;
42 KernelHelpers::ServiceContext service_context;
43 Kernel::KEvent* event;
44 std::shared_ptr<AudioCore::AudioIn::In> impl;
45 Common::ScratchBuffer<u64> released_buffer;
46};
47
48} // namespace Service::Audio