From 9afc668bfa3cd4c72c2dd033d55be5a175bbb893 Mon Sep 17 00:00:00 2001 From: sonninnos Date: Tue, 28 May 2024 14:27:02 +0300 Subject: [PATCH 1/5] libretro: upload audio once per frame --- libretro/libretro.cpp | 61 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index bed538a66b..1e30b63d11 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -69,6 +69,13 @@ #define SAMPLERATE 44100 +/* Audio output buffer */ +static struct { + int16_t *data; + int32_t size; + int32_t capacity; +} output_audio_buffer = {NULL, 0, 0}; + // Calculated swap interval is 'stable' if the same // value is recorded for a number of retro_run() // calls equal to VSYNC_SWAP_INTERVAL_FRAMES @@ -97,6 +104,7 @@ namespace Libretro static retro_audio_sample_batch_t audio_batch_cb; static retro_input_poll_t input_poll_cb; static retro_input_state_t input_state_cb; + static retro_log_printf_t log_cb; static bool detectVsyncSwapInterval = false; static bool detectVsyncSwapIntervalOptShown = true; @@ -110,6 +118,40 @@ namespace Libretro static float runSpeed = 0.0f; static s64 runTicksLast = 0; + static void ensure_output_audio_buffer_capacity(int32_t capacity) + { + if (capacity <= output_audio_buffer.capacity) { + return; + } + + output_audio_buffer.data = (int16_t*)realloc(output_audio_buffer.data, capacity * sizeof(*output_audio_buffer.data)); + output_audio_buffer.capacity = capacity; + log_cb(RETRO_LOG_DEBUG, "Output audio buffer capacity set to %d\n", capacity); + } + + static void init_output_audio_buffer(int32_t capacity) + { + output_audio_buffer.data = NULL; + output_audio_buffer.size = 0; + output_audio_buffer.capacity = 0; + ensure_output_audio_buffer_capacity(capacity); + } + + static void free_output_audio_buffer() + { + free(output_audio_buffer.data); + output_audio_buffer.data = NULL; + output_audio_buffer.size = 0; + output_audio_buffer.capacity = 0; + } + + static void upload_output_audio_buffer() + { + audio_batch_cb(output_audio_buffer.data, output_audio_buffer.size / 2); + output_audio_buffer.size = 0; + } + + /** * Clamp a value to a given range. * @@ -1103,6 +1145,7 @@ void retro_init(void) struct retro_log_callback log; if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) { + log_cb = log.log; LogManager::Init(&g_Config.bEnableLogging); printfLogger = new PrintfLogger(log); LogManager* logman = LogManager::GetInstance(); @@ -1140,6 +1183,8 @@ void retro_init(void) g_Config.bDiscordPresence = false; g_VFS.Register("", new DirectoryReader(retro_base_dir)); + + init_output_audio_buffer(2048); } void retro_deinit(void) @@ -1154,6 +1199,8 @@ void retro_deinit(void) libretro_supports_option_categories = false; VsyncSwapIntervalReset(); + + free_output_audio_buffer(); } void retro_set_controller_port_device(unsigned port, unsigned device) @@ -1500,6 +1547,7 @@ void retro_run(void) VsyncSwapIntervalDetect(); ctx->SwapBuffers(); + upload_output_audio_buffer(); } unsigned retro_get_region(void) { return RETRO_REGION_NTSC; } @@ -1753,6 +1801,8 @@ inline int16_t Clamp16(int32_t sample) { void System_AudioPushSamples(const int32_t *audio, int numSamples) { // Convert to 16-bit audio for further processing. int16_t buffer[1024 * 2]; + int origSamples = numSamples * 2; + while (numSamples > 0) { int blockSize = std::min(1024, numSamples); for (int i = 0; i < blockSize; i++) { @@ -1760,14 +1810,13 @@ void System_AudioPushSamples(const int32_t *audio, int numSamples) { buffer[i * 2 + 1] = Clamp16(audio[i * 2 + 1]); } - int framesToWrite = blockSize; - uint32_t framesWritten = audio_batch_cb(buffer, framesToWrite); - if (framesWritten != framesToWrite) { - // Let's just stop, and eat any left-over samples. - break; - } numSamples -= blockSize; } + + if (output_audio_buffer.capacity - output_audio_buffer.size < origSamples) + ensure_output_audio_buffer_capacity((output_audio_buffer.capacity + origSamples) * 1.5); + memcpy(output_audio_buffer.data + output_audio_buffer.size, buffer, origSamples * sizeof(*output_audio_buffer.data)); + output_audio_buffer.size += origSamples; } void System_AudioGetDebugStats(char *buf, size_t bufSize) { if (buf) buf[0] = '\0'; } From c3469ca1bb28195b37bcf6f0039b39daf3d71295 Mon Sep 17 00:00:00 2001 From: sonninnos Date: Tue, 28 May 2024 15:02:42 +0300 Subject: [PATCH 2/5] libretro: remove unused StereoResampler --- libretro/Makefile.common | 1 - libretro/libretro.cpp | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 8a5b0b9214..cacd212a52 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -726,7 +726,6 @@ SOURCES_CXX += \ $(COREDIR)/HW/MemoryStick.cpp \ $(COREDIR)/HW/SasAudio.cpp \ $(COREDIR)/HW/SasReverb.cpp \ - $(COREDIR)/HW/StereoResampler.cpp \ $(COREDIR)/Compatibility.cpp \ $(COREDIR)/FrameTiming.cpp \ $(COREDIR)/Loaders.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 1e30b63d11..2704fb3e8e 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -32,7 +32,6 @@ #include "Core/HLE/sceUtility.h" #include "Core/HLE/__sceAudio.h" #include "Core/HW/MemoryStick.h" -#include "Core/HW/StereoResampler.h" #include "Core/MemMap.h" #include "Core/System.h" #include "Core/CoreTiming.h" @@ -1743,11 +1742,7 @@ float System_GetPropertyFloat(SystemProperty prop) switch (prop) { case SYSPROP_DISPLAY_REFRESH_RATE: - // Have to lie here and report 60 Hz instead - // of (60.0 / 1.001), otherwise the internal - // stereo resampler will output at the wrong - // frequency... - return 60.0f; + return 60.0f / 1.001f; case SYSPROP_DISPLAY_SAFE_INSET_LEFT: case SYSPROP_DISPLAY_SAFE_INSET_RIGHT: case SYSPROP_DISPLAY_SAFE_INSET_TOP: From 3d96a071bca84ac75b353c9fd1226f944dddc17b Mon Sep 17 00:00:00 2001 From: sonninnos Date: Tue, 28 May 2024 15:04:13 +0300 Subject: [PATCH 3/5] libretro: add chd to valid extensions --- libretro/libretro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 2704fb3e8e..9816dbd5e6 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1214,7 +1214,7 @@ void retro_get_system_info(struct retro_system_info *info) info->library_name = "PPSSPP"; info->library_version = PPSSPP_GIT_VERSION; info->need_fullpath = true; - info->valid_extensions = "elf|iso|cso|prx|pbp"; + info->valid_extensions = "elf|iso|cso|prx|pbp|chd"; } void retro_get_system_av_info(struct retro_system_av_info *info) From a1b7d6e84aabee6a79ca5fee7c718a8ea570ac22 Mon Sep 17 00:00:00 2001 From: sonninnos Date: Tue, 28 May 2024 15:09:14 +0300 Subject: [PATCH 4/5] libretro: easier debug building --- libretro/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro/Makefile b/libretro/Makefile index 4625c9da0f..a1d87a82e2 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -1,4 +1,4 @@ -DEBUG=0 +DEBUG := 0 WITH_DYNAREC := 1 DYNAFLAGS := From 3766a84792ad25985ebb4f3eb4cc34a251c69750 Mon Sep 17 00:00:00 2001 From: sonninnos Date: Tue, 28 May 2024 15:22:28 +0300 Subject: [PATCH 5/5] libretro: core option label reformat + default --- libretro/libretro_core_options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro/libretro_core_options.h b/libretro/libretro_core_options.h index 9894c422f8..082edcbad5 100644 --- a/libretro/libretro_core_options.h +++ b/libretro/libretro_core_options.h @@ -279,7 +279,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { }, { "ppsspp_memstick_inserted", - "Memory Stick inserted", + "Memory Stick Inserted", NULL, "Some games require ejecting/inserting the Memory Stick.", NULL, @@ -390,7 +390,7 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "video", BOOL_OPTIONS, - "disabled" + "enabled" }, { "ppsspp_detect_vsync_swap_interval",