Repository navigation
fix(haptics): no click after Switch HD rumble, retry lost PCM frames - #15
Merged
Merged
Conversation
When an HD rumble went silent, the grip stream ran 500 ms of silence and then hdStop sent two -128 dB pad cuts and a 0x86 op 1. Sent to idle actuators, these play as a click of their own, at a strength no rumble setting changes. hdStop now cuts the pads only while a tone is on, and trims the grip stream only if it played within the last 150 ms. A silent stream just stops sending frames, like the DualSense wave stream. A PCM stream keeps a fixed fill once it starts, so a frame lost on a bad channel takes its samples out of that cushion for good, and two or three losses run the stream dry. A 0x86-0x89 frame still unanswered after its same-PID resend now goes back to the front of the ring for up to two later cycles. The same cycle's backlog flush is skipped after a requeue. Fixes #14 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #14 (Switch HD rumble issues), both symptoms.
Click after the rumble ends. When an HD rumble went silent, the grip stream sent 500 ms of silence and then
hdStopsent two-128 dB0x83cuts to both pads and a0x86op 1. Sent to idle actuators, these play as a click of their own, at a strength no rumble setting changes (the report says it is the same at 10% and 500%). The DualSense wave stream ends its hang by just stopping frames and has no such click.hdStopcuts the pads only while a pad tone is still on.hdStoptrims the grip stream with op 1 only if it sounded within the last 150 ms (HD_PCM_TAIL_MS: ~40 ms pre-buffer plus 60-85 ms play-out, PROTOCOL.md §9.1).Jitter on bad channels. A PCM stream keeps a fixed fill once it starts, so a lost frame takes its samples out of that cushion for good, and two or three losses run it dry. A
0x86-0x89frame that is still unanswered after its same-PID resend now goes back to the front of the ring for up to two later cycles (PCM_RELAY_RETRIES). The same cycle's backlog flush is skipped after a requeue. This path is shared, so DualSense wave and Steam-mode0x87-0x89relay get the retry too. If only the ACK was lost, the retry lands a duplicate frame: ~8 ms of extra fill until the stream next stops.Changes
OpenPuck/haptics.cpp:hdStop,hdPcmStop(slot, trim),RelayMsg.tries,relayRequeue, retry inrfConnFlushRelay.OpenPuck/haptics.h,OpenPuck/rf_link.cpp:rfConnFlushRelay(..., bool *requeued).tests/hd_rumble/run.py: hang expiry sends nothing; new abrupt-stop and rumble-off-during-hang cases.docs/PROTOCOL.md§9.1: the retry, and why stop messages go only to actuators that may still be playing.Testing
python3 tests/hd_rumble/run.py(ASan/UBSan,-Werror) and every othertests/*/run.pypass.make check(clang-format 18.1.8) andtools/check-trailing-comments.pypass.make build(arduino-cli, adafruit:nrf52 1.7.0) compiles and links: 283,656 bytes (34% of flash), 54,432 bytes of RAM. Not run on hardware. To check on a puck in Switch Pro mode: press Test rumble at 10% and 500% and listen for a click about 0.5 s after the buzz; toggle rumble off mid-buzz to confirm an abrupt stop still ends cleanly. For jitter, use a noisy channel and a long rumble.The upstream PR (safijari#238) is not touched; this is fork main only.
🤖 Generated with Claude Code