Files
AnyPS5/docs/dev/debt/libSceAudio3d.md
T
BunnyFlandClaude Opus 5.5 f4d2d44466 fix(libSceAudio3d): let open ex check like open in a PS4 process
In firmware 13.42 sceAudio3dPortOpenEx only sets the flag that skips
the PS4-process AudioOut2 advances, which this library never makes, so
it now opens like sceAudio3dPortOpen. A PS4-process open reports an
open port before an unsupported buffer mode or bed count, as the
firmware does, and the debt entry records the advances after an open
and a push for a PS4 SDK of 0x11000000 or later.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-31 09:30:55 +01:00

9.4 KiB

libSceAudio3d technical debt

Silent stubs

  • libSceAudio3d (libSceAudio3d) - sceAudio3dObjectSetAttributes makes the firmware 13.42 checks (the count and the array, then the port, attribute ids 1 to 11, the format and sample count of a PCM block, the reserved object, then a value for every id except RESET_STATE) but applies nothing, so an object has no samples, no gain and no position; the value checks AudioOut2 makes when it applies them are not modelled. sceAudio3dPortSetAttribute checks the late reverb level (0 to 1), the downmix spread radius (0.1 to 2) and the height-aware value as firmware 13.42's AudioOut2 (libSceAudioOut.sprx) does when Audio3d passes them on, and ignores them, and sceAudio3dPortFlush drops the frames queued by sceAudio3dPortAdvance instead of mixing and submitting them to an output

Functional

  • libSceAudio3d bed path (libSceAudio3d) - bed PCM is mixed and played: sceAudio3dBedWrite and sceAudio3dBedWrite2 queue a bed, bounded by queue_depth and NOT_READY when full, sceAudio3dPortAdvance consumes one and mixes it into a stereo frame with a linear-balance pan and a 5.1/7.1 downmix, and an advance with no bed queued mixes silence (Mixer.hpp) and queues the frame, and sceAudio3dPortPush opens a type-126 AudioOut port on first use and submits the queued frames to it. The explicit sceAudio3dAudioOutOpen, sceAudio3dAudioOutOutput and sceAudio3dAudioOutOutputs exports queue their blocks and the port drains them. The attribute enum values and the panning model are unverified

