AnyPS5/docs/dev/debt/libSceNgs2.native.md

16 KiB

libSceNgs2.native technical debt

Unknown function info

  • NGS2 ATRAC9 waveform loops accepts one integer forward smpl loop. Inclusive RIFF endpoints and encoder-delay adjustment follow vgmstream riff.c. PPSA03747 supplies a 60-byte sampler chunk with one loop, samplerData 24, start 256, inclusive end 299224 and delay 256 for 298969 audible samples. The chunk size and loop count bound the records; samplerData is not interpreted. Output positions are assumed to use audible samples and an exclusive end. Blocks split into an optional intro, a repeated range and an optional tail; zero play count means infinite repeats, positive play count includes the first pass. ATRAC9 ranges include a preceding codec frame for decoder history. The output block layout, repeat-count mapping and error codes are unverified on hardware. Multiple, reverse, alternating and fractional loops throw.
  • NGS2 submixer UserFx (control 0x20000004) invokes the title's callback after input mixing on every playing grain, including silence. The 40-byte control and 48-byte process context follow shadPS4. PPSA03747 installs a peak-meter callback; its code confirms the channel pointers, user data 0, channel count, grain size and sample-rate offsets and returns 0. Other user data words are preserved. Flags are assumed to be 1 after registration/restart and 0 thereafter, following UserFx2's first-process convention; this callback does not inspect them. Null handlers disable the effect, setup clears it, and nonzero callback results throw. These lifecycle and error semantics are unverified on console hardware.
  • NGS2 ATRAC9 streaming keeps waveform duration and skip counts across compressed input blocks. The shared APPEND flag (2), called ONLY_DATA in the compressed-data reference, ignores an ATRAC9 continuation block's sample, skip and repeat counts, following KytyPS5; PPSA03747 confirms a 262044-byte initial buffer declaring 11310532 samples, followed by 16384-byte buffers with flags 3. Incomplete superframes are retained until more input arrives. Input-block completion callbacks allow refills; the final callback of a logical waveform waits for its buffered PCM to drain, preserving the existing complete-block repeat behaviour. This buffering, callback timing, decoded-byte accounting and starvation silence are unverified on hardware. A closed ATRAC9 stream ending before its declared samples throws; fragmented ATRAC9 waveforms with repeats are unsupported. PCM streaming retains its existing append validation and early-close behaviour.
  • NGS2 mastering voice gain (libSceNgs2.native) - the param id 0x30000004 is taken from PPSA22520 and the layout from shadPS4's OrbisNgs2MasteringVoiceGainParam; no reference gives the units or range. The levels are assumed to be linear factors applied when the mastering voice is mixed into the render buffer, so the voice's own samples stay unscaled; the LFE level applies to channel 3 of 6- and 8-channel voices, assuming the L R C LFE order of the AudioOut2 entries above, and the full-band level to the rest. Negative levels are accepted, and a new setup resets both levels to 1
  • NGS2 stereo mastering voice into a surround buffer (libSceNgs2.native) - PPSA21402 renders a 2-channel mastering voice into a 6- or 8-channel render buffer, which the mixing stage rejected. The console's conversion is unknown: the left and right channels are assumed to go to the first two buffer channels (front left and right) and the remaining channels stay silent, with no centre, LFE or surround content. Any other channel count mismatch still throws
  • NGS2 silent waveform blocks (libSceNgs2.native): flag 0x10 (named SILENCE here; no public reference names it) lets a waveform block declare samples without data. PPSA04867 adds one block with flags 0x11, data_size 0 and num_samples 16385, then another with flags 0x11 and a fully specified 0x800-byte, 1024-sample mono block, which takes the ordinary path. A dataless block under the flag outputs num_samples frames of silence, reports them through decoded_data_size, and finishes like a complete block; a dataless block without the flag still throws as not fitting its data. The flag's real name, its interaction with ATRAC9 and repeats, and the console's waveform_data for silent blocks are unverified on hardware
  • NGS2 streaming PCM waveforms (libSceNgs2.native) - PPSA21402 streams its music by adding one block whose num_samples is the whole track and whose data_size is a 16 KiB first piece, with CONTINUE, and then adds each following piece with flag 0x2 (called APPEND here) and the same num_samples. No reference describes flag 0x2. A 16-bit PCM block without skipped samples or repeats whose num_samples exceed its data is assumed to start such a stream; flag 0x2 is assumed to append the block's data to the last streaming block, ignoring its num_samples; the voice is assumed to output silence without advancing while it has played all appended data and CONTINUE is set; and the waveform is assumed to end at num_samples or, once CONTINUE is cleared, at the end of the appended data. sceNgs2VoiceGetState reports the bytes played as decoded_data_size, which the title uses to release its queued data, and the read position as waveform_data. Appending to a block that is not a stream, or other formats, skipped samples, repeats and partial frames, throw
  • NGS2 matrix levels (libSceNgs2.native) - levels are clamped to -4..4 and NaN is kept, as the PS4 firmware 11.00 libSceNgs2.sprx stores them; not yet confirmed on the PS5 library. That library rejects a level count of 0 and keeps the matrix; the PS5 error code is unknown, so a count of 0 throws. sceNgs2VoiceRunCommands is not in that library, so its matrix levels command is assumed to clamp the same way
  • NGS2 sampler voice state flag EMPTY (libSceNgs2.native) - a playing sampler voice that still accepts blocks (CONTINUE) and has played all queued blocks reports INUSE|PLAYING|EMPTY (0x20) and keeps playing, so blocks added later play on. PPSA18391 (engine: Clickteam Fusion) reads state_flags & 0x22 != 2 from sceNgs2VoiceGetState as the end of a sound and only then reuses the voice. When the console sets and clears EMPTY, and whether it also reports it for other voice types, is unverified on hardware.
  • NGS2 port matrix (libSceNgs2.native) - a port without a matrix, or with a selected matrix whose levels were never set, mixes through a default channel map: mono reaches both stereo channels at -3 dB and the 5.1 and 7.1 centre, stereo folds to mono at -3 dB per side, and wider sources fold down with 0.5 and -3 dB gains. The map and the equivalence of an unset matrix with no matrix were measured from the PS4 firmware 11.00 libSceNgs2.sprx, not yet from the PS5 library. That library only accepts submixer and mastering voices with 1, 2, 6 or 8 channels, so the map into 3, 4, 5 or 7 channels throws. A matrix set with fewer levels than the destination needs still mixes only the rows it has
  • NGS2 custom submixer rack (libSceNgs2.native, rack 0x4002) - structure layouts from shadPS4's ngs2_custom.h; module id 0x1f for UserFx2, the voice parameter id 0x40001f00 | module index, the process flags (1 on the first process call after setup, 2 after a parameter change, 0 otherwise) and the call order (setup per voice at rack creation, process after the inputs are mixed, cleanup at destruction) come only from KytyPS5. Only UserFx2 modules on a single buffer are accepted: other module ids, more buffers, a module control handler, different input and output channel counts, setup flags and default rack options throw. Each module's state is a separate buffer, not the state_offset slice of the voice state, and sceNgs2VoiceGetState still throws for this rack. As in KytyPS5, process runs only on grains where an input produced samples, so an effect tail stops with the input and a pending flag 2 waits for the next audible grain
  • NGS2 reverb rack (libSceNgs2.native, rack 0x2001) - follows the PS4 firmware 11.00 libSceNgs2.sprx, read and checked against its output at 11.025 to 48 kHz, including parameter changes during playback (differences at float rounding level); not yet compared with the PS5 library. Structure layouts come from shadPS4's ngs2_reverb.h and the param ids 0x20010000 (setup) and 0x20010001 (I3DL2) from PPSA22520. Only the default reverb_size of 1 is handled, with its 14400-sample reflection buffer; other sizes and the library's half-rate mode throw. System sample rates below about 7.5 kHz, where an allpass delay would have no samples, throw. Setup only accepts equal input and output channel counts
  • sceNgs2ReportRegisterHandler, sceNgs2ReportUnregisterHandler (libSceNgs2.native, NIDs uBIN24Tv2MI, nPzb7Ly-VjE) are throwing stubs. The signatures (report type, handler, user data, out handle) and (report handle) follow SharpProspero and shadPS4's ngs2_report.h. No report is produced yet, so registering a handler cannot be honoured. PPSA04540 imports both and registers a CPU load handler (type 5)
  • sceNgs2SystemSetSampleRate, sceNgs2SystemSetUserData, sceNgs2SystemGetUserData, sceNgs2SystemLock, sceNgs2SystemUnlock (libSceNgs2.native) - shadPS4 only checks the system handle (INVALID_SYSTEM_HANDLE) and SharpProspero names what each call does; neither gives the other limits. A sample rate of 0 and a null user data pointer throw, any other rate is accepted, and changing the rate while a sampler filter is enabled throws because the filter coefficients were computed for the old rate. Lock and unlock take the same lock as sceNgs2RackLock
  • sceNgs2RackGetInfo (libSceNgs2.native) - field order from shadPS4's OrbisNgs2RackInfo with the 64-byte name of the other info structures (216 bytes); type is assumed to be the rack id divided by 0x1000, min_grain_samples 64 (the system minimum) and state_flags 1; uid comes from a per-process rack counter, render_count is the owning system's render count and active_voice_count counts voices that are not empty (paused and stopped voices included). The last process ratio and tick and active_channel_work_count are left zero
  • sceNgs2VoiceQueryInfo (libSceNgs2.native) - only info id 0x4001 is known: PPSA22520 passes an 8-byte buffer and branches on the first word being 1 or 2, so it is assumed to be the voice channel count (0 before the voice is set up); the second word is zeroed and other ids throw
  • sceNgs2VoiceGetPortInfo (libSceNgs2.native) - layout from shadPS4; the delay and destination input are zero because ports have neither yet
  • sceNgs2ParseWaveformFile (libSceNgs2.native) - the signature (path, offset, info) is taken from the call site of PPSA21402, which sets only three argument registers; the file is read from offset to its end, the data and block offsets are taken to be relative to the start of the file, not of offset, and an unreadable file throws. The audio unit fields of a 16-bit PCM waveform are assumed to be one sample frame per unit and per frame; INVALID_WAVEFORM_DATA for a data chunk that runs past the buffer or ends inside a frame is assumed, and looped PCM and other PCM formats throw
  • sceNgs2VoiceControl sampler filter (libSceNgs2.native) - param 0x1000000a, its layout and meaning follow KytyPS5 only: location 1 type 1 is an RBJ low-pass biquad at the system sample rate after resampling, scaled by level, a set channel_mask bit bypasses that channel, type 0 turns the filter off. Other locations and types throw. The voice keeps playing a filter tail after its last block until the history is zero, with outputs below 1e-20 flushed to zero (a KytyPS5 choice); the console's tail length is unknown
  • sceNgs2PanInit / sceNgs2PanGetVolumeMatrix (libSceNgs2.native) - follow the PS4 firmware 11.00 libSceNgs2.sprx, read and checked against its output for 2, 4, 5 and 7 speakers into 1, 2, 6 and 8 channels; not yet confirmed on the PS5 library. Speakers are taken in the order L R, L R Ls Rs, L R C Ls Rs or L R C Ls Rs Lb Rb and kept in a fixed circular order, not sorted; without angles the defaults are 90/270, 40/110/250/320, 0/40/110/250/320 and 0/40/110/150/210/250/320 degrees. As in that library, defaults converted to radians keep the wrap-around entry in degrees, so angles past the last speaker pan almost fully to it. Error codes are not known for the PS5, so invalid arguments throw, including a speaker angle equal to the unit angle, on which that library loops forever. Angles so large that adding or subtracting a turn leaves them unchanged throw for the same reason
  • sceNgs2GeomResetListenerParam, sceNgs2GeomResetSourceParam (libSceNgs2.native) - the structures (12, 16, 16, 60, 96, 108, 32 and 308 bytes) come from KytyPS5's ngs2.cpp and match shadPS4's ngs2_geom.h field for field, but only KytyPS5 gives the behaviour - shadPS4 logs and returns success without writing the output. The defaults (orient front +Z, orient up +Y, sound speed 343, cone 1/360/1/360, rolloff 0/1000000/1/1, doppler factor, full-band, LFE and maximum level 1, two speakers and matrix format 2) are unverified on a PS5 title; KytyPS5 and iStark/PS5PCEM agree on them. PPSA15552 (Dead Cells) calls sceNgs2GeomResetSourceParam after creating its racks. A null output address returns INVALID_OUT_ADDRESS as elsewhere in the library rather than throwing as KytyPS5 does. sceNgs2GeomApply stays unimplemented
  • sceNgs2GeomCalcListener supports only a listener at the origin with front +Z, up +Y and flags 0. The identity matrix and preserved finite velocity and positive finite sound speed follow KytyPS5 and PS5PCEM for that case, not a PS5 measurement. Other orientations (including non-unit vectors), translations and flags throw without changing the output; the matrix convention, handedness flags and console error codes remain unverified. Nonfinite input and nonpositive sound speed also throw. Dead Cells (PPSA15552) reaches this call after the custom sampler rack in #4334, but its arguments have not been captured here. Source attenuation, panning and Doppler in sceNgs2GeomApply remain unimplemented