mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-23 10:19:05 +00:00
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
shared_memory = &shared_memory_;
|
||||
}
|
||||
|
||||
void NotifyShutdown();
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -24,8 +24,6 @@ public:
|
||||
explicit AudioCore(Core::System& system);
|
||||
~AudioCore();
|
||||
|
||||
void NotifyShutdown();
|
||||
|
||||
/**
|
||||
* Shutdown the audio core.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +39,6 @@ class AudioManager {
|
||||
public:
|
||||
explicit AudioManager();
|
||||
|
||||
/// @brief Notify of impending shutdown
|
||||
void NotifyShutdown();
|
||||
|
||||
/// @brief Shutdown the audio manager.
|
||||
void Shutdown();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user