Unknown function info

  • sceAudio3dInitialize (libSceAudio3d) - a repeated call throws (NOT_READY in shadPS4, 0 in prosper). In firmware 13.42 a PS5 process gets 0 when sceAudioOut2Initialize returns 0 again and NOT_READY when it returns 0x80268004, and this project's sceAudioOut2Initialize does not model a repeated initialization. A PS4 process gets NOT_READY for a repeated call before reserved is checked, as in the firmware
  • sceAudio3dPortGetAttributesSupported: the native export validates the port before the count pointer, writes the total count without reading its incoming value, and writes the complete list when an array is supplied. These checks are matched. The list itself remains the host's three port attributes: the native list derives from AudioOut2 device capability masks, SDK version and platform mode, which the host does not yet model.
  • sceAudio3dObjectReserve (libSceAudio3d) - object ids and the max_objects limit follow shadPS4 (PS4), the only reference with a body: ids count up from 1 per port, skipping 0, 0xFFFFFFFF and ids in use. In firmware 13.42 AudioOut2 hands out the ids. The checks follow firmware 13.42: the port first, leaving the id untouched, then the pointer, and a failed reserve then writes 0xFFFFFFFF
  • sceAudio3dReportRegisterHandler (libSceAudio3d) - the 20 call reports reach the type 0 handlers after the call's own lock is released, while firmware 13.42 calls them under its report lock, where a handler that registers or unregisters a handler never returns. Here a report already under way on another thread can still call a handler after sceAudio3dReportUnregisterHandler returned, which the console's lock prevents
  • sceAudio3dPortDestroy (libSceAudio3d) - closes port 0 through sceAudio3dPortClose. Firmware 13.42 passes the port's AudioOut2 context number, not the port id, to sceAudio3dPortClose, which accepts only 0, so the console closes the port only when that number is 0. The number comes from the audio service and cannot be read from the module; this project's port is context 0
  • sceAudio3dPortOpen (libSceAudio3d) - a failed open leaves the open port's settings alone, while firmware 13.42 stores a parameter block of a known size before it checks the user, the values or the open port, so on the console a failed open while a port is open changes the granularity and buffer mode that sceAudio3dAudioOutOpen, sceAudio3dPortAdvance and sceAudio3dPortPush check afterwards
  • sceAudio3dPortOpen, sceAudio3dPortPush, sceAudio3dBedWrite2 and sceAudio3dAudioOutOpen in a PS4 process (libSceAudio3d) - firmware 13.42 stores sceKernelIsPs4Process at sceAudio3dInitialize and takes a PS4 branch in these calls. Its answers are followed where this project can give them: buffer mode 0 to 2 and 2 or 3 beds are valid, route 1 is rejected on a 2-bed port, and type 3 with param bit 17 is 0x80260007. Buffer modes 0 and 1 and 3 beds throw (not modelled), and so do formats 6 and 7, which the firmware rewrites to 2 and 5 for a PS4 SDK up to 0x3FFFFFF while sceKernelGetPs4CompiledSdkVersion throws here. For a PS4 SDK of 0x11000000 or later the firmware also advances the AudioOut2 context after a successful open and after a push that leaves the queue empty, unless sceAudio3dPortOpenEx was called; neither advance happens here. Routes 1 and 2 play on both outputs
  • sceAudio3dBedWrite2 (libSceAudio3d) - 24 channels return INVALID_PARAMETER, while firmware 13.42 also accepts 24 (besides 2, 6 and 8) and passes the bed to AudioOut2, whose handling of it is unknown
  • sceAudio3dCreateSpeakerArray (libSceAudio3d) - the speaker-array calls return the AudioOut2 result unchanged: the console translates AudioOut2 speaker-array errors into Audio3d codes, but this project's AudioOut2 speaker-array calls throw instead of returning error codes, so there is nothing to translate yet
  • Audio3d bed downmix coefficients (libSceAudio3d) - the centre and the surrounds fold into stereo with a 0.7071 gain and the LFE channel is dropped, which follows shadPS4 (PS4): its DOWNMIX_CENTER and DOWNMIX_SURROUND are 0.7071 and its DOWNMIX_LFE is 0, so the if constexpr that adds the LFE is compiled out. prosper disagrees on the LFE only: it folds it into both sides with a 0.5 gain, in its AudioOut2 main bed path, which is not an Audio3d path. KytyPS5 has no Audio3d mixing at all. The absolute level is unmeasured: fpPS4 scales the front by 1 + 3/sqrt(2) instead of 1
  • Audio3d bed channel order (libSceAudio3d) - the buffer is read as L, R, C, LFE, Ls, Rs, Lrs, Rrs, the standard order, which three references agree on: shadPS4 reads the front, centre, LFE and surround samples at those indices, prosper documents FL, FR, FC, LFE and then surround pairs, and fpPS4 names them _FL=0 _FR=1 _FC=2 _LF=3 _SL=4 _SR=5 _BL=6 _BR=7. fpPS4's STD layout swaps the side and back pairs, which this library does not model
  • sceAudio3dAudioOutOutput (libSceAudio3d) - returns 0 as firmware 13.42 does (it hands the block to AudioOut2 and returns its result), but queues the block itself, returns NOT_READY when queue_depth blocks are pending and accepts only handles opened through sceAudio3dAudioOutOpen, while the console accepts any AudioOut handle and leaves the queue to AudioOut2
  • sceAudio3dAudioOutClose (libSceAudio3d) - closes only handles opened through sceAudio3dAudioOutOpen and returns INVALID_PORT for any other, while firmware 13.42 asks libSceAudioOut for the handle's AudioOut2 port and closes every handle that lookup accepts. sceAudio3dPortClose leaves these handles open as firmware 13.42 does, but drops their pending blocks, and sceAudio3dAudioOutOutput on them returns INVALID_PORT, while the console hands the block to AudioOut2, whose result once the port's context is destroyed is unknown
  • sceAudio3dPortAdvance buffer mode (libSceAudio3d) - a mode other than 2 returns NOT_SUPPORTED (0x80EA0008), the value shadPS4 uses for it and the one prosper reads from the PS5 module's own error table, where 0x80EA0008 is what the per-port calls return for a buffer mode they do not support. shadPS4 and prosper refuse only mode 0 in sceAudio3dPortAdvance and modes 0 and 1 in sceAudio3dPortPush, while KytyPS5 requires mode 2 at sceAudio3dPortOpen and halts otherwise, so this library refuses every other mode at the open and the check here is unreachable. 0x80EA0005 is OUT_OF_MEMORY, not NOT_SUPPORTED
  • sceAudio3dPortAdvance on a full queue (libSceAudio3d) - a full queue returns NOT_READY (0x80EA0007) instead of throwing, which follows shadPS4, the only reference with a body: it returns ORBIS_AUDIO3D_ERROR_NOT_READY when the mixed queue is at the port's depth. KytyPS5 halts instead and prosper has no queue at all