summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/device/audio_buffers.h4
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/audio/audio_in.cpp26
-rw-r--r--src/core/hle/service/audio/audio_in.h9
-rw-r--r--src/core/hle/service/audio/audio_out.cpp146
-rw-r--r--src/core/hle/service/audio/audio_out.h58
-rw-r--r--src/core/hle/service/audio/audout_u.cpp207
7 files changed, 236 insertions, 216 deletions
diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h
index 5d8ed0ef7..25da4c8a2 100644
--- a/src/audio_core/device/audio_buffers.h
+++ b/src/audio_core/device/audio_buffers.h
@@ -146,11 +146,11 @@ public:
146 break; 146 break;
147 } 147 }
148 148
149 tags[released++] = tag;
150
151 if (released >= tags.size()) { 149 if (released >= tags.size()) {
152 break; 150 break;
153 } 151 }
152
153 tags[released++] = tag;
154 } 154 }
155 155
156 return released; 156 return released;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 51fe8c500..1255ee6bf 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -493,6 +493,8 @@ 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.cpp
497 hle/service/audio/audio_out.h
496 hle/service/audio/audio.cpp 498 hle/service/audio/audio.cpp
497 hle/service/audio/audio.h 499 hle/service/audio/audio.h
498 hle/service/audio/audio_controller.cpp 500 hle/service/audio/audio_controller.cpp
diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp
index d847e0fc8..31d136077 100644
--- a/src/core/hle/service/audio/audio_in.cpp
+++ b/src/core/hle/service/audio/audio_in.cpp
@@ -21,12 +21,12 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
21 {2, C<&IAudioIn::Stop>, "Stop"}, 21 {2, C<&IAudioIn::Stop>, "Stop"},
22 {3, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"}, 22 {3, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"},
23 {4, C<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"}, 23 {4, C<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"},
24 {5, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffer"}, 24 {5, C<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"},
25 {6, C<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"}, 25 {6, C<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"},
26 {7, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"}, 26 {7, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"},
27 {8, C<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBufferAuto"}, 27 {8, C<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"},
28 {9, C<&IAudioIn::GetReleasedAudioInBuffer>, "GetReleasedAudioInBuffersAuto"}, 28 {9, C<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"},
29 {10, C<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBufferAuto"}, 29 {10, C<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"},
30 {11, C<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"}, 30 {11, C<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"},
31 {12, C<&IAudioIn::SetDeviceGain>, "SetDeviceGain"}, 31 {12, C<&IAudioIn::SetDeviceGain>, "SetDeviceGain"},
32 {13, C<&IAudioIn::GetDeviceGain>, "GetDeviceGain"}, 32 {13, C<&IAudioIn::GetDeviceGain>, "GetDeviceGain"},
@@ -69,6 +69,11 @@ Result IAudioIn::Stop() {
69 69
70Result IAudioIn::AppendAudioInBuffer(InArray<AudioInBuffer, BufferAttr_HipcMapAlias> buffer, 70Result IAudioIn::AppendAudioInBuffer(InArray<AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
71 u64 buffer_client_ptr) { 71 u64 buffer_client_ptr) {
72 R_RETURN(this->AppendAudioInBufferAuto(buffer, buffer_client_ptr));
73}
74
75Result IAudioIn::AppendAudioInBufferAuto(InArray<AudioInBuffer, BufferAttr_HipcAutoSelect> buffer,
76 u64 buffer_client_ptr) {
72 if (buffer.empty()) { 77 if (buffer.empty()) {
73 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!"); 78 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!");
74 R_THROW(Audio::ResultInsufficientBuffer); 79 R_THROW(Audio::ResultInsufficientBuffer);
@@ -87,8 +92,17 @@ Result IAudioIn::RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_e
87 R_SUCCEED(); 92 R_SUCCEED();
88} 93}
89 94
90Result IAudioIn::GetReleasedAudioInBuffer(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer, 95Result IAudioIn::GetReleasedAudioInBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
91 Out<u32> out_count) { 96 Out<u32> out_count) {
97 R_RETURN(this->GetReleasedAudioInBuffersAuto(out_audio_buffer, out_count));
98}
99
100Result IAudioIn::GetReleasedAudioInBuffersAuto(
101 OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer, Out<u32> out_count) {
102
103 if (!out_audio_buffer.empty()) {
104 out_audio_buffer[0] = 0;
105 }
92 *out_count = impl->GetReleasedBuffers(out_audio_buffer); 106 *out_count = impl->GetReleasedBuffers(out_audio_buffer);
93 107
94 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers", 108 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
diff --git a/src/core/hle/service/audio/audio_in.h b/src/core/hle/service/audio/audio_in.h
index 8d6398ef6..3fe1e1e87 100644
--- a/src/core/hle/service/audio/audio_in.h
+++ b/src/core/hle/service/audio/audio_in.h
@@ -28,9 +28,14 @@ public:
28 Result AppendAudioInBuffer( 28 Result AppendAudioInBuffer(
29 InArray<AudioCore::AudioIn::AudioInBuffer, BufferAttr_HipcMapAlias> buffer, 29 InArray<AudioCore::AudioIn::AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
30 u64 buffer_client_ptr); 30 u64 buffer_client_ptr);
31 Result AppendAudioInBufferAuto(
32 InArray<AudioCore::AudioIn::AudioInBuffer, BufferAttr_HipcAutoSelect> buffer,
33 u64 buffer_client_ptr);
31 Result RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); 34 Result RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
32 Result GetReleasedAudioInBuffer(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer, 35 Result GetReleasedAudioInBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
33 Out<u32> out_count); 36 Out<u32> out_count);
37 Result GetReleasedAudioInBuffersAuto(OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer,
38 Out<u32> out_count);
34 Result ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr); 39 Result ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr);
35 Result GetAudioInBufferCount(Out<u32> out_buffer_count); 40 Result GetAudioInBufferCount(Out<u32> out_buffer_count);
36 Result SetDeviceGain(f32 device_gain); 41 Result SetDeviceGain(f32 device_gain);
diff --git a/src/core/hle/service/audio/audio_out.cpp b/src/core/hle/service/audio/audio_out.cpp
new file mode 100644
index 000000000..cd2dc1f6f
--- /dev/null
+++ b/src/core/hle/service/audio/audio_out.cpp
@@ -0,0 +1,146 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "audio_core/out/audio_out.h"
5#include "audio_core/out/audio_out_system.h"
6#include "core/hle/kernel/k_process.h"
7#include "core/hle/service/audio/audio_out.h"
8#include "core/hle/service/cmif_serialization.h"
9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/service.h"
11
12namespace Service::Audio {
13using namespace AudioCore::AudioOut;
14
15IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id,
16 const std::string& device_name, const AudioOutParameter& in_params,
17 Kernel::KProcess* handle, u64 applet_resource_user_id)
18 : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
19 event{service_context.CreateEvent("AudioOutEvent")}, process{handle},
20 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
21
22 // clang-format off
23 static const FunctionInfo functions[] = {
24 {0, C<&IAudioOut::GetAudioOutState>, "GetAudioOutState"},
25 {1, C<&IAudioOut::Start>, "Start"},
26 {2, C<&IAudioOut::Stop>, "Stop"},
27 {3, C<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"},
28 {4, C<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"},
29 {5, C<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"},
30 {6, C<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"},
31 {7, C<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"},
32 {8, C<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"},
33 {9, C<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"},
34 {10, C<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"},
35 {11, C<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"},
36 {12, C<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"},
37 {13, C<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"},
38 };
39 // clang-format on
40 RegisterHandlers(functions);
41
42 process->Open();
43}
44
45IAudioOut::~IAudioOut() {
46 impl->Free();
47 service_context.CloseEvent(event);
48 process->Close();
49}
50
51Result IAudioOut::GetAudioOutState(Out<u32> out_state) {
52 *out_state = static_cast<u32>(impl->GetState());
53 LOG_DEBUG(Service_Audio, "called. state={}", *out_state);
54 R_SUCCEED();
55}
56
57Result IAudioOut::Start() {
58 LOG_DEBUG(Service_Audio, "called");
59 R_RETURN(impl->StartSystem());
60}
61
62Result IAudioOut::Stop() {
63 LOG_DEBUG(Service_Audio, "called");
64 R_RETURN(impl->StopSystem());
65}
66
67Result IAudioOut::AppendAudioOutBuffer(
68 InArray<AudioOutBuffer, BufferAttr_HipcMapAlias> audio_out_buffer, u64 buffer_client_ptr) {
69 R_RETURN(this->AppendAudioOutBufferAuto(audio_out_buffer, buffer_client_ptr));
70}
71
72Result IAudioOut::AppendAudioOutBufferAuto(
73 InArray<AudioOutBuffer, BufferAttr_HipcAutoSelect> audio_out_buffer, u64 buffer_client_ptr) {
74 if (audio_out_buffer.empty()) {
75 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioOutBuffer!");
76 R_THROW(Audio::ResultInsufficientBuffer);
77 }
78
79 LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}",
80 impl->GetSystem().GetSessionId(), buffer_client_ptr);
81 R_RETURN(impl->AppendBuffer(audio_out_buffer[0], buffer_client_ptr));
82}
83
84Result IAudioOut::RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
85 LOG_DEBUG(Service_Audio, "called");
86 *out_event = &impl->GetBufferEvent();
87 R_SUCCEED();
88}
89
90Result IAudioOut::GetReleasedAudioOutBuffers(
91 OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer, Out<u32> out_count) {
92 R_RETURN(this->GetReleasedAudioOutBuffersAuto(out_audio_buffer, out_count));
93}
94
95Result IAudioOut::GetReleasedAudioOutBuffersAuto(
96 OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer, Out<u32> out_count) {
97
98 if (!out_audio_buffer.empty()) {
99 out_audio_buffer[0] = 0;
100 }
101 *out_count = impl->GetReleasedBuffers(out_audio_buffer);
102
103 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
104 impl->GetSystem().GetSessionId(), *out_count);
105 R_SUCCEED();
106}
107
108Result IAudioOut::ContainsAudioOutBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr) {
109 *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr);
110
111 LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr,
112 *out_contains_buffer);
113 R_SUCCEED();
114}
115
116Result IAudioOut::GetAudioOutBufferCount(Out<u32> out_buffer_count) {
117 *out_buffer_count = impl->GetBufferCount();
118 LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count);
119 R_SUCCEED();
120}
121
122Result IAudioOut::GetAudioOutPlayedSampleCount(Out<u64> out_played_sample_count) {
123 *out_played_sample_count = impl->GetPlayedSampleCount();
124 LOG_DEBUG(Service_Audio, "called. Played samples={}", *out_played_sample_count);
125 R_SUCCEED();
126}
127
128Result IAudioOut::FlushAudioOutBuffers(Out<bool> out_flushed) {
129 *out_flushed = impl->FlushAudioOutBuffers();
130 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed);
131 R_SUCCEED();
132}
133
134Result IAudioOut::SetAudioOutVolume(f32 volume) {
135 LOG_DEBUG(Service_Audio, "called. Volume={}", volume);
136 impl->SetVolume(volume);
137 R_SUCCEED();
138}
139
140Result IAudioOut::GetAudioOutVolume(Out<f32> out_volume) {
141 *out_volume = impl->GetVolume();
142 LOG_DEBUG(Service_Audio, "called. Volume={}", *out_volume);
143 R_SUCCEED();
144}
145
146} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_out.h b/src/core/hle/service/audio/audio_out.h
new file mode 100644
index 000000000..779b213e7
--- /dev/null
+++ b/src/core/hle/service/audio/audio_out.h
@@ -0,0 +1,58 @@
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_out_manager.h"
7#include "audio_core/out/audio_out_system.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/service.h"
11
12namespace Kernel {
13class KReadableEvent;
14}
15
16namespace Service::Audio {
17
18class IAudioOut : public ServiceFramework<IAudioOut> {
19public:
20 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
21 size_t session_id, const std::string& device_name,
22 const AudioCore::AudioOut::AudioOutParameter& in_params,
23 Kernel::KProcess* handle, u64 applet_resource_user_id);
24 ~IAudioOut() override;
25
26 std::shared_ptr<AudioCore::AudioOut::Out> GetImpl() {
27 return impl;
28 }
29
30 Result GetAudioOutState(Out<u32> out_state);
31 Result Start();
32 Result Stop();
33 Result AppendAudioOutBuffer(
34 InArray<AudioCore::AudioOut::AudioOutBuffer, BufferAttr_HipcMapAlias> audio_out_buffer,
35 u64 buffer_client_ptr);
36 Result AppendAudioOutBufferAuto(
37 InArray<AudioCore::AudioOut::AudioOutBuffer, BufferAttr_HipcAutoSelect> audio_out_buffer,
38 u64 buffer_client_ptr);
39 Result RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
40 Result GetReleasedAudioOutBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
41 Out<u32> out_count);
42 Result GetReleasedAudioOutBuffersAuto(OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer,
43 Out<u32> out_count);
44 Result ContainsAudioOutBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr);
45 Result GetAudioOutBufferCount(Out<u32> out_buffer_count);
46 Result GetAudioOutPlayedSampleCount(Out<u64> out_played_sample_count);
47 Result FlushAudioOutBuffers(Out<bool> out_flushed);
48 Result SetAudioOutVolume(f32 volume);
49 Result GetAudioOutVolume(Out<f32> out_volume);
50
51private:
52 KernelHelpers::ServiceContext service_context;
53 Kernel::KEvent* event;
54 Kernel::KProcess* process;
55 std::shared_ptr<AudioCore::AudioOut::Out> impl;
56};
57
58} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 8cc7b69f4..5364177ba 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -1,220 +1,15 @@
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 <array>
5#include <cstring>
6#include <vector>
7
8#include "audio_core/out/audio_out_system.h"
9#include "audio_core/renderer/audio_device.h"
10#include "common/common_funcs.h"
11#include "common/logging/log.h"
12#include "common/scratch_buffer.h"
13#include "common/string_util.h" 4#include "common/string_util.h"
14#include "common/swap.h" 5#include "core/hle/service/audio/audio_out.h"
15#include "core/core.h"
16#include "core/hle/kernel/k_event.h"
17#include "core/hle/service/audio/audout_u.h" 6#include "core/hle/service/audio/audout_u.h"
18#include "core/hle/service/audio/errors.h"
19#include "core/hle/service/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
20#include "core/memory.h" 8#include "core/memory.h"
21 9
22namespace Service::Audio { 10namespace Service::Audio {
23using namespace AudioCore::AudioOut; 11using namespace AudioCore::AudioOut;
24 12
25class IAudioOut final : public ServiceFramework<IAudioOut> {
26public:
27 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
28 size_t session_id, const std::string& device_name,
29 const AudioOutParameter& in_params, Kernel::KProcess* handle,
30 u64 applet_resource_user_id)
31 : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
32 event{service_context.CreateEvent("AudioOutEvent")}, process{handle},
33 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
34
35 // clang-format off
36 static const FunctionInfo functions[] = {
37 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
38 {1, &IAudioOut::Start, "Start"},
39 {2, &IAudioOut::Stop, "Stop"},
40 {3, &IAudioOut::AppendAudioOutBuffer, "AppendAudioOutBuffer"},
41 {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
42 {5, &IAudioOut::GetReleasedAudioOutBuffers, "GetReleasedAudioOutBuffers"},
43 {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
44 {7, &IAudioOut::AppendAudioOutBuffer, "AppendAudioOutBufferAuto"},
45 {8, &IAudioOut::GetReleasedAudioOutBuffers, "GetReleasedAudioOutBuffersAuto"},
46 {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
47 {10, &IAudioOut::GetAudioOutPlayedSampleCount, "GetAudioOutPlayedSampleCount"},
48 {11, &IAudioOut::FlushAudioOutBuffers, "FlushAudioOutBuffers"},
49 {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"},
50 {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"},
51 };
52 // clang-format on
53 RegisterHandlers(functions);
54
55 process->Open();
56 }
57
58 ~IAudioOut() override {
59 impl->Free();
60 service_context.CloseEvent(event);
61 process->Close();
62 }
63
64 [[nodiscard]] std::shared_ptr<AudioCore::AudioOut::Out> GetImpl() {
65 return impl;
66 }
67
68private:
69 void GetAudioOutState(HLERequestContext& ctx) {
70 const auto state = static_cast<u32>(impl->GetState());
71
72 LOG_DEBUG(Service_Audio, "called. State={}", state);
73
74 IPC::ResponseBuilder rb{ctx, 3};
75 rb.Push(ResultSuccess);
76 rb.Push(state);
77 }
78
79 void Start(HLERequestContext& ctx) {
80 LOG_DEBUG(Service_Audio, "called");
81
82 auto result = impl->StartSystem();
83
84 IPC::ResponseBuilder rb{ctx, 2};
85 rb.Push(result);
86 }
87
88 void Stop(HLERequestContext& ctx) {
89 LOG_DEBUG(Service_Audio, "called");
90
91 auto result = impl->StopSystem();
92
93 IPC::ResponseBuilder rb{ctx, 2};
94 rb.Push(result);
95 }
96
97 void AppendAudioOutBuffer(HLERequestContext& ctx) {
98 IPC::RequestParser rp{ctx};
99 u64 tag = rp.PopRaw<u64>();
100
101 const auto in_buffer_size{ctx.GetReadBufferSize()};
102 if (in_buffer_size < sizeof(AudioOutBuffer)) {
103 LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioOutBuffer!");
104 }
105
106 const auto& in_buffer = ctx.ReadBuffer();
107 AudioOutBuffer buffer{};
108 std::memcpy(&buffer, in_buffer.data(), sizeof(AudioOutBuffer));
109
110 LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}",
111 impl->GetSystem().GetSessionId(), tag);
112
113 auto result = impl->AppendBuffer(buffer, tag);
114
115 IPC::ResponseBuilder rb{ctx, 2};
116 rb.Push(result);
117 }
118
119 void RegisterBufferEvent(HLERequestContext& ctx) {
120 LOG_DEBUG(Service_Audio, "called");
121
122 auto& buffer_event = impl->GetBufferEvent();
123
124 IPC::ResponseBuilder rb{ctx, 2, 1};
125 rb.Push(ResultSuccess);
126 rb.PushCopyObjects(buffer_event);
127 }
128
129 void GetReleasedAudioOutBuffers(HLERequestContext& ctx) {
130 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
131 released_buffer.resize_destructive(write_buffer_size);
132 released_buffer[0] = 0;
133
134 const auto count = impl->GetReleasedBuffers(released_buffer);
135
136 ctx.WriteBuffer(released_buffer);
137
138 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
139 impl->GetSystem().GetSessionId(), count);
140
141 IPC::ResponseBuilder rb{ctx, 3};
142 rb.Push(ResultSuccess);
143 rb.Push(count);
144 }
145
146 void ContainsAudioOutBuffer(HLERequestContext& ctx) {
147 IPC::RequestParser rp{ctx};
148
149 const u64 tag{rp.Pop<u64>()};
150 const auto buffer_queued{impl->ContainsAudioBuffer(tag)};
151
152 LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", tag, buffer_queued);
153
154 IPC::ResponseBuilder rb{ctx, 3};
155 rb.Push(ResultSuccess);
156 rb.Push(buffer_queued);
157 }
158
159 void GetAudioOutBufferCount(HLERequestContext& ctx) {
160 const auto buffer_count = impl->GetBufferCount();
161
162 LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count);
163
164 IPC::ResponseBuilder rb{ctx, 3};
165 rb.Push(ResultSuccess);
166 rb.Push(buffer_count);
167 }
168
169 void GetAudioOutPlayedSampleCount(HLERequestContext& ctx) {
170 const auto samples_played = impl->GetPlayedSampleCount();
171
172 LOG_DEBUG(Service_Audio, "called. Played samples={}", samples_played);
173
174 IPC::ResponseBuilder rb{ctx, 4};
175 rb.Push(ResultSuccess);
176 rb.Push(samples_played);
177 }
178
179 void FlushAudioOutBuffers(HLERequestContext& ctx) {
180 bool flushed{impl->FlushAudioOutBuffers()};
181
182 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed);
183
184 IPC::ResponseBuilder rb{ctx, 3};
185 rb.Push(ResultSuccess);
186 rb.Push(flushed);
187 }
188
189 void SetAudioOutVolume(HLERequestContext& ctx) {
190 IPC::RequestParser rp{ctx};
191 const auto volume = rp.Pop<f32>();
192
193 LOG_DEBUG(Service_Audio, "called. Volume={}", volume);
194
195 impl->SetVolume(volume);
196
197 IPC::ResponseBuilder rb{ctx, 2};
198 rb.Push(ResultSuccess);
199 }
200
201 void GetAudioOutVolume(HLERequestContext& ctx) {
202 const auto volume = impl->GetVolume();
203
204 LOG_DEBUG(Service_Audio, "called. Volume={}", volume);
205
206 IPC::ResponseBuilder rb{ctx, 3};
207 rb.Push(ResultSuccess);
208 rb.Push(volume);
209 }
210
211 KernelHelpers::ServiceContext service_context;
212 Kernel::KEvent* event;
213 Kernel::KProcess* process;
214 std::shared_ptr<AudioCore::AudioOut::Out> impl;
215 Common::ScratchBuffer<u64> released_buffer;
216};
217
218AudOutU::AudOutU(Core::System& system_) 13AudOutU::AudOutU(Core::System& system_)
219 : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, 14 : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"},
220 impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} { 15 impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} {