system.h 10 KB

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