The null buffer list check in Append ran for every batch-job builder,
although only sceAjmBatchJobRunSplit and sceAjmBatchJobControl pass a
caller's buffer lists. It now runs in CheckedAppend, after the same
invalid-parameter checks, for those two and for
sceAjmBatchJobGetStatistics, whose zero-filled result has no source.
The other builders append without it. No job is built or run
differently.
The guest test builds Initialize, ClearContext, SetGaplessDecode,
SetResampleParameters, SetResampleParametersEx and GetResampleInfo jobs
without buffers and runs them, and checks that RunSplit still throws
for a null input or output list with a nonzero count without writing
to the batch.
A probe on a PS4 decoded exactly one frame and reported 0 for an ATRAC9
run job without RUN_MULTIPLE_FRAMES. Jobs read from a PS4 batch buffer
now do the same. Jobs from the PS5 builders keep decoding their whole
input, which FMOD in PPSA29141 relies on.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceAjmBatchStartBuffer let a null batch of zero bytes through its
parameter check and formed the end pointer from it. A null batch now
returns INVALID_PARAMETER whatever the size, as the PS5 builders'
sceAjmBatchInitialize does; a batch of zero bytes still starts, runs
nothing and completes at once. A test covers both; neither was measured
on a console, which the debt entry says.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Review of the PS4 batch buffer change. The libSceAjmi stub of
sceAjmBatchJobRunBufferRa stays, declared with the _nid_disambig1 suffix
so that both libraries export the NID without defining one name.
sceAjmBatchStartBuffer reads the whole batch before running any job, as
probe batches on a PS4 showed: a buffer chunk of size zero is dropped
whatever its address, and a null address with a nonzero size refuses
the batch with INVALID_ADDRESS in the error record together with the job
chunk, the chunk's offset in the job and the job's return address, with
nothing of the batch run. Inputs and outputs share that rule. The
console-measured result flags move from test comments to the debt
entries.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
PS4 titles build AJM batches with the SDK's inline helpers, which call
sceAjmBatchJobControlBufferRa, sceAjmBatchJobRunBufferRa and
sceAjmBatchJobRunSplitBufferRa and start the buffer with
sceAjmBatchStartBuffer. The buffer belongs to the title, so it has to use
the console's chunk layout rather than this library's private records.
The builders write console jobs (job, return address, buffer and flags
chunks) and return the position after them. StartBuffer checks the
context, walks the chunks, skips inline data and runs each job as the
library's existing control, run or statistics job. Chunk headers are read
as the console's builders write them: bits 0-3 the kind, bit 4 a buffer's
output direction, bits 6-25 the payload; the other bits keep a reused
buffer's old bytes on a PS4. Malformed batches return MALFORMED_BATCH,
unknown chunk kinds and unimplemented control flags throw.
An ATRAC9 run with RUN_MULTIPLE_FRAMES reports which side ran out as a
PS4 does (0x8 input, 0x10 room, 0x18 both), and the ATRAC9 format reports
the frame's bitrate; both were measured on a PS4 with Knowledge is Power:
Decades (Wwise) batch dumps and probe runs. The vibration test's exact-fit
run expects 0x18 accordingly.
The throwing stubs in libSceAjm and the libSceAjmi copy of
sceAjmBatchJobRunBufferRa are dropped.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Fable 5.1 <[email protected]>
atrac9_gradient_tests is a C program linked against the static atrac9
library, whose band_extension.c calls pow. The test never listed libm.
The default Linux build links tests statically with --gc-sections, which
drops the unreferenced band extension code before pow has to resolve,
so the missing library went unnoticed. A shared link, as in an
ANYPS5_ENABLE_ASAN build, resolves symbols before collecting sections:
ld finds pow only in the libm.so.6 that libasan pulls in and stops with
"DSO missing from command line", so the test is never built and ctest
reports it as not run.
Link libm outside Windows, as atrac9_config_data_tests next to it
already does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
NpTrophy reads the trophy count and icons from the title's trophy
package (names are encrypted and stay not implemented), PS4 v1 save data
calls wrap the native v2/v3 ones, and NpWebApi library contexts, handles
and push event filters work offline (service filters fail without a
signed-in user). libSceAjm is built from the libSceAjm.native sources
for PS4 titles. Limbo's (CUSA01664) remaining PS4 imports, including the
synchronous PS4 TUS calls and the Facebook dialog calls next to the
existing libraries, are exported as not implemented.
sceAjmDecWVorbisCreateHeaderPacket checks its 0x48-byte parameter as the
PS5 module does and writes a five-entry length table, a Vorbis
identification header from the parameters, an empty comment header and
the setup packet.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
Parse Xing/Info and LAME tags across candidate offsets covering both CRC-protected and unprotected streams, and accept VBRI headers at byte 36 for non-stereo / MPEG-2 frames. Reject non-Layer-3 streams with SCE_AJM_ERROR_INVALID_PARAMETER without throwing.
Progress: sceAjmDecMp3ParseFrame implemented (libSceAjm.native: 19/40 -> 20/40, 50.0%)
The NetCtl ApRp calls, the SaveData debug calls, HttpDbgEnableProfile,
HttpDbgSetPrintf, PadEnableExtensionPort and VideoRecording Init, Term
and SendCommand return 0; ImeForTestFunction returns 0x80BC00FF; the Hmd
distortion work memory align and size are 0x400 and 0x20000 and
DistortionGetCompoundEyeCorrectionCommand returns 0x81110009;
AjmInstanceCodecType returns the instance id shifted right by 14.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
AnyPS5 resolves a title's imports by NID, so a title that imports a system
function no library provides fails to load with an unresolved import. The
PS5 3.20 export inventory lists 193 such exports across 37 PS5 system
libraries AnyPS5 implements but does not provide.
Declare them as throwing stubs so those titles load and reach their next
blocker. Each declaration calls NotImplemented_nid_no_patch and returns 0;
none of them implements the function. Declarations with a credible
prototype use it and cite the source with a pinned commit, and the rest
are declared without parameters, which resolves the import without making
an ABI claim. The technical-debt files record the limitation per library.
libSceMbus and libSceSystemService are left out because pull request #7821
declares them. libSceAgc is left out because its exports are versioned, so
the 3.20 NID names a different symbol from the one AnyPS5 ships.
libSceAvPlayer.native is left out because it compiles libSceAvPlayer's
Export.cpp.
Names and NIDs come from the PS5 3.20 export inventory at
https://github.com/DNNDHH/PS5-3.20_Libs/tree/b2a77c09cd71c01f34c790cfbe98c751a13262ad
Broken Sword - Shadow of the Templars: Reforged (PPSA21480) decodes its
audio itself and uses AJM codec 23 only to resample interleaved s16 PCM
from 44.1 to 48 kHz: every block initializes the instance with
0, 2, 44100, sets the ratio 0.91875 and decodes 235 frames into a
256-frame output. The run threw "AJM: decoding codec 23 is not
implemented".
A codec 23 run now consumes its whole input and emits every output
frame whose position lies inside it, with the Catmull-Rom of the
existing resampler. Cases the title does not show throw, among them a
run after a resampled run without a new initialize.
LibAtrac9 defines six channel configurations but indexed the table with all eight values of the 3-bit field, so indices 6 and 7 read past it and initialized a decoder from the bytes that follow. The config data check now fails for them, which sceAjmDecAt9ParseConfigData, AJM initialization, libSceAudiodec and NGS2 already report as invalid config data.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Ghost of Yotei (PPSA26344, v1.008, eboot 0x2e1cfc) creates an M4AAC
instance (codec 2) and calls sceAjmBatchJobControl with flags
0x200000006000 (RESET | INITIALIZE | SIDEBAND_GAPLESS_DECODE), 8 bytes of
gapless decode plus 8 bytes of M4AAC initialize parameters and an 8-byte
result (#884); INITIALIZE for M4AAC threw on main.
- INITIALIZE (control and sceAjmBatchJobInitialize) reads the 8-byte
{config type (1 ADTS, 2 raw), sampling frequency index} block of
shadPS4 ajm_aac.h at 443f0224; an invalid type or a raw index above 11
returns the invalid parameter result. Raw input is configured from the
instance channels (0 is stereo) as in shadPS4 ajm_aac.cpp.
- RUN decodes ADTS frames (length from the header) and raw access units
(the whole input, as fdk-aac's raw transport) with FFmpeg's AAC decoder
into the instance's S16, S32 or float PCM, with the framework's gapless,
resampling, stream, format and multiple-frames sidebands.
- Without ENABLE_NONDELAY_OUTPUT the first two frames after
initialization or reset produce no output, as in shadPS4. A decoder
error returns CODEC_ERROR | FATAL. The codec info is {heaac, reserved};
the format reports the last frame's bitrate with fdk-aac's formula.
- Throws for what the sources do not settle: ADTS resynchronization,
profiles other than AAC LC, several raw data blocks per frame, channel
configurations other than 1, 2 and 6, more channels than the instance,
HE-AAC without ENABLE_SBR_DECODE, raw input with RUN_MULTIPLE_FRAMES or
several access units, a frame longer than the reserved room, and
unknown codec flags.
guest_ajm decodes an embedded 5-frame stereo ADTS fixture (two chirps,
encoded by FFmpeg 6.1.1's aac encoder at 64 kbit/s) frame by frame, in
one multiple-frames run, as float, as raw access units and with gapless
trimming, and checks sample counts, format, codec info, the delay frames,
RESET, partial input, missing room and the correlation of each channel
with its input chirp at the 1024-sample encoder delay; plus the
INITIALIZE validation results and the refusals.
Co-Authored-By: Claude Fable 5.1 <[email protected]>