summaryrefslogtreecommitdiff
path: root/src/audio_core/renderer/system.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/renderer/system.h')
-rw-r--r--src/audio_core/renderer/system.h307
1 files changed, 307 insertions, 0 deletions
diff --git a/src/audio_core/renderer/system.h b/src/audio_core/renderer/system.h
new file mode 100644
index 000000000..bcbe65b07
--- /dev/null
+++ b/src/audio_core/renderer/system.h
@@ -0,0 +1,307 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <mutex>
8#include <span>
9
10#include "audio_core/renderer/behavior/behavior_info.h"
11#include "audio_core/renderer/command/command_processing_time_estimator.h"
12#include "audio_core/renderer/effect/effect_context.h"
13#include "audio_core/renderer/memory/memory_pool_info.h"
14#include "audio_core/renderer/mix/mix_context.h"
15#include "audio_core/renderer/performance/performance_manager.h"
16#include "audio_core/renderer/sink/sink_context.h"
17#include "audio_core/renderer/splitter/splitter_context.h"
18#include "audio_core/renderer/upsampler/upsampler_manager.h"
19#include "audio_core/renderer/voice/voice_context.h"
20#include "common/thread.h"
21#include "core/hle/service/audio/errors.h"
22
23namespace Core {
24namespace Memory {
25class Memory;
26}
27class System;
28} // namespace Core
29
30namespace Kernel {
31class KEvent;
32class KTransferMemory;
33} // namespace Kernel
34
35namespace AudioCore {
36struct AudioRendererParameterInternal;
37
38namespace AudioRenderer {
39class CommandBuffer;
40namespace ADSP {
41class ADSP;
42}
43
44/**
45 * Audio Renderer System, the main worker for audio rendering.
46 */
47class System {
48 enum class State {
49 Started = 0,
50 Stopped = 2,
51 };
52
53public:
54 explicit System(Core::System& core, Kernel::KEvent* adsp_rendered_event);
55
56 /**
57 * Calculate the total size required for all audio render workbuffers.
58 *
59 * @param params - Input parameters with the numbers of voices/mixes/sinks/etc.
60 * @return Size (in bytes) required for the audio renderer.
61 */
62 static u64 GetWorkBufferSize(const AudioRendererParameterInternal& params);
63
64 /**
65 * Initialize the renderer system.
66 * Allocates workbuffers and initializes everything to a default state, ready to receive a
67 * RequestUpdate.
68 *
69 * @param params - Input parameters to initialize the system with.
70 * @param transfer_memory - Game-supplied memory for all workbuffers. Unused.
71 * @param transfer_memory_size - Size of the transfer memory. Unused.
72 * @param process_handle - Process handle, also used for memory. Unused.
73 * @param applet_resource_user_id - Applet id for this renderer. Unused.
74 * @param session_id - Session id of this renderer.
75 * @return Result code.
76 */
77 Result Initialize(const AudioRendererParameterInternal& params,
78 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
79 u32 process_handle, u64 applet_resource_user_id, s32 session_id);
80
81 /**
82 * Finalize the system.
83 */
84 void Finalize();
85
86 /**
87 * Start the system.
88 */
89 void Start();
90
91 /**
92 * Stop the system.
93 */
94 void Stop();
95
96 /**
97 * Update the system.
98 *
99 * @param input - Inout buffer containing the update data.
100 * @param performance - Optional buffer for writing back performance metrics.
101 * @param output - Output information from rendering.
102 * @return Result code.
103 */
104 Result Update(std::span<const u8> input, std::span<u8> performance, std::span<u8> output);
105
106 /**
107 * Get the time limit (percent) for rendering
108 *
109 * @return Time limit as a percent.
110 */
111 u32 GetRenderingTimeLimit() const;
112
113 /**
114 * Set the time limit (percent) for rendering
115 *
116 * @param limit - New time limit.
117 */
118 void SetRenderingTimeLimit(u32 limit);
119
120 /**
121 * Get the session id for this system.
122 *
123 * @return Session id of this system.
124 */
125 u32 GetSessionId() const;
126
127 /**
128 * Get the sample rate of this system.
129 *
130 * @return Sample rate of this system.
131 */
132 u32 GetSampleRate() const;
133
134 /**
135 * Get the sample count of this system.
136 *
137 * @return Sample count of this system.
138 */
139 u32 GetSampleCount() const;
140
141 /**
142 * Get the number of mix buffers for this system.
143 *
144 * @return Number of mix buffers in the system.
145 */
146 u32 GetMixBufferCount() const;
147
148 /**
149 * Get the execution mode of this system.
150 * Note: Only Auto is implemented.
151 *
152 * @return Execution mode for this system.
153 */
154 ExecutionMode GetExecutionMode() const;
155
156 /**
157 * Get the rendering deivce for this system.
158 * This is unused.
159 *
160 * @return Rendering device for this system.
161 */
162 u32 GetRenderingDevice() const;
163
164 /**
165 * Check if this system is currently active.
166 *
167 * @return True if active, otherwise false.
168 */
169 bool IsActive() const;
170
171 /**
172 * Prepare and generate a list of commands for the AudioRenderer based on current state,
173 * signalling the buffer event when all processed.
174 */
175 void SendCommandToDsp();
176
177 /**
178 * Generate a list of commands for the AudioRenderer based on current state.
179 *
180 * @param command_buffer - Buffer for commands to be written to.
181 * @param command_buffer_size - Size of the command_buffer.
182 *
183 * @return Number of bytes written.
184 */
185 u64 GenerateCommand(std::span<u8> command_buffer, u64 command_buffer_size);
186
187 /**
188 * Try to drop some voices if the AudioRenderer fell behind.
189 *
190 * @param command_buffer - Command buffer to drop voices from.
191 * @param estimated_process_time - Current estimated processing time of all commands.
192 * @param time_limit - Time limit for rendering, voices are dropped if estimated
193 * exceeds this.
194 *
195 * @return Number of voices dropped.
196 */
197 u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit);
198
199private:
200 /// Core system
201 Core::System& core;
202 /// Reference to the ADSP for communication
203 ADSP::ADSP& adsp;
204 /// Is this system initialized?
205 bool initialized{};
206 /// Is this system currently active?
207 std::atomic<bool> active{};
208 /// State of the system
209 State state{State::Stopped};
210 /// Sample rate for the system
211 u32 sample_rate{};
212 /// Sample count of the system
213 u32 sample_count{};
214 /// Number of mix buffers in use by the system
215 s16 mix_buffer_count{};
216 /// Workbuffer for mix buffers, used by the AudioRenderer
217 std::span<s32> samples_workbuffer{};
218 /// Depop samples for depopping commands
219 std::span<s32> depop_buffer{};
220 /// Number of memory pools in the buffer
221 u32 memory_pool_count{};
222 /// Workbuffer for memory pools
223 std::span<MemoryPoolInfo> memory_pool_workbuffer{};
224 /// System memory pool info
225 MemoryPoolInfo memory_pool_info{};
226 /// Workbuffer that commands will be generated into
227 std::span<u8> command_workbuffer{};
228 /// Size of command workbuffer
229 u64 command_workbuffer_size{};
230 /// Numebr of commands in the workbuffer
231 u64 command_buffer_size{};
232 /// Manager for upsamplers
233 UpsamplerManager* upsampler_manager{};
234 /// Upsampler workbuffer
235 std::span<UpsamplerInfo> upsampler_infos{};
236 /// Number of upsamplers in the workbuffer
237 u32 upsampler_count{};
238 /// Holds and controls all voices
239 VoiceContext voice_context{};
240 /// Holds and controls all mixes
241 MixContext mix_context{};
242 /// Holds and controls all effects
243 EffectContext effect_context{};
244 /// Holds and controls all sinks
245 SinkContext sink_context{};
246 /// Holds and controls all splitters
247 SplitterContext splitter_context{};
248 /// Estimates the time taken for each command
249 std::unique_ptr<ICommandProcessingTimeEstimator> command_processing_time_estimator{};
250 /// Session id of this system
251 s32 session_id{};
252 /// Number of channels in use by voices
253 s32 voice_channels{};
254 /// Event to be called when the AudioRenderer processes a command list
255 Kernel::KEvent* adsp_rendered_event{};
256 /// Event signalled on system terminate
257 Common::Event terminate_event{};
258 /// Does what locks do
259 std::mutex lock{};
260 /// Handle for the process for this system, unused
261 u32 process_handle{};
262 /// Applet resource id for this system, unused
263 u64 applet_resource_user_id{};
264 /// Controls performance input and output
265 PerformanceManager performance_manager{};
266 /// Workbuffer for performance metrics
267 std::span<u8> performance_workbuffer{};
268 /// Main workbuffer, from which all other workbuffers here allocate into
269 std::unique_ptr<u8[]> workbuffer{};
270 /// Size of the main workbuffer
271 u64 workbuffer_size{};
272 /// Unknown buffer/marker
273 std::span<u8> unk_2A8{};
274 /// Size of the above unknown buffer/marker
275 u64 unk_2B0{};
276 /// Rendering time limit (percent)
277 u32 render_time_limit_percent{};
278 /// Should any voices be dropped?
279 bool drop_voice{};
280 /// Should the backend stream have its buffers flushed?
281 bool reset_command_buffers{};
282 /// Execution mode of this system, only Auto is supported
283 ExecutionMode execution_mode{ExecutionMode::Auto};
284 /// Render device, unused
285 u32 render_device{};
286 /// Behaviour to check which features are supported by the user revision
287 BehaviorInfo behavior{};
288 /// Total ticks the audio system has been running
289 u64 total_ticks_elapsed{};
290 /// Ticks the system has spent in updates
291 u64 ticks_spent_updating{};
292 /// Number of times a command list was generated
293 u64 num_command_lists_generated{};
294 /// Number of times the system has updated
295 u64 num_times_updated{};
296 /// Number of frames generated, written back to the game
297 std::atomic<u64> frames_elapsed{};
298 /// Is the AudioRenderer running too slow?
299 bool adsp_behind{};
300 /// Number of voices dropped
301 u32 num_voices_dropped{};
302 /// Tick that rendering started
303 u64 render_start_tick{};
304};
305
306} // namespace AudioRenderer
307} // namespace AudioCore