Files
AnyPS5/docs/dev/debt/libSceVoice.md
T
Dean e3f384b216 Merge pull request #9656 from MarcZX10/codex/voice-vad-inactive-9601
fix(libSceVoice): report inactive input voice activity
2026-11-02 20:54:30 +13:00

8.5 KiB

libSceVoice technical debt

Functional

  • Voice resource and port state: resource information is eight bytes containing four 16-bit limits selected by initialization mode. Reset, pause and resume use confirmed initialization, range and missing-port errors; repeated pause/resume succeed. GetPortInfo preserves unused output fields and reports native frame sizes, but still reports a constant ready state and does not reproduce stopped-state or snapshot-slot errors. The host has no buffered voice processing or device reset backend, so reset only covers empty software ports and pause flags currently affect no audio. Initialization validates native modes and version 100, but still lacks event callback delivery and backend creation. Port creation enforces recovered format and resource limits, but does not allocate device or codec backends.
  • sceVoiceGetPortAttr: attribute 1001 is modeled as zero for an input port because the host has no capture backend and therefore has no active input voice. PPSA34502 previously reached its war-room menu with that zero result; after the fallback was removed, it stopped on this call, and #9656 reports that it reaches its Zombies intro with the host model restored. Attribute 1001 is CELLVOICE_ATTR_VAD in RPCS3's cellVoice.h, but that mapping is not confirmed for PS5. The console's result and eligible conditions remain unknown; zero is this host's model, not a measured console value. Other supported device attributes throw because the host has no device state or voice-activity processing.
  • sceVoiceEnableChat and sceVoiceDisableChat: zero-argument signatures and the not-initialized error are confirmed. Initialized calls throw because the required audio chat backend is not implemented; they no longer report success for a local flag change.

Unknown function info

  • sceVoiceVADAdjustment, sceVoiceVADPVTAdjustment and sceVoiceQAEnableRecording (libSceVoice) - follow @BunnyFl's firmware 13.42 run under an emulator with imports stubbed, not on a console. VADAdjustment(float, float) and VADPVTAdjustment (four floats) store their arguments, one copy for the library, with no argument or initialization check, and set no return value (rax came back unchanged), so they return void here; nothing reads the values. QAEnableRecording() returns 0x804E0801 before initialization and otherwise sets the recording flag and returns 0. Its busy answer (0x804E080C) and a state that returns 0 without setting the flag come from the disassembly and aren't reachable here.

  • sceVoiceDeviceInCustomerData and sceVoiceGetMemorySize (libSceVoice) - same run. DeviceInCustomerData(uint32_t port, const void* data, uint32_t size, float* gain) checks initialization (0x804E0801), a null data or gain and a *gain that is infinite, NaN or negative (0x804E0805) and an unknown port (0x804E0804), then returns 0x804E0803 for an input device port, which has no device bound here. Other port types weren't run and throw; the busy check and gain write-back past that didn't run. GetMemorySize takes nine uint32_t counts and a uint32_t*: after the initialization and null checks it writes 0 and returns 0x804E080F, as it needs initialization with version 200 and sceVoiceInit accepts only 100.

  • sceVoiceInit, sceVoiceStart, sceVoiceCreatePort, sceVoiceGetPortInfo (libSceVoice) - a second sceVoiceInit returns 0x804E0802, and Start, CreatePort and GetPortInfo return 0x804E0801 before checking any argument while the library is not initialized, as prosper reads them from the shipped module. ConnectIPortToOPort, DisconnectIPortFromOPort and ReadFromOPort throw while the library is not initialized, and WriteToIPort always does; other port and lifecycle calls return 0x804E0801, unverified unless an entry says otherwise. Whether sceVoiceInit checks a null param before its state is unknown; it checks the state first, and that sceVoiceEnd returns the library to the not-initialized state is assumed. Closes when: the other entry points are read from the module or measured on a PS5

  • sceVoiceInitHQ, sceVoiceVADSetVersion (libSceVoice) - not measured on a PS5: the signatures and rules follow shadPS4. sceVoiceInitHQ runs sceVoiceInit, as shadPS4's two share one path. sceVoiceVADSetVersion accepts versions 0 and 1 and returns 0x804E0805 for any other; nothing uses the version, as no voice activity detection runs

  • sceVoicePausePortAll, sceVoiceResumePortAll (libSceVoice) - not measured on a PS5: both return 0x804E0801 while the library is not initialized and 0 otherwise, as in shadPS4; prosper reads the same code for sceVoiceStart, and the PS3 calls in RPCS3 make the same check. Like sceVoicePausePort they change nothing that is reported: VitaSDK documents that pausing every port keeps the buffered data and the reported state, and nothing here processes port data

  • sceVoiceGetPortInfo and sceVoiceReadFromOPort (libSceVoice) - on firmware 13.42 libSceVoice.sprx, both calls check library initialization (0x804E0801) before port-range and null-pointer validation (0x804E0805). In tested configurations, sceVoiceReadFromOPort was observed to use the 0x7f upper port boundary, while sceVoiceGetPortInfo was observed to use a 0x3f boundary when native module byte 0x69d20 was 0 and a 0x7f boundary when it was 1. Which call, configuration or subsystem transition selects or changes that byte, and whether other native behavior beyond the tested argument-validation cases differs, remain unknown. AnyPS5 does not currently model the state selecting between the two sceVoiceGetPortInfo boundaries and uses the general 0x7f boundary consistent with the other port checks, as an explicit compatibility limitation rather than full reproduction of both native states.

  • sceVoiceSetMuteFlagAll, sceVoiceSetBitRate, sceVoiceUpdatePort (libSceVoice) - not measured on a PS5; signatures follow Orbital, behaviour the Vita's VitaSDK. They return the not-initialized, port-range and missing-port codes the other port calls return. The mute-all flag makes sceVoiceGetMuteFlag report every port muted without changing port flags. A non-voice port, a bitrate sceVoiceCreatePort rejects, a null param or a different port type throw, since the console's codes for them are unknown

  • sceVoiceSetThreadsParams: the priorities and affinity masks that mode 1 sets reach no host scheduling, because no voice worker threads run (see sceVoiceStart below). Mode 1 returns 0 for priorities 256-767 with non-zero masks within 0x1fff, the values a PS5 thread takes; the native result for other values is unverified, so they throw. The 32-byte event callback union is recovered, but callback delivery and device-state byte semantics remain unimplemented.

  • sceVoiceStart, sceVoiceStop and sceVoiceEnd validate initialization, container presence and native mode-dependent memory sizes, but do not partition guest working memory or run the audio workers. Start/stop currently change software state only; backend failures and active-stream shutdown are not reproduced.