audio_renderer.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <memory>
  6. #include <thread>
  7. #include "audio_core/renderer/adsp/command_buffer.h"
  8. #include "audio_core/renderer/adsp/command_list_processor.h"
  9. #include "common/common_types.h"
  10. #include "common/reader_writer_queue.h"
  11. #include "common/thread.h"
  12. namespace Core {
  13. namespace Timing {
  14. struct EventType;
  15. }
  16. class System;
  17. } // namespace Core
  18. namespace AudioCore {
  19. namespace Sink {
  20. class Sink;
  21. }
  22. namespace AudioRenderer::ADSP {
  23. enum class RenderMessage {
  24. /* 0x00 */ Invalid,
  25. /* 0x01 */ AudioRenderer_MapUnmap_Map,
  26. /* 0x02 */ AudioRenderer_MapUnmap_MapResponse,
  27. /* 0x03 */ AudioRenderer_MapUnmap_Unmap,
  28. /* 0x04 */ AudioRenderer_MapUnmap_UnmapResponse,
  29. /* 0x05 */ AudioRenderer_MapUnmap_InvalidateCache,
  30. /* 0x06 */ AudioRenderer_MapUnmap_InvalidateCacheResponse,
  31. /* 0x07 */ AudioRenderer_MapUnmap_Shutdown,
  32. /* 0x08 */ AudioRenderer_MapUnmap_ShutdownResponse,
  33. /* 0x16 */ AudioRenderer_InitializeOK = 0x16,
  34. /* 0x20 */ AudioRenderer_RenderResponse = 0x20,
  35. /* 0x2A */ AudioRenderer_Render = 0x2A,
  36. /* 0x34 */ AudioRenderer_Shutdown = 0x34,
  37. };
  38. /**
  39. * A mailbox for the AudioRenderer, allowing communication between the host and the AudioRenderer
  40. * running on the ADSP.
  41. */
  42. class AudioRenderer_Mailbox {
  43. public:
  44. /**
  45. * Send a message from the host to the AudioRenderer.
  46. *
  47. * @param message_ - The message to send to the AudioRenderer.
  48. */
  49. void HostSendMessage(RenderMessage message);
  50. /**
  51. * Host wait for a message from the AudioRenderer.
  52. *
  53. * @return The message returned from the AudioRenderer.
  54. */
  55. RenderMessage HostWaitMessage();
  56. /**
  57. * Send a message from the AudioRenderer to the host.
  58. *
  59. * @param message_ - The message to send to the host.
  60. */
  61. void ADSPSendMessage(RenderMessage message);
  62. /**
  63. * AudioRenderer wait for a message from the host.
  64. *
  65. * @return The message returned from the AudioRenderer.
  66. */
  67. RenderMessage ADSPWaitMessage();
  68. /**
  69. * Get the command buffer with the given session id (0 or 1).
  70. *
  71. * @param session_id - The session id to get (0 or 1).
  72. * @return The command buffer.
  73. */
  74. CommandBuffer& GetCommandBuffer(s32 session_id);
  75. /**
  76. * Set the command buffer with the given session id (0 or 1).
  77. *
  78. * @param session_id - The session id to get (0 or 1).
  79. * @param buffer - The command buffer to set.
  80. */
  81. void SetCommandBuffer(u32 session_id, CommandBuffer& buffer);
  82. /**
  83. * Get the total render time taken for the last command lists sent.
  84. *
  85. * @return Total render time taken for the last command lists.
  86. */
  87. u64 GetRenderTimeTaken() const;
  88. /**
  89. * Get the tick the AudioRenderer was signalled.
  90. *
  91. * @return The tick the AudioRenderer was signalled.
  92. */
  93. u64 GetSignalledTick() const;
  94. /**
  95. * Set the tick the AudioRenderer was signalled.
  96. *
  97. * @param tick - The tick the AudioRenderer was signalled.
  98. */
  99. void SetSignalledTick(u64 tick);
  100. /**
  101. * Clear the remaining command count.
  102. *
  103. * @param session_id - Index for which command list to clear (0 or 1).
  104. */
  105. void ClearRemainCount(u32 session_id);
  106. /**
  107. * Get the remaining command count for a given command list.
  108. *
  109. * @param session_id - Index for which command list to clear (0 or 1).
  110. * @return The remaining command count.
  111. */
  112. u32 GetRemainCommandCount(u32 session_id) const;
  113. /**
  114. * Clear the command buffers (does not clear the time taken or the remaining command count).
  115. */
  116. void ClearCommandBuffers();
  117. private:
  118. /// Host signalling event
  119. Common::Event host_event{};
  120. /// AudioRenderer signalling event
  121. Common::Event adsp_event{};
  122. /// Host message queue
  123. Common::ReaderWriterQueue<RenderMessage> host_messages{};
  124. /// AudioRenderer message queue
  125. Common::ReaderWriterQueue<RenderMessage> adsp_messages{};
  126. /// Command buffers
  127. std::array<CommandBuffer, MaxRendererSessions> command_buffers{};
  128. /// Tick the AudioRnederer was signalled
  129. u64 signalled_tick{};
  130. };
  131. /**
  132. * The AudioRenderer application running on the ADSP.
  133. */
  134. class AudioRenderer {
  135. public:
  136. explicit AudioRenderer(Core::System& system);
  137. ~AudioRenderer();
  138. /**
  139. * Start the AudioRenderer.
  140. *
  141. * @param The mailbox to use for this session.
  142. */
  143. void Start(AudioRenderer_Mailbox* mailbox);
  144. /**
  145. * Stop the AudioRenderer.
  146. */
  147. void Stop();
  148. private:
  149. /**
  150. * Main AudioRenderer thread, responsible for processing the command lists.
  151. */
  152. void ThreadFunc();
  153. /**
  154. * Creates the streams which will receive the processed samples.
  155. */
  156. void CreateSinkStreams();
  157. /// Core system
  158. Core::System& system;
  159. /// Main thread
  160. std::thread thread{};
  161. /// The current state
  162. std::atomic<bool> running{};
  163. /// The active mailbox
  164. AudioRenderer_Mailbox* mailbox{};
  165. /// The command lists to process
  166. std::array<CommandListProcessor, MaxRendererSessions> command_list_processors{};
  167. /// The output sink the AudioRenderer will use
  168. Sink::Sink& sink;
  169. /// The streams which will receive the processed samples
  170. std::array<Sink::SinkStream*, MaxRendererSessions> streams;
  171. };
  172. } // namespace AudioRenderer::ADSP
  173. } // namespace AudioCore