summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Liam2024-02-20 20:16:41 -0500
committerGravatar Liam2024-02-20 22:15:38 -0500
commit0471e54e5a74e3171da77ca95f0420142d675947 (patch)
treea436bbcb763a23e58ed91844e5ca3906e6ef7523 /src
parentaudio: rewrite IAudioRendererManager (diff)
downloadyuzu-0471e54e5a74e3171da77ca95f0420142d675947.tar.gz
yuzu-0471e54e5a74e3171da77ca95f0420142d675947.tar.xz
yuzu-0471e54e5a74e3171da77ca95f0420142d675947.zip
audio: rewrite IAudioRenderer
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/audio/audio_renderer.cpp198
-rw-r--r--src/core/hle/service/audio/audio_renderer.h35
-rw-r--r--src/core/hle/service/cmif_serialization.h2
3 files changed, 86 insertions, 149 deletions
diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp
index a408fc3cf..fc20054b4 100644
--- a/src/core/hle/service/audio/audio_renderer.cpp
+++ b/src/core/hle/service/audio/audio_renderer.cpp
@@ -2,7 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/audio/audio_renderer.h" 4#include "core/hle/service/audio/audio_renderer.h"
5#include "core/hle/service/ipc_helpers.h" 5#include "core/hle/service/cmif_serialization.h"
6 6
7namespace Service::Audio { 7namespace Service::Audio {
8using namespace AudioCore::Renderer; 8using namespace AudioCore::Renderer;
@@ -18,20 +18,20 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_,
18 process_handle{process_handle_} { 18 process_handle{process_handle_} {
19 // clang-format off 19 // clang-format off
20 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
21 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, 21 {0, C<&IAudioRenderer::GetSampleRate>, "GetSampleRate"},
22 {1, &IAudioRenderer::GetSampleCount, "GetSampleCount"}, 22 {1, C<&IAudioRenderer::GetSampleCount>, "GetSampleCount"},
23 {2, &IAudioRenderer::GetMixBufferCount, "GetMixBufferCount"}, 23 {2, C<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"},
24 {3, &IAudioRenderer::GetState, "GetState"}, 24 {3, C<&IAudioRenderer::GetState>, "GetState"},
25 {4, &IAudioRenderer::RequestUpdate, "RequestUpdate"}, 25 {4, C<&IAudioRenderer::RequestUpdate>, "RequestUpdate"},
26 {5, &IAudioRenderer::Start, "Start"}, 26 {5, C<&IAudioRenderer::Start>, "Start"},
27 {6, &IAudioRenderer::Stop, "Stop"}, 27 {6, C<&IAudioRenderer::Stop>, "Stop"},
28 {7, &IAudioRenderer::QuerySystemEvent, "QuerySystemEvent"}, 28 {7, C<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"},
29 {8, &IAudioRenderer::SetRenderingTimeLimit, "SetRenderingTimeLimit"}, 29 {8, C<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"},
30 {9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"}, 30 {9, C<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"},
31 {10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"}, 31 {10, C<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto"},
32 {11, nullptr, "ExecuteAudioRendererRendering"}, 32 {11, nullptr, "ExecuteAudioRendererRendering"},
33 {12, &IAudioRenderer::SetVoiceDropParameter, "SetVoiceDropParameter"}, 33 {12, C<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter"},
34 {13, &IAudioRenderer::GetVoiceDropParameter, "GetVoiceDropParameter"}, 34 {13, C<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter"},
35 }; 35 };
36 // clang-format on 36 // clang-format on
37 RegisterHandlers(functions); 37 RegisterHandlers(functions);
@@ -47,165 +47,93 @@ IAudioRenderer::~IAudioRenderer() {
47 process_handle->Close(); 47 process_handle->Close();
48} 48}
49 49
50void IAudioRenderer::GetSampleRate(HLERequestContext& ctx) { 50Result IAudioRenderer::GetSampleRate(Out<u32> out_sample_rate) {
51 const auto sample_rate{impl->GetSystem().GetSampleRate()}; 51 *out_sample_rate = impl->GetSystem().GetSampleRate();
52 52 LOG_DEBUG(Service_Audio, "called. Sample rate {}", *out_sample_rate);
53 LOG_DEBUG(Service_Audio, "called. Sample rate {}", sample_rate); 53 R_SUCCEED();
54
55 IPC::ResponseBuilder rb{ctx, 3};
56 rb.Push(ResultSuccess);
57 rb.Push(sample_rate);
58} 54}
59 55
60void IAudioRenderer::GetSampleCount(HLERequestContext& ctx) { 56Result IAudioRenderer::GetSampleCount(Out<u32> out_sample_count) {
61 const auto sample_count{impl->GetSystem().GetSampleCount()}; 57 *out_sample_count = impl->GetSystem().GetSampleCount();
62 58 LOG_DEBUG(Service_Audio, "called. Sample count {}", *out_sample_count);
63 LOG_DEBUG(Service_Audio, "called. Sample count {}", sample_count); 59 R_SUCCEED();
64
65 IPC::ResponseBuilder rb{ctx, 3};
66 rb.Push(ResultSuccess);
67 rb.Push(sample_count);
68} 60}
69 61
70void IAudioRenderer::GetState(HLERequestContext& ctx) { 62Result IAudioRenderer::GetState(Out<u32> out_state) {
71 const u32 state{!impl->GetSystem().IsActive()}; 63 *out_state = !impl->GetSystem().IsActive();
72 64 LOG_DEBUG(Service_Audio, "called, state {}", *out_state);
73 LOG_DEBUG(Service_Audio, "called, state {}", state); 65 R_SUCCEED();
74
75 IPC::ResponseBuilder rb{ctx, 3};
76 rb.Push(ResultSuccess);
77 rb.Push(state);
78} 66}
79 67
80void IAudioRenderer::GetMixBufferCount(HLERequestContext& ctx) { 68Result IAudioRenderer::GetMixBufferCount(Out<u32> out_mix_buffer_count) {
81 LOG_DEBUG(Service_Audio, "called"); 69 LOG_DEBUG(Service_Audio, "called");
70 *out_mix_buffer_count = impl->GetSystem().GetMixBufferCount();
71 R_SUCCEED();
72}
82 73
83 const auto buffer_count{impl->GetSystem().GetMixBufferCount()}; 74Result IAudioRenderer::RequestUpdate(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
84 75 OutBuffer<BufferAttr_HipcMapAlias> out_performance_buffer,
85 IPC::ResponseBuilder rb{ctx, 3}; 76 InBuffer<BufferAttr_HipcMapAlias> input) {
86 rb.Push(ResultSuccess); 77 R_RETURN(this->RequestUpdateAuto(out_buffer, out_performance_buffer, input));
87 rb.Push(buffer_count);
88} 78}
89 79
90void IAudioRenderer::RequestUpdate(HLERequestContext& ctx) { 80Result IAudioRenderer::RequestUpdateAuto(
81 OutBuffer<BufferAttr_HipcAutoSelect> out_buffer,
82 OutBuffer<BufferAttr_HipcAutoSelect> out_performance_buffer,
83 InBuffer<BufferAttr_HipcAutoSelect> input) {
91 LOG_TRACE(Service_Audio, "called"); 84 LOG_TRACE(Service_Audio, "called");
92 85
93 const auto input{ctx.ReadBuffer(0)}; 86 const auto result = impl->RequestUpdate(input, out_performance_buffer, out_buffer);
94 87 if (result.IsFailure()) {
95 // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for
96 // checking size 0. Performance size is 0 for most games.
97
98 auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0};
99 if (is_buffer_b) {
100 const auto buffersB{ctx.BufferDescriptorB()};
101 output_buffer.resize_destructive(buffersB[0].Size());
102 performance_buffer.resize_destructive(buffersB[1].Size());
103 } else {
104 const auto buffersC{ctx.BufferDescriptorC()};
105 output_buffer.resize_destructive(buffersC[0].Size());
106 performance_buffer.resize_destructive(buffersC[1].Size());
107 }
108
109 auto result = impl->RequestUpdate(input, performance_buffer, output_buffer);
110
111 if (result.IsSuccess()) {
112 if (is_buffer_b) {
113 ctx.WriteBufferB(output_buffer.data(), output_buffer.size(), 0);
114 ctx.WriteBufferB(performance_buffer.data(), performance_buffer.size(), 1);
115 } else {
116 ctx.WriteBufferC(output_buffer.data(), output_buffer.size(), 0);
117 ctx.WriteBufferC(performance_buffer.data(), performance_buffer.size(), 1);
118 }
119 } else {
120 LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.GetDescription()); 88 LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.GetDescription());
121 } 89 }
122 90
123 IPC::ResponseBuilder rb{ctx, 2}; 91 R_RETURN(result);
124 rb.Push(result);
125} 92}
126 93
127void IAudioRenderer::Start(HLERequestContext& ctx) { 94Result IAudioRenderer::Start() {
128 LOG_DEBUG(Service_Audio, "called"); 95 LOG_DEBUG(Service_Audio, "called");
129
130 impl->Start(); 96 impl->Start();
131 97 R_SUCCEED();
132 IPC::ResponseBuilder rb{ctx, 2};
133 rb.Push(ResultSuccess);
134} 98}
135 99
136void IAudioRenderer::Stop(HLERequestContext& ctx) { 100Result IAudioRenderer::Stop() {
137 LOG_DEBUG(Service_Audio, "called"); 101 LOG_DEBUG(Service_Audio, "called");
138
139 impl->Stop(); 102 impl->Stop();
140 103 R_SUCCEED();
141 IPC::ResponseBuilder rb{ctx, 2};
142 rb.Push(ResultSuccess);
143} 104}
144 105
145void IAudioRenderer::QuerySystemEvent(HLERequestContext& ctx) { 106Result IAudioRenderer::QuerySystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
146 LOG_DEBUG(Service_Audio, "called"); 107 LOG_DEBUG(Service_Audio, "called");
147 108 R_UNLESS(impl->GetSystem().GetExecutionMode() != AudioCore::ExecutionMode::Manual,
148 if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { 109 Audio::ResultNotSupported);
149 IPC::ResponseBuilder rb{ctx, 2}; 110 *out_event = &rendered_event->GetReadableEvent();
150 rb.Push(Audio::ResultNotSupported); 111 R_SUCCEED();
151 return;
152 }
153
154 IPC::ResponseBuilder rb{ctx, 2, 1};
155 rb.Push(ResultSuccess);
156 rb.PushCopyObjects(rendered_event->GetReadableEvent());
157}
158
159void IAudioRenderer::SetRenderingTimeLimit(HLERequestContext& ctx) {
160 LOG_DEBUG(Service_Audio, "called");
161
162 IPC::RequestParser rp{ctx};
163 auto limit = rp.PopRaw<u32>();
164
165 auto& system_ = impl->GetSystem();
166 system_.SetRenderingTimeLimit(limit);
167
168 IPC::ResponseBuilder rb{ctx, 2};
169 rb.Push(ResultSuccess);
170} 112}
171 113
172void IAudioRenderer::GetRenderingTimeLimit(HLERequestContext& ctx) { 114Result IAudioRenderer::SetRenderingTimeLimit(u32 rendering_time_limit) {
173 LOG_DEBUG(Service_Audio, "called"); 115 LOG_DEBUG(Service_Audio, "called");
174 116 impl->GetSystem().SetRenderingTimeLimit(rendering_time_limit);
175 auto& system_ = impl->GetSystem(); 117 ;
176 auto time = system_.GetRenderingTimeLimit(); 118 R_SUCCEED();
177
178 IPC::ResponseBuilder rb{ctx, 3};
179 rb.Push(ResultSuccess);
180 rb.Push(time);
181} 119}
182 120
183void IAudioRenderer::ExecuteAudioRendererRendering(HLERequestContext& ctx) { 121Result IAudioRenderer::GetRenderingTimeLimit(Out<u32> out_rendering_time_limit) {
184 LOG_DEBUG(Service_Audio, "called"); 122 LOG_DEBUG(Service_Audio, "called");
123 *out_rendering_time_limit = impl->GetSystem().GetRenderingTimeLimit();
124 R_SUCCEED();
185} 125}
186 126
187void IAudioRenderer::SetVoiceDropParameter(HLERequestContext& ctx) { 127Result IAudioRenderer::SetVoiceDropParameter(f32 voice_drop_parameter) {
188 LOG_DEBUG(Service_Audio, "called"); 128 LOG_DEBUG(Service_Audio, "called");
189 129 impl->GetSystem().SetVoiceDropParameter(voice_drop_parameter);
190 IPC::RequestParser rp{ctx}; 130 R_SUCCEED();
191 auto voice_drop_param{rp.Pop<f32>()};
192
193 auto& system_ = impl->GetSystem();
194 system_.SetVoiceDropParameter(voice_drop_param);
195
196 IPC::ResponseBuilder rb{ctx, 2};
197 rb.Push(ResultSuccess);
198} 131}
199 132
200void IAudioRenderer::GetVoiceDropParameter(HLERequestContext& ctx) { 133Result IAudioRenderer::GetVoiceDropParameter(Out<f32> out_voice_drop_parameter) {
201 LOG_DEBUG(Service_Audio, "called"); 134 LOG_DEBUG(Service_Audio, "called");
202 135 *out_voice_drop_parameter = impl->GetSystem().GetVoiceDropParameter();
203 auto& system_ = impl->GetSystem(); 136 R_SUCCEED();
204 auto voice_drop_param{system_.GetVoiceDropParameter()};
205
206 IPC::ResponseBuilder rb{ctx, 3};
207 rb.Push(ResultSuccess);
208 rb.Push(voice_drop_param);
209} 137}
210 138
211} // namespace Service::Audio 139} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_renderer.h b/src/core/hle/service/audio/audio_renderer.h
index d3e7461ef..f25c50ce8 100644
--- a/src/core/hle/service/audio/audio_renderer.h
+++ b/src/core/hle/service/audio/audio_renderer.h
@@ -4,9 +4,14 @@
4#pragma once 4#pragma once
5 5
6#include "audio_core/renderer/audio_renderer.h" 6#include "audio_core/renderer/audio_renderer.h"
7#include "core/hle/service/cmif_types.h"
7#include "core/hle/service/kernel_helpers.h" 8#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
11namespace Kernel {
12class KReadableEvent;
13}
14
10namespace Service::Audio { 15namespace Service::Audio {
11 16
12class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { 17class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
@@ -19,19 +24,23 @@ public:
19 ~IAudioRenderer() override; 24 ~IAudioRenderer() override;
20 25
21private: 26private:
22 void GetSampleRate(HLERequestContext& ctx); 27 Result GetSampleRate(Out<u32> out_sample_rate);
23 void GetSampleCount(HLERequestContext& ctx); 28 Result GetSampleCount(Out<u32> out_sample_count);
24 void GetState(HLERequestContext& ctx); 29 Result GetState(Out<u32> out_state);
25 void GetMixBufferCount(HLERequestContext& ctx); 30 Result GetMixBufferCount(Out<u32> out_mix_buffer_count);
26 void RequestUpdate(HLERequestContext& ctx); 31 Result RequestUpdate(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
27 void Start(HLERequestContext& ctx); 32 OutBuffer<BufferAttr_HipcMapAlias> out_performance_buffer,
28 void Stop(HLERequestContext& ctx); 33 InBuffer<BufferAttr_HipcMapAlias> input);
29 void QuerySystemEvent(HLERequestContext& ctx); 34 Result RequestUpdateAuto(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer,
30 void SetRenderingTimeLimit(HLERequestContext& ctx); 35 OutBuffer<BufferAttr_HipcAutoSelect> out_performance_buffer,
31 void GetRenderingTimeLimit(HLERequestContext& ctx); 36 InBuffer<BufferAttr_HipcAutoSelect> input);
32 void ExecuteAudioRendererRendering(HLERequestContext& ctx); 37 Result Start();
33 void SetVoiceDropParameter(HLERequestContext& ctx); 38 Result Stop();
34 void GetVoiceDropParameter(HLERequestContext& ctx); 39 Result QuerySystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
40 Result SetRenderingTimeLimit(u32 rendering_time_limit);
41 Result GetRenderingTimeLimit(Out<u32> out_rendering_time_limit);
42 Result SetVoiceDropParameter(f32 voice_drop_parameter);
43 Result GetVoiceDropParameter(Out<f32> out_voice_drop_parameter);
35 44
36 KernelHelpers::ServiceContext service_context; 45 KernelHelpers::ServiceContext service_context;
37 Kernel::KEvent* rendered_event; 46 Kernel::KEvent* rendered_event;
diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h
index f24682c34..5a5f610f3 100644
--- a/src/core/hle/service/cmif_serialization.h
+++ b/src/core/hle/service/cmif_serialization.h
@@ -415,7 +415,7 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
415 auto& buffer = temp[OutBufferIndex]; 415 auto& buffer = temp[OutBufferIndex];
416 const size_t size = buffer.size(); 416 const size_t size = buffer.size();
417 417
418 if (ctx.CanWriteBuffer(OutBufferIndex)) { 418 if (size > 0 && ctx.CanWriteBuffer(OutBufferIndex)) {
419 if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) { 419 if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) {
420 ctx.WriteBuffer(buffer.data(), size, OutBufferIndex); 420 ctx.WriteBuffer(buffer.data(), size, OutBufferIndex);
421 } else if constexpr (ArgType::Attr & BufferAttr_HipcMapAlias) { 421 } else if constexpr (ArgType::Attr & BufferAttr_HipcMapAlias) {