Commit Graph
29 Commits
Author SHA1 Message Date
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
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
2026-10-14 00:03:21 +02:00
485f638a53 fix(ajm): accept Opus mapping family 255 for a mono stream
Co-authored-by: poonasor <12569806+poonasor@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:14:43 +05:30
eljackjoestar-cmd 9a0c59570c feat(ajm): decode Opus surround mapping family 2026-10-12 02:28:14 +04:00
raghav314andClaude Opus 5.5 29c0814c90 fix(ajm): an Opus run stops before the next packet once the output has no room for its frame
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:00:50 +05:30
raghav314andClaude Opus 5.5 26bd36df84 fix(ajm): decode a single input buffer in place instead of copying its stated size
A job's inputs were joined into one vector before decoding, copying every
input buffer at its stated size. PPSA36082's FMOD submits Opus run jobs
whose one input buffer states 0xFFFFFE74 bytes (a remaining size that
went below zero) ahead of a single packet, so each such job copied about
4 GiB and sceAjmBatchStart took about a second; the mixer missed its
deadline and the title pushed silence. A job with one input buffer now
decodes from that buffer in place, reading only the packets it decodes;
jobs with several input buffers are joined as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:00:50 +05:30
MathiasDevelopesandClaude Opus 5.5 e8209307e9 feat(libSceAjm): implement sceAjmBatchJobDecodeSplit and sceAjmBatchJobSetResampleParametersEx
sceAjmBatchJobDecodeSplit queues a split run job with the stream
sideband, as sceAjmBatchJobDecode does for a single buffer pair.
sceAjmBatchJobSetResampleParametersEx with a zero ratio change per
sample sets the ratio as sceAjmBatchJobSetResampleParameters does; a
non-zero change throws, since its ramp is unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:24:54 +02:00
Dean c323d49386 Merge pull request #2052 from esatturan/fix/ajm-atrac9-gapless-segments
fix(ajm): decode an ATRAC9 run's whole input and follow gapless segments
2026-10-10 18:36:09 +13:00
Dean 07633df7fb Merge pull request #1549 from LeandroLP23/fix/gcc-warnings
fix: clear the GCC warnings in ProfileOutput, fopen, Ajm batch jobs and the SHA-256 test
2026-10-10 17:39:38 +13:00
esatturanandClaude Opus 5.5 9c95d4810e fix(ajm): decode an ATRAC9 run's whole input and follow gapless segments
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:29:58 +03:00
Zheorgyan ed8bf0bd14 test(ajm): use a synthetic AT9 block that stays inside the gradient table 2026-10-09 12:03:22 +02:00
LeandroLP23andClaude Opus 5.5 c2231a821a fix(ajm): throw for a null buffer list with a nonzero count
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 11:37:04 +02:00
LeandroLP23andClaude Opus 5.5 2bdb979e69 fix: clear the GCC warnings in ProfileOutput, fopen, Ajm batch jobs and the SHA-256 test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 11:37:04 +02:00
Joey Fisher 24623021cd fix(ajm): decode multichannel ATRAC9 streams
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.
2026-10-08 15:44:01 -06:00
raghav314andClaude Opus 5.5 72be77590c feat(ajm): implement sceAjmBatchJobSetResampleParameters and sceAjmBatchJobGetResampleInfo
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 05:36:31 +05:30
Dean e323c1f2b9 Merge pull request #909 from adriadam10/feat/ajm-batch-job-get-info
feat(libSceAjm.native): implement sceAjmBatchJobGetInfo
2026-10-07 10:08:12 +13:00
Adrià FranchandClaude 05de11ac1e feat(libSceAjm.native): implement sceAjmBatchJobGetInfo
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-06 18:01:46 +02:00
Celegans12 5e18e84f33 feat(ajm): implement sceAjmBatchJobControl
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.
2026-10-06 14:45:10 +02:00
Dean 52ae2270fc Merge pull request #768 from adriadam10/feat/ajm-mp3-parse-ofl
feat(ajm): parse the original file length in sceAjmDecMp3ParseFrame
2026-10-06 12:41:38 +13:00
Adrià FranchandClaude fc96f96ac5 feat(ajm): parse the original file length in sceAjmDecMp3ParseFrame
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-06 00:26:19 +02:00
raghav314andClaude Opus 5.5 c0c34cc83c feat(ajm): implement sceAjmBatchCancel
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>
2026-10-06 03:45:33 +05:30
raghav314andClaude Opus 5.5 23c2816d21 fix(ajm): release a batch when sceAjmBatchWait returns
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>
2026-10-05 20:36:40 +05:30
raghav314andClaude Opus 5.5 2771eeea77 feat(ajm): implement DecodeSingle, GetGaplessDecode and GetCodecInfo
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>
2026-10-05 05:55:12 +05:30
DotDebianandClaude Opus 5.5 f99be7e4d3 feat(ajm): implement sceAjmDecMp3ParseFrame
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>
2026-10-05 01:24:18 +02:00
PacukaandClaude Opus 5.5 5ecf80e2f5 feat(ajm): decode Opus (codec 24) through FFmpeg
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 14:26:57 +02:00
MichonandClaude Opus 5.5 8bbba91a04 fix(ajm): a decode job fits the 64-byte batch titles allocate
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>
2026-10-03 01:18:56 +02:00
Adrià FranchandClaude 2036697758 fix(ajm): convert planar 16-bit MP3 output from FFmpeg
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-02 09:20:45 +02:00