mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-22 23:02:47 +01:00
Rework ADSP into a wrapper for apps
This commit is contained in:
parent
5ce41fa213
commit
ebd19dec99
173 changed files with 1059 additions and 1265 deletions
|
@ -2,6 +2,14 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
add_library(audio_core STATIC
|
add_library(audio_core STATIC
|
||||||
|
adsp/adsp.cpp
|
||||||
|
adsp/adsp.h
|
||||||
|
adsp/mailbox.h
|
||||||
|
adsp/apps/audio_renderer/audio_renderer.cpp
|
||||||
|
adsp/apps/audio_renderer/audio_renderer.h
|
||||||
|
adsp/apps/audio_renderer/command_buffer.h
|
||||||
|
adsp/apps/audio_renderer/command_list_processor.cpp
|
||||||
|
adsp/apps/audio_renderer/command_list_processor.h
|
||||||
audio_core.cpp
|
audio_core.cpp
|
||||||
audio_core.h
|
audio_core.h
|
||||||
audio_event.h
|
audio_event.h
|
||||||
|
@ -32,13 +40,6 @@ add_library(audio_core STATIC
|
||||||
out/audio_out_system.cpp
|
out/audio_out_system.cpp
|
||||||
out/audio_out_system.h
|
out/audio_out_system.h
|
||||||
precompiled_headers.h
|
precompiled_headers.h
|
||||||
renderer/adsp/adsp.cpp
|
|
||||||
renderer/adsp/adsp.h
|
|
||||||
renderer/adsp/audio_renderer.cpp
|
|
||||||
renderer/adsp/audio_renderer.h
|
|
||||||
renderer/adsp/command_buffer.h
|
|
||||||
renderer/adsp/command_list_processor.cpp
|
|
||||||
renderer/adsp/command_list_processor.h
|
|
||||||
renderer/audio_device.cpp
|
renderer/audio_device.cpp
|
||||||
renderer/audio_device.h
|
renderer/audio_device.h
|
||||||
renderer/audio_renderer.h
|
renderer/audio_renderer.h
|
||||||
|
|
18
src/audio_core/adsp/adsp.cpp
Normal file
18
src/audio_core/adsp/adsp.cpp
Normal file
|
@ -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
|
50
src/audio_core/adsp/adsp.h
Normal file
50
src/audio_core/adsp/adsp.h
Normal file
|
@ -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
|
|
@ -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
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "audio_core/adsp/apps/audio_renderer/audio_renderer.h"
|
||||||
#include "audio_core/audio_core.h"
|
#include "audio_core/audio_core.h"
|
||||||
#include "audio_core/common/common.h"
|
#include "audio_core/common/common.h"
|
||||||
#include "audio_core/renderer/adsp/audio_renderer.h"
|
|
||||||
#include "audio_core/sink/sink.h"
|
#include "audio_core/sink/sink.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
@ -16,95 +16,29 @@
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(Audio_Renderer, "Audio", "DSP", MP_RGB(60, 19, 97));
|
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_) {
|
AudioRenderer::AudioRenderer(Core::System& system_, Core::Memory::Memory& memory_,
|
||||||
adsp_messages.enqueue(message_);
|
Sink::Sink& sink_)
|
||||||
adsp_event.Set();
|
: 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioRenderer_Mailbox::ADSPSendMessage(const RenderMessage message_) {
|
|
||||||
host_messages.enqueue(message_);
|
|
||||||
host_event.Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const u32 session_id) {
|
|
||||||
return command_buffers[session_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioRenderer_Mailbox::SetCommandBuffer(const u32 session_id, const CommandBuffer& buffer) {
|
|
||||||
command_buffers[session_id] = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 AudioRenderer_Mailbox::GetRenderTimeTaken() const {
|
|
||||||
return command_buffers[0].render_time_taken + command_buffers[1].render_time_taken;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 AudioRenderer_Mailbox::GetSignalledTick() const {
|
|
||||||
return signalled_tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioRenderer_Mailbox::SetSignalledTick(const u64 tick) {
|
|
||||||
signalled_tick = tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioRenderer_Mailbox::ClearRemainCount(const u32 session_id) {
|
|
||||||
command_buffers[session_id].remaining_command_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 AudioRenderer_Mailbox::GetRemainCommandCount(const u32 session_id) const {
|
|
||||||
return command_buffers[session_id].remaining_command_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioRenderer::AudioRenderer(Core::System& system_)
|
|
||||||
: system{system_}, sink{system.AudioCore().GetOutputSink()} {
|
|
||||||
CreateSinkStreams();
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioRenderer::~AudioRenderer() {
|
AudioRenderer::~AudioRenderer() {
|
||||||
Stop();
|
Stop();
|
||||||
for (auto& stream : streams) {
|
|
||||||
if (stream) {
|
|
||||||
sink.CloseStream(stream);
|
|
||||||
}
|
|
||||||
stream = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRenderer::Start(AudioRenderer_Mailbox* mailbox_) {
|
void AudioRenderer::Start() {
|
||||||
if (running) {
|
CreateSinkStreams();
|
||||||
|
|
||||||
|
mailbox.Initialize(AppMailboxId::AudioRenderer);
|
||||||
|
|
||||||
|
main_thread = std::jthread([this](std::stop_token stop_token) { Main(stop_token); });
|
||||||
|
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mailbox = mailbox_;
|
|
||||||
thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); });
|
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,13 +47,63 @@ void AudioRenderer::Stop() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& stream : streams) {
|
mailbox.Send(Direction::DSP, {Message::Shutdown, {}});
|
||||||
stream->Stop();
|
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();
|
||||||
|
|
||||||
|
for (auto& stream : streams) {
|
||||||
|
if (stream) {
|
||||||
|
stream->Stop();
|
||||||
|
sink.CloseStream(stream);
|
||||||
|
stream = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
thread.join();
|
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioRenderer::Signal() {
|
||||||
|
signalled_tick = system.CoreTiming().GetGlobalTimeNs().count();
|
||||||
|
Send(Direction::DSP, {Message::Render, {}});
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Send(Direction dir, MailboxMessage message) {
|
||||||
|
mailbox.Send(dir, std::move(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
MailboxMessage AudioRenderer::Receive(Direction dir, bool block) {
|
||||||
|
return mailbox.Receive(dir, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioRenderer::SetCommandBuffer(s32 session_id, CommandBuffer& buffer) noexcept {
|
||||||
|
command_buffers[session_id] = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AudioRenderer::GetRemainCommandCount(s32 session_id) const noexcept {
|
||||||
|
return command_buffers[session_id].remaining_command_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioRenderer::ClearRemainCommandCount(s32 session_id) noexcept {
|
||||||
|
command_buffers[session_id].remaining_command_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 AudioRenderer::GetRenderingStartTick(s32 session_id) const noexcept {
|
||||||
|
return (1000 * command_buffers[session_id].render_time_taken_us) + signalled_tick;
|
||||||
|
}
|
||||||
|
|
||||||
void AudioRenderer::CreateSinkStreams() {
|
void AudioRenderer::CreateSinkStreams() {
|
||||||
u32 channels{sink.GetDeviceChannels()};
|
u32 channels{sink.GetDeviceChannels()};
|
||||||
for (u32 i = 0; i < MaxRendererSessions; i++) {
|
for (u32 i = 0; i < MaxRendererSessions; i++) {
|
||||||
|
@ -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"};
|
static constexpr char name[]{"AudioRenderer"};
|
||||||
MicroProfileOnThreadCreate(name);
|
MicroProfileOnThreadCreate(name);
|
||||||
Common::SetCurrentThreadName(name);
|
Common::SetCurrentThreadName(name);
|
||||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
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,
|
LOG_ERROR(Service_Audio,
|
||||||
"ADSP Audio Renderer -- Failed to receive initialize message from host!");
|
"ADSP Audio Renderer -- Failed to receive initialize message from host!");
|
||||||
return;
|
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};
|
constexpr u64 max_process_time{2'304'000ULL};
|
||||||
|
|
||||||
while (!stop_token.stop_requested()) {
|
while (!stop_token.stop_requested()) {
|
||||||
auto message{mailbox->ADSPWaitMessage()};
|
auto received{mailbox.Receive(Direction::DSP)};
|
||||||
switch (message) {
|
switch (received.msg) {
|
||||||
case RenderMessage::AudioRenderer_Shutdown:
|
case Message::Shutdown:
|
||||||
mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_Shutdown);
|
mailbox.Send(Direction::Host, {Message::Shutdown, {}});
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RenderMessage::AudioRenderer_Render: {
|
case Message::Render: {
|
||||||
if (system.IsShuttingDown()) [[unlikely]] {
|
if (system.IsShuttingDown()) [[unlikely]] {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_RenderResponse);
|
mailbox.Send(Direction::Host, {Message::RenderResponse, {}});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::array<bool, MaxRendererSessions> buffers_reset{};
|
std::array<bool, MaxRendererSessions> buffers_reset{};
|
||||||
std::array<u64, MaxRendererSessions> render_times_taken{};
|
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++) {
|
for (u32 index = 0; index < MaxRendererSessions; index++) {
|
||||||
auto& command_buffer{mailbox->GetCommandBuffer(index)};
|
auto& command_buffer{command_buffers[index]};
|
||||||
auto& command_list_processor{command_list_processors[index]};
|
auto& command_list_processor{command_list_processors[index]};
|
||||||
|
|
||||||
// Check this buffer is valid, as it may not be used.
|
// 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]);
|
command_buffer.size, streams[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command_buffer.reset_buffers && !buffers_reset[index]) {
|
if (command_buffer.reset_buffer && !buffers_reset[index]) {
|
||||||
streams[index]->ClearQueue();
|
streams[index]->ClearQueue();
|
||||||
buffers_reset[index] = true;
|
buffers_reset[index] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 max_time{max_process_time};
|
u64 max_time{max_process_time};
|
||||||
if (index == 1 && command_buffer.applet_resource_user_id ==
|
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];
|
max_time = max_process_time - render_times_taken[0];
|
||||||
if (render_times_taken[0] > max_process_time) {
|
if (render_times_taken[0] > max_process_time) {
|
||||||
max_time = 0;
|
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);
|
max_time = std::min(command_buffer.time_limit, max_time);
|
||||||
command_list_processor.SetProcessTimeMax(max_time);
|
command_list_processor.SetProcessTimeMax(max_time);
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
streams[index]->WaitFreeSpace(stop_token);
|
streams[index]->WaitFreeSpace(stop_token);
|
||||||
|
}
|
||||||
|
|
||||||
// Process the command list
|
// Process the command list
|
||||||
{
|
{
|
||||||
|
@ -202,24 +192,24 @@ void AudioRenderer::ThreadFunc(std::stop_token stop_token) {
|
||||||
command_list_processor.Process(index) - start_time;
|
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_buffer.remaining_command_count =
|
||||||
command_list_processor.GetRemainingCommandCount();
|
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;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_WARNING(Service_Audio,
|
LOG_WARNING(Service_Audio,
|
||||||
"ADSP AudioRenderer received an invalid message, msg={:02X}!",
|
"ADSP AudioRenderer received an invalid message, msg={:02X}!",
|
||||||
static_cast<u32>(message));
|
received.msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer::ADSP
|
} // namespace AudioCore::ADSP::AudioRenderer
|
115
src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
Normal file
115
src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
Normal file
|
@ -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
|
23
src/audio_core/adsp/apps/audio_renderer/command_buffer.h
Normal file
23
src/audio_core/adsp/apps/audio_renderer/command_buffer.h
Normal file
|
@ -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
|
|
@ -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
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <string>
|
#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/command_list_header.h"
|
||||||
#include "audio_core/renderer/command/commands.h"
|
#include "audio_core/renderer/command/commands.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
@ -11,15 +11,15 @@
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer::ADSP {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
|
|
||||||
void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size,
|
void CommandListProcessor::Initialize(Core::System& system_, CpuAddr buffer, u64 size,
|
||||||
Sink::SinkStream* stream_) {
|
Sink::SinkStream* stream_) {
|
||||||
system = &system_;
|
system = &system_;
|
||||||
memory = &system->ApplicationMemory();
|
memory = &system->ApplicationMemory();
|
||||||
stream = stream_;
|
stream = stream_;
|
||||||
header = reinterpret_cast<CommandListHeader*>(buffer);
|
header = reinterpret_cast<Renderer::CommandListHeader*>(buffer);
|
||||||
commands = reinterpret_cast<u8*>(buffer + sizeof(CommandListHeader));
|
commands = reinterpret_cast<u8*>(buffer + sizeof(Renderer::CommandListHeader));
|
||||||
commands_buffer_size = size;
|
commands_buffer_size = size;
|
||||||
command_count = header->command_count;
|
command_count = header->command_count;
|
||||||
sample_count = header->sample_count;
|
sample_count = header->sample_count;
|
||||||
|
@ -38,7 +38,7 @@ u32 CommandListProcessor::GetRemainingCommandCount() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandListProcessor::SetBuffer(const CpuAddr buffer, const u64 size) {
|
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;
|
commands_buffer_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ Sink::SinkStream* CommandListProcessor::GetOutputSinkStream() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 CommandListProcessor::Process(u32 session_id) {
|
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)};
|
const auto command_base{CpuAddr(commands)};
|
||||||
|
|
||||||
if (processed_command_count > 0) {
|
if (processed_command_count > 0) {
|
||||||
|
@ -60,12 +60,12 @@ u64 CommandListProcessor::Process(u32 session_id) {
|
||||||
std::string dump{fmt::format("\nSession {}\n", session_id)};
|
std::string dump{fmt::format("\nSession {}\n", session_id)};
|
||||||
|
|
||||||
for (u32 index = 0; index < command_count; index++) {
|
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) {
|
if (command.magic != 0xCAFEBABE) {
|
||||||
LOG_ERROR(Service_Audio, "Command has invalid magic! Expected 0xCAFEBABE, got {:08X}",
|
LOG_ERROR(Service_Audio, "Command has invalid magic! Expected 0xCAFEBABE, got {:08X}",
|
||||||
command.magic);
|
command.magic);
|
||||||
return system->CoreTiming().GetClockTicks() - start_time_;
|
return system->CoreTiming().GetGlobalTimeUs().count() - start_time_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto current_offset{CpuAddr(commands) - command_base};
|
auto current_offset{CpuAddr(commands) - command_base};
|
||||||
|
@ -74,8 +74,8 @@ u64 CommandListProcessor::Process(u32 session_id) {
|
||||||
LOG_ERROR(Service_Audio,
|
LOG_ERROR(Service_Audio,
|
||||||
"Command exceeded command buffer, buffer size {:08X}, command ends at {:08X}",
|
"Command exceeded command buffer, buffer size {:08X}, command ends at {:08X}",
|
||||||
commands_buffer_size,
|
commands_buffer_size,
|
||||||
CpuAddr(commands) + command.size - sizeof(CommandListHeader));
|
CpuAddr(commands) + command.size - sizeof(Renderer::CommandListHeader));
|
||||||
return system->CoreTiming().GetClockTicks() - start_time_;
|
return system->CoreTiming().GetGlobalTimeUs().count() - start_time_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings::values.dump_audio_commands) {
|
if (Settings::values.dump_audio_commands) {
|
||||||
|
@ -101,8 +101,8 @@ u64 CommandListProcessor::Process(u32 session_id) {
|
||||||
last_dump = dump;
|
last_dump = dump;
|
||||||
}
|
}
|
||||||
|
|
||||||
end_time = system->CoreTiming().GetClockTicks();
|
end_time = system->CoreTiming().GetGlobalTimeUs().count();
|
||||||
return end_time - start_time_;
|
return end_time - start_time_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer::ADSP
|
} // namespace AudioCore::ADSP::AudioRenderer
|
|
@ -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
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -6,6 +6,7 @@
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#include "audio_core/common/common.h"
|
#include "audio_core/common/common.h"
|
||||||
|
#include "audio_core/renderer/command/command_list_header.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -20,10 +21,11 @@ namespace Sink {
|
||||||
class SinkStream;
|
class SinkStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace AudioRenderer {
|
namespace Renderer {
|
||||||
struct CommandListHeader;
|
struct CommandListHeader;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ADSP {
|
namespace ADSP::AudioRenderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A processor for command lists given to the AudioRenderer.
|
* A processor for command lists given to the AudioRenderer.
|
||||||
|
@ -85,7 +87,7 @@ public:
|
||||||
/// Stream for the processed samples
|
/// Stream for the processed samples
|
||||||
Sink::SinkStream* stream{};
|
Sink::SinkStream* stream{};
|
||||||
/// Header info for this command list
|
/// Header info for this command list
|
||||||
CommandListHeader* header{};
|
Renderer::CommandListHeader* header{};
|
||||||
/// The command buffer
|
/// The command buffer
|
||||||
u8* commands{};
|
u8* commands{};
|
||||||
/// The command buffer size
|
/// The command buffer size
|
||||||
|
@ -114,6 +116,5 @@ public:
|
||||||
std::string last_dump{};
|
std::string last_dump{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ADSP
|
} // namespace ADSP::AudioRenderer
|
||||||
} // namespace AudioRenderer
|
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
69
src/audio_core/adsp/mailbox.h
Normal file
69
src/audio_core/adsp/mailbox.h
Normal file
|
@ -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
|
|
@ -11,7 +11,7 @@ namespace AudioCore {
|
||||||
AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>()} {
|
AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>()} {
|
||||||
CreateSinks();
|
CreateSinks();
|
||||||
// Must be created after the sinks
|
// Must be created after the sinks
|
||||||
adsp = std::make_unique<AudioRenderer::ADSP::ADSP>(system, *output_sink);
|
adsp = std::make_unique<ADSP::ADSP>(system, *output_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioCore ::~AudioCore() {
|
AudioCore ::~AudioCore() {
|
||||||
|
@ -43,7 +43,7 @@ Sink::Sink& AudioCore::GetInputSink() {
|
||||||
return *input_sink;
|
return *input_sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioRenderer::ADSP::ADSP& AudioCore::GetADSP() {
|
ADSP::ADSP& AudioCore::ADSP() {
|
||||||
return *adsp;
|
return *adsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "audio_core/adsp/adsp.h"
|
||||||
#include "audio_core/audio_manager.h"
|
#include "audio_core/audio_manager.h"
|
||||||
#include "audio_core/renderer/adsp/adsp.h"
|
|
||||||
#include "audio_core/sink/sink.h"
|
#include "audio_core/sink/sink.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -55,7 +55,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return Ref to the ADSP.
|
* @return Ref to the ADSP.
|
||||||
*/
|
*/
|
||||||
AudioRenderer::ADSP::ADSP& GetADSP();
|
ADSP::ADSP& ADSP();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +70,7 @@ private:
|
||||||
/// Sink used for audio input
|
/// Sink used for audio input
|
||||||
std::unique_ptr<Sink::Sink> input_sink;
|
std::unique_ptr<Sink::Sink> input_sink;
|
||||||
/// The ADSP in the sysmodule
|
/// The ADSP in the sysmodule
|
||||||
std::unique_ptr<AudioRenderer::ADSP::ADSP> adsp;
|
std::unique_ptr<ADSP::ADSP> adsp;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -73,7 +73,7 @@ void Manager::BufferReleaseAndRegister() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Manager::GetDeviceNames(std::vector<AudioRenderer::AudioDevice::AudioDeviceName>& names,
|
u32 Manager::GetDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names,
|
||||||
[[maybe_unused]] const u32 max_count,
|
[[maybe_unused]] const u32 max_count,
|
||||||
[[maybe_unused]] const bool filter) {
|
[[maybe_unused]] const bool filter) {
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
|
|
|
@ -65,8 +65,8 @@ public:
|
||||||
*
|
*
|
||||||
* @return Number of names written.
|
* @return Number of names written.
|
||||||
*/
|
*/
|
||||||
u32 GetDeviceNames(std::vector<AudioRenderer::AudioDevice::AudioDeviceName>& names,
|
u32 GetDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names, u32 max_count,
|
||||||
u32 max_count, bool filter);
|
bool filter);
|
||||||
|
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
|
@ -73,7 +73,7 @@ void Manager::BufferReleaseAndRegister() {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Manager::GetAudioOutDeviceNames(
|
u32 Manager::GetAudioOutDeviceNames(
|
||||||
std::vector<AudioRenderer::AudioDevice::AudioDeviceName>& names) const {
|
std::vector<Renderer::AudioDevice::AudioDeviceName>& names) const {
|
||||||
names.emplace_back("DeviceOut");
|
names.emplace_back("DeviceOut");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,7 @@ public:
|
||||||
* @param names - Output container to write names to.
|
* @param names - Output container to write names to.
|
||||||
* @return Number of names written.
|
* @return Number of names written.
|
||||||
*/
|
*/
|
||||||
u32 GetAudioOutDeviceNames(
|
u32 GetAudioOutDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names) const;
|
||||||
std::vector<AudioRenderer::AudioDevice::AudioDeviceName>& names) const;
|
|
||||||
|
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "audio_core/common/feature_support.h"
|
#include "audio_core/common/feature_support.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
Manager::Manager(Core::System& system_)
|
Manager::Manager(Core::System& system_)
|
||||||
: system{system_}, system_manager{std::make_unique<SystemManager>(system)} {
|
: system{system_}, system_manager{std::make_unique<SystemManager>(system)} {
|
||||||
|
@ -67,4 +67,4 @@ bool Manager::RemoveSystem(System& system_) {
|
||||||
return system_manager->Remove(system_);
|
return system_manager->Remove(system_);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -20,7 +20,7 @@ class System;
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
struct AudioRendererParameterInternal;
|
struct AudioRendererParameterInternal;
|
||||||
|
|
||||||
namespace AudioRenderer {
|
namespace Renderer {
|
||||||
/**
|
/**
|
||||||
* Wrapper for the audio system manager, handles service calls.
|
* Wrapper for the audio system manager, handles service calls.
|
||||||
*/
|
*/
|
||||||
|
@ -101,5 +101,5 @@ private:
|
||||||
std::unique_ptr<SystemManager> system_manager{};
|
std::unique_ptr<SystemManager> system_manager{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioRenderer
|
} // namespace Renderer
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -51,10 +51,10 @@ struct AudioRendererSystemContext {
|
||||||
s32 session_id;
|
s32 session_id;
|
||||||
s8 channels;
|
s8 channels;
|
||||||
s16 mix_buffer_count;
|
s16 mix_buffer_count;
|
||||||
AudioRenderer::BehaviorInfo* behavior;
|
Renderer::BehaviorInfo* behavior;
|
||||||
std::span<s32> depop_buffer;
|
std::span<s32> depop_buffer;
|
||||||
AudioRenderer::UpsamplerManager* upsampler_manager;
|
Renderer::UpsamplerManager* upsampler_manager;
|
||||||
AudioRenderer::MemoryPoolInfo* memory_pool_info;
|
Renderer::MemoryPoolInfo* memory_pool_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "audio_core/renderer/adsp/adsp.h"
|
|
||||||
#include "audio_core/renderer/adsp/command_buffer.h"
|
|
||||||
#include "audio_core/sink/sink.h"
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/core_timing.h"
|
|
||||||
#include "core/memory.h"
|
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer::ADSP {
|
|
||||||
|
|
||||||
ADSP::ADSP(Core::System& system_, Sink::Sink& sink_)
|
|
||||||
: system{system_}, memory{system.ApplicationMemory()}, sink{sink_} {}
|
|
||||||
|
|
||||||
ADSP::~ADSP() {
|
|
||||||
ClearCommandBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
State ADSP::GetState() const {
|
|
||||||
if (running) {
|
|
||||||
return State::Started;
|
|
||||||
}
|
|
||||||
return State::Stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioRenderer_Mailbox* ADSP::GetRenderMailbox() {
|
|
||||||
return &render_mailbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADSP::ClearRemainCount(const u32 session_id) {
|
|
||||||
render_mailbox.ClearRemainCount(session_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 ADSP::GetSignalledTick() const {
|
|
||||||
return render_mailbox.GetSignalledTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 ADSP::GetTimeTaken() const {
|
|
||||||
return render_mailbox.GetRenderTimeTaken();
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 ADSP::GetRenderTimeTaken(const u32 session_id) {
|
|
||||||
return render_mailbox.GetCommandBuffer(session_id).render_time_taken;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 ADSP::GetRemainCommandCount(const u32 session_id) const {
|
|
||||||
return render_mailbox.GetRemainCommandCount(session_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADSP::SendCommandBuffer(const u32 session_id, const CommandBuffer& command_buffer) {
|
|
||||||
render_mailbox.SetCommandBuffer(session_id, command_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 ADSP::GetRenderingStartTick(const u32 session_id) {
|
|
||||||
return render_mailbox.GetSignalledTick() +
|
|
||||||
render_mailbox.GetCommandBuffer(session_id).render_time_taken;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ADSP::Start() {
|
|
||||||
if (running) {
|
|
||||||
return running;
|
|
||||||
}
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
systems_active++;
|
|
||||||
audio_renderer = std::make_unique<AudioRenderer>(system);
|
|
||||||
audio_renderer->Start(&render_mailbox);
|
|
||||||
render_mailbox.HostSendMessage(RenderMessage::AudioRenderer_InitializeOK);
|
|
||||||
if (render_mailbox.HostWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) {
|
|
||||||
LOG_ERROR(
|
|
||||||
Service_Audio,
|
|
||||||
"Host Audio Renderer -- Failed to receive initialize message response from ADSP!");
|
|
||||||
}
|
|
||||||
return running;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADSP::Stop() {
|
|
||||||
systems_active--;
|
|
||||||
if (running && systems_active == 0) {
|
|
||||||
{
|
|
||||||
std::scoped_lock l{mailbox_lock};
|
|
||||||
render_mailbox.HostSendMessage(RenderMessage::AudioRenderer_Shutdown);
|
|
||||||
if (render_mailbox.HostWaitMessage() != RenderMessage::AudioRenderer_Shutdown) {
|
|
||||||
LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown "
|
|
||||||
"message response from ADSP!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
audio_renderer->Stop();
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADSP::Signal() {
|
|
||||||
const auto signalled_tick{system.CoreTiming().GetClockTicks()};
|
|
||||||
render_mailbox.SetSignalledTick(signalled_tick);
|
|
||||||
render_mailbox.HostSendMessage(RenderMessage::AudioRenderer_Render);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADSP::Wait() {
|
|
||||||
std::scoped_lock l{mailbox_lock};
|
|
||||||
auto response{render_mailbox.HostWaitMessage()};
|
|
||||||
if (response != RenderMessage::AudioRenderer_RenderResponse) {
|
|
||||||
LOG_ERROR(Service_Audio, "Invalid ADSP response message, expected 0x{:02X}, got 0x{:02X}",
|
|
||||||
static_cast<u32>(RenderMessage::AudioRenderer_RenderResponse),
|
|
||||||
static_cast<u32>(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearCommandBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADSP::ClearCommandBuffers() {
|
|
||||||
render_mailbox.ClearCommandBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer::ADSP
|
|
|
@ -1,171 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#include "audio_core/renderer/adsp/audio_renderer.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
namespace Memory {
|
|
||||||
class Memory;
|
|
||||||
}
|
|
||||||
class System;
|
|
||||||
} // namespace Core
|
|
||||||
|
|
||||||
namespace AudioCore {
|
|
||||||
namespace Sink {
|
|
||||||
class Sink;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace AudioRenderer::ADSP {
|
|
||||||
struct CommandBuffer;
|
|
||||||
|
|
||||||
enum class State {
|
|
||||||
Started,
|
|
||||||
Stopped,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 apps you program 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, processes them, and sends the samples to Gmix.
|
|
||||||
*
|
|
||||||
* OpusDecoder - Contains libopus, and controls processing Opus audio and sends it to Gmix.
|
|
||||||
* Not much research done here, TODO if needed.
|
|
||||||
*
|
|
||||||
* We only implement the AudioRenderer for now.
|
|
||||||
*
|
|
||||||
* Communication for the apps is done through mailboxes, and some shared memory.
|
|
||||||
*/
|
|
||||||
class ADSP {
|
|
||||||
public:
|
|
||||||
explicit ADSP(Core::System& system, Sink::Sink& sink);
|
|
||||||
~ADSP();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the ADSP.
|
|
||||||
*
|
|
||||||
* @return True if started or already running, otherwise false.
|
|
||||||
*/
|
|
||||||
bool Start();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop the ADSP.
|
|
||||||
*/
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ADSP's state.
|
|
||||||
*
|
|
||||||
* @return Started or Stopped.
|
|
||||||
*/
|
|
||||||
State GetState() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the AudioRenderer mailbox to communicate with it.
|
|
||||||
*
|
|
||||||
* @return The AudioRenderer mailbox.
|
|
||||||
*/
|
|
||||||
AudioRenderer_Mailbox* GetRenderMailbox();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tick the ADSP was signalled.
|
|
||||||
*
|
|
||||||
* @return The tick the ADSP was signalled.
|
|
||||||
*/
|
|
||||||
u64 GetSignalledTick() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the total time it took for the ADSP to run the last command lists (both command lists).
|
|
||||||
*
|
|
||||||
* @return The tick the ADSP was signalled.
|
|
||||||
*/
|
|
||||||
u64 GetTimeTaken() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the last time a given command list took to run.
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to check (0 or 1).
|
|
||||||
* @return The time it took.
|
|
||||||
*/
|
|
||||||
u64 GetRenderTimeTaken(u32 session_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the remaining command count for a given session.
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to check (0 or 1).
|
|
||||||
*/
|
|
||||||
void ClearRemainCount(u32 session_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the remaining number of commands left to process for a command list.
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to check (0 or 1).
|
|
||||||
* @return The number of commands remaining.
|
|
||||||
*/
|
|
||||||
u32 GetRemainCommandCount(u32 session_id) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the last tick a command list started processing.
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to check (0 or 1).
|
|
||||||
* @return The last tick the given command list started.
|
|
||||||
*/
|
|
||||||
u64 GetRenderingStartTick(u32 session_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a command buffer to be processed.
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to check (0 or 1).
|
|
||||||
* @param command_buffer - The command buffer to process.
|
|
||||||
*/
|
|
||||||
void SendCommandBuffer(u32 session_id, const CommandBuffer& command_buffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the command buffers (does not clear the time taken or the remaining command count)
|
|
||||||
*/
|
|
||||||
void ClearCommandBuffers();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signal the AudioRenderer to begin processing.
|
|
||||||
*/
|
|
||||||
void Signal();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for the AudioRenderer to finish processing.
|
|
||||||
*/
|
|
||||||
void Wait();
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Core system
|
|
||||||
Core::System& system;
|
|
||||||
/// Core memory
|
|
||||||
Core::Memory::Memory& memory;
|
|
||||||
/// Number of systems active, used to prevent accidental shutdowns
|
|
||||||
u8 systems_active{0};
|
|
||||||
/// ADSP running state
|
|
||||||
std::atomic<bool> running{false};
|
|
||||||
/// Output sink used by the ADSP
|
|
||||||
Sink::Sink& sink;
|
|
||||||
/// AudioRenderer app
|
|
||||||
std::unique_ptr<AudioRenderer> audio_renderer{};
|
|
||||||
/// Communication for the AudioRenderer
|
|
||||||
AudioRenderer_Mailbox render_mailbox{};
|
|
||||||
/// Mailbox lock ffor the render mailbox
|
|
||||||
std::mutex mailbox_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace AudioRenderer::ADSP
|
|
||||||
} // namespace AudioCore
|
|
|
@ -1,204 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "audio_core/renderer/adsp/command_buffer.h"
|
|
||||||
#include "audio_core/renderer/adsp/command_list_processor.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include "common/polyfill_thread.h"
|
|
||||||
#include "common/reader_writer_queue.h"
|
|
||||||
#include "common/thread.h"
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
namespace Timing {
|
|
||||||
struct EventType;
|
|
||||||
}
|
|
||||||
class System;
|
|
||||||
} // namespace Core
|
|
||||||
|
|
||||||
namespace AudioCore {
|
|
||||||
namespace Sink {
|
|
||||||
class Sink;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace AudioRenderer::ADSP {
|
|
||||||
|
|
||||||
enum class RenderMessage {
|
|
||||||
/* 0x00 */ Invalid,
|
|
||||||
/* 0x01 */ AudioRenderer_MapUnmap_Map,
|
|
||||||
/* 0x02 */ AudioRenderer_MapUnmap_MapResponse,
|
|
||||||
/* 0x03 */ AudioRenderer_MapUnmap_Unmap,
|
|
||||||
/* 0x04 */ AudioRenderer_MapUnmap_UnmapResponse,
|
|
||||||
/* 0x05 */ AudioRenderer_MapUnmap_InvalidateCache,
|
|
||||||
/* 0x06 */ AudioRenderer_MapUnmap_InvalidateCacheResponse,
|
|
||||||
/* 0x07 */ AudioRenderer_MapUnmap_Shutdown,
|
|
||||||
/* 0x08 */ AudioRenderer_MapUnmap_ShutdownResponse,
|
|
||||||
/* 0x16 */ AudioRenderer_InitializeOK = 0x16,
|
|
||||||
/* 0x20 */ AudioRenderer_RenderResponse = 0x20,
|
|
||||||
/* 0x2A */ AudioRenderer_Render = 0x2A,
|
|
||||||
/* 0x34 */ AudioRenderer_Shutdown = 0x34,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A mailbox for the AudioRenderer, allowing communication between the host and the AudioRenderer
|
|
||||||
* running on the ADSP.
|
|
||||||
*/
|
|
||||||
class AudioRenderer_Mailbox {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Send a message from the host to the AudioRenderer.
|
|
||||||
*
|
|
||||||
* @param message - The message to send to the AudioRenderer.
|
|
||||||
*/
|
|
||||||
void HostSendMessage(RenderMessage message);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Host wait for a message from the AudioRenderer.
|
|
||||||
*
|
|
||||||
* @return The message returned from the AudioRenderer.
|
|
||||||
*/
|
|
||||||
RenderMessage HostWaitMessage();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a message from the AudioRenderer to the host.
|
|
||||||
*
|
|
||||||
* @param message - The message to send to the host.
|
|
||||||
*/
|
|
||||||
void ADSPSendMessage(RenderMessage message);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AudioRenderer wait for a message from the host.
|
|
||||||
*
|
|
||||||
* @return The message returned from the AudioRenderer.
|
|
||||||
*/
|
|
||||||
RenderMessage ADSPWaitMessage();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the command buffer with the given session id (0 or 1).
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to get (0 or 1).
|
|
||||||
* @return The command buffer.
|
|
||||||
*/
|
|
||||||
CommandBuffer& GetCommandBuffer(u32 session_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the command buffer with the given session id (0 or 1).
|
|
||||||
*
|
|
||||||
* @param session_id - The session id to get (0 or 1).
|
|
||||||
* @param buffer - The command buffer to set.
|
|
||||||
*/
|
|
||||||
void SetCommandBuffer(u32 session_id, const CommandBuffer& buffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the total render time taken for the last command lists sent.
|
|
||||||
*
|
|
||||||
* @return Total render time taken for the last command lists.
|
|
||||||
*/
|
|
||||||
u64 GetRenderTimeTaken() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tick the AudioRenderer was signalled.
|
|
||||||
*
|
|
||||||
* @return The tick the AudioRenderer was signalled.
|
|
||||||
*/
|
|
||||||
u64 GetSignalledTick() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the tick the AudioRenderer was signalled.
|
|
||||||
*
|
|
||||||
* @param tick - The tick the AudioRenderer was signalled.
|
|
||||||
*/
|
|
||||||
void SetSignalledTick(u64 tick);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the remaining command count.
|
|
||||||
*
|
|
||||||
* @param session_id - Index for which command list to clear (0 or 1).
|
|
||||||
*/
|
|
||||||
void ClearRemainCount(u32 session_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the remaining command count for a given command list.
|
|
||||||
*
|
|
||||||
* @param session_id - Index for which command list to clear (0 or 1).
|
|
||||||
* @return The remaining command count.
|
|
||||||
*/
|
|
||||||
u32 GetRemainCommandCount(u32 session_id) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the command buffers (does not clear the time taken or the remaining command count).
|
|
||||||
*/
|
|
||||||
void ClearCommandBuffers();
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Host signalling event
|
|
||||||
Common::Event host_event{};
|
|
||||||
/// AudioRenderer signalling event
|
|
||||||
Common::Event adsp_event{};
|
|
||||||
/// Host message queue
|
|
||||||
|
|
||||||
Common::ReaderWriterQueue<RenderMessage> host_messages{};
|
|
||||||
/// AudioRenderer message queue
|
|
||||||
|
|
||||||
Common::ReaderWriterQueue<RenderMessage> adsp_messages{};
|
|
||||||
/// Command buffers
|
|
||||||
|
|
||||||
std::array<CommandBuffer, MaxRendererSessions> command_buffers{};
|
|
||||||
/// Tick the AudioRnederer was signalled
|
|
||||||
u64 signalled_tick{};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The AudioRenderer application running on the ADSP.
|
|
||||||
*/
|
|
||||||
class AudioRenderer {
|
|
||||||
public:
|
|
||||||
explicit AudioRenderer(Core::System& system);
|
|
||||||
~AudioRenderer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the AudioRenderer.
|
|
||||||
*
|
|
||||||
* @param mailbox The mailbox to use for this session.
|
|
||||||
*/
|
|
||||||
void Start(AudioRenderer_Mailbox* mailbox);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop the AudioRenderer.
|
|
||||||
*/
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* Main AudioRenderer thread, responsible for processing the command lists.
|
|
||||||
*/
|
|
||||||
void ThreadFunc(std::stop_token stop_token);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the streams which will receive the processed samples.
|
|
||||||
*/
|
|
||||||
void CreateSinkStreams();
|
|
||||||
|
|
||||||
/// Core system
|
|
||||||
Core::System& system;
|
|
||||||
/// Main thread
|
|
||||||
std::jthread thread{};
|
|
||||||
/// The current state
|
|
||||||
std::atomic<bool> running{};
|
|
||||||
/// The active mailbox
|
|
||||||
AudioRenderer_Mailbox* mailbox{};
|
|
||||||
/// The command lists to process
|
|
||||||
std::array<CommandListProcessor, MaxRendererSessions> command_list_processors{};
|
|
||||||
/// The output sink the AudioRenderer will use
|
|
||||||
Sink::Sink& sink;
|
|
||||||
/// The streams which will receive the processed samples
|
|
||||||
std::array<Sink::SinkStream*, MaxRendererSessions> streams;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace AudioRenderer::ADSP
|
|
||||||
} // namespace AudioCore
|
|
|
@ -1,21 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 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::AudioRenderer::ADSP {
|
|
||||||
|
|
||||||
struct CommandBuffer {
|
|
||||||
CpuAddr buffer;
|
|
||||||
u64 size;
|
|
||||||
u64 time_limit;
|
|
||||||
u32 remaining_command_count;
|
|
||||||
bool reset_buffers;
|
|
||||||
u64 applet_resource_user_id;
|
|
||||||
u64 render_time_taken;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer::ADSP
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "audio_core/sink/sink.h"
|
#include "audio_core/sink/sink.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
constexpr std::array usb_device_names{
|
constexpr std::array usb_device_names{
|
||||||
AudioDevice::AudioDeviceName{"AudioStereoJackOutput"},
|
AudioDevice::AudioDeviceName{"AudioStereoJackOutput"},
|
||||||
|
@ -71,4 +71,4 @@ f32 AudioDevice::GetDeviceVolume([[maybe_unused]] std::string_view name) const {
|
||||||
return output_sink.GetDeviceVolume();
|
return output_sink.GetDeviceVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Sink {
|
||||||
class Sink;
|
class Sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace AudioRenderer {
|
namespace Renderer {
|
||||||
/**
|
/**
|
||||||
* An interface to an output audio device available to the Switch.
|
* An interface to an output audio device available to the Switch.
|
||||||
*/
|
*/
|
||||||
|
@ -76,5 +76,5 @@ private:
|
||||||
const u32 user_revision;
|
const u32 user_revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioRenderer
|
} // namespace Renderer
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "core/hle/kernel/k_transfer_memory.h"
|
#include "core/hle/kernel/k_transfer_memory.h"
|
||||||
#include "core/hle/service/audio/errors.h"
|
#include "core/hle/service/audio/errors.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* rendered_event)
|
Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* rendered_event)
|
||||||
: core{system_}, manager{manager_}, system{system_, rendered_event} {}
|
: core{system_}, manager{manager_}, system{system_, rendered_event} {}
|
||||||
|
@ -64,4 +64,4 @@ Result Renderer::RequestUpdate(std::span<const u8> input, std::span<u8> performa
|
||||||
return system.Update(input, performance, output);
|
return system.Update(input, performance, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -19,7 +19,7 @@ class KTransferMemory;
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
struct AudioRendererParameterInternal;
|
struct AudioRendererParameterInternal;
|
||||||
|
|
||||||
namespace AudioRenderer {
|
namespace Renderer {
|
||||||
class Manager;
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +31,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the renderer.
|
* Initialize the renderer.
|
||||||
* Registers the system with the AudioRenderer::Manager, allocates workbuffers and initializes
|
* Registers the system with the Renderer::Manager, allocates workbuffers and initializes
|
||||||
* everything to a default state.
|
* everything to a default state.
|
||||||
*
|
*
|
||||||
* @param params - Input parameters to initialize the system with.
|
* @param params - Input parameters to initialize the system with.
|
||||||
|
@ -93,5 +93,5 @@ private:
|
||||||
System system;
|
System system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioRenderer
|
} // namespace Renderer
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "audio_core/common/feature_support.h"
|
#include "audio_core/common/feature_support.h"
|
||||||
#include "audio_core/renderer/behavior/behavior_info.h"
|
#include "audio_core/renderer/behavior/behavior_info.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
BehaviorInfo::BehaviorInfo() : process_revision{CurrentRevision} {}
|
BehaviorInfo::BehaviorInfo() : process_revision{CurrentRevision} {}
|
||||||
|
|
||||||
|
@ -190,4 +190,4 @@ bool BehaviorInfo::IsI3dl2ReverbChannelMappingChanged() const {
|
||||||
return CheckFeatureSupported(SupportTags::I3dl2ReverbChannelMappingChange, user_revision);
|
return CheckFeatureSupported(SupportTags::I3dl2ReverbChannelMappingChange, user_revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/audio/errors.h"
|
#include "core/hle/service/audio/errors.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Holds host and user revisions, checks whether render features can be enabled, and reports errors.
|
* Holds host and user revisions, checks whether render features can be enabled, and reports errors.
|
||||||
*/
|
*/
|
||||||
|
@ -264,7 +264,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Check if skipping voice pitch and sample rate conversion is supported.
|
* Check if skipping voice pitch and sample rate conversion is supported.
|
||||||
* This speeds up the data source commands by skipping resampling if unwanted.
|
* This speeds up the data source commands by skipping resampling if unwanted.
|
||||||
* See AudioCore::AudioRenderer::DecodeFromWaveBuffers
|
* See AudioCore::Renderer::DecodeFromWaveBuffers
|
||||||
*
|
*
|
||||||
* @return True if supported, otherwise false.
|
* @return True if supported, otherwise false.
|
||||||
*/
|
*/
|
||||||
|
@ -273,7 +273,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Check if resetting played sample count at loop points is supported.
|
* Check if resetting played sample count at loop points is supported.
|
||||||
* This resets the number of samples played in a voice state when a loop point is reached.
|
* This resets the number of samples played in a voice state when a loop point is reached.
|
||||||
* See AudioCore::AudioRenderer::DecodeFromWaveBuffers
|
* See AudioCore::Renderer::DecodeFromWaveBuffers
|
||||||
*
|
*
|
||||||
* @return True if supported, otherwise false.
|
* @return True if supported, otherwise false.
|
||||||
*/
|
*/
|
||||||
|
@ -373,4 +373,4 @@ public:
|
||||||
u32 error_count{};
|
u32 error_count{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "audio_core/renderer/splitter/splitter_context.h"
|
#include "audio_core/renderer/splitter/splitter_context.h"
|
||||||
#include "audio_core/renderer/voice/voice_context.h"
|
#include "audio_core/renderer/voice/voice_context.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
InfoUpdater::InfoUpdater(std::span<const u8> input_, std::span<u8> output_,
|
InfoUpdater::InfoUpdater(std::span<const u8> input_, std::span<u8> output_,
|
||||||
const u32 process_handle_, BehaviorInfo& behaviour_)
|
const u32 process_handle_, BehaviorInfo& behaviour_)
|
||||||
|
@ -536,4 +536,4 @@ Result InfoUpdater::CheckConsumedSize() {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/audio/errors.h"
|
#include "core/hle/service/audio/errors.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
class BehaviorInfo;
|
class BehaviorInfo;
|
||||||
class VoiceContext;
|
class VoiceContext;
|
||||||
class MixContext;
|
class MixContext;
|
||||||
|
@ -202,4 +202,4 @@ private:
|
||||||
BehaviorInfo& behaviour;
|
BehaviorInfo& behaviour;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "audio_core/renderer/voice/voice_info.h"
|
#include "audio_core/renderer/voice/voice_info.h"
|
||||||
#include "audio_core/renderer/voice/voice_state.h"
|
#include "audio_core/renderer/voice/voice_state.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
template <typename T, CommandId Id>
|
template <typename T, CommandId Id>
|
||||||
T& CommandBuffer::GenerateStart(const s32 node_id) {
|
T& CommandBuffer::GenerateStart(const s32 node_id) {
|
||||||
|
@ -713,4 +713,4 @@ void CommandBuffer::GenerateCompressorCommand(s16 buffer_offset, EffectInfoBase&
|
||||||
GenerateEnd<CompressorCommand>(cmd);
|
GenerateEnd<CompressorCommand>(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "audio_core/renderer/performance/performance_manager.h"
|
#include "audio_core/renderer/performance/performance_manager.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
struct UpsamplerInfo;
|
struct UpsamplerInfo;
|
||||||
struct VoiceState;
|
struct VoiceState;
|
||||||
class EffectInfoBase;
|
class EffectInfoBase;
|
||||||
|
@ -465,4 +465,4 @@ private:
|
||||||
void GenerateEnd(T& cmd);
|
void GenerateEnd(T& cmd);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "audio_core/renderer/voice/voice_context.h"
|
#include "audio_core/renderer/voice/voice_context.h"
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
CommandGenerator::CommandGenerator(CommandBuffer& command_buffer_,
|
CommandGenerator::CommandGenerator(CommandBuffer& command_buffer_,
|
||||||
const CommandListHeader& command_list_header_,
|
const CommandListHeader& command_list_header_,
|
||||||
|
@ -793,4 +793,4 @@ void CommandGenerator::GeneratePerformanceCommand(
|
||||||
command_buffer.GeneratePerformanceCommand(node_id, state, entry_addresses);
|
command_buffer.GeneratePerformanceCommand(node_id, state, entry_addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
struct AudioRendererSystemContext;
|
struct AudioRendererSystemContext;
|
||||||
|
|
||||||
namespace AudioRenderer {
|
namespace Renderer {
|
||||||
class CommandBuffer;
|
class CommandBuffer;
|
||||||
struct CommandListHeader;
|
struct CommandListHeader;
|
||||||
class VoiceContext;
|
class VoiceContext;
|
||||||
|
@ -345,5 +345,5 @@ private:
|
||||||
PerformanceManager* performance_manager;
|
PerformanceManager* performance_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioRenderer
|
} // namespace Renderer
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "audio_core/common/common.h"
|
#include "audio_core/common/common.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
struct CommandListHeader {
|
struct CommandListHeader {
|
||||||
u64 buffer_size;
|
u64 buffer_size;
|
||||||
|
@ -19,4 +19,4 @@ struct CommandListHeader {
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "audio_core/renderer/command/command_processing_time_estimator.h"
|
#include "audio_core/renderer/command/command_processing_time_estimator.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
u32 CommandProcessingTimeEstimatorVersion1::Estimate(
|
u32 CommandProcessingTimeEstimatorVersion1::Estimate(
|
||||||
const PcmInt16DataSourceVersion1Command& command) const {
|
const PcmInt16DataSourceVersion1Command& command) const {
|
||||||
|
@ -3617,4 +3617,4 @@ u32 CommandProcessingTimeEstimatorVersion5::Estimate(const CompressorCommand& co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "audio_core/renderer/command/commands.h"
|
#include "audio_core/renderer/command/commands.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Estimate the processing time required for all commands.
|
* Estimate the processing time required for all commands.
|
||||||
*/
|
*/
|
||||||
|
@ -251,4 +251,4 @@ private:
|
||||||
u32 buffer_count{};
|
u32 buffer_count{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,20 +3,20 @@
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#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/data_source/adpcm.h"
|
#include "audio_core/renderer/command/data_source/adpcm.h"
|
||||||
#include "audio_core/renderer/command/data_source/decode.h"
|
#include "audio_core/renderer/command/data_source/decode.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void AdpcmDataSourceVersion1Command::Dump(const ADSP::CommandListProcessor& processor,
|
void AdpcmDataSourceVersion1Command::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("AdpcmDataSourceVersion1Command\n\toutput_index {:02X} source sample "
|
string += fmt::format("AdpcmDataSourceVersion1Command\n\toutput_index {:02X} source sample "
|
||||||
"rate {} target sample rate {} src quality {}\n",
|
"rate {} target sample rate {} src quality {}\n",
|
||||||
output_index, sample_rate, processor.target_sample_rate, src_quality);
|
output_index, sample_rate, processor.target_sample_rate, src_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdpcmDataSourceVersion1Command::Process(const ADSP::CommandListProcessor& processor) {
|
void AdpcmDataSourceVersion1Command::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count)};
|
processor.sample_count)};
|
||||||
|
|
||||||
|
@ -41,18 +41,18 @@ void AdpcmDataSourceVersion1Command::Process(const ADSP::CommandListProcessor& p
|
||||||
DecodeFromWaveBuffers(*processor.memory, args);
|
DecodeFromWaveBuffers(*processor.memory, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdpcmDataSourceVersion1Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool AdpcmDataSourceVersion1Command::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdpcmDataSourceVersion2Command::Dump(const ADSP::CommandListProcessor& processor,
|
void AdpcmDataSourceVersion2Command::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("AdpcmDataSourceVersion2Command\n\toutput_index {:02X} source sample "
|
string += fmt::format("AdpcmDataSourceVersion2Command\n\toutput_index {:02X} source sample "
|
||||||
"rate {} target sample rate {} src quality {}\n",
|
"rate {} target sample rate {} src quality {}\n",
|
||||||
output_index, sample_rate, processor.target_sample_rate, src_quality);
|
output_index, sample_rate, processor.target_sample_rate, src_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdpcmDataSourceVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
|
void AdpcmDataSourceVersion2Command::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count)};
|
processor.sample_count)};
|
||||||
|
|
||||||
|
@ -77,8 +77,8 @@ void AdpcmDataSourceVersion2Command::Process(const ADSP::CommandListProcessor& p
|
||||||
DecodeFromWaveBuffers(*processor.memory, args);
|
DecodeFromWaveBuffers(*processor.memory, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdpcmDataSourceVersion2Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool AdpcmDataSourceVersion2Command::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -11,11 +11,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command to decode ADPCM-encoded version 1 wavebuffers
|
* AudioRenderer command to decode ADPCM-encoded version 1 wavebuffers
|
||||||
* into the output_index mix buffer.
|
* into the output_index mix buffer.
|
||||||
|
@ -27,14 +28,14 @@ struct AdpcmDataSourceVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -42,13 +43,13 @@ struct AdpcmDataSourceVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Quality used for sample rate conversion
|
/// Quality used for sample rate conversion
|
||||||
SrcQuality src_quality;
|
SrcQuality src_quality;
|
||||||
/// Mix buffer index for decoded samples
|
/// Mix buffer index for decoded samples
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
/// Flags to control decoding (see AudioCore::AudioRenderer::VoiceInfo::Flags)
|
/// Flags to control decoding (see AudioCore::Renderer::VoiceInfo::Flags)
|
||||||
u16 flags;
|
u16 flags;
|
||||||
/// Wavebuffer sample rate
|
/// Wavebuffer sample rate
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
|
@ -75,14 +76,14 @@ struct AdpcmDataSourceVersion2Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -90,13 +91,13 @@ struct AdpcmDataSourceVersion2Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Quality used for sample rate conversion
|
/// Quality used for sample rate conversion
|
||||||
SrcQuality src_quality;
|
SrcQuality src_quality;
|
||||||
/// Mix buffer index for decoded samples
|
/// Mix buffer index for decoded samples
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
/// Flags to control decoding (see AudioCore::AudioRenderer::VoiceInfo::Flags)
|
/// Flags to control decoding (see AudioCore::Renderer::VoiceInfo::Flags)
|
||||||
u16 flags;
|
u16 flags;
|
||||||
/// Wavebuffer sample rate
|
/// Wavebuffer sample rate
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
|
@ -116,4 +117,4 @@ struct AdpcmDataSourceVersion2Command : ICommand {
|
||||||
u64 data_size;
|
u64 data_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "common/scratch_buffer.h"
|
#include "common/scratch_buffer.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
constexpr u32 TempBufferSize = 0x3F00;
|
constexpr u32 TempBufferSize = 0x3F00;
|
||||||
constexpr std::array<u8, 3> PitchBySrcQuality = {4, 8, 4};
|
constexpr std::array<u8, 3> PitchBySrcQuality = {4, 8, 4};
|
||||||
|
@ -364,7 +364,7 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf
|
||||||
wavebuffers_consumed++;
|
wavebuffers_consumed++;
|
||||||
} else {
|
} else {
|
||||||
voice_state.loop_count++;
|
voice_state.loop_count++;
|
||||||
if (wavebuffer.loop_count > 0 &&
|
if (wavebuffer.loop_count >= 0 &&
|
||||||
(voice_state.loop_count > wavebuffer.loop_count || samples_decoded == 0)) {
|
(voice_state.loop_count > wavebuffer.loop_count || samples_decoded == 0)) {
|
||||||
voice_state.wave_buffer_valid[wavebuffer_index] = false;
|
voice_state.wave_buffer_valid[wavebuffer_index] = false;
|
||||||
voice_state.loop_count = 0;
|
voice_state.loop_count = 0;
|
||||||
|
@ -423,4 +423,4 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf
|
||||||
voice_state.fraction = fraction;
|
voice_state.fraction = fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Core::Memory {
|
||||||
class Memory;
|
class Memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
struct DecodeFromWaveBuffersArgs {
|
struct DecodeFromWaveBuffersArgs {
|
||||||
SampleFormat sample_format;
|
SampleFormat sample_format;
|
||||||
|
@ -56,4 +56,4 @@ struct DecodeArg {
|
||||||
*/
|
*/
|
||||||
void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args);
|
void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args);
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/data_source/decode.h"
|
#include "audio_core/renderer/command/data_source/decode.h"
|
||||||
#include "audio_core/renderer/command/data_source/pcm_float.h"
|
#include "audio_core/renderer/command/data_source/pcm_float.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void PcmFloatDataSourceVersion1Command::Dump(const ADSP::CommandListProcessor& processor,
|
void PcmFloatDataSourceVersion1Command::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string +=
|
string +=
|
||||||
fmt::format("PcmFloatDataSourceVersion1Command\n\toutput_index {:02X} channel {} "
|
fmt::format("PcmFloatDataSourceVersion1Command\n\toutput_index {:02X} channel {} "
|
||||||
|
@ -16,7 +16,8 @@ void PcmFloatDataSourceVersion1Command::Dump(const ADSP::CommandListProcessor& p
|
||||||
processor.target_sample_rate, src_quality);
|
processor.target_sample_rate, src_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmFloatDataSourceVersion1Command::Process(const ADSP::CommandListProcessor& processor) {
|
void PcmFloatDataSourceVersion1Command::Process(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
|
|
||||||
|
@ -41,11 +42,12 @@ void PcmFloatDataSourceVersion1Command::Process(const ADSP::CommandListProcessor
|
||||||
DecodeFromWaveBuffers(*processor.memory, args);
|
DecodeFromWaveBuffers(*processor.memory, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PcmFloatDataSourceVersion1Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool PcmFloatDataSourceVersion1Command::Verify(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmFloatDataSourceVersion2Command::Dump(const ADSP::CommandListProcessor& processor,
|
void PcmFloatDataSourceVersion2Command::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string +=
|
string +=
|
||||||
fmt::format("PcmFloatDataSourceVersion2Command\n\toutput_index {:02X} channel {} "
|
fmt::format("PcmFloatDataSourceVersion2Command\n\toutput_index {:02X} channel {} "
|
||||||
|
@ -54,7 +56,8 @@ void PcmFloatDataSourceVersion2Command::Dump(const ADSP::CommandListProcessor& p
|
||||||
processor.target_sample_rate, src_quality);
|
processor.target_sample_rate, src_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmFloatDataSourceVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
|
void PcmFloatDataSourceVersion2Command::Process(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
|
|
||||||
|
@ -79,8 +82,9 @@ void PcmFloatDataSourceVersion2Command::Process(const ADSP::CommandListProcessor
|
||||||
DecodeFromWaveBuffers(*processor.memory, args);
|
DecodeFromWaveBuffers(*processor.memory, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PcmFloatDataSourceVersion2Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool PcmFloatDataSourceVersion2Command::Verify(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command to decode PCM float-encoded version 1 wavebuffers
|
* AudioRenderer command to decode PCM float-encoded version 1 wavebuffers
|
||||||
* into the output_index mix buffer.
|
* into the output_index mix buffer.
|
||||||
|
@ -25,14 +26,14 @@ struct PcmFloatDataSourceVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,13 +41,13 @@ struct PcmFloatDataSourceVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Quality used for sample rate conversion
|
/// Quality used for sample rate conversion
|
||||||
SrcQuality src_quality;
|
SrcQuality src_quality;
|
||||||
/// Mix buffer index for decoded samples
|
/// Mix buffer index for decoded samples
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
/// Flags to control decoding (see AudioCore::AudioRenderer::VoiceInfo::Flags)
|
/// Flags to control decoding (see AudioCore::Renderer::VoiceInfo::Flags)
|
||||||
u16 flags;
|
u16 flags;
|
||||||
/// Wavebuffer sample rate
|
/// Wavebuffer sample rate
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
|
@ -73,14 +74,14 @@ struct PcmFloatDataSourceVersion2Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -88,13 +89,13 @@ struct PcmFloatDataSourceVersion2Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Quality used for sample rate conversion
|
/// Quality used for sample rate conversion
|
||||||
SrcQuality src_quality;
|
SrcQuality src_quality;
|
||||||
/// Mix buffer index for decoded samples
|
/// Mix buffer index for decoded samples
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
/// Flags to control decoding (see AudioCore::AudioRenderer::VoiceInfo::Flags)
|
/// Flags to control decoding (see AudioCore::Renderer::VoiceInfo::Flags)
|
||||||
u16 flags;
|
u16 flags;
|
||||||
/// Wavebuffer sample rate
|
/// Wavebuffer sample rate
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
|
@ -110,4 +111,4 @@ struct PcmFloatDataSourceVersion2Command : ICommand {
|
||||||
CpuAddr voice_state;
|
CpuAddr voice_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#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/data_source/decode.h"
|
#include "audio_core/renderer/command/data_source/decode.h"
|
||||||
#include "audio_core/renderer/command/data_source/pcm_int16.h"
|
#include "audio_core/renderer/command/data_source/pcm_int16.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void PcmInt16DataSourceVersion1Command::Dump(const ADSP::CommandListProcessor& processor,
|
void PcmInt16DataSourceVersion1Command::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string +=
|
string +=
|
||||||
fmt::format("PcmInt16DataSourceVersion1Command\n\toutput_index {:02X} channel {} "
|
fmt::format("PcmInt16DataSourceVersion1Command\n\toutput_index {:02X} channel {} "
|
||||||
|
@ -18,7 +18,8 @@ void PcmInt16DataSourceVersion1Command::Dump(const ADSP::CommandListProcessor& p
|
||||||
processor.target_sample_rate, src_quality);
|
processor.target_sample_rate, src_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmInt16DataSourceVersion1Command::Process(const ADSP::CommandListProcessor& processor) {
|
void PcmInt16DataSourceVersion1Command::Process(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
|
|
||||||
|
@ -43,11 +44,12 @@ void PcmInt16DataSourceVersion1Command::Process(const ADSP::CommandListProcessor
|
||||||
DecodeFromWaveBuffers(*processor.memory, args);
|
DecodeFromWaveBuffers(*processor.memory, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PcmInt16DataSourceVersion1Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool PcmInt16DataSourceVersion1Command::Verify(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmInt16DataSourceVersion2Command::Dump(const ADSP::CommandListProcessor& processor,
|
void PcmInt16DataSourceVersion2Command::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string +=
|
string +=
|
||||||
fmt::format("PcmInt16DataSourceVersion2Command\n\toutput_index {:02X} channel {} "
|
fmt::format("PcmInt16DataSourceVersion2Command\n\toutput_index {:02X} channel {} "
|
||||||
|
@ -56,7 +58,8 @@ void PcmInt16DataSourceVersion2Command::Dump(const ADSP::CommandListProcessor& p
|
||||||
processor.target_sample_rate, src_quality);
|
processor.target_sample_rate, src_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmInt16DataSourceVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
|
void PcmInt16DataSourceVersion2Command::Process(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
DecodeFromWaveBuffersArgs args{
|
DecodeFromWaveBuffersArgs args{
|
||||||
|
@ -80,8 +83,9 @@ void PcmInt16DataSourceVersion2Command::Process(const ADSP::CommandListProcessor
|
||||||
DecodeFromWaveBuffers(*processor.memory, args);
|
DecodeFromWaveBuffers(*processor.memory, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PcmInt16DataSourceVersion2Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool PcmInt16DataSourceVersion2Command::Verify(
|
||||||
|
const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command to decode PCM s16-encoded version 1 wavebuffers
|
* AudioRenderer command to decode PCM s16-encoded version 1 wavebuffers
|
||||||
* into the output_index mix buffer.
|
* into the output_index mix buffer.
|
||||||
|
@ -25,14 +26,14 @@ struct PcmInt16DataSourceVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,13 +41,13 @@ struct PcmInt16DataSourceVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Quality used for sample rate conversion
|
/// Quality used for sample rate conversion
|
||||||
SrcQuality src_quality;
|
SrcQuality src_quality;
|
||||||
/// Mix buffer index for decoded samples
|
/// Mix buffer index for decoded samples
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
/// Flags to control decoding (see AudioCore::AudioRenderer::VoiceInfo::Flags)
|
/// Flags to control decoding (see AudioCore::Renderer::VoiceInfo::Flags)
|
||||||
u16 flags;
|
u16 flags;
|
||||||
/// Wavebuffer sample rate
|
/// Wavebuffer sample rate
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
|
@ -72,26 +73,26 @@ struct PcmInt16DataSourceVersion2Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Quality used for sample rate conversion
|
/// Quality used for sample rate conversion
|
||||||
SrcQuality src_quality;
|
SrcQuality src_quality;
|
||||||
/// Mix buffer index for decoded samples
|
/// Mix buffer index for decoded samples
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
/// Flags to control decoding (see AudioCore::AudioRenderer::VoiceInfo::Flags)
|
/// Flags to control decoding (see AudioCore::Renderer::VoiceInfo::Flags)
|
||||||
u16 flags;
|
u16 flags;
|
||||||
/// Wavebuffer sample rate
|
/// Wavebuffer sample rate
|
||||||
u32 sample_rate;
|
u32 sample_rate;
|
||||||
|
@ -107,4 +108,4 @@ struct PcmInt16DataSourceVersion2Command : ICommand {
|
||||||
CpuAddr voice_state;
|
CpuAddr voice_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/effect/aux_.h"
|
#include "audio_core/renderer/command/effect/aux_.h"
|
||||||
#include "audio_core/renderer/effect/aux_.h"
|
#include "audio_core/renderer/effect/aux_.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Reset an AuxBuffer.
|
* Reset an AuxBuffer.
|
||||||
*
|
*
|
||||||
|
@ -175,13 +175,13 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
|
||||||
return read_count_;
|
return read_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void AuxCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("AuxCommand\n\tenabled {} input {:02X} output {:02X}\n", effect_enabled,
|
string += fmt::format("AuxCommand\n\tenabled {} input {:02X} output {:02X}\n", effect_enabled,
|
||||||
input, output);
|
input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuxCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void AuxCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto input_buffer{
|
auto input_buffer{
|
||||||
processor.mix_buffers.subspan(input * processor.sample_count, processor.sample_count)};
|
processor.mix_buffers.subspan(input * processor.sample_count, processor.sample_count)};
|
||||||
auto output_buffer{
|
auto output_buffer{
|
||||||
|
@ -208,8 +208,8 @@ void AuxCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuxCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool AuxCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command to read and write an auxiliary buffer, writing the input mix buffer to game
|
* AudioRenderer command to read and write an auxiliary buffer, writing the input mix buffer to game
|
||||||
* memory, and reading into the output buffer from game memory.
|
* memory, and reading into the output buffer from game memory.
|
||||||
|
@ -24,14 +25,14 @@ struct AuxCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct AuxCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer index
|
/// Input mix buffer index
|
||||||
s16 input;
|
s16 input;
|
||||||
|
@ -63,4 +64,4 @@ struct AuxCommand : ICommand {
|
||||||
bool effect_enabled;
|
bool effect_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/effect/biquad_filter.h"
|
#include "audio_core/renderer/command/effect/biquad_filter.h"
|
||||||
#include "audio_core/renderer/voice/voice_state.h"
|
#include "audio_core/renderer/voice/voice_state.h"
|
||||||
#include "common/bit_cast.h"
|
#include "common/bit_cast.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Biquad filter float implementation.
|
* Biquad filter float implementation.
|
||||||
*
|
*
|
||||||
|
@ -76,14 +76,14 @@ static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> inp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiquadFilterCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void BiquadFilterCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format(
|
string += fmt::format(
|
||||||
"BiquadFilterCommand\n\tinput {:02X} output {:02X} needs_init {} use_float_processing {}\n",
|
"BiquadFilterCommand\n\tinput {:02X} output {:02X} needs_init {} use_float_processing {}\n",
|
||||||
input, output, needs_init, use_float_processing);
|
input, output, needs_init, use_float_processing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiquadFilterCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void BiquadFilterCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto state_{reinterpret_cast<VoiceState::BiquadFilterState*>(state)};
|
auto state_{reinterpret_cast<VoiceState::BiquadFilterState*>(state)};
|
||||||
if (needs_init) {
|
if (needs_init) {
|
||||||
*state_ = {};
|
*state_ = {};
|
||||||
|
@ -103,8 +103,8 @@ void BiquadFilterCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BiquadFilterCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool BiquadFilterCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/voice/voice_state.h"
|
#include "audio_core/renderer/voice/voice_state.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for applying a biquad filter to the input mix buffer, saving the results to
|
* AudioRenderer command for applying a biquad filter to the input mix buffer, saving the results to
|
||||||
* the output mix buffer.
|
* the output mix buffer.
|
||||||
|
@ -26,14 +27,14 @@ struct BiquadFilterCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -41,7 +42,7 @@ struct BiquadFilterCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer index
|
/// Input mix buffer index
|
||||||
s16 input;
|
s16 input;
|
||||||
|
@ -71,4 +72,4 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
|
||||||
std::array<s16, 3>& b, std::array<s16, 2>& a,
|
std::array<s16, 3>& b, std::array<s16, 2>& a,
|
||||||
VoiceState::BiquadFilterState& state, const u32 sample_count);
|
VoiceState::BiquadFilterState& state, const u32 sample_count);
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/effect/capture.h"
|
#include "audio_core/renderer/command/effect/capture.h"
|
||||||
#include "audio_core/renderer/effect/aux_.h"
|
#include "audio_core/renderer/effect/aux_.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Reset an AuxBuffer.
|
* Reset an AuxBuffer.
|
||||||
*
|
*
|
||||||
|
@ -118,13 +118,13 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
|
||||||
return write_count_;
|
return write_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void CaptureCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("CaptureCommand\n\tenabled {} input {:02X} output {:02X}", effect_enabled,
|
string += fmt::format("CaptureCommand\n\tenabled {} input {:02X} output {:02X}", effect_enabled,
|
||||||
input, output);
|
input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void CaptureCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
if (effect_enabled) {
|
if (effect_enabled) {
|
||||||
auto input_buffer{
|
auto input_buffer{
|
||||||
processor.mix_buffers.subspan(input * processor.sample_count, processor.sample_count)};
|
processor.mix_buffers.subspan(input * processor.sample_count, processor.sample_count)};
|
||||||
|
@ -135,8 +135,8 @@ void CaptureCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CaptureCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool CaptureCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for capturing a mix buffer. That is, writing it back to a given game memory
|
* AudioRenderer command for capturing a mix buffer. That is, writing it back to a given game memory
|
||||||
* address.
|
* address.
|
||||||
|
@ -24,14 +25,14 @@ struct CaptureCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct CaptureCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer index
|
/// Input mix buffer index
|
||||||
s16 input;
|
s16 input;
|
||||||
|
@ -59,4 +60,4 @@ struct CaptureCommand : ICommand {
|
||||||
bool effect_enabled;
|
bool effect_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#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/effect/compressor.h"
|
#include "audio_core/renderer/command/effect/compressor.h"
|
||||||
#include "audio_core/renderer/effect/compressor.h"
|
#include "audio_core/renderer/effect/compressor.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
static void SetCompressorEffectParameter(const CompressorInfo::ParameterVersion2& params,
|
static void SetCompressorEffectParameter(const CompressorInfo::ParameterVersion2& params,
|
||||||
CompressorInfo::State& state) {
|
CompressorInfo::State& state) {
|
||||||
|
@ -110,7 +110,7 @@ static void ApplyCompressorEffect(const CompressorInfo::ParameterVersion2& param
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompressorCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void CompressorCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("CompressorCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
|
string += fmt::format("CompressorCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
|
||||||
for (s16 i = 0; i < parameter.channel_count; i++) {
|
for (s16 i = 0; i < parameter.channel_count; i++) {
|
||||||
|
@ -123,7 +123,7 @@ void CompressorCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompressorCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void CompressorCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
||||||
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
||||||
|
|
||||||
|
@ -148,8 +148,8 @@ void CompressorCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompressorCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool CompressorCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/effect/compressor.h"
|
#include "audio_core/renderer/effect/compressor.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for limiting volume between a high and low threshold.
|
* AudioRenderer command for limiting volume between a high and low threshold.
|
||||||
* Version 1.
|
* Version 1.
|
||||||
|
@ -26,14 +27,14 @@ struct CompressorCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -41,7 +42,7 @@ struct CompressorCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -57,4 +58,4 @@ struct CompressorCommand : ICommand {
|
||||||
bool effect_enabled;
|
bool effect_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/effect/delay.h"
|
#include "audio_core/renderer/command/effect/delay.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Update the DelayInfo state according to the given parameters.
|
* Update the DelayInfo state according to the given parameters.
|
||||||
*
|
*
|
||||||
|
@ -194,7 +194,7 @@ static void ApplyDelayEffect(const DelayInfo::ParameterVersion1& params, DelayIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelayCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void DelayCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("DelayCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
|
string += fmt::format("DelayCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
|
||||||
for (u32 i = 0; i < MaxChannels; i++) {
|
for (u32 i = 0; i < MaxChannels; i++) {
|
||||||
|
@ -207,7 +207,7 @@ void DelayCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proce
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelayCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void DelayCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
||||||
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
||||||
|
|
||||||
|
@ -231,8 +231,8 @@ void DelayCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DelayCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool DelayCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/effect/delay.h"
|
#include "audio_core/renderer/effect/delay.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for a delay effect. Delays inputs mix buffers according to the parameters
|
* AudioRenderer command for a delay effect. Delays inputs mix buffers according to the parameters
|
||||||
* and state, outputs receives the delayed samples.
|
* and state, outputs receives the delayed samples.
|
||||||
|
@ -26,14 +27,14 @@ struct DelayCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -41,7 +42,7 @@ struct DelayCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -57,4 +58,4 @@ struct DelayCommand : ICommand {
|
||||||
bool effect_enabled;
|
bool effect_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
|
|
||||||
#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/effect/i3dl2_reverb.h"
|
#include "audio_core/renderer/command/effect/i3dl2_reverb.h"
|
||||||
#include "common/polyfill_ranges.h"
|
#include "common/polyfill_ranges.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
constexpr std::array<f32, I3dl2ReverbInfo::MaxDelayLines> MinDelayLineTimes{
|
constexpr std::array<f32, I3dl2ReverbInfo::MaxDelayLines> MinDelayLineTimes{
|
||||||
5.0f,
|
5.0f,
|
||||||
|
@ -394,7 +394,7 @@ static void ApplyI3dl2ReverbEffect(const I3dl2ReverbInfo::ParameterVersion1& par
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I3dl2ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void I3dl2ReverbCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("I3dl2ReverbCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
|
string += fmt::format("I3dl2ReverbCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
|
||||||
for (u32 i = 0; i < parameter.channel_count; i++) {
|
for (u32 i = 0; i < parameter.channel_count; i++) {
|
||||||
|
@ -407,7 +407,7 @@ void I3dl2ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void I3dl2ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void I3dl2ReverbCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
||||||
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
||||||
|
|
||||||
|
@ -431,8 +431,8 @@ void I3dl2ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I3dl2ReverbCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool I3dl2ReverbCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/effect/i3dl2.h"
|
#include "audio_core/renderer/effect/i3dl2.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for a I3DL2Reverb effect. Apply a reverb to inputs mix buffer according to
|
* AudioRenderer command for a I3DL2Reverb effect. Apply a reverb to inputs mix buffer according to
|
||||||
* the I3DL2 spec, outputs receives the results.
|
* the I3DL2 spec, outputs receives the results.
|
||||||
|
@ -26,14 +27,14 @@ struct I3dl2ReverbCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -41,7 +42,7 @@ struct I3dl2ReverbCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -57,4 +58,4 @@ struct I3dl2ReverbCommand : ICommand {
|
||||||
bool effect_enabled;
|
bool effect_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/effect/light_limiter.h"
|
#include "audio_core/renderer/command/effect/light_limiter.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Update the LightLimiterInfo state according to the given parameters.
|
* Update the LightLimiterInfo state according to the given parameters.
|
||||||
* A no-op.
|
* A no-op.
|
||||||
|
@ -133,8 +133,8 @@ static void ApplyLightLimiterEffect(const LightLimiterInfo::ParameterVersion2& p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightLimiterVersion1Command::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void LightLimiterVersion1Command::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("LightLimiterVersion1Command\n\tinputs: ");
|
string += fmt::format("LightLimiterVersion1Command\n\tinputs: ");
|
||||||
for (u32 i = 0; i < MaxChannels; i++) {
|
for (u32 i = 0; i < MaxChannels; i++) {
|
||||||
string += fmt::format("{:02X}, ", inputs[i]);
|
string += fmt::format("{:02X}, ", inputs[i]);
|
||||||
|
@ -146,7 +146,7 @@ void LightLimiterVersion1Command::Dump([[maybe_unused]] const ADSP::CommandListP
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightLimiterVersion1Command::Process(const ADSP::CommandListProcessor& processor) {
|
void LightLimiterVersion1Command::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
||||||
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
||||||
|
|
||||||
|
@ -172,12 +172,12 @@ void LightLimiterVersion1Command::Process(const ADSP::CommandListProcessor& proc
|
||||||
processor.sample_count, statistics);
|
processor.sample_count, statistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LightLimiterVersion1Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool LightLimiterVersion1Command::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightLimiterVersion2Command::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void LightLimiterVersion2Command::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("LightLimiterVersion2Command\n\tinputs: \n");
|
string += fmt::format("LightLimiterVersion2Command\n\tinputs: \n");
|
||||||
for (u32 i = 0; i < MaxChannels; i++) {
|
for (u32 i = 0; i < MaxChannels; i++) {
|
||||||
string += fmt::format("{:02X}, ", inputs[i]);
|
string += fmt::format("{:02X}, ", inputs[i]);
|
||||||
|
@ -189,7 +189,7 @@ void LightLimiterVersion2Command::Dump([[maybe_unused]] const ADSP::CommandListP
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightLimiterVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
|
void LightLimiterVersion2Command::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
||||||
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
||||||
|
|
||||||
|
@ -215,8 +215,8 @@ void LightLimiterVersion2Command::Process(const ADSP::CommandListProcessor& proc
|
||||||
processor.sample_count, statistics);
|
processor.sample_count, statistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LightLimiterVersion2Command::Verify(const ADSP::CommandListProcessor& processor) {
|
bool LightLimiterVersion2Command::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/effect/light_limiter.h"
|
#include "audio_core/renderer/effect/light_limiter.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for limiting volume between a high and low threshold.
|
* AudioRenderer command for limiting volume between a high and low threshold.
|
||||||
* Version 1.
|
* Version 1.
|
||||||
|
@ -26,14 +27,14 @@ struct LightLimiterVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -41,7 +42,7 @@ struct LightLimiterVersion1Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -68,21 +69,21 @@ struct LightLimiterVersion2Command : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -100,4 +101,4 @@ struct LightLimiterVersion2Command : ICommand {
|
||||||
bool effect_enabled;
|
bool effect_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/effect/biquad_filter.h"
|
#include "audio_core/renderer/command/effect/biquad_filter.h"
|
||||||
#include "audio_core/renderer/command/effect/multi_tap_biquad_filter.h"
|
#include "audio_core/renderer/command/effect/multi_tap_biquad_filter.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void MultiTapBiquadFilterCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void MultiTapBiquadFilterCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format(
|
string += fmt::format(
|
||||||
"MultiTapBiquadFilterCommand\n\tinput {:02X}\n\toutput {:02X}\n\tneeds_init ({}, {})\n",
|
"MultiTapBiquadFilterCommand\n\tinput {:02X}\n\toutput {:02X}\n\tneeds_init ({}, {})\n",
|
||||||
input, output, needs_init[0], needs_init[1]);
|
input, output, needs_init[0], needs_init[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiTapBiquadFilterCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void MultiTapBiquadFilterCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
if (filter_tap_count > MaxBiquadFilters) {
|
if (filter_tap_count > MaxBiquadFilters) {
|
||||||
LOG_ERROR(Service_Audio, "Too many filter taps! {}", filter_tap_count);
|
LOG_ERROR(Service_Audio, "Too many filter taps! {}", filter_tap_count);
|
||||||
filter_tap_count = MaxBiquadFilters;
|
filter_tap_count = MaxBiquadFilters;
|
||||||
|
@ -38,8 +38,8 @@ void MultiTapBiquadFilterCommand::Process(const ADSP::CommandListProcessor& proc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiTapBiquadFilterCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool MultiTapBiquadFilterCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/voice/voice_info.h"
|
#include "audio_core/renderer/voice/voice_info.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for applying multiple biquads at once.
|
* AudioRenderer command for applying multiple biquads at once.
|
||||||
*/
|
*/
|
||||||
|
@ -25,14 +26,14 @@ struct MultiTapBiquadFilterCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,7 +41,7 @@ struct MultiTapBiquadFilterCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer index
|
/// Input mix buffer index
|
||||||
s16 input;
|
s16 input;
|
||||||
|
@ -56,4 +57,4 @@ struct MultiTapBiquadFilterCommand : ICommand {
|
||||||
u8 filter_tap_count;
|
u8 filter_tap_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
#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/effect/reverb.h"
|
#include "audio_core/renderer/command/effect/reverb.h"
|
||||||
#include "common/polyfill_ranges.h"
|
#include "common/polyfill_ranges.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
constexpr std::array<f32, ReverbInfo::MaxDelayLines> FdnMaxDelayLineTimes = {
|
constexpr std::array<f32, ReverbInfo::MaxDelayLines> FdnMaxDelayLineTimes = {
|
||||||
53.9532470703125f,
|
53.9532470703125f,
|
||||||
|
@ -396,7 +396,7 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void ReverbCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format(
|
string += fmt::format(
|
||||||
"ReverbCommand\n\tenabled {} long_size_pre_delay_supported {}\n\tinputs: ", effect_enabled,
|
"ReverbCommand\n\tenabled {} long_size_pre_delay_supported {}\n\tinputs: ", effect_enabled,
|
||||||
|
@ -411,7 +411,7 @@ void ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proc
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void ReverbCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
std::array<std::span<const s32>, MaxChannels> input_buffers{};
|
||||||
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
std::array<std::span<s32>, MaxChannels> output_buffers{};
|
||||||
|
|
||||||
|
@ -435,8 +435,8 @@ void ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
processor.sample_count);
|
processor.sample_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReverbCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool ReverbCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/effect/reverb.h"
|
#include "audio_core/renderer/effect/reverb.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for a Reverb effect. Apply a reverb to inputs mix buffer, outputs receives
|
* AudioRenderer command for a Reverb effect. Apply a reverb to inputs mix buffer, outputs receives
|
||||||
* the results.
|
* the results.
|
||||||
|
@ -26,14 +27,14 @@ struct ReverbCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -41,7 +42,7 @@ struct ReverbCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -59,4 +60,4 @@ struct ReverbCommand : ICommand {
|
||||||
bool long_size_pre_delay_supported;
|
bool long_size_pre_delay_supported;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,14 +3,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "audio_core/common/common.h"
|
#include "audio_core/common/common.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
using namespace ::AudioCore::ADSP;
|
||||||
|
|
||||||
enum class CommandId : u8 {
|
enum class CommandId : u8 {
|
||||||
/* 0x00 */ Invalid,
|
/* 0x00 */ Invalid,
|
||||||
/* 0x01 */ DataSourcePcmInt16Version1,
|
/* 0x01 */ DataSourcePcmInt16Version1,
|
||||||
|
@ -59,14 +63,15 @@ struct ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
virtual void Dump(const ADSP::CommandListProcessor& processor, std::string& string) = 0;
|
virtual void Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
|
std::string& string) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
virtual void Process(const ADSP::CommandListProcessor& processor) = 0;
|
virtual void Process(const AudioRenderer::CommandListProcessor& processor) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -74,7 +79,7 @@ struct ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
virtual bool Verify(const ADSP::CommandListProcessor& processor) = 0;
|
virtual bool Verify(const AudioRenderer::CommandListProcessor& processor) = 0;
|
||||||
|
|
||||||
/// Command magic 0xCAFEBABE
|
/// Command magic 0xCAFEBABE
|
||||||
u32 magic{};
|
u32 magic{};
|
||||||
|
@ -90,4 +95,4 @@ struct ICommand {
|
||||||
u32 node_id{};
|
u32 node_id{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,22 +3,22 @@
|
||||||
|
|
||||||
#include <string>
|
#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/mix/clear_mix.h"
|
#include "audio_core/renderer/command/mix/clear_mix.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void ClearMixBufferCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void ClearMixBufferCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("ClearMixBufferCommand\n");
|
string += fmt::format("ClearMixBufferCommand\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearMixBufferCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void ClearMixBufferCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
memset(processor.mix_buffers.data(), 0, processor.mix_buffers.size_bytes());
|
memset(processor.mix_buffers.data(), 0, processor.mix_buffers.size_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClearMixBufferCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool ClearMixBufferCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for a clearing the mix buffers.
|
* AudioRenderer command for a clearing the mix buffers.
|
||||||
* Used at the start of each command list.
|
* Used at the start of each command list.
|
||||||
|
@ -24,14 +25,14 @@ struct ClearMixBufferCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct ClearMixBufferCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/mix/copy_mix.h"
|
#include "audio_core/renderer/command/mix/copy_mix.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void CopyMixBufferCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void CopyMixBufferCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("CopyMixBufferCommand\n\tinput {:02X} output {:02X}\n", input_index,
|
string += fmt::format("CopyMixBufferCommand\n\tinput {:02X} output {:02X}\n", input_index,
|
||||||
output_index);
|
output_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyMixBufferCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void CopyMixBufferCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count)};
|
processor.sample_count)};
|
||||||
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
||||||
|
@ -20,8 +20,8 @@ void CopyMixBufferCommand::Process(const ADSP::CommandListProcessor& processor)
|
||||||
std::memcpy(output.data(), input.data(), processor.sample_count * sizeof(s32));
|
std::memcpy(output.data(), input.data(), processor.sample_count * sizeof(s32));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CopyMixBufferCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool CopyMixBufferCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for a copying a mix buffer from input to output.
|
* AudioRenderer command for a copying a mix buffer from input to output.
|
||||||
*/
|
*/
|
||||||
|
@ -23,14 +24,14 @@ struct CopyMixBufferCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -38,7 +39,7 @@ struct CopyMixBufferCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer index
|
/// Input mix buffer index
|
||||||
s16 input_index;
|
s16 input_index;
|
||||||
|
@ -46,4 +47,4 @@ struct CopyMixBufferCommand : ICommand {
|
||||||
s16 output_index;
|
s16 output_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "audio_core/adsp/apps/audio_renderer/command_list_processor.h"
|
||||||
#include "audio_core/common/common.h"
|
#include "audio_core/common/common.h"
|
||||||
#include "audio_core/renderer/adsp/command_list_processor.h"
|
|
||||||
#include "audio_core/renderer/command/mix/depop_for_mix_buffers.h"
|
#include "audio_core/renderer/command/mix/depop_for_mix_buffers.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Apply depopping. Add the depopped sample to each incoming new sample, decaying it each time
|
* Apply depopping. Add the depopped sample to each incoming new sample, decaying it each time
|
||||||
* according to decay.
|
* according to decay.
|
||||||
|
@ -36,13 +36,13 @@ static s32 ApplyDepopMix(std::span<s32> output, const s32 depop_sample,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepopForMixBuffersCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void DepopForMixBuffersCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("DepopForMixBuffersCommand\n\tinput {:02X} count {} decay {}\n", input,
|
string += fmt::format("DepopForMixBuffersCommand\n\tinput {:02X} count {} decay {}\n", input,
|
||||||
count, decay.to_float());
|
count, decay.to_float());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepopForMixBuffersCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void DepopForMixBuffersCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto end_index{std::min(processor.buffer_count, input + count)};
|
auto end_index{std::min(processor.buffer_count, input + count)};
|
||||||
std::span<s32> depop_buff{reinterpret_cast<s32*>(depop_buffer), end_index};
|
std::span<s32> depop_buff{reinterpret_cast<s32*>(depop_buffer), end_index};
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ void DepopForMixBuffersCommand::Process(const ADSP::CommandListProcessor& proces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepopForMixBuffersCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool DepopForMixBuffersCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for depopping a mix buffer.
|
* AudioRenderer command for depopping a mix buffer.
|
||||||
* Adds a cumulation of previous samples to the current mix buffer with a decay.
|
* Adds a cumulation of previous samples to the current mix buffer with a decay.
|
||||||
|
@ -25,14 +26,14 @@ struct DepopForMixBuffersCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,7 +41,7 @@ struct DepopForMixBuffersCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Starting input mix buffer index
|
/// Starting input mix buffer index
|
||||||
u32 input;
|
u32 input;
|
||||||
|
@ -52,4 +53,4 @@ struct DepopForMixBuffersCommand : ICommand {
|
||||||
CpuAddr depop_buffer;
|
CpuAddr depop_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/mix/depop_prepare.h"
|
#include "audio_core/renderer/command/mix/depop_prepare.h"
|
||||||
#include "audio_core/renderer/voice/voice_state.h"
|
#include "audio_core/renderer/voice/voice_state.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void DepopPrepareCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void DepopPrepareCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("DepopPrepareCommand\n\tinputs: ");
|
string += fmt::format("DepopPrepareCommand\n\tinputs: ");
|
||||||
for (u32 i = 0; i < buffer_count; i++) {
|
for (u32 i = 0; i < buffer_count; i++) {
|
||||||
string += fmt::format("{:02X}, ", inputs[i]);
|
string += fmt::format("{:02X}, ", inputs[i]);
|
||||||
|
@ -17,7 +17,7 @@ void DepopPrepareCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepopPrepareCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void DepopPrepareCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto samples{reinterpret_cast<s32*>(previous_samples)};
|
auto samples{reinterpret_cast<s32*>(previous_samples)};
|
||||||
auto buffer{reinterpret_cast<s32*>(depop_buffer)};
|
auto buffer{reinterpret_cast<s32*>(depop_buffer)};
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ void DepopPrepareCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepopPrepareCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool DepopPrepareCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for preparing depop.
|
* AudioRenderer command for preparing depop.
|
||||||
* Adds the previusly output last samples to the depop buffer.
|
* Adds the previusly output last samples to the depop buffer.
|
||||||
|
@ -24,14 +25,14 @@ struct DepopPrepareCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct DepopPrepareCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Depop buffer offset for each mix buffer
|
/// Depop buffer offset for each mix buffer
|
||||||
std::array<s16, MaxMixBuffers> inputs;
|
std::array<s16, MaxMixBuffers> inputs;
|
||||||
|
@ -51,4 +52,4 @@ struct DepopPrepareCommand : ICommand {
|
||||||
CpuAddr depop_buffer;
|
CpuAddr depop_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#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/mix/mix.h"
|
#include "audio_core/renderer/command/mix/mix.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Mix input mix buffer into output mix buffer, with volume applied to the input.
|
* Mix input mix buffer into output mix buffer, with volume applied to the input.
|
||||||
*
|
*
|
||||||
|
@ -28,7 +28,7 @@ static void ApplyMix(std::span<s32> output, std::span<const s32> input, const f3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void MixCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("MixCommand");
|
string += fmt::format("MixCommand");
|
||||||
string += fmt::format("\n\tinput {:02X}", input_index);
|
string += fmt::format("\n\tinput {:02X}", input_index);
|
||||||
|
@ -37,7 +37,7 @@ void MixCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& process
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void MixCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count)};
|
processor.sample_count)};
|
||||||
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
||||||
|
@ -63,8 +63,8 @@ void MixCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MixCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool MixCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for mixing an input mix buffer to an output mix buffer, with a volume
|
* AudioRenderer command for mixing an input mix buffer to an output mix buffer, with a volume
|
||||||
* applied to the input.
|
* applied to the input.
|
||||||
|
@ -24,14 +25,14 @@ struct MixCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct MixCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Fixed point precision
|
/// Fixed point precision
|
||||||
u8 precision;
|
u8 precision;
|
||||||
|
@ -51,4 +52,4 @@ struct MixCommand : ICommand {
|
||||||
f32 volume;
|
f32 volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/mix/mix_ramp.h"
|
#include "audio_core/renderer/command/mix/mix_ramp.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
template <size_t Q>
|
template <size_t Q>
|
||||||
s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, const f32 volume_,
|
s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, const f32 volume_,
|
||||||
|
@ -33,7 +33,8 @@ s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, const f32 vo
|
||||||
template s32 ApplyMixRamp<15>(std::span<s32>, std::span<const s32>, f32, f32, u32);
|
template s32 ApplyMixRamp<15>(std::span<s32>, std::span<const s32>, f32, f32, u32);
|
||||||
template s32 ApplyMixRamp<23>(std::span<s32>, std::span<const s32>, f32, f32, u32);
|
template s32 ApplyMixRamp<23>(std::span<s32>, std::span<const s32>, f32, f32, u32);
|
||||||
|
|
||||||
void MixRampCommand::Dump(const ADSP::CommandListProcessor& processor, std::string& string) {
|
void MixRampCommand::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
|
std::string& string) {
|
||||||
const auto ramp{(volume - prev_volume) / static_cast<f32>(processor.sample_count)};
|
const auto ramp{(volume - prev_volume) / static_cast<f32>(processor.sample_count)};
|
||||||
string += fmt::format("MixRampCommand");
|
string += fmt::format("MixRampCommand");
|
||||||
string += fmt::format("\n\tinput {:02X}", input_index);
|
string += fmt::format("\n\tinput {:02X}", input_index);
|
||||||
|
@ -44,7 +45,7 @@ void MixRampCommand::Dump(const ADSP::CommandListProcessor& processor, std::stri
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixRampCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void MixRampCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count)};
|
processor.sample_count)};
|
||||||
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
||||||
|
@ -75,8 +76,8 @@ void MixRampCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MixRampCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool MixRampCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for mixing an input mix buffer to an output mix buffer, with a volume
|
* AudioRenderer command for mixing an input mix buffer to an output mix buffer, with a volume
|
||||||
* applied to the input, and volume ramping to smooth out the transition.
|
* applied to the input, and volume ramping to smooth out the transition.
|
||||||
|
@ -25,14 +26,14 @@ struct MixRampCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,7 +41,7 @@ struct MixRampCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Fixed point precision
|
/// Fixed point precision
|
||||||
u8 precision;
|
u8 precision;
|
||||||
|
@ -70,4 +71,4 @@ template <size_t Q>
|
||||||
s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, f32 volume_, f32 ramp_,
|
s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, f32 volume_, f32 ramp_,
|
||||||
u32 sample_count);
|
u32 sample_count);
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/mix/mix_ramp.h"
|
#include "audio_core/renderer/command/mix/mix_ramp.h"
|
||||||
#include "audio_core/renderer/command/mix/mix_ramp_grouped.h"
|
#include "audio_core/renderer/command/mix/mix_ramp_grouped.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void MixRampGroupedCommand::Dump(const ADSP::CommandListProcessor& processor, std::string& string) {
|
void MixRampGroupedCommand::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
|
std::string& string) {
|
||||||
string += "MixRampGroupedCommand";
|
string += "MixRampGroupedCommand";
|
||||||
for (u32 i = 0; i < buffer_count; i++) {
|
for (u32 i = 0; i < buffer_count; i++) {
|
||||||
string += fmt::format("\n\t{}", i);
|
string += fmt::format("\n\t{}", i);
|
||||||
|
@ -21,7 +22,7 @@ void MixRampGroupedCommand::Dump(const ADSP::CommandListProcessor& processor, st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixRampGroupedCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void MixRampGroupedCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
std::span<s32> prev_samples = {reinterpret_cast<s32*>(previous_samples), MaxMixBuffers};
|
std::span<s32> prev_samples = {reinterpret_cast<s32*>(previous_samples), MaxMixBuffers};
|
||||||
|
|
||||||
for (u32 i = 0; i < buffer_count; i++) {
|
for (u32 i = 0; i < buffer_count; i++) {
|
||||||
|
@ -58,8 +59,8 @@ void MixRampGroupedCommand::Process(const ADSP::CommandListProcessor& processor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MixRampGroupedCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool MixRampGroupedCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for mixing multiple input mix buffers to multiple output mix buffers, with
|
* AudioRenderer command for mixing multiple input mix buffers to multiple output mix buffers, with
|
||||||
* a volume applied to the input, and volume ramping to smooth out the transition.
|
* a volume applied to the input, and volume ramping to smooth out the transition.
|
||||||
|
@ -25,14 +26,14 @@ struct MixRampGroupedCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,7 +41,7 @@ struct MixRampGroupedCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Fixed point precision
|
/// Fixed point precision
|
||||||
u8 precision;
|
u8 precision;
|
||||||
|
@ -58,4 +59,4 @@ struct MixRampGroupedCommand : ICommand {
|
||||||
CpuAddr previous_samples;
|
CpuAddr previous_samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/mix/volume.h"
|
#include "audio_core/renderer/command/mix/volume.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Apply volume to the input mix buffer, saving to the output buffer.
|
* Apply volume to the input mix buffer, saving to the output buffer.
|
||||||
*
|
*
|
||||||
|
@ -29,7 +29,7 @@ static void ApplyUniformGain(std::span<s32> output, std::span<const s32> input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void VolumeCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("VolumeCommand");
|
string += fmt::format("VolumeCommand");
|
||||||
string += fmt::format("\n\tinput {:02X}", input_index);
|
string += fmt::format("\n\tinput {:02X}", input_index);
|
||||||
|
@ -38,7 +38,7 @@ void VolumeCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proc
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void VolumeCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
// If input and output buffers are the same, and the volume is 1.0f, this won't do
|
// If input and output buffers are the same, and the volume is 1.0f, this won't do
|
||||||
// anything, so just skip.
|
// anything, so just skip.
|
||||||
if (input_index == output_index && volume == 1.0f) {
|
if (input_index == output_index && volume == 1.0f) {
|
||||||
|
@ -65,8 +65,8 @@ void VolumeCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VolumeCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool VolumeCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for applying volume to a mix buffer.
|
* AudioRenderer command for applying volume to a mix buffer.
|
||||||
*/
|
*/
|
||||||
|
@ -23,14 +24,14 @@ struct VolumeCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -38,7 +39,7 @@ struct VolumeCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Fixed point precision
|
/// Fixed point precision
|
||||||
u8 precision;
|
u8 precision;
|
||||||
|
@ -50,4 +51,4 @@ struct VolumeCommand : ICommand {
|
||||||
f32 volume;
|
f32 volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/mix/volume_ramp.h"
|
#include "audio_core/renderer/command/mix/volume_ramp.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Apply volume with ramping to the input mix buffer, saving to the output buffer.
|
* Apply volume with ramping to the input mix buffer, saving to the output buffer.
|
||||||
*
|
*
|
||||||
|
@ -38,7 +38,8 @@ static void ApplyLinearEnvelopeGain(std::span<s32> output, std::span<const s32>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeRampCommand::Dump(const ADSP::CommandListProcessor& processor, std::string& string) {
|
void VolumeRampCommand::Dump(const AudioRenderer::CommandListProcessor& processor,
|
||||||
|
std::string& string) {
|
||||||
const auto ramp{(volume - prev_volume) / static_cast<f32>(processor.sample_count)};
|
const auto ramp{(volume - prev_volume) / static_cast<f32>(processor.sample_count)};
|
||||||
string += fmt::format("VolumeRampCommand");
|
string += fmt::format("VolumeRampCommand");
|
||||||
string += fmt::format("\n\tinput {:02X}", input_index);
|
string += fmt::format("\n\tinput {:02X}", input_index);
|
||||||
|
@ -49,7 +50,7 @@ void VolumeRampCommand::Dump(const ADSP::CommandListProcessor& processor, std::s
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeRampCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void VolumeRampCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
auto output{processor.mix_buffers.subspan(output_index * processor.sample_count,
|
||||||
processor.sample_count)};
|
processor.sample_count)};
|
||||||
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
auto input{processor.mix_buffers.subspan(input_index * processor.sample_count,
|
||||||
|
@ -77,8 +78,8 @@ void VolumeRampCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VolumeRampCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool VolumeRampCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for applying volume to a mix buffer, with ramping for the volume to smooth
|
* AudioRenderer command for applying volume to a mix buffer, with ramping for the volume to smooth
|
||||||
* out the transition.
|
* out the transition.
|
||||||
|
@ -24,14 +25,14 @@ struct VolumeRampCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct VolumeRampCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Fixed point precision
|
/// Fixed point precision
|
||||||
u8 precision;
|
u8 precision;
|
||||||
|
@ -53,4 +54,4 @@ struct VolumeRampCommand : ICommand {
|
||||||
f32 volume;
|
f32 volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/performance/performance.h"
|
#include "audio_core/renderer/command/performance/performance.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void PerformanceCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void PerformanceCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("PerformanceCommand\n\tstate {}\n", static_cast<u32>(state));
|
string += fmt::format("PerformanceCommand\n\tstate {}\n", static_cast<u32>(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerformanceCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void PerformanceCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto base{entry_address.translated_address};
|
auto base{entry_address.translated_address};
|
||||||
if (state == PerformanceState::Start) {
|
if (state == PerformanceState::Start) {
|
||||||
auto start_time_ptr{reinterpret_cast<u32*>(base + entry_address.entry_start_time_offset)};
|
auto start_time_ptr{reinterpret_cast<u32*>(base + entry_address.entry_start_time_offset)};
|
||||||
*start_time_ptr =
|
*start_time_ptr =
|
||||||
static_cast<u32>(processor.system->CoreTiming().GetClockTicks() - processor.start_time -
|
static_cast<u32>(processor.system->CoreTiming().GetGlobalTimeUs().count() -
|
||||||
processor.current_processing_time);
|
processor.start_time - processor.current_processing_time);
|
||||||
} else if (state == PerformanceState::Stop) {
|
} else if (state == PerformanceState::Stop) {
|
||||||
auto processed_time_ptr{
|
auto processed_time_ptr{
|
||||||
reinterpret_cast<u32*>(base + entry_address.entry_processed_time_offset)};
|
reinterpret_cast<u32*>(base + entry_address.entry_processed_time_offset)};
|
||||||
|
@ -27,14 +27,14 @@ void PerformanceCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
reinterpret_cast<u32*>(base + entry_address.header_entry_count_offset)};
|
reinterpret_cast<u32*>(base + entry_address.header_entry_count_offset)};
|
||||||
|
|
||||||
*processed_time_ptr =
|
*processed_time_ptr =
|
||||||
static_cast<u32>(processor.system->CoreTiming().GetClockTicks() - processor.start_time -
|
static_cast<u32>(processor.system->CoreTiming().GetGlobalTimeUs().count() -
|
||||||
processor.current_processing_time);
|
processor.start_time - processor.current_processing_time);
|
||||||
(*entry_count_ptr)++;
|
(*entry_count_ptr)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PerformanceCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool PerformanceCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/performance/performance_manager.h"
|
#include "audio_core/renderer/performance/performance_manager.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for writing AudioRenderer performance metrics back to the sysmodule.
|
* AudioRenderer command for writing AudioRenderer performance metrics back to the sysmodule.
|
||||||
*/
|
*/
|
||||||
|
@ -25,14 +26,14 @@ struct PerformanceCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,7 +41,7 @@ struct PerformanceCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// State of the performance
|
/// State of the performance
|
||||||
PerformanceState state;
|
PerformanceState state;
|
||||||
|
@ -48,4 +49,4 @@ struct PerformanceCommand : ICommand {
|
||||||
PerformanceEntryAddresses entry_address;
|
PerformanceEntryAddresses entry_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#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/resample/downmix_6ch_to_2ch.h"
|
#include "audio_core/renderer/command/resample/downmix_6ch_to_2ch.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void DownMix6chTo2chCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void DownMix6chTo2chCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format("DownMix6chTo2chCommand\n\tinputs: ");
|
string += fmt::format("DownMix6chTo2chCommand\n\tinputs: ");
|
||||||
for (u32 i = 0; i < MaxChannels; i++) {
|
for (u32 i = 0; i < MaxChannels; i++) {
|
||||||
string += fmt::format("{:02X}, ", inputs[i]);
|
string += fmt::format("{:02X}, ", inputs[i]);
|
||||||
|
@ -19,7 +19,7 @@ void DownMix6chTo2chCommand::Dump([[maybe_unused]] const ADSP::CommandListProces
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownMix6chTo2chCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void DownMix6chTo2chCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
auto in_front_left{
|
auto in_front_left{
|
||||||
processor.mix_buffers.subspan(inputs[0] * processor.sample_count, processor.sample_count)};
|
processor.mix_buffers.subspan(inputs[0] * processor.sample_count, processor.sample_count)};
|
||||||
auto in_front_right{
|
auto in_front_right{
|
||||||
|
@ -67,8 +67,8 @@ void DownMix6chTo2chCommand::Process(const ADSP::CommandListProcessor& processor
|
||||||
std::memset(out_back_right.data(), 0, out_back_right.size_bytes());
|
std::memset(out_back_right.data(), 0, out_back_right.size_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DownMix6chTo2chCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool DownMix6chTo2chCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for downmixing 6 channels to 2.
|
* AudioRenderer command for downmixing 6 channels to 2.
|
||||||
* Channel layout (SMPTE):
|
* Channel layout (SMPTE):
|
||||||
|
@ -31,14 +32,14 @@ struct DownMix6chTo2chCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -46,7 +47,7 @@ struct DownMix6chTo2chCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Input mix buffer offsets for each channel
|
/// Input mix buffer offsets for each channel
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
|
@ -56,4 +57,4 @@ struct DownMix6chTo2chCommand : ICommand {
|
||||||
std::array<Common::FixedPoint<48, 16>, 4> down_mix_coeff;
|
std::array<Common::FixedPoint<48, 16>, 4> down_mix_coeff;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "audio_core/renderer/command/resample/resample.h"
|
#include "audio_core/renderer/command/resample/resample.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
static void ResampleLowQuality(std::span<s32> output, std::span<const s16> input,
|
static void ResampleLowQuality(std::span<s32> output, std::span<const s16> input,
|
||||||
const Common::FixedPoint<49, 15>& sample_rate_ratio,
|
const Common::FixedPoint<49, 15>& sample_rate_ratio,
|
||||||
|
@ -880,4 +880,4 @@ void Resample(std::span<s32> output, std::span<const s16> input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/fixed_point.h"
|
#include "common/fixed_point.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Resample an input buffer into an output buffer, according to the sample_rate_ratio.
|
* Resample an input buffer into an output buffer, according to the sample_rate_ratio.
|
||||||
*
|
*
|
||||||
|
@ -26,4 +26,4 @@ void Resample(std::span<s32> output, std::span<const s16> input,
|
||||||
const Common::FixedPoint<49, 15>& sample_rate_ratio,
|
const Common::FixedPoint<49, 15>& sample_rate_ratio,
|
||||||
Common::FixedPoint<49, 15>& fraction, u32 samples_to_write, SrcQuality src_quality);
|
Common::FixedPoint<49, 15>& fraction, u32 samples_to_write, SrcQuality src_quality);
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#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/resample/upsample.h"
|
#include "audio_core/renderer/command/resample/upsample.h"
|
||||||
#include "audio_core/renderer/upsampler/upsampler_info.h"
|
#include "audio_core/renderer/upsampler/upsampler_info.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Upsampling impl. Input must be 8K, 16K or 32K, output is 48K.
|
* Upsampling impl. Input must be 8K, 16K or 32K, output is 48K.
|
||||||
*
|
*
|
||||||
|
@ -198,7 +198,7 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto UpsampleCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
auto UpsampleCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) -> void {
|
std::string& string) -> void {
|
||||||
string += fmt::format("UpsampleCommand\n\tsource_sample_count {} source_sample_rate {}",
|
string += fmt::format("UpsampleCommand\n\tsource_sample_count {} source_sample_rate {}",
|
||||||
source_sample_count, source_sample_rate);
|
source_sample_count, source_sample_rate);
|
||||||
|
@ -213,7 +213,7 @@ auto UpsampleCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& pr
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpsampleCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void UpsampleCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
const auto info{reinterpret_cast<UpsamplerInfo*>(upsampler_info)};
|
const auto info{reinterpret_cast<UpsamplerInfo*>(upsampler_info)};
|
||||||
const auto input_count{std::min(info->input_count, buffer_count)};
|
const auto input_count{std::min(info->input_count, buffer_count)};
|
||||||
const std::span<const s16> inputs_{reinterpret_cast<const s16*>(inputs), input_count};
|
const std::span<const s16> inputs_{reinterpret_cast<const s16*>(inputs), input_count};
|
||||||
|
@ -234,8 +234,8 @@ void UpsampleCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpsampleCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool UpsampleCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for upsampling a mix buffer to 48Khz.
|
* AudioRenderer command for upsampling a mix buffer to 48Khz.
|
||||||
* Input must be 8Khz, 16Khz or 32Khz, and output will be 48Khz.
|
* Input must be 8Khz, 16Khz or 32Khz, and output will be 48Khz.
|
||||||
|
@ -24,14 +25,14 @@ struct UpsampleCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -39,7 +40,7 @@ struct UpsampleCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Pointer to the output samples buffer.
|
/// Pointer to the output samples buffer.
|
||||||
CpuAddr samples_buffer;
|
CpuAddr samples_buffer;
|
||||||
|
@ -57,4 +58,4 @@ struct UpsampleCommand : ICommand {
|
||||||
CpuAddr upsampler_info;
|
CpuAddr upsampler_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#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/sink/circular_buffer.h"
|
#include "audio_core/renderer/command/sink/circular_buffer.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void CircularBufferSinkCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void CircularBufferSinkCommand::Dump(
|
||||||
std::string& string) {
|
[[maybe_unused]] const AudioRenderer::CommandListProcessor& processor, std::string& string) {
|
||||||
string += fmt::format(
|
string += fmt::format(
|
||||||
"CircularBufferSinkCommand\n\tinput_count {} ring size {:04X} ring pos {:04X}\n\tinputs: ",
|
"CircularBufferSinkCommand\n\tinput_count {} ring size {:04X} ring pos {:04X}\n\tinputs: ",
|
||||||
input_count, size, pos);
|
input_count, size, pos);
|
||||||
|
@ -20,7 +20,7 @@ void CircularBufferSinkCommand::Dump([[maybe_unused]] const ADSP::CommandListPro
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircularBufferSinkCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void CircularBufferSinkCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
constexpr s32 min{std::numeric_limits<s16>::min()};
|
constexpr s32 min{std::numeric_limits<s16>::min()};
|
||||||
constexpr s32 max{std::numeric_limits<s16>::max()};
|
constexpr s32 max{std::numeric_limits<s16>::max()};
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ void CircularBufferSinkCommand::Process(const ADSP::CommandListProcessor& proces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CircularBufferSinkCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool CircularBufferSinkCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for sinking samples to a circular buffer.
|
* AudioRenderer command for sinking samples to a circular buffer.
|
||||||
*/
|
*/
|
||||||
|
@ -23,14 +24,14 @@ struct CircularBufferSinkCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -38,7 +39,7 @@ struct CircularBufferSinkCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Number of input mix buffers
|
/// Number of input mix buffers
|
||||||
u32 input_count;
|
u32 input_count;
|
||||||
|
@ -52,4 +53,4 @@ struct CircularBufferSinkCommand : ICommand {
|
||||||
u32 pos;
|
u32 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#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/sink/device.h"
|
#include "audio_core/renderer/command/sink/device.h"
|
||||||
#include "audio_core/sink/sink.h"
|
#include "audio_core/sink/sink.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void DeviceSinkCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
|
void DeviceSinkCommand::Dump([[maybe_unused]] const AudioRenderer::CommandListProcessor& processor,
|
||||||
std::string& string) {
|
std::string& string) {
|
||||||
string += fmt::format("DeviceSinkCommand\n\t{} session {} input_count {}\n\tinputs: ",
|
string += fmt::format("DeviceSinkCommand\n\t{} session {} input_count {}\n\tinputs: ",
|
||||||
std::string_view(name), session_id, input_count);
|
std::string_view(name), session_id, input_count);
|
||||||
|
@ -19,7 +19,7 @@ void DeviceSinkCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
|
||||||
string += "\n";
|
string += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceSinkCommand::Process(const ADSP::CommandListProcessor& processor) {
|
void DeviceSinkCommand::Process(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
constexpr s32 min = std::numeric_limits<s16>::min();
|
constexpr s32 min = std::numeric_limits<s16>::min();
|
||||||
constexpr s32 max = std::numeric_limits<s16>::max();
|
constexpr s32 max = std::numeric_limits<s16>::max();
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ void DeviceSinkCommand::Process(const ADSP::CommandListProcessor& processor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceSinkCommand::Verify(const ADSP::CommandListProcessor& processor) {
|
bool DeviceSinkCommand::Verify(const AudioRenderer::CommandListProcessor& processor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#include "audio_core/renderer/command/icommand.h"
|
#include "audio_core/renderer/command/icommand.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::ADSP::AudioRenderer {
|
||||||
namespace ADSP {
|
|
||||||
class CommandListProcessor;
|
class CommandListProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioRenderer command for sinking samples to an output device.
|
* AudioRenderer command for sinking samples to an output device.
|
||||||
*/
|
*/
|
||||||
|
@ -25,14 +26,14 @@ struct DeviceSinkCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @param string - The string to print into.
|
* @param string - The string to print into.
|
||||||
*/
|
*/
|
||||||
void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
|
void Dump(const AudioRenderer::CommandListProcessor& processor, std::string& string) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process this command.
|
* Process this command.
|
||||||
*
|
*
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
*/
|
*/
|
||||||
void Process(const ADSP::CommandListProcessor& processor) override;
|
void Process(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this command's data is valid.
|
* Verify this command's data is valid.
|
||||||
|
@ -40,7 +41,7 @@ struct DeviceSinkCommand : ICommand {
|
||||||
* @param processor - The CommandListProcessor processing this command.
|
* @param processor - The CommandListProcessor processing this command.
|
||||||
* @return True if the command is valid, otherwise false.
|
* @return True if the command is valid, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool Verify(const ADSP::CommandListProcessor& processor) override;
|
bool Verify(const AudioRenderer::CommandListProcessor& processor) override;
|
||||||
|
|
||||||
/// Device name
|
/// Device name
|
||||||
char name[0x100];
|
char name[0x100];
|
||||||
|
@ -54,4 +55,4 @@ struct DeviceSinkCommand : ICommand {
|
||||||
std::array<s16, MaxChannels> inputs;
|
std::array<s16, MaxChannels> inputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "audio_core/renderer/effect/aux_.h"
|
#include "audio_core/renderer/effect/aux_.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void AuxInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
|
void AuxInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
|
||||||
const PoolMapper& pool_mapper) {
|
const PoolMapper& pool_mapper) {
|
||||||
|
@ -90,4 +90,4 @@ CpuAddr AuxInfo::GetWorkbuffer(s32 index) {
|
||||||
return workbuffers[index].GetReference(true);
|
return workbuffers[index].GetReference(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "audio_core/renderer/effect/effect_info_base.h"
|
#include "audio_core/renderer/effect/effect_info_base.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
/**
|
/**
|
||||||
* Auxiliary Buffer used for Aux commands.
|
* Auxiliary Buffer used for Aux commands.
|
||||||
* Send and return buffers are available (names from the game's perspective).
|
* Send and return buffers are available (names from the game's perspective).
|
||||||
|
@ -120,4 +120,4 @@ public:
|
||||||
CpuAddr GetWorkbuffer(s32 index) override;
|
CpuAddr GetWorkbuffer(s32 index) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "audio_core/renderer/effect/biquad_filter.h"
|
#include "audio_core/renderer/effect/biquad_filter.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void BiquadFilterInfo::Update(BehaviorInfo::ErrorInfo& error_info,
|
void BiquadFilterInfo::Update(BehaviorInfo::ErrorInfo& error_info,
|
||||||
const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
|
const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
|
||||||
|
@ -49,4 +49,4 @@ void BiquadFilterInfo::InitializeResultState(EffectResultState& result_state) {}
|
||||||
void BiquadFilterInfo::UpdateResultState(EffectResultState& cpu_state,
|
void BiquadFilterInfo::UpdateResultState(EffectResultState& cpu_state,
|
||||||
EffectResultState& dsp_state) {}
|
EffectResultState& dsp_state) {}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "audio_core/renderer/effect/effect_info_base.h"
|
#include "audio_core/renderer/effect/effect_info_base.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
class BiquadFilterInfo : public EffectInfoBase {
|
class BiquadFilterInfo : public EffectInfoBase {
|
||||||
public:
|
public:
|
||||||
|
@ -76,4 +76,4 @@ public:
|
||||||
void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
|
void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "audio_core/renderer/effect/buffer_mixer.h"
|
#include "audio_core/renderer/effect/buffer_mixer.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
void BufferMixerInfo::Update(BehaviorInfo::ErrorInfo& error_info,
|
void BufferMixerInfo::Update(BehaviorInfo::ErrorInfo& error_info,
|
||||||
const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
|
const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
|
||||||
|
@ -46,4 +46,4 @@ void BufferMixerInfo::InitializeResultState(EffectResultState& result_state) {}
|
||||||
void BufferMixerInfo::UpdateResultState(EffectResultState& cpu_state,
|
void BufferMixerInfo::UpdateResultState(EffectResultState& cpu_state,
|
||||||
EffectResultState& dsp_state) {}
|
EffectResultState& dsp_state) {}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "audio_core/renderer/effect/effect_info_base.h"
|
#include "audio_core/renderer/effect/effect_info_base.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore::AudioRenderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
class BufferMixerInfo : public EffectInfoBase {
|
class BufferMixerInfo : public EffectInfoBase {
|
||||||
public:
|
public:
|
||||||
|
@ -72,4 +72,4 @@ public:
|
||||||
void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
|
void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue