Commit Graph
45 Commits
Author SHA1 Message Date
ntamas94andClaude Opus 5.5 43c82acb0f docs(libSceAjm): say the empty PS4 batch contract needs a non-null address
A null batch address is refused whatever the size, so the accepted batch
of zero bytes is one at a real address, which is what TestConsoleEmptyBatch
starts.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 18:10:39 +01:00
ntamas94andClaude Opus 5.5 8c9c50b0b2 fix(libSceAjm): decode one ATRAC9 frame per PS4 run job without RUN_MULTIPLE_FRAMES
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]>
2026-10-25 18:10:39 +01:00
ntamas94andClaude Fable 5.1 414985e073 docs(libSceAjm): say the null batch probe froze the console
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-25 18:10:39 +01:00
ntamas94andClaude Fable 5.1 46f0e90b92 fix(libSceAjm): reject a null PS4 batch address
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]>
2026-10-25 18:10:39 +01:00
ntamas94andClaude Fable 5.1 e3917fa218 docs(libSceAjm): align the gapless and libSceAjmi debt entries with the PS4 probe
The gapless entry no longer says the one-frame behaviour is unverified,
since the probe measured it, and the libSceAjmi entry names the two
exports its file declares.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-25 18:10:39 +01:00
ntamas94andClaude Fable 5.1 6559a413b0 fix(libSceAjm): keep the libSceAjmi stub and refuse null batch buffers as a PS4 does
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]>
2026-10-25 18:10:25 +01:00
ntamas94andClaude Opus 5.5 e2096fa49a feat(libSceAjm): run PS4 batch buffer jobs in the console's chunk layout
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]>
2026-10-25 18:10:24 +01:00
Adrià FranchandClaude Sonnet 5.5 949a1e47ab docs(ajm): move the batch bounds debt line inside the Functional section
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-25 15:53:00 +01:00
JJenkx bd31542d50 fix(ajm): bound private batch job reads before execution 2026-10-25 15:52:55 +01:00
Adrià b64df51467 Merge pull request #8353 from MarrasFederico/docs/ajm-instance-signature-sources
docs(libSceAjm.native): credit the instance call signatures to the sources that give them
2026-10-24 11:08:39 +02:00
Adrià 7b32a842f8 Merge pull request #9984 from xXPBSXx/docs/debt-ajm-codec-info-callsite
docs(debt): note that a title call of sceAjmBatchJobGetCodecInfo agrees with the result size
2026-10-23 04:38:29 +02:00
Adrià 095474e4d4 Merge pull request #9986 from xXPBSXx/docs/debt-ajm-control-callsite
docs(debt): note that a title call of sceAjmBatchJobControl agrees with the INITIALIZE flag and sizes
2026-10-23 04:38:25 +02:00
xXPBSXxandClaude Sonnet 5.5 4d05702cdd docs(debt): note that a title call of sceAjmBatchJobGetCodecInfo agrees with the result size
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-23 03:22:58 +02:00
xXPBSXxandClaude Sonnet 5.5 e9229a1f8e docs(debt): note that a title call of sceAjmBatchJobControl agrees with the INITIALIZE flag and sizes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-23 03:14:57 +02:00
Dean 928b2a52f5 Merge pull request #9034 from hypermoist/feat/ajm-wvorbis-header-packet
feat(libSceAjm.native): build the WVorbis header packet
2026-10-23 14:14:40 +13:00
Dean 3bbd2321de Merge pull request #8468 from Gabrieljr42/feat/ajm-mp3-frame-metadata
feat(libSceAjm): parse CRC-protected and non-stereo MP3 metadata frames
2026-10-23 09:14:29 +13:00
Federico Marras a242637da4 Merge commit '3ca07d086d5f44fbe3c00370e7f03953ab46ca1b' into docs/ajm-instance-signature-sources 2026-10-22 15:47:23 +02:00
hypermist 9f6a71b6a5 Merge remote-tracking branch 'upstream/main' into feat/ajm-wvorbis-header-packet
# Conflicts:
#	core/libs/prx/libSceAjm.native/Export.cpp
#	docs/dev/debt/libSceAjm.native.md
2026-10-22 15:02:48 +13:00
xXPBSXxandClaude Sonnet 5.5 c3bd7c5f63 docs(debt): note that a title call of sceAjmBatchJobSetResampleParametersEx agrees with the argument registers
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-22 00:53:16 +02:00
boykopovar 7b1451b99b fix(ajm): recover vorbis packet parameter layouts 2026-10-21 21:45:12 +03:00
Gabrieljr42 df0a74e7c6 fix(ajm): parse protected MP3 frame metadata correctly 2026-10-21 08:48:05 -03:00
Gabrieljr42 5df064ebda Merge remote-tracking branch 'upstream/main' into feat/ajm-mp3-frame-metadata 2026-10-21 08:35:45 -03:00
Federico Marras 49f1c7207b Merge remote-tracking branch 'upstream/main' into docs/ajm-instance-signature-sources
# Conflicts:
#	docs/dev/debt/libSceAjm.native.md
2026-10-21 13:16:27 +02:00
hypermistandClaude Opus 5.5 573113e8af feat(libSceAjm.native): build the WVorbis header packet
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
2026-10-21 23:18:21 +13:00
Dean 1bcaa14234 Merge pull request #8307 from hypermoist/fix/libs-console-results-part2
fix(libs): return what the firmware returns from 31 more calls it does not implement
2026-10-21 20:57:00 +13:00
hypermistandClaude Opus 5.5 f4689c27a5 docs(libSceAjm.native): drop sceAjmInstanceCodecType from the throwing declarations
It returns the codec from the instance id as the firmware does, so the
entry for declarations that only resolve imports no longer covers it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
2026-10-21 19:56:43 +13:00
Dean 4936df7889 Merge pull request #6721 from JJenkx/feat/ajm-atrac9-vibration
feat(ajm): decode ATRAC9 vibration streams
2026-10-21 17:55:47 +13:00
Gabrieljr42 78bf409ec5 feat(libSceAjm): parse CRC-protected and non-stereo MP3 metadata frames
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%)
2026-10-20 10:08:57 -03:00
Federico Marras e517ac5281 docs(libSceAjm.native): credit the instance call signatures to the sources that give them 2026-10-20 12:54:14 +02:00
Dean Galvin eeff77c380 Merge main into pr-8106
# Conflicts:
#	docs/dev/debt/libSceAcm.md
#	docs/dev/debt/libScePlayGo.md
#	docs/dev/debt/libSceSystemGesture.md
#	docs/dev/debt/libSceWebBrowserDialog.md
2026-10-20 17:58:28 +13:00
Adrià 306bb17a27 Merge pull request #7789 from JJenkx/fix/ajm-batch-context-ownership
fix(ajm): keep batch handles within their creating context
2026-10-20 03:45:02 +02:00
juanpimg 2f0ed638dc feat(prx): declare the missing PS5 3.20 system exports
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
2026-10-19 23:16:55 +02:00
JJenkx d16e9beed9 fix(ajm): keep batch handles within their creating context 2026-10-19 03:39:00 -04:00
sebastian 3f5f84996a feat(ajm): resample interleaved s16 PCM through codec 23
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.
2026-10-17 16:40:32 +02:00
JJenkx d0f2684dce feat(ajm): decode ATRAC9 vibration channel configurations 2026-10-17 00:48:16 -04:00
Adrià 142f7555aa Merge pull request #6051 from Ondra97/codex/fix-ajm-live-instance-handles
fix(ajm): preserve live decoder handles across ID wrap
2026-10-17 06:10:21 +02:00
xXPBSXxandClaude Sonnet 5.5 4dc23f9c14 docs(debt): list the unimplemented AJM codec 23 of PPSA21480
Broken Sword - Shadow of the Templars: Reforged stops at AJM decoding codec 23, which is not one of the codec ids known in Ajm.cpp (MP3 0, ATRAC9 1, M4AAC 2, Opus 24).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-16 05:45:41 +02:00
Dean 9bec202332 Merge pull request #5517 from ps54all/feat/libsceajm-opus-family255-multistream
feat(ajm): decode Opus mapping family 255 with several channels
2026-10-15 10:48:06 +13:00
Ondra97 e60dd9d5a7 fix(ajm): preserve live decoder handles across ID wrap 2026-10-14 22:45:37 +02:00
Adrià FranchandClaude 3faeae816b docs(debt): mark the ratio ramp semantics as assumed
Co-Authored-By: Claude <[email protected]>
2026-10-14 14:46:30 +02:00
pushkarreddyy 4c58702fd0 feat(libSceAjm): support ratio ramp in sceAjmBatchJobSetResampleParametersEx 2026-10-14 14:46:23 +02:00
DavidandClaude Fable 5.1 7cc6baf118 feat(libSceAjm.native): implement the M4AAC decoder
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]>
2026-10-14 13:32:37 +02:00
ps54allandClaude Opus 5.5 911e6c83ba feat(ajm): decode Opus mapping family 255 with several channels
A family 255 instance with more than one channel carries no stream count
or mapping in its initialization words, so its decoder now opens on the
first packet: the multistream packet's self-delimited streams are counted
(RFC 6716 appendix B), each stream's TOC stereo flag marks it as coupled,
and the channels map in order. A packet whose streams do not make the
channel count throws.

Metal Gear Solid 4 Master Collection (PPSA18194) initializes a 4-channel
family 255 decoder for its intro movie.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 00:03:21 +02:00
485f638a53 fix(ajm): accept Opus mapping family 255 for a mono stream
Co-authored-by: poonasor <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 16:14:43 +05:30
Adrià FranchandClaude 342a8c4590 docs(debt): move library entries to one file per library
Co-Authored-By: Claude <[email protected]>
2026-10-12 20:38:29 +02:00