From c35572ec18dd068286a574fd17bf3ceee49e2e67 Mon Sep 17 00:00:00 2001 From: PrintOrb Date: Mon, 12 Oct 2026 00:17:17 -0500 Subject: [PATCH] fix(audioout): serialize shared SDL audio initialization --- core/libs/prx/libSceAudioOut/include/AudioOutSdl.hpp | 6 ++++++ core/libs/prx/libSceAudioOut/src/AudioOut.cpp | 9 ++++++++- core/libs/prx/libSceAudioOut/src/AudioOut2Context.cpp | 5 +++-- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 core/libs/prx/libSceAudioOut/include/AudioOutSdl.hpp diff --git a/core/libs/prx/libSceAudioOut/include/AudioOutSdl.hpp b/core/libs/prx/libSceAudioOut/include/AudioOutSdl.hpp new file mode 100644 index 000000000..f0e8c87cc --- /dev/null +++ b/core/libs/prx/libSceAudioOut/include/AudioOutSdl.hpp @@ -0,0 +1,6 @@ +#ifndef CORE_LIBS_PRX_LIBSCEAUDIOOUT_INCLUDE_AUDIOOUTSDL_HPP +#define CORE_LIBS_PRX_LIBSCEAUDIOOUT_INCLUDE_AUDIOOUTSDL_HPP + +int InitializeSdlAudio_nid_no_patch(); + +#endif diff --git a/core/libs/prx/libSceAudioOut/src/AudioOut.cpp b/core/libs/prx/libSceAudioOut/src/AudioOut.cpp index c8adb77b2..db1ecd88b 100644 --- a/core/libs/prx/libSceAudioOut/src/AudioOut.cpp +++ b/core/libs/prx/libSceAudioOut/src/AudioOut.cpp @@ -16,6 +16,7 @@ #include "SceTypes.hpp" #include "prx/libc/include/PreciseWait.hpp" #include "prx/libkernel/Time/include/Time.hpp" +#include "prx/libSceAudioOut/include/AudioOutSdl.hpp" static constexpr int PORT_TYPE_MAIN = 0; static constexpr int PORT_TYPE_BGM = 1; @@ -103,11 +104,17 @@ static std::mutex g_outputMutex; static Port g_ports[PORTS_MAX]; static bool g_sdlInitialized = false; +int InitializeSdlAudio_nid_no_patch() { + static std::mutex initializationMutex; + std::lock_guard lock(initializationMutex); + return SDL_InitSubSystem(SDL_INIT_AUDIO); +} + static bool ensureSdlAudio() { if (g_sdlInitialized) { return true; } - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + if (InitializeSdlAudio_nid_no_patch() < 0) { return false; } g_sdlInitialized = true; diff --git a/core/libs/prx/libSceAudioOut/src/AudioOut2Context.cpp b/core/libs/prx/libSceAudioOut/src/AudioOut2Context.cpp index 383ad018f..3f8827744 100644 --- a/core/libs/prx/libSceAudioOut/src/AudioOut2Context.cpp +++ b/core/libs/prx/libSceAudioOut/src/AudioOut2Context.cpp @@ -14,6 +14,7 @@ #include "prx/libc/include/General.hpp" #include "prx/libc/include/PreciseWait.hpp" #include "AudioOut2Internal.hpp" +#include "prx/libSceAudioOut/include/AudioOutSdl.hpp" // An AudioOut2 context is the hardware output queue: every push appends a grain (num_grains samples) // to a queue of queue_depth grains that plays in real time. Titles pace their mixer on that queue, so @@ -106,7 +107,7 @@ static std::uint32_t QueueLevel(AudioOut2Context& context, Clock::time_point now static void DeviceCallback(void* userdata, Uint8* stream, int length); static void OpenDevice(AudioOut2Context& context) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + if (InitializeSdlAudio_nid_no_patch() < 0) { AUDIOOUT2_TRACE("SDL audio init failed: %s\n", SDL_GetError()); return; } @@ -134,7 +135,7 @@ static void CloseDevice(SDL_AudioDeviceID device) { } static void OpenPadDevice(AudioOut2Context& context) { - if (SDL_WasInit(SDL_INIT_AUDIO) == 0 && SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) return; + if (SDL_WasInit(SDL_INIT_AUDIO) == 0 && InitializeSdlAudio_nid_no_patch() < 0) return; const int count = SDL_GetNumAudioDevices(0); for (int index = 0; index < count; index++) { const char* listed = SDL_GetAudioDeviceName(index, 0);