From 178186ef4e7b73bdc4ed2e83ee6f0123242fadfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2026 10:43:01 -0600 Subject: [PATCH] sceVaudio: Reserving the channel waits about 250us On hardware sceVaudioChReserve takes ~260us once it gets past the busy check, succeed or fail, and worse threads can run meanwhile. Releasing takes ~25us and doesn't wait. We returned at once, which is what audio/sceaudio/reserve's [r] markers showed; it now passes. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/HLE/sceVaudio.cpp | 9 ++++++--- test.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceVaudio.cpp b/Core/HLE/sceVaudio.cpp index 71ccce2dbf..4876c57f83 100644 --- a/Core/HLE/sceVaudio.cpp +++ b/Core/HLE/sceVaudio.cpp @@ -64,15 +64,18 @@ static u32 sceVaudioChReserve(int sampleCount, int freq, int format) { // reserved before handing over - it does not undo that when the reserve fails. So a caller // that got 0x80268002 because Output2 held the channel is told 0x80000021 next time round, // until a release clears it. + // From here on the call waits about 250us, whether it succeeds or not; on hardware worse + // threads get to run meanwhile (pspautotests audio/sceaudio/reserve shows the reschedule). vaudioReserved = true; + const int reserveUs = 250; if (freq != 0 && !SRCFrequencyAllowed(freq)) { ERROR_LOG(Log::sceAudio, "sceVaudioChReserve(%i, %i, %i) - invalid frequency", sampleCount, freq, format); - return SCE_ERROR_AUDIO_INVALID_FREQUENCY; + return hleDelayResult(SCE_ERROR_AUDIO_INVALID_FREQUENCY, "vaudio reserve", reserveUs); } // We still have to check the channel also, which gives a different error. if (g_audioSRC.reserved) { ERROR_LOG(Log::sceAudio, "sceVaudioChReserve(%i, %i, %i) - channel already reserved", sampleCount, freq, format); - return SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED; + return hleDelayResult(SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED, "vaudio reserve", reserveUs); } DEBUG_LOG(Log::sceAudio, "sceVaudioChReserve(%i, %i, %i)", sampleCount, freq, format); g_audioSRC.clear(); @@ -80,7 +83,7 @@ static u32 sceVaudioChReserve(int sampleCount, int freq, int format) { g_audioSRC.sampleCount = sampleCount; g_audioSRC.format = format == 2 ? PSP_AUDIO_FORMAT_STEREO : PSP_AUDIO_FORMAT_MONO; __AudioSetSRCFrequency(freq); - return 0; + return hleDelayResult(0, "vaudio reserve", reserveUs); } static u32 sceVaudioChRelease() { diff --git a/test.py b/test.py index bef07f61a3..8372e4a349 100755 --- a/test.py +++ b/test.py @@ -156,6 +156,7 @@ tests_good = [ "audio/blocking/oneshot", "audio/blocking/restlen", "audio/blocking/vaudio", + "audio/sceaudio/reserve", "audio/sceaudio/datalen", "audio/output2/changelength", "audio/output2/release", @@ -531,7 +532,6 @@ tests_next = [ "cpu/vfpu/vector", "cpu/vfpu/vregs", "audio/sceaudio/output", - "audio/sceaudio/reserve", "audio/sascore/setadsr", "audio/mp3/init", "audio/output2/frequency",