Files
punktfunk/crates
enricobuehler 23edf4e702
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Failing after 4m11s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Failing after 4m24s
ci / rust-arm64 (pull_request) Successful in 2m50s
android / android (pull_request) Successful in 6m29s
ci / web (pull_request) Successful in 1m53s
ci / docs-site (pull_request) Failing after 45s
ci / rust (pull_request) Successful in 7m2s
ci / bun-nix (pull_request) Successful in 23s
fix(client): the pad's speaker shares a channel with its headphone jack, and powers up on the jack
Field result from the Deck: haptics FELT, speaker inaudible — with the routing
already proven correct. Capturing the sink's own monitor while the client renders
shows the speaker pair carrying full-scale signal:

  --coils    ch0 0.0000  ch1 0.0000  ch2 0.5000  ch3 0.5000
  --speaker  ch0 0.5000  ch1 0.5000  ch2 0.0000  ch3 0.0000

so nothing was lost on the way to the pad. The loss is inside it. Channel 1 of the
DualSense's audio function is the headphone jack's RIGHT channel *and* the built-in
mono speaker — #259 reads the same thing out of the UCM from the host side ("ch1 is
the built-in mono speaker") — and which of the two physically sounds is chosen by
`ucAudioEnableBits`, report byte 8. A pad powers up pointing at the jack, so with
nothing plugged in the speaker pair goes nowhere. The coils are channels 2/3 and are
NOT affected by that select, which is exactly why haptics worked the instant the
samples were routed right and the speaker did not.

We only ever wrote those bytes when a host forwarded a game's `AudioCtl`, so a title
that manages no audio settings of its own — and every standalone test — got silence.
A tier-A slot with the speaker capability now sends a default speaker-enable packet
beside the audio-haptics packet it already sends. A later `AudioCtl` still overrides
it verbatim, so a game driving its own volume still wins.

⚠ The path byte is EMPIRICAL, not documented: SDL's vendored SDL_hidapi_ps5.c pins
the struct layout but never writes these fields. Measured on 054c:0ce6 using the
pad's own microphone as the detector (Goertzel at the test tone): 0x20 loudest at
~5x the noise floor, 0x30 also sounds, 0x10 silent. That is thin evidence for a
constant, so both it and the volume are field levers —
PUNKTFUNK_PAD_SPEAKER_PATH / PUNKTFUNK_PAD_SPEAKER_VOLUME, hex or decimal — and an
on-glass confirmation of which value a human actually hears is still owed.

The test pins what must not regress: the two validity bits are set, volume and path
land at the same offsets the AudioCtl fold uses, every other byte stays zero, and
`ucEnableBits1` bits 0/1 stay CLEAR — asserting either would enable rumble emulation
and disable audio haptics, muting the coils to make the speaker audible.

Gates: clippy -D warnings over the four client packages, build, 207 tests (204 in
pf-client-core), fmt — on top of current main.
2026-08-16 00:53:18 +02:00
..