diff options
author | Kelebek1 <eeeedddccc@hotmail.co.uk> | 2023-08-31 16:09:15 +0200 |
---|---|---|
committer | Kelebek1 <eeeedddccc@hotmail.co.uk> | 2023-09-04 18:12:16 +0200 |
commit | ebd19dec99d9809a669f63294745d7c8facc6d31 (patch) | |
tree | cd1f34cac0c091c2ffd16c429ac33b8fe133e06e /src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp | |
parent | Merge pull request #11420 from t895/long-install-fix (diff) | |
download | yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.tar yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.tar.gz yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.tar.bz2 yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.tar.lz yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.tar.xz yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.tar.zst yuzu-ebd19dec99d9809a669f63294745d7c8facc6d31.zip |
Diffstat (limited to '')
-rw-r--r-- | src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp (renamed from src/audio_core/renderer/adsp/audio_renderer.cpp) | 188 |
1 files changed, 89 insertions, 99 deletions
diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp index 9ca716b60..3da342ea3 100644 --- a/src/audio_core/renderer/adsp/audio_renderer.cpp +++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp @@ -1,12 +1,12 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include <array> #include <chrono> +#include "audio_core/adsp/apps/audio_renderer/audio_renderer.h" #include "audio_core/audio_core.h" #include "audio_core/common/common.h" -#include "audio_core/renderer/adsp/audio_renderer.h" #include "audio_core/sink/sink.h" #include "common/logging/log.h" #include "common/microprofile.h" @@ -16,108 +16,92 @@ MICROPROFILE_DEFINE(Audio_Renderer, "Audio", "DSP", MP_RGB(60, 19, 97)); -namespace AudioCore::AudioRenderer::ADSP { +namespace AudioCore::ADSP::AudioRenderer { -void AudioRenderer_Mailbox::HostSendMessage(RenderMessage message_) { - adsp_messages.enqueue(message_); - adsp_event.Set(); -} +AudioRenderer::AudioRenderer(Core::System& system_, Core::Memory::Memory& memory_, + Sink::Sink& sink_) + : system{system_}, memory{memory_}, sink{sink_} {} -RenderMessage AudioRenderer_Mailbox::HostWaitMessage() { - host_event.Wait(); - RenderMessage msg{RenderMessage::Invalid}; - if (!host_messages.try_dequeue(msg)) { - LOG_ERROR(Service_Audio, "Failed to dequeue host message!"); - } - return msg; +AudioRenderer::~AudioRenderer() { + Stop(); } -void AudioRenderer_Mailbox::ADSPSendMessage(const RenderMessage message_) { - host_messages.enqueue(message_); - host_event.Set(); -} +void AudioRenderer::Start() { + CreateSinkStreams(); -RenderMessage AudioRenderer_Mailbox::ADSPWaitMessage() { - adsp_event.Wait(); - RenderMessage msg{RenderMessage::Invalid}; - if (!adsp_messages.try_dequeue(msg)) { - LOG_ERROR(Service_Audio, "Failed to dequeue ADSP message!"); - } - return msg; -} + mailbox.Initialize(AppMailboxId::AudioRenderer); -CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const u32 session_id) { - return command_buffers[session_id]; -} + main_thread = std::jthread([this](std::stop_token stop_token) { Main(stop_token); }); -void AudioRenderer_Mailbox::SetCommandBuffer(const u32 session_id, const CommandBuffer& buffer) { - command_buffers[session_id] = buffer; + mailbox.Send(Direction::DSP, {Message::InitializeOK, {}}); + if (mailbox.Receive(Direction::Host).msg != Message::InitializeOK) { + LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown " + "message response from ADSP!"); + return; + } + running = true; } -u64 AudioRenderer_Mailbox::GetRenderTimeTaken() const { - return command_buffers[0].render_time_taken + command_buffers[1].render_time_taken; -} +void AudioRenderer::Stop() { + if (!running) { + return; + } -u64 AudioRenderer_Mailbox::GetSignalledTick() const { - return signalled_tick; -} + mailbox.Send(Direction::DSP, {Message::Shutdown, {}}); + if (mailbox.Receive(Direction::Host).msg != Message::Shutdown) { + LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown " + "message response from ADSP!"); + } + main_thread.request_stop(); + main_thread.join(); -void AudioRenderer_Mailbox::SetSignalledTick(const u64 tick) { - signalled_tick = tick; + for (auto& stream : streams) { + if (stream) { + stream->Stop(); + sink.CloseStream(stream); + stream = nullptr; + } + } + running = false; } -void AudioRenderer_Mailbox::ClearRemainCount(const u32 session_id) { - command_buffers[session_id].remaining_command_count = 0; +void AudioRenderer::Signal() { + signalled_tick = system.CoreTiming().GetGlobalTimeNs().count(); + Send(Direction::DSP, {Message::Render, {}}); } -u32 AudioRenderer_Mailbox::GetRemainCommandCount(const u32 session_id) const { - return command_buffers[session_id].remaining_command_count; +void AudioRenderer::Wait() { + auto received = Receive(Direction::Host); + if (received.msg != Message::RenderResponse) { + LOG_ERROR(Service_Audio, + "Did not receive the expected render response from the AudioRenderer! Expected " + "{}, got {}", + Message::RenderResponse, received.msg); + } } -void AudioRenderer_Mailbox::ClearCommandBuffers() { - command_buffers[0].buffer = 0; - command_buffers[0].size = 0; - command_buffers[0].reset_buffers = false; - command_buffers[1].buffer = 0; - command_buffers[1].size = 0; - command_buffers[1].reset_buffers = false; +void AudioRenderer::Send(Direction dir, MailboxMessage message) { + mailbox.Send(dir, std::move(message)); } -AudioRenderer::AudioRenderer(Core::System& system_) - : system{system_}, sink{system.AudioCore().GetOutputSink()} { - CreateSinkStreams(); +MailboxMessage AudioRenderer::Receive(Direction dir, bool block) { + return mailbox.Receive(dir, block); } -AudioRenderer::~AudioRenderer() { - Stop(); - for (auto& stream : streams) { - if (stream) { - sink.CloseStream(stream); - } - stream = nullptr; - } +void AudioRenderer::SetCommandBuffer(s32 session_id, CommandBuffer& buffer) noexcept { + command_buffers[session_id] = buffer; } -void AudioRenderer::Start(AudioRenderer_Mailbox* mailbox_) { - if (running) { - return; - } - - mailbox = mailbox_; - thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); }); - running = true; +u32 AudioRenderer::GetRemainCommandCount(s32 session_id) const noexcept { + return command_buffers[session_id].remaining_command_count; } -void AudioRenderer::Stop() { - if (!running) { - return; - } +void AudioRenderer::ClearRemainCommandCount(s32 session_id) noexcept { + command_buffers[session_id].remaining_command_count = 0; +} - for (auto& stream : streams) { - stream->Stop(); - } - thread.join(); - running = false; +u64 AudioRenderer::GetRenderingStartTick(s32 session_id) const noexcept { + return (1000 * command_buffers[session_id].render_time_taken_us) + signalled_tick; } void AudioRenderer::CreateSinkStreams() { @@ -130,41 +114,45 @@ void AudioRenderer::CreateSinkStreams() { } } -void AudioRenderer::ThreadFunc(std::stop_token stop_token) { +void AudioRenderer::Main(std::stop_token stop_token) { static constexpr char name[]{"AudioRenderer"}; MicroProfileOnThreadCreate(name); Common::SetCurrentThreadName(name); Common::SetCurrentThreadPriority(Common::ThreadPriority::High); - if (mailbox->ADSPWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) { + + // TODO: Create buffer map/unmap thread + mailbox + // TODO: Create gMix devices, initialize them here + + if (mailbox.Receive(Direction::DSP).msg != Message::InitializeOK) { LOG_ERROR(Service_Audio, "ADSP Audio Renderer -- Failed to receive initialize message from host!"); return; } - mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_InitializeOK); + mailbox.Send(Direction::Host, {Message::InitializeOK, {}}); - // 0.12 seconds (2304000 / 19200000) + // 0.12 seconds (2,304,000 / 19,200,000) constexpr u64 max_process_time{2'304'000ULL}; while (!stop_token.stop_requested()) { - auto message{mailbox->ADSPWaitMessage()}; - switch (message) { - case RenderMessage::AudioRenderer_Shutdown: - mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_Shutdown); + auto received{mailbox.Receive(Direction::DSP)}; + switch (received.msg) { + case Message::Shutdown: + mailbox.Send(Direction::Host, {Message::Shutdown, {}}); return; - case RenderMessage::AudioRenderer_Render: { + case Message::Render: { if (system.IsShuttingDown()) [[unlikely]] { std::this_thread::sleep_for(std::chrono::milliseconds(5)); - mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_RenderResponse); + mailbox.Send(Direction::Host, {Message::RenderResponse, {}}); continue; } std::array<bool, MaxRendererSessions> buffers_reset{}; std::array<u64, MaxRendererSessions> render_times_taken{}; - const auto start_time{system.CoreTiming().GetClockTicks()}; + const auto start_time{system.CoreTiming().GetGlobalTimeUs().count()}; - for (u32 index = 0; index < 2; index++) { - auto& command_buffer{mailbox->GetCommandBuffer(index)}; + for (u32 index = 0; index < MaxRendererSessions; index++) { + auto& command_buffer{command_buffers[index]}; auto& command_list_processor{command_list_processors[index]}; // Check this buffer is valid, as it may not be used. @@ -176,14 +164,14 @@ void AudioRenderer::ThreadFunc(std::stop_token stop_token) { command_buffer.size, streams[index]); } - if (command_buffer.reset_buffers && !buffers_reset[index]) { + if (command_buffer.reset_buffer && !buffers_reset[index]) { streams[index]->ClearQueue(); buffers_reset[index] = true; } u64 max_time{max_process_time}; if (index == 1 && command_buffer.applet_resource_user_id == - mailbox->GetCommandBuffer(0).applet_resource_user_id) { + command_buffers[0].applet_resource_user_id) { max_time = max_process_time - render_times_taken[0]; if (render_times_taken[0] > max_process_time) { max_time = 0; @@ -193,7 +181,9 @@ void AudioRenderer::ThreadFunc(std::stop_token stop_token) { max_time = std::min(command_buffer.time_limit, max_time); command_list_processor.SetProcessTimeMax(max_time); - streams[index]->WaitFreeSpace(stop_token); + if (index == 0) { + streams[index]->WaitFreeSpace(stop_token); + } // Process the command list { @@ -202,24 +192,24 @@ void AudioRenderer::ThreadFunc(std::stop_token stop_token) { command_list_processor.Process(index) - start_time; } - const auto end_time{system.CoreTiming().GetClockTicks()}; + const auto end_time{system.CoreTiming().GetGlobalTimeUs().count()}; command_buffer.remaining_command_count = command_list_processor.GetRemainingCommandCount(); - command_buffer.render_time_taken = end_time - start_time; + command_buffer.render_time_taken_us = end_time - start_time; } } - mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_RenderResponse); + mailbox.Send(Direction::Host, {Message::RenderResponse, {}}); } break; default: LOG_WARNING(Service_Audio, "ADSP AudioRenderer received an invalid message, msg={:02X}!", - static_cast<u32>(message)); + received.msg); break; } } } -} // namespace AudioCore::AudioRenderer::ADSP +} // namespace AudioCore::ADSP::AudioRenderer |