Config 0x30 (the ambisonic layout, 4 to 16 channels) was rejected at instance init, so Demon's Souls asserted in
its audio player and crashed entering the tutorial level. Each channel is decoded as a mono stream and the
blocks are interleaved.
sceAjmBatchJobControl threw. It now appends a control job that keeps
the sideband input pointer and runs at sceAjmBatchStart: RESET (bit 13)
clears the context as sceAjmBatchJobClearContext does, INITIALIZE
(bit 14) initializes the codec, and SIDEBAND_GAPLESS_DECODE (bit 45)
overwrites the gapless total and skip counts, in this order.
The sideband input holds the gapless decode first, then the codec's
initialize parameters: 8 bytes for ATRAC9, 12 for Opus, none for MP3.
The output is the 8-byte result. Other flags, INITIALIZE for other
codecs, and other sizes throw. SIDEBAND_GAPLESS_DECODE without RESET
throws too: RPCSX and shadPS4 keep zero counts there. The bits and the
order follow shadPS4 (PS4), the overwrite with RESET follows RPCSX, and
the sizes follow the one title seen.
sceAjmBatchStart processes every job before it returns the batch id, so a
batch that has not been waited on is never pending: cancelling it returns 0.
A batch that was never issued or was already waited on returns INVALID_BATCH,
and a context id that was never issued returns INVALID_CONTEXT, as in shadPS4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAjmBatchStart records the batch id it hands out and sceAjmBatchWait
removes it. Waiting on a batch id that was never issued or was already
waited on returns INVALID_BATCH instead of 0, as in shadPS4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAjmBatchJobDecodeSingle runs a single-frame decode job with the stream
sideband. sceAjmBatchJobGetGaplessDecode and sceAjmBatchJobGetCodecInfo
append run jobs without buffers that return the gapless-decode and codec-info
sidebands.
A run job without input or output buffers no longer decodes: it reports the
instance state with a zero result instead of PARTIAL_INPUT on MP3 and Opus.
RUN_GET_CODEC_INFO (bit 11) writes the ATRAC9 codec info after the gapless
sideband. Codec info for other codecs, and codec info together with
RUN_MULTIPLE_FRAMES, throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the MPEG audio frame header and report the frame size, channel
count, samples per channel, bitrate and sample rate. The signature,
the result layout and the rate tables follow shadPS4's reimplementation
of the PS4 library. Requesting the original file length throws: that
lookup is not implemented.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Batch jobs were stored as a 72-byte header plus 16 bytes per buffer, so one decode
job took 104 bytes. GTA V initializes its MP3 batches with 0x40 bytes, every
sceAjmBatchJobDecode returned SCE_AJM_ERROR_OUT_OF_RESOURCES and its streamed
music and speech stayed silent. A job is now a 32-byte record, its buffers, and
its parameters only when it has any; the MP3 test decodes through a 64-byte batch.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>