PPSA01289 (Sackboy: A Big Adventure) calls sceAudioOut2MasteringTerm when it
replaces its world, which threw. Like Init and SetParam it has no effect, as
there is no mastering stage. The title creates its next world's audio device
before it destroys the previous one, so Init runs twice before Term runs
twice; whether the console reports an error for either is unknown, so both
return 0 and the case is recorded in TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on a PS5 (firmware 13.60) through dlopen of libSceAudioOut.sprx:
a MAIN (type 0) port accepts 1, 2, 8 or 12 channels (bits 8-11) with
sample type 0 or 1 (bits 0-6). Bit 7 without 8 channels returns
0x80268001, any other unsupported format returns 0x8026800E, and both
write UINT64_MAX to the output handle. Bits 12-31 do not affect the
result. Other port types keep their current validation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A captured grain stored only the port slot and data pointer, so a port
created in a destroyed port's slot before the next push mixed the old
pointer with its own format. Ports now carry a generation that the
capture records. TechnicalDebt notes that the last grain pushed before a
title stops is never played.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The host mixes without the console's mastering stage, so the mastering
parameters have nothing to configure, as with sceAudioOut2MasteringInit.
Accept them instead of aborting, keep throwing for a null parameter
block, and record SetParam next to MasteringInit in TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Address review: read a grain's buffers at the next push without spinning
under the context lock, keep the no-device model mixing at push time,
size the pad queue from the unplayed main grains again, use generic
names in comments and TechnicalDebt, and add audio_out2_timing (next-push
read, queue level beyond the cushion, priming after running dry).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A port without an SDL device slept one block after its previous output on
every call. Rounded-up sleeps held titles that write several ports from one
thread below real time. Such ports now keep a virtual queue that drains in
real time and only wait when it holds more than the target latency.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PPSA14632 calls sceAudioOut2Set3DLatency(0xFF, 1) during its audio
setup (eboot 0x5613e2c) and fails the setup on a nonzero return. Only
latency 2 from PPSA26344 was accepted, so the call threw. Latency 1 and
2 are now accepted for the system user; 0, 3 and other users still
throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAudioOut2PortCreate threw for 12-channel ports, which PPSA26344
creates as its two 7.1.4 float beds (data format 0xc00).
Each accepted layout (1, 2, 6, 8 or 12 channels, float or int16) now
folds into the stereo mix through a coefficient table: centre, side,
back and top front channels at -3 dB, top back channels at -6 dB into
the front, LFE dropped. Zero coefficients are skipped, so NaN or Inf on
a dropped channel does not reach the mix. Ports of 3, 4, 5 or 7
channels, which were mixed as L/R, now throw, as do other counts and
formats with any of bits 12-31 set. The assumed format fields,
channel order and coefficients are listed in TechnicalDebt.
The new audio_out2_port_layouts test checks each layout's fold, float
and int16, and the formats that throw.
PPSA26344 calls sceAudioOut2Set3DLatency(0xFF, 2) right after
sceAudioOut2Initialize and fails its audio initialization on a negative
return; the export was missing, so the import did not resolve. Its
audio subsystem setup also calls sceAudioOut2MasteringInit(0), which
threw.
sceAudioOut2Set3DLatency accepts a latency of 2 for the system user
(0xFF) and throws for any other user or latency, as the unit and range
are unknown. sceAudioOut2MasteringInit accepts flags 0 and throws for
other flags. There is no 3D rendering or mastering stage, so neither
call changes the output; TechnicalDebt lists this under Functional and
the assumed signatures under Unknown function info.
The new audio_out2_latency test covers the accepted and thrown values.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report the process time at which sceAudioOutOutput or sceAudioOutOutputs
accepted the port's last block. A port that never output reports 0, and
waiting with a null pointer does not move the time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mix level is a linear gain on the pad speaker port, 32768 being 0 dB.
A pad speaker port opens at 11626 (-9 dB). An unknown handle, a port of
another type and a level above 0 dB return the AudioOut error codes; a
negative level throws, as its effect is unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title can open AudioOut2 ports of type 0x3 (the controller's speaker)
and 0x6 (its two voice-coil actuators) next to its bed and object ports.
Both were folded into the TV mix, so the haptics came out of the PC
speakers as low thumps and the controller got nothing.
A USB DualSense is also a 4-channel 48 kHz sound card: channels 1-2 feed
the speaker and headset jack, channels 3-4 the left and right actuators.
When SDL lists such a card, a context with these ports opens it and
queues a grain on it with every push: the speaker port on channels 1-2
(a mono port duplicated) and the vibration port's left and right
channels on 3-4, at the port volumes and clamped. Both ports then leave
the main mix. The card's queue gets the main queue's silence cushion when
it runs dry and drops grains that run more than two grains beyond the
main queue, so the controller keeps pace with the TV. An unplugged card
is released (its ports return to the main mix) and looked for again
every 2 s. Without a card nothing changes, and other port types and
channel counts keep their routing.
SDL2's PulseAudio backend labels a 4-channel stream FL FR FC LFE instead
of quad, and the sound server then folds channels 3-4 into the speaker.
Under that backend the card is opened as 5.1 with FC and LFE silent and
the actuators on the back pair, which lands on the card's RL/RR.