adsp.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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 "audio_core/renderer/adsp/audio_renderer.h"
  7. #include "common/common_types.h"
  8. namespace Core {
  9. namespace Memory {
  10. class Memory;
  11. }
  12. class System;
  13. } // namespace Core
  14. namespace AudioCore {
  15. namespace Sink {
  16. class Sink;
  17. }
  18. namespace AudioRenderer::ADSP {
  19. struct CommandBuffer;
  20. enum class State {
  21. Started,
  22. Stopped,
  23. };
  24. /**
  25. * Represents the ADSP embedded within the audio sysmodule.
  26. * This is a 32-bit Linux4Tegra kernel from nVidia, which is launched with the sysmodule on boot.
  27. *
  28. * The kernel will run apps you program for it, Nintendo have the following:
  29. *
  30. * Gmix - Responsible for mixing final audio and sending it out to hardware. This is last place all
  31. * audio samples end up, and we skip it entirely, since we have very different backends and
  32. * mixing is implicitly handled by the OS (but also due to lack of research/simplicity).
  33. *
  34. * AudioRenderer - Receives command lists generated by the audio render
  35. * system, processes them, and sends the samples to Gmix.
  36. *
  37. * OpusDecoder - Contains libopus, and controls processing Opus audio and sends it to Gmix.
  38. * Not much research done here, TODO if needed.
  39. *
  40. * We only implement the AudioRenderer for now.
  41. *
  42. * Communication for the apps is done through mailboxes, and some shared memory.
  43. */
  44. class ADSP {
  45. public:
  46. explicit ADSP(Core::System& system, Sink::Sink& sink);
  47. ~ADSP();
  48. /**
  49. * Start the ADSP.
  50. *
  51. * @return True if started or already running, otherwise false.
  52. */
  53. bool Start();
  54. /**
  55. * Stop the ADSP.
  56. */
  57. void Stop();
  58. /**
  59. * Get the ADSP's state.
  60. *
  61. * @return Started or Stopped.
  62. */
  63. State GetState() const;
  64. /**
  65. * Get the AudioRenderer mailbox to communicate with it.
  66. *
  67. * @return The AudioRenderer mailbox.
  68. */
  69. AudioRenderer_Mailbox* GetRenderMailbox();
  70. /**
  71. * Get the tick the ADSP was signalled.
  72. *
  73. * @return The tick the ADSP was signalled.
  74. */
  75. u64 GetSignalledTick() const;
  76. /**
  77. * Get the total time it took for the ADSP to run the last command lists (both command lists).
  78. *
  79. * @return The tick the ADSP was signalled.
  80. */
  81. u64 GetTimeTaken() const;
  82. /**
  83. * Get the last time a given command list took to run.
  84. *
  85. * @param session_id - The session id to check (0 or 1).
  86. * @return The time it took.
  87. */
  88. u64 GetRenderTimeTaken(u32 session_id);
  89. /**
  90. * Clear the remaining command count for a given session.
  91. *
  92. * @param session_id - The session id to check (0 or 1).
  93. */
  94. void ClearRemainCount(u32 session_id);
  95. /**
  96. * Get the remaining number of commands left to process for a command list.
  97. *
  98. * @param session_id - The session id to check (0 or 1).
  99. * @return The number of commands remaining.
  100. */
  101. u32 GetRemainCommandCount(u32 session_id) const;
  102. /**
  103. * Get the last tick a command list started processing.
  104. *
  105. * @param session_id - The session id to check (0 or 1).
  106. * @return The last tick the given command list started.
  107. */
  108. u64 GetRenderingStartTick(u32 session_id);
  109. /**
  110. * Set a command buffer to be processed.
  111. *
  112. * @param session_id - The session id to check (0 or 1).
  113. * @param command_buffer - The command buffer to process.
  114. */
  115. void SendCommandBuffer(u32 session_id, const CommandBuffer& command_buffer);
  116. /**
  117. * Clear the command buffers (does not clear the time taken or the remaining command count)
  118. */
  119. void ClearCommandBuffers();
  120. /**
  121. * Signal the AudioRenderer to begin processing.
  122. */
  123. void Signal();
  124. /**
  125. * Wait for the AudioRenderer to finish processing.
  126. */
  127. void Wait();
  128. private:
  129. /// Core system
  130. Core::System& system;
  131. /// Core memory
  132. Core::Memory::Memory& memory;
  133. /// Number of systems active, used to prevent accidental shutdowns
  134. u8 systems_active{0};
  135. /// ADSP running state
  136. std::atomic<bool> running{false};
  137. /// Output sink used by the ADSP
  138. Sink::Sink& sink;
  139. /// AudioRenderer app
  140. std::unique_ptr<AudioRenderer> audio_renderer{};
  141. /// Communication for the AudioRenderer
  142. AudioRenderer_Mailbox render_mailbox{};
  143. /// Mailbox lock ffor the render mailbox
  144. std::mutex mailbox_lock;
  145. };
  146. } // namespace AudioRenderer::ADSP
  147. } // namespace AudioCore