2026-09-23 02:07:39

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie
2026-09-23 02:07:39 +00:00
parent 8ddd0f3cc4
commit cb85810ffd
14 changed files with 53 additions and 95 deletions
+3 -3
View File
@@ -19,9 +19,9 @@ ADSP::ADSP(Core::System& system, Sink::Sink& sink) {
}
}
void ADSP::NotifyShutdown() {
audio_renderer->NotifyShutdown();
opus_decoder->NotifyShutdown();
void ADSP::Shutdown() {
audio_renderer->Stop();
opus_decoder->Shutdown();
}
AudioRenderer::AudioRenderer& ADSP::AudioRenderer() {
+1 -1
View File
@@ -45,7 +45,7 @@ public:
explicit ADSP(Core::System& system, Sink::Sink& sink);
~ADSP() = default;
void NotifyShutdown();
void Shutdown();
AudioRenderer::AudioRenderer& AudioRenderer();
OpusDecoder::OpusDecoder& OpusDecoder();
@@ -34,36 +34,19 @@ void AudioRenderer::Start() {
mailbox.Send(Direction::DSP, Message::InitializeOK);
if (mailbox.Receive(Direction::Host) != Message::InitializeOK) {
LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown "
"message response from ADSP!");
return;
}
running = true;
}
void AudioRenderer::NotifyShutdown() {
if (main_thread.joinable()) {
main_thread.request_stop();
mailbox.Send(Direction::DSP, Message::Shutdown);
main_thread.join();
LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown message response from ADSP!");
}
}
void AudioRenderer::Stop() {
if (!running) {
return;
}
if (main_thread.joinable()) {
main_thread.request_stop();
mailbox.Send(Direction::DSP, Message::Shutdown);
if (mailbox.Receive(Direction::Host, main_thread.get_stop_token()) != Message::Shutdown) {
LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown "
"message response from ADSP!");
LOG_ERROR(Service_Audio, "Host Audio Renderer -- Failed to receive shutdown message response from ADSP!");
}
main_thread.join();
}
for (auto& stream : streams) {
if (stream) {
stream->Stop();
@@ -71,7 +54,6 @@ void AudioRenderer::Stop() {
stream = nullptr;
}
}
running = false;
}
void AudioRenderer::Signal() {
@@ -104,8 +104,6 @@ private:
Mailbox mailbox;
/// Main thread
std::jthread main_thread{};
/// The current state
std::atomic<bool> running{};
/// Shared memory of input command buffers, set by host, read by DSP
std::array<CommandBuffer, MaxRendererSessions> command_buffers{};
/// The command lists to process
+20 -15
View File
@@ -82,11 +82,11 @@ void OpusDecoder::Main(std::stop_token stop_token) {
break;
switch (msg) {
case Shutdown:
case Message::Shutdown:
Send(Direction::Host, Message::ShutdownOK);
return;
case GetWorkBufferSize: {
case Message::GetWorkBufferSize: {
auto channel_count = static_cast<s32>(shared_memory->host_send_data[0]);
ASSERT(IsValidChannelCount(channel_count));
@@ -95,7 +95,7 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::GetWorkBufferSizeOK);
} break;
case InitializeDecodeObject: {
case Message::InitializeDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
auto buffer_size = shared_memory->host_send_data[1];
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
@@ -112,7 +112,7 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::InitializeDecodeObjectOK);
} break;
case ShutdownDecodeObject: {
case Message::ShutdownDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
@@ -122,7 +122,7 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::ShutdownDecodeObjectOK);
} break;
case DecodeInterleaved: {
case Message::DecodeInterleaved: {
auto start_time = system.CoreTiming().GetGlobalTimeUs();
auto buffer = shared_memory->host_send_data[0];
@@ -160,19 +160,19 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::DecodeInterleavedOK);
} break;
case MapMemory: {
case Message::MapMemory: {
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
Send(Direction::Host, Message::MapMemoryOK);
} break;
case UnmapMemory: {
case Message::UnmapMemory: {
[[maybe_unused]] auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
Send(Direction::Host, Message::UnmapMemoryOK);
} break;
case GetWorkBufferSizeForMultiStream: {
case Message::GetWorkBufferSizeForMultiStream: {
auto total_stream_count = static_cast<s32>(shared_memory->host_send_data[0]);
auto stereo_stream_count = static_cast<s32>(shared_memory->host_send_data[1]);
@@ -183,7 +183,7 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::GetWorkBufferSizeForMultiStreamOK);
} break;
case InitializeMultiStreamDecodeObject: {
case Message::InitializeMultiStreamDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
auto buffer_size = shared_memory->host_send_data[1];
auto sample_rate = static_cast<s32>(shared_memory->host_send_data[2]);
@@ -210,7 +210,7 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::InitializeMultiStreamDecodeObjectOK);
} break;
case ShutdownMultiStreamDecodeObject: {
case Message::ShutdownMultiStreamDecodeObject: {
auto buffer = shared_memory->host_send_data[0];
[[maybe_unused]] auto buffer_size = shared_memory->host_send_data[1];
@@ -220,7 +220,7 @@ void OpusDecoder::Main(std::stop_token stop_token) {
Send(Direction::Host, Message::ShutdownMultiStreamDecodeObjectOK);
} break;
case DecodeInterleavedForMultiStream: {
case Message::DecodeInterleavedForMultiStream: {
auto start_time = system.CoreTiming().GetGlobalTimeUs();
auto buffer = shared_memory->host_send_data[0];
@@ -265,10 +265,15 @@ void OpusDecoder::Main(std::stop_token stop_token) {
}
}
void OpusDecoder::NotifyShutdown() {
init_thread.request_stop();
main_thread.request_stop();
Send(Direction::DSP, Message::Shutdown);
void OpusDecoder::Shutdown() {
if (init_thread.joinable()) {
init_thread.request_stop();
init_thread.join(); //must explicitly wait for init to join
}
if (main_thread.joinable()) {
main_thread.request_stop();
Send(Direction::DSP, Message::Shutdown);
}
}
} // namespace AudioCore::ADSP::OpusDecoder
+1 -1
View File
@@ -67,7 +67,7 @@ public:
shared_memory = &shared_memory_;
}
void NotifyShutdown();
void Shutdown();
private:
/**
+1 -5
View File
@@ -31,13 +31,9 @@ void AudioCore::CreateSinks() {
input_sink = Sink::CreateSinkFromID(sink_id.GetValue(), audio_input_device_id.GetValue());
}
void AudioCore::NotifyShutdown() {
audio_manager->NotifyShutdown();
adsp->NotifyShutdown();
}
void AudioCore::Shutdown() {
audio_manager->Shutdown();
adsp->Shutdown();
}
AudioManager& AudioCore::GetAudioManager() {
-2
View File
@@ -24,8 +24,6 @@ public:
explicit AudioCore(Core::System& system);
~AudioCore();
void NotifyShutdown();
/**
* Shutdown the audio core.
*/
+1 -6
View File
@@ -34,15 +34,10 @@ AudioManager::AudioManager() {
});
}
void AudioManager::NotifyShutdown() {
events.SetAudioEvent(Event::Type::Max, true);
thread.request_stop();
}
void AudioManager::Shutdown() {
events.SetAudioEvent(Event::Type::Max, true);
if (thread.joinable()) {
thread.request_stop();
events.SetAudioEvent(Event::Type::Max, true);
thread.join();
}
}
-3
View File
@@ -39,9 +39,6 @@ class AudioManager {
public:
explicit AudioManager();
/// @brief Notify of impending shutdown
void NotifyShutdown();
/// @brief Shutdown the audio manager.
void Shutdown();
+20 -27
View File
@@ -11,71 +11,64 @@
#include "audio_core/renderer/system_manager.h"
#include "common/thread.h"
#include "core/core.h"
#include "core/hle/kernel/kernel.h"
#include "core/core_timing.h"
namespace AudioCore::Renderer {
SystemManager::SystemManager(Core::System& core_)
: core{core_}, audio_renderer{core.AudioCore().ADSP().AudioRenderer()} {}
: core{core_}
{}
SystemManager::~SystemManager() {
Stop();
}
void SystemManager::InitializeUnsafe() {
if (!active) {
active = true;
audio_renderer.Start();
thread = std::jthread([this](std::stop_token stop_token) {
Common::SetCurrentThreadName("AudioRenderSystemManager");
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
while (active && !stop_token.stop_requested()) {
if (!thread.joinable()) {
thread = core.Kernel().RunOnHostCoreThread("AudioRenderSystemManager", [this]() {
auto& audio_renderer = core.AudioCore().ADSP().AudioRenderer();
audio_renderer.Start();
auto const stop_token = thread.get_stop_token();
while (!stop_token.stop_requested()) {
{
std::scoped_lock l{mutex1};
std::scoped_lock lk{mutex};
for (auto system : systems)
system->SendCommandToDsp();
}
audio_renderer.Signal();
audio_renderer.Wait(stop_token);
}
audio_renderer.Stop();
});
}
}
void SystemManager::Stop() {
if (active) {
active = false;
if (thread.joinable()) {
thread.request_stop();
thread.join();
audio_renderer.Stop();
}
}
bool SystemManager::Add(System& system_) {
std::scoped_lock l2{mutex2};
if (systems.size() + 1 > MaxRendererSessions) {
std::scoped_lock lk{mutex};
if (systems.size() >= MaxRendererSessions) {
LOG_ERROR(Service_Audio, "Maximum AudioRenderer Systems active, cannot add more!");
return false;
}
{
std::scoped_lock l{mutex1};
if (systems.empty())
InitializeUnsafe();
}
if (systems.empty())
InitializeUnsafe();
systems.push_back(&system_);
return true;
}
bool SystemManager::Remove(System& system_) {
std::scoped_lock l2{mutex2};
{
std::scoped_lock l{mutex1};
if (systems.remove(&system_) == 0) {
LOG_ERROR(Service_Audio, "Failed to remove a render system, it was not found in the list!");
return false;
}
std::scoped_lock lk{mutex};
if (systems.remove(&system_) == 0) {
LOG_ERROR(Service_Audio, "Failed to remove a render system, it was not found in the list!");
return false;
}
if (systems.empty())
Stop();
return true;
+2 -8
View File
@@ -75,14 +75,8 @@ private:
std::list<System*> systems{};
/// Main worker thread for generating command lists
std::jthread thread;
/// Mutex for the systems
std::mutex mutex1{};
/// Mutex for adding/removing systems
std::mutex mutex2{};
/// Is the system manager thread active?
std::atomic<bool> active{};
/// Reference to the ADSP's AudioRenderer for communication
::AudioCore::ADSP::AudioRenderer::AudioRenderer& audio_renderer;
/// Mutex for the reading and adding/removing systems
std::mutex mutex{};
};
} // namespace AudioCore::Renderer
+1 -1
View File
@@ -442,7 +442,7 @@ struct System::Impl {
kernel.ShutdownCores();
// Notify services helpers of shutdown
audio_core->NotifyShutdown();
audio_core->Shutdown();
// Wait for threads/services to join
kernel.CloseServices();
+1 -1
View File
@@ -191,7 +191,7 @@ void LoopProcess(Core::System& system) {
server_manager->RegisterNamedService("audout:d", std::make_shared<IAudioOutManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audin:d", std::make_shared<IAudioInManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audrec:d", std::make_shared<IFinalOutputRecorderManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioInManager>(system), 30);
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioRendererManagerForDebugger>(system), 30);
server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system), 30);
server_manager->RegisterNamedService("audin:a", std::make_shared<IAudioInManagerForApplet>(system), 30);