From e7494667adbb5c0a5264eb3872f83cc4099881ea Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 1 Dec 2024 13:55:50 +0300 Subject: [PATCH] Use readerwriterqueue for SDL2 audio. --- UnleashedRecomp/CMakeLists.txt | 2 + UnleashedRecomp/apu/driver/sdl2_driver.cpp | 44 ++++++---------------- UnleashedRecomp/stdafx.h | 1 + vcpkg.json | 3 +- 4 files changed, 17 insertions(+), 33 deletions(-) diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index f206680..6f0af6e 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -160,6 +160,7 @@ find_package(unofficial-concurrentqueue REQUIRED) find_package(imgui CONFIG REQUIRED) find_package(magic_enum CONFIG REQUIRED) find_package(unofficial-tiny-aes-c CONFIG REQUIRED) +find_path(READERWRITERQUEUE_INCLUDE_DIRS "readerwriterqueue/atomicops.h") file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) add_custom_command(TARGET UnleashedRecomp POST_BUILD @@ -207,6 +208,7 @@ target_include_directories(UnleashedRecomp PRIVATE ${LIBMSPACK_PATH} ${Stb_INCLUDE_DIR} ${SMOLV_SOURCE_DIR} + ${READERWRITERQUEUE_INCLUDE_DIRS} ) target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS}) diff --git a/UnleashedRecomp/apu/driver/sdl2_driver.cpp b/UnleashedRecomp/apu/driver/sdl2_driver.cpp index 87c7e2f..da4cba7 100644 --- a/UnleashedRecomp/apu/driver/sdl2_driver.cpp +++ b/UnleashedRecomp/apu/driver/sdl2_driver.cpp @@ -5,35 +5,22 @@ #include #define SDLAUDIO_DRIVER_KEY (uint32_t)('SDLA') -constexpr uint32_t g_semaphoreCount = 16; -constexpr uint32_t g_audioFrameSize = XAUDIO_NUM_SAMPLES * XAUDIO_NUM_CHANNELS; -PPCFunc* volatile g_clientCallback{}; -DWORD g_clientCallbackParam{}; // pointer in guest memory +static constexpr uint32_t AUDIO_FRAME_SIZE = XAUDIO_NUM_SAMPLES * XAUDIO_NUM_CHANNELS; -SDL_AudioDeviceID g_audioDevice{}; -SDL_sem* g_audioSemaphore{ SDL_CreateSemaphore(g_semaphoreCount) }; -uint32_t g_audioFrames[g_audioFrameSize * g_semaphoreCount]; -uint32_t g_audioFrameIndex = 0; -uint32_t g_renderFrameIndex = 0; // Index of frame that's being rendered -uint32_t g_numRenderFrames = 0; // Number of frames to render -Mutex g_framesMutex{}; +static std::atomic g_clientCallback{}; +static DWORD g_clientCallbackParam{}; // pointer in guest memory + +static SDL_AudioDeviceID g_audioDevice{}; +static moodycamel::BlockingReaderWriterCircularBuffer> g_audioQueue(16); static void SDLAudioCallback(void*, uint8_t* frames, int len) { - std::lock_guard guard{ g_framesMutex }; - if (g_numRenderFrames == 0) - { - memset(frames, 0, len); - } + std::array audioFrame; + if (g_audioQueue.try_dequeue(audioFrame)) + memcpy(frames, &audioFrame, sizeof(audioFrame)); else - { - g_renderFrameIndex = (g_renderFrameIndex + 1) % g_semaphoreCount; - auto* srcFrames = &g_audioFrames[g_renderFrameIndex * g_audioFrameSize]; - memcpy(frames, srcFrames, g_audioFrameSize * sizeof(float)); - --g_numRenderFrames; - } - SDL_SemPost(g_audioSemaphore); + memset(frames, 0, len); } static PPC_FUNC(DriverLoop) @@ -43,11 +30,8 @@ static PPC_FUNC(DriverLoop) while (true) { if (!g_clientCallback) - { continue; - } - SDL_SemWait(g_audioSemaphore); ctx.r3.u64 = g_clientCallbackParam; GuestCode::Run((void*)g_clientCallback, &ctx); } @@ -55,8 +39,6 @@ static PPC_FUNC(DriverLoop) void XAudioInitializeSystem() { - assert(g_audioSemaphore); - SDL_SetHint(SDL_HINT_AUDIO_CATEGORY, "playback"); SDL_SetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, "SWA"); @@ -87,9 +69,7 @@ void XAudioRegisterClient(PPCFunc* callback, uint32_t param) void XAudioSubmitFrame(void* samples) { - std::lock_guard guard{ g_framesMutex }; - uint32_t* audioFrame = &g_audioFrames[g_audioFrameSize * g_audioFrameIndex]; - g_audioFrameIndex = (g_audioFrameIndex + 1) % g_semaphoreCount; + std::array audioFrame; for (size_t i = 0; i < XAUDIO_NUM_SAMPLES; i++) { @@ -97,5 +77,5 @@ void XAudioSubmitFrame(void* samples) audioFrame[i * XAUDIO_NUM_CHANNELS + j] = std::byteswap(((uint32_t*)samples)[j * XAUDIO_NUM_SAMPLES + i]); } - ++g_numRenderFrames; + g_audioQueue.wait_enqueue(audioFrame); } diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index 8fd5bb2..bf52446 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -32,6 +32,7 @@ #include #include #include +#include using Microsoft::WRL::ComPtr; diff --git a/vcpkg.json b/vcpkg.json index e5db0fe..5e13523 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -21,6 +21,7 @@ "name": "imgui", "features": [ "sdl2-binding" ] }, - "magic-enum" + "magic-enum", + "readerwriterqueue" ] }