adsp.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "audio_core/renderer/adsp/adsp.h"
  4. #include "audio_core/renderer/adsp/command_buffer.h"
  5. #include "audio_core/sink/sink.h"
  6. #include "common/logging/log.h"
  7. #include "core/core.h"
  8. #include "core/core_timing.h"
  9. #include "core/memory.h"
  10. namespace AudioCore::AudioRenderer::ADSP {
  11. ADSP::ADSP(Core::System& system_, Sink::Sink& sink_)
  12. : system{system_}, memory{system.ApplicationMemory()}, sink{sink_} {}
  13. ADSP::~ADSP() {
  14. ClearCommandBuffers();
  15. }
  16. State ADSP::GetState() const {
  17. if (running) {
  18. return State::Started;
  19. }
  20. return State::Stopped;
  21. }
  22. AudioRenderer_Mailbox* ADSP::GetRenderMailbox() {
  23. return &render_mailbox;
  24. }
  25. void ADSP::ClearRemainCount(const u32 session_id) {
  26. render_mailbox.ClearRemainCount(session_id);
  27. }
  28. u64 ADSP::GetSignalledTick() const {
  29. return render_mailbox.GetSignalledTick();
  30. }
  31. u64 ADSP::GetTimeTaken() const {
  32. return render_mailbox.GetRenderTimeTaken();
  33. }
  34. u64 ADSP::GetRenderTimeTaken(const u32 session_id) {
  35. return render_mailbox.GetCommandBuffer(session_id).render_time_taken;
  36. }
  37. u32 ADSP::GetRemainCommandCount(const u32 session_id) const {
  38. return render_mailbox.GetRemainCommandCount(session_id);
  39. }
  40. void ADSP::SendCommandBuffer(const u32 session_id, const CommandBuffer& command_buffer) {
  41. render_mailbox.SetCommandBuffer(session_id, command_buffer);
  42. }
  43. u64 ADSP::GetRenderingStartTick(const u32 session_id) {
  44. return render_mailbox.GetSignalledTick() +
  45. render_mailbox.GetCommandBuffer(session_id).render_time_taken;
  46. }
  47. bool ADSP::Start() {
  48. if (running) {
  49. return running;
  50. }
  51. running = true;
  52. systems_active++;
  53. audio_renderer = std::make_unique<AudioRenderer>(system);
  54. audio_renderer->Start(&render_mailbox);
  55. render_mailbox.HostSendMessage(RenderMessage::AudioRenderer_InitializeOK);
  56. if (render_mailbox.HostWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) {
  57. LOG_ERROR(
  58. Service_Audio,
  59. "Host Audio Renderer -- Failed to receive initialize message response from ADSP!");
  60. }
  61. return running;
  62. }
  63. void ADSP::Stop() {
  64. systems_active--;
  65. if (running && systems_active == 0) {
  66. {
  67. std::scoped_lock l{mailbox_lock};
  68. render_mailbox.HostSendMessage(RenderMessage::AudioRenderer_Shutdown);
  69. if (render_mailbox.HostWaitMessage() != RenderMessage::AudioRenderer_Shutdown) {
  70. LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown "
  71. "message response from ADSP!");
  72. }
  73. }
  74. audio_renderer->Stop();
  75. running = false;
  76. }
  77. }
  78. void ADSP::Signal() {
  79. const auto signalled_tick{system.CoreTiming().GetClockTicks()};
  80. render_mailbox.SetSignalledTick(signalled_tick);
  81. render_mailbox.HostSendMessage(RenderMessage::AudioRenderer_Render);
  82. }
  83. void ADSP::Wait() {
  84. std::scoped_lock l{mailbox_lock};
  85. auto response{render_mailbox.HostWaitMessage()};
  86. if (response != RenderMessage::AudioRenderer_RenderResponse) {
  87. LOG_ERROR(Service_Audio, "Invalid ADSP response message, expected 0x{:02X}, got 0x{:02X}",
  88. static_cast<u32>(RenderMessage::AudioRenderer_RenderResponse),
  89. static_cast<u32>(response));
  90. }
  91. ClearCommandBuffers();
  92. }
  93. void ADSP::ClearCommandBuffers() {
  94. render_mailbox.ClearCommandBuffers();
  95. }
  96. } // namespace AudioCore::AudioRenderer::ADSP