mirror of
https://github.com/starr-dusT/yuzu-mainline
synced 2024-03-05 21:12:25 -08:00
174 lines
4.5 KiB
C++
174 lines
4.5 KiB
C++
// 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.
|
|
*
|
|
* @return True if started or already running, otherwise false.
|
|
*/
|
|
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, 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
|