Skip to content

feat(ajm): decode Opus surround mapping family - #3831

Merged
oneandonlydean merged 2 commits into
boykopovar:mainfrom
eljackjoestar-cmd:codex/opus-surround
Oct 12, 2026
Merged

oneandonlydean merged 2 commits into
boykopovar:mainfrom
eljackjoestar-cmd:codex/opus-surround

Conversation

@eljackjoestar-cmd

@eljackjoestar-cmd eljackjoestar-cmd commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What

Lost Soul Aside (PPSA26358) submits the AJM Opus initialization tuple 4, 48000, 1. Main rejects the nonzero third word. Interpret it as the channel mapping family and provide FFmpeg with the conventional family-1 multistream layout through an OpusHead header. This enables actual surround packet decoding instead of dropping the restriction while leaving the decoder unable to open.

The parameter name follows KytyPS5's initialize structure. Header fields follow RFC 7845 section 5.1; the implicit stream allocation follows libopus 1.5.2's surround layout. The header has zero gain and pre-skip; existing AJM gapless controls retain responsibility for skipping. PCM stays in FFmpeg's native speaker order. These console ABI assumptions are recorded in TechnicalDebt. Other mapping families and sample rates still throw; family 0 rejects more than two channels.

Open PR searches for Opus, mapping family and sceAjmBatchJobInitialize found no duplicate. #3626 concerns the separate libSceOpusCeltDec API.

Tested

Windows 11 x86-64, Ryzen 7 7800X3D, 32 GB RAM, RTX 5070, WinLibs GCC 15.2.0, Release, BUILD_TESTING=ON.

  • Built the explicit libs and guest_ajm_tests targets. guest_ajm passes in approximately 0.05 s, including the existing decoding, control and resampling tests.
  • Added family-1 stereo and surround decode cases for 3 through 8 channels. Multistream fixtures combine the existing synthetic stereo tone with self-delimited silence packets, without game assets. Move the tone through every coupled stream and check its native speaker positions while all other channels stay silent. Verify 512-sample output followed by the remaining 448 samples, input consumption and decoded sample totals. Check rejection of four-channel family 0.
  • Removing the OpusHead setup makes the new regression abort at FFmpeg decoder initialization. Restoring it passes.
  • tools/check_conventions.py --base origin/main and git diff --check pass.
  • A normal title run with the local graphics integration stack changed its stopping point from the observed Opus initialization refusal to buffer descriptor uses an unsupported type during level loading. Audio output and gameplay are not claimed as verified. That run did not enable the correctly named AJM trace option, so further title tracing remains necessary.

Rebased onto main 5aaf26bd3. The Opus change is 9a0c59570. Windows main did not compile because HostPoll was defined only on Unix but called from unguarded branches; this branch includes #4021's 121b16fb4 fix with its original author, as ac4954c6e, without resubmitting that fix. The updated local integration build passes guest_ajm, guest_sce_net, masked-select, graphics, and both focused layered-volume tests. Broader integration testing has failures and a hanging layered-volume submission test; the full suite is not claimed green. Local title testing additionally used #3391, #3739, #3633, #1077, #3763, #425 and #3523; those graphics changes are excluded from this PR. Linux and macOS were not run. Console PCM comparison and the implicit surround layout remain unverified.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw; silent stubs are listed in TechnicalDebt
  • No notes, investigation files or images added to the repository
  • New third-party code is a submodule built from source (none added)
  • Generic behaviour, not specific to one title
  • Depends on: fix(libkernel): restore Windows select build for Demons Souls testing #4021 (Windows build)
  • AI-assisted: yes (Codex)

@tv7

tv7 commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

@eljackjoestar-cmd Wolverine data point for this PR. Marvel's Wolverine (PPSA03671), Windows 11, RTX 3070, Release. Main a11c8f7f7 + #757, #3588, #3633, #3846, #3867 and #3336, with and without this PR at its current head.

  • Without it, the title stops right after its intro videos: sceAjmBatchJobInitialize (Opus sample rate other than 48000 or nonzero third parameter word) not implemented. The init parameters (12 bytes, logged locally) are 00000001 0000bb80 00000000 for one instance and 00000004 0000bb80 00000001 for another: 4 channels, 48000 Hz, mapping family 1.
  • With it, both instances initialize and the title runs on to a later, unrelated graphics stop (VGT_SHADER_STAGES_EN=0x482030).

I did not check the decoded surround audio itself, only that initialization and decoding no longer stop the title.

AI-assisted: yes (Claude Code)

@eljackjoestar-cmd
eljackjoestar-cmd marked this pull request as ready for review October 11, 2026 22:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants