On hardware InitMono only takes the mono Atrac3 parameters (0x0E, 0x0F),
and the stereo ones fail with 0x807f00ff. Init fills in the context: 44100
at 0x2c, the frame size at 0x30, and the output channels at 0x34, which
InitMono sets to 1. The ME reads that at every decode, and writes a mono
layout as stereo only when it's 2. We accepted every parameter, wrote
nothing there, and always wrote stereo.
A bad frame's ctx.err is 0x183 when a joint stereo frame's second part
lacks its marker, and 0x182 for any other bad sound unit. The decoder now
reports which, and we give 0x183 where we gave 0x182
(pspautotests audio/audiocodec/at3errors).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The area after the 0x5c0 workarea is double buffered - a half only becomes
writable again once the decoder has consumed past its end, so decoding a
single frame usually frees nothing at all. We instead reported every byte a
decode had just consumed, which made sceMp3CheckStreamDataNeeded() answer
"yes" after every single frame.
Beats sleeps 50ms whenever that call says the file thread is behind, so it
slept once per decoded frame and delivered audio at 46% of realtime - the
badly stuttering custom soundtracks. It now decodes 3-4 frames per 3360 byte
refill, with the write pointer alternating between the two halves exactly as
audio/mp3/stream records from hardware, and keeps up.
AuGetInfoToAddStreamData/AuNotifyAddStreamData now derive the write position
from how much has been added rather than from how much is still buffered,
since the write pointer walks the halves in turn and doesn't follow the
decoder.
Fixes audio/mp3/notifyadd, moved to tests_good, and the "after decode" case
in audio/mp3/checkneeded.
sceMp3: note that the half-buffer split is only verified at 8192 bytes
Hopefully will move to reading RAM directly. I think this was not always
adding data properly, as I got wrong output after decode. Makes more
sense as a vector, anyway.
If the offset points to an ID3 tag or the middle of a frame, that's fine -
it should just search forward to the next sync. FFmpeg just returns a
decode error, so we do this first.
If we just ask what we should add, that is meant to stay static until we
do actually add it.
This also reduces the max we ask for at a time, which better matches
correct behavior and might impact game behavior.
This method can automatically read audio information from file (as channels, sample rate etc) via ffmpeg,
and create accurate ffmpeg's codec context.
Especially used for unknown audio format but supported by ffmpeg.