summaryrefslogtreecommitdiffstats
path: root/src/audio_core/adsp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio_core/adsp/adsp.cpp18
-rw-r--r--src/audio_core/adsp/adsp.h50
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/audio_renderer.cpp (renamed from src/audio_core/renderer/adsp/audio_renderer.cpp)188
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/audio_renderer.h115
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_buffer.h23
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp (renamed from src/audio_core/renderer/adsp/command_list_processor.cpp)26
-rw-r--r--src/audio_core/adsp/apps/audio_renderer/command_list_processor.h (renamed from src/audio_core/renderer/adsp/command_list_processor.h)13
-rw-r--r--src/audio_core/adsp/mailbox.h69
8 files changed, 384 insertions, 118 deletions
diff --git a/src/audio_core/adsp/adsp.cpp b/src/audio_core/adsp/adsp.cpp
new file mode 100644
index 000000000..0580990f5
--- /dev/null
+++ b/src/audio_core/adsp/adsp.cpp
@@ -0,0 +1,18 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/adsp/adsp.h"
+#include "core/core.h"
+
+namespace AudioCore::ADSP {
+
+ADSP::ADSP(Core::System& system, Sink::Sink& sink) {
+ audio_renderer =
+ std::make_unique<AudioRenderer::AudioRenderer>(system, system.ApplicationMemory(), sink);
+}
+
+AudioRenderer::AudioRenderer& ADSP::AudioRenderer() {
+ return *audio_renderer.get();
+}
+
+} // namespace AudioCore::ADSP
diff --git a/src/audio_core/adsp/adsp.h b/src/audio_core/adsp/adsp.h
new file mode 100644
index 000000000..bd5bcc63b
--- /dev/null
+++ b/src/audio_core/adsp/adsp.h
@@ -0,0 +1,50 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "audio_core/adsp/apps/audio_renderer/audio_renderer.h"
+#include "common/common_types.h"
+
+namespace Core {
+class System;
+} // namespace Core
+
+namespace AudioCore {
+namespace Sink {
+class Sink;
+}
+
+namespace ADSP {
+
+/**
+ * Represents the ADSP embedded within the audio sysmodule.
+ * This is a 32-bit Linux4Tegra kernel from nVidia, which is launched with the sysmodule on boot.
+ *
+ * The kernel will run the apps you write for it, Nintendo have the following:
+ *
+ * Gmix - Responsible for mixing final audio and sending it out to hardware. This is last place all
+ * audio samples end up, and we skip it entirely, since we have very different backends and
+ * mixing is implicitly handled by the OS (but also due to lack of research/simplicity).
+ *
+ * AudioRenderer - Receives command lists generated by the audio render
+ * system on the host, processes them, and sends the samples to Gmix.
+ *
+ * OpusDecoder - Contains libopus, and decodes Opus audio packets into raw pcm data.
+ *
+ * Communication between the host and ADSP is done through mailboxes, and mapping of shared memory.
+ */
+class ADSP {
+public:
+ explicit ADSP(Core::System& system, Sink::Sink& sink);
+ ~ADSP() = default;
+
+ AudioRenderer::AudioRenderer& AudioRenderer();
+
+private:
+ /// AudioRenderer app
+ std::unique_ptr<AudioRenderer::AudioRenderer> audio_renderer{};
+};
+
+} // namespace ADSP
+} // namespace AudioCore
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
diff --git a/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
new file mode 100644
index 000000000..b225e10fb
--- /dev/null
+++ b/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
@@ -0,0 +1,115 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <memory>
+#include <thread>
+
+#include "audio_core/adsp/apps/audio_renderer/command_buffer.h"
+#include "audio_core/adsp/apps/audio_renderer/command_list_processor.h"
+#include "audio_core/adsp/mailbox.h"
+#include "common/common_types.h"
+#include "common/polyfill_thread.h"
+#include "common/reader_writer_queue.h"
+#include "common/thread.h"
+
+namespace Core {
+class System;
+namespace Timing {
+struct EventType;
+}
+namespace Memory {
+class Memory;
+}
+class System;
+} // namespace Core
+
+namespace AudioCore {
+namespace Sink {
+class Sink;
+}
+
+namespace ADSP::AudioRenderer {
+
+enum Message : u32 {
+ Invalid = 0x00,
+ MapUnmap_Map = 0x01,
+ MapUnmap_MapResponse = 0x02,
+ MapUnmap_Unmap = 0x03,
+ MapUnmap_UnmapResponse = 0x04,
+ MapUnmap_InvalidateCache = 0x05,
+ MapUnmap_InvalidateCacheResponse = 0x06,
+ MapUnmap_Shutdown = 0x07,
+ MapUnmap_ShutdownResponse = 0x08,
+ InitializeOK = 0x16,
+ RenderResponse = 0x20,
+ Render = 0x2A,
+ Shutdown = 0x34,
+};
+
+/**
+ * The AudioRenderer application running on the ADSP.
+ */
+class AudioRenderer {
+public:
+ explicit AudioRenderer(Core::System& system, Core::Memory::Memory& memory, Sink::Sink& sink);
+ ~AudioRenderer();
+
+ /**
+ * Start the AudioRenderer.
+ *
+ * @param mailbox The mailbox to use for this session.
+ */
+ void Start();
+
+ /**
+ * Stop the AudioRenderer.
+ */
+ void Stop();
+
+ void Signal();
+ void Wait();
+
+ void Send(Direction dir, MailboxMessage message);
+ MailboxMessage Receive(Direction dir, bool block = true);
+
+ void SetCommandBuffer(s32 session_id, CommandBuffer& buffer) noexcept;
+ u32 GetRemainCommandCount(s32 session_id) const noexcept;
+ void ClearRemainCommandCount(s32 session_id) noexcept;
+ u64 GetRenderingStartTick(s32 session_id) const noexcept;
+
+private:
+ /**
+ * Main AudioRenderer thread, responsible for processing the command lists.
+ */
+ void Main(std::stop_token stop_token);
+
+ /**
+ * Creates the streams which will receive the processed samples.
+ */
+ void CreateSinkStreams();
+
+ /// Core system
+ Core::System& system;
+ /// Memory
+ Core::Memory::Memory& memory;
+ /// The output sink the AudioRenderer will use
+ Sink::Sink& sink;
+ /// The active mailbox
+ Mailbox mailbox;
+ /// Main thread
+ std::jthread main_thread{};
+ /// The current state
+ std::atomic<bool> running{};
+ std::array<CommandBuffer, MaxRendererSessions> command_buffers{};
+ /// The command lists to process
+ std::array<CommandListProcessor, MaxRendererSessions> command_list_processors{};
+ /// The streams which will receive the processed samples
+ std::array<Sink::SinkStream*, MaxRendererSessions> streams{};
+ u64 signalled_tick{0};
+};
+
+} // namespace ADSP::AudioRenderer
+} // namespace AudioCore
diff --git a/src/audio_core/adsp/apps/audio_renderer/command_buffer.h b/src/audio_core/adsp/apps/audio_renderer/command_buffer.h
new file mode 100644
index 000000000..3fd1b09dc
--- /dev/null
+++ b/src/audio_core/adsp/apps/audio_renderer/command_buffer.h
@@ -0,0 +1,23 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "audio_core/common/common.h"
+#include "common/common_types.h"
+
+namespace AudioCore::ADSP::AudioRenderer {
+
+struct CommandBuffer {
+ // Set by the host
+ CpuAddr buffer{};
+ u64 size{};
+ u64 time_limit{};
+ u64 applet_resource_user_id{};
+ bool reset_buffer{};
+ // Set by the DSP
+ u32 remaining_command_count{};
+ u64 render_time_taken_us{};
+};
+
+} // namespace AudioCore::ADSP::AudioRenderer
diff --git a/src/audio_core/renderer/adsp/command_list_processor.cpp b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp
index 3a0f1ae38..acbc9100c 100644
--- a/src/audio_core/renderer/adsp/command_list_processor.cpp
+++ b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.cpp
@@ -1,9 +1,9 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string>
-#include "audio_core/renderer/adsp/command_list_processor.h"
+#include "audio_core/adsp/apps/audio_renderer/command_list_processor.h"
#include "audio_core/renderer/command/command_list_header.h"
#include "audio_core/renderer/command/commands.h"
#include "common/settings.h"
@@ -11,15 +11,15 @@
#include "core/core_timing.h"
#include "core/memory.h"
-namespace AudioCore::AudioRenderer::ADSP {
+namespace AudioCore::ADSP::AudioRenderer {
void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size,
Sink::SinkStream* stream_) {
system = &system_;
memory = &system->ApplicationMemory();
stream = stream_;
- header = reinterpret_cast<CommandListHeader*>(buffer);
- commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader));
+ header = reinterpret_cast<Renderer::CommandListHeader*>(buffer);
+ commands = reinterpret_cast<u8*>(buffer + sizeof(Renderer::CommandListHeader));
commands_buffer_size = size;
command_count = header->command_count;
sample_count = header->sample_count;
@@ -38,7 +38,7 @@ u32 CommandListProcessor::GetRemainingCommandCount() const {
}
void CommandListProcessor::SetBuffer(const CpuAddr buffer, const u64 size) {
- commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader));
+ commands = reinterpret_cast<u8*>(buffer + sizeof(Renderer::CommandListHeader));
commands_buffer_size = size;
}
@@ -47,7 +47,7 @@ Sink::SinkStream* CommandListProcessor::GetOutputSinkStream() const {
}
u64 CommandListProcessor::Process(u32 session_id) {
- const auto start_time_{system->CoreTiming().GetClockTicks()};
+ const auto start_time_{system->CoreTiming().GetGlobalTimeUs().count()};
const auto command_base{CpuAddr(commands)};
if (processed_command_count > 0) {
@@ -60,12 +60,12 @@ u64 CommandListProcessor::Process(u32 session_id) {
std::string dump{fmt::format("\nSession {}\n", session_id)};
for (u32 index = 0; index < command_count; index++) {
- auto& command{*reinterpret_cast<ICommand*>(commands)};
+ auto& command{*reinterpret_cast<Renderer::ICommand*>(commands)};
if (command.magic != 0xCAFEBABE) {
LOG_ERROR(Service_Audio, "Command has invalid magic! Expected 0xCAFEBABE, got {:08X}",
command.magic);
- return system->CoreTiming().GetClockTicks() - start_time_;
+ return system->CoreTiming().GetGlobalTimeUs().count() - start_time_;
}
auto current_offset{CpuAddr(commands) - command_base};
@@ -74,8 +74,8 @@ u64 CommandListProcessor::Process(u32 session_id) {
LOG_ERROR(Service_Audio,
"Command exceeded command buffer, buffer size {:08X}, command ends at {:08X}",
commands_buffer_size,
- CpuAddr(commands) + command.size - sizeof(CommandListHeader));
- return system->CoreTiming().GetClockTicks() - start_time_;
+ CpuAddr(commands) + command.size - sizeof(Renderer::CommandListHeader));
+ return system->CoreTiming().GetGlobalTimeUs().count() - start_time_;
}
if (Settings::values.dump_audio_commands) {
@@ -101,8 +101,8 @@ u64 CommandListProcessor::Process(u32 session_id) {
last_dump = dump;
}
- end_time = system->CoreTiming().GetClockTicks();
+ end_time = system->CoreTiming().GetGlobalTimeUs().count();
return end_time - start_time_;
}
-} // namespace AudioCore::AudioRenderer::ADSP
+} // namespace AudioCore::ADSP::AudioRenderer
diff --git a/src/audio_core/renderer/adsp/command_list_processor.h b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h
index d78269e1d..9d6fe1851 100644
--- a/src/audio_core/renderer/adsp/command_list_processor.h
+++ b/src/audio_core/adsp/apps/audio_renderer/command_list_processor.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -6,6 +6,7 @@
#include <span>
#include "audio_core/common/common.h"
+#include "audio_core/renderer/command/command_list_header.h"
#include "common/common_types.h"
namespace Core {
@@ -20,10 +21,11 @@ namespace Sink {
class SinkStream;
}
-namespace AudioRenderer {
+namespace Renderer {
struct CommandListHeader;
+}
-namespace ADSP {
+namespace ADSP::AudioRenderer {
/**
* A processor for command lists given to the AudioRenderer.
@@ -85,7 +87,7 @@ public:
/// Stream for the processed samples
Sink::SinkStream* stream{};
/// Header info for this command list
- CommandListHeader* header{};
+ Renderer::CommandListHeader* header{};
/// The command buffer
u8* commands{};
/// The command buffer size
@@ -114,6 +116,5 @@ public:
std::string last_dump{};
};
-} // namespace ADSP
-} // namespace AudioRenderer
+} // namespace ADSP::AudioRenderer
} // namespace AudioCore
diff --git a/src/audio_core/adsp/mailbox.h b/src/audio_core/adsp/mailbox.h
new file mode 100644
index 000000000..c31b73717
--- /dev/null
+++ b/src/audio_core/adsp/mailbox.h
@@ -0,0 +1,69 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/bounded_threadsafe_queue.h"
+#include "common/common_types.h"
+
+namespace AudioCore::ADSP {
+
+enum class AppMailboxId : u32 {
+ Invalid = 0,
+ AudioRenderer = 50,
+ AudioRendererMemoryMapUnmap = 51,
+};
+
+enum class Direction : u32 {
+ Host,
+ DSP,
+};
+
+struct MailboxMessage {
+ u32 msg;
+ std::span<u8> data;
+};
+
+class Mailbox {
+public:
+ void Initialize(AppMailboxId id_) {
+ Reset();
+ id = id_;
+ }
+
+ AppMailboxId Id() const noexcept {
+ return id;
+ }
+
+ void Send(Direction dir, MailboxMessage&& message) {
+ auto& queue = dir == Direction::Host ? host_queue : adsp_queue;
+ queue.EmplaceWait(std::move(message));
+ }
+
+ MailboxMessage Receive(Direction dir, bool block = true) {
+ auto& queue = dir == Direction::Host ? host_queue : adsp_queue;
+ MailboxMessage t;
+ if (block) {
+ queue.PopWait(t);
+ } else {
+ queue.TryPop(t);
+ }
+ return t;
+ }
+
+ void Reset() {
+ id = AppMailboxId::Invalid;
+ MailboxMessage t;
+ while (host_queue.TryPop(t)) {
+ }
+ while (adsp_queue.TryPop(t)) {
+ }
+ }
+
+private:
+ AppMailboxId id{0};
+ Common::SPSCQueue<MailboxMessage> host_queue;
+ Common::SPSCQueue<MailboxMessage> adsp_queue;
+};
+
+} // namespace AudioCore::ADSP