From 114fd9e0e1f539f9bc551562f70d8f773f911bfa Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 16 Feb 2026 17:12:36 +0100 Subject: [PATCH] cellMusicDecode: Do not early out if size_to_read is 0 and the position is POSITION_END Probably fixes this case: last call: track_fully_decoded == false, size_left == reqSize next call: track_fully_decoded == true, size_left == 0 --- rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp | 52 +++++++++++----------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp index b7f21b90ad..efa6006520 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp @@ -195,7 +195,7 @@ error_code cell_music_decode_read(vm::ptr buf, vm::ptr startTime, u64 if (dec.decoder.m_size == 0) { - return CELL_MUSIC_DECODE_ERROR_NO_LPCM_DATA; + return {CELL_MUSIC_DECODE_ERROR_NO_LPCM_DATA, "m_size=0"}; } const u64 size_left = dec.decoder.m_size - dec.read_pos; @@ -227,34 +227,32 @@ error_code cell_music_decode_read(vm::ptr buf, vm::ptr startTime, u64 const u64 size_to_read = std::min(reqSize, size_left); *readSize = size_to_read; - if (size_to_read == 0) + if (size_to_read > 0) { - return CELL_MUSIC_DECODE_ERROR_NO_LPCM_DATA; // TODO: speculative - } + std::memcpy(buf.get_ptr(), &dec.decoder.data[dec.read_pos], size_to_read); - std::memcpy(buf.get_ptr(), &dec.decoder.data[dec.read_pos], size_to_read); - - if (size_to_read < reqSize) - { - // Set the rest of the buffer to zero to prevent loud pops at the end of the stream if the game ignores the readSize. - std::memset(vm::static_ptr_cast(buf).get_ptr() + size_to_read, 0, reqSize - size_to_read); - } - - dec.read_pos += size_to_read; - - s64 start_time_ms = 0; - - if (!dec.decoder.timestamps_ms.empty()) - { - start_time_ms = dec.decoder.timestamps_ms.front().second; - - while (dec.decoder.timestamps_ms.size() > 1 && dec.read_pos >= ::at32(dec.decoder.timestamps_ms, 1).first) + if (size_to_read < reqSize) { - dec.decoder.timestamps_ms.pop_front(); + // Set the rest of the buffer to zero to prevent loud pops at the end of the stream if the game ignores the readSize. + std::memset(vm::static_ptr_cast(buf).get_ptr() + size_to_read, 0, reqSize - size_to_read); } - } - *startTime = static_cast(start_time_ms); // startTime is milliseconds + dec.read_pos += size_to_read; + + s64 start_time_ms = 0; + + if (!dec.decoder.timestamps_ms.empty()) + { + start_time_ms = dec.decoder.timestamps_ms.front().second; + + while (dec.decoder.timestamps_ms.size() > 1 && dec.read_pos >= ::at32(dec.decoder.timestamps_ms, 1).first) + { + dec.decoder.timestamps_ms.pop_front(); + } + } + + *startTime = static_cast(start_time_ms); // startTime is milliseconds + } switch (*position) { @@ -275,11 +273,15 @@ error_code cell_music_decode_read(vm::ptr buf, vm::ptr startTime, u64 } default: { + if (size_to_read == 0) + { + return {CELL_MUSIC_DECODE_ERROR_NO_LPCM_DATA, "size_to_read=0"}; // TODO: speculative + } break; } } - cellMusicDecode.trace("cell_music_decode_read(size_to_read=%d, samples=%d, start_time_ms=%d)", size_to_read, size_to_read / sizeof(u64), start_time_ms); + cellMusicDecode.trace("cell_music_decode_read(size_to_read=%d, samples=%d, start_time_ms=%d)", size_to_read, size_to_read / sizeof(u64), *startTime); return CELL_OK; }