From 76a8e9d45f32faca55899fff37956d87dcde782e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 10 Oct 2026 20:04:37 +0200 Subject: [PATCH] sceAudio: Don't reschedule before the mixed block is pushed Waking a thread from the mixer reschedules, which runs any due CoreTiming events. When an audio tick runs late, the next tick would already be due, and it would mix over mixBuffer before this one had been output. The next block would then be played twice and this one dropped. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/HLE/__sceAudio.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 2be45a25c2..1e1bd874dc 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -639,10 +639,6 @@ void __AudioUpdate(bool resetRecording) { woke |= __AudioMixSRC(g_audioSRC); audioMixing = false; - if (woke) { - __AudioReScheduleAfterWake(); - } - if (g_Config.bEnableSound) { float multiplier = Volume100ToMultiplier(std::clamp(g_Config.iGameVolume, 0, VOLUMEHI_FULL)); if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL || PSP_CoreParameter().fastForward) { @@ -689,6 +685,13 @@ void __AudioUpdate(bool resetRecording) { } #endif } + + // Only once the block is out. Rescheduling runs any due events, and when this tick was late + // that includes the next one, which would mix over mixBuffer before it was pushed - playing + // the next block twice and dropping this one. + if (woke) { + __AudioReScheduleAfterWake(); + } } #ifndef MOBILE_DEVICE