Skip to content

Reaction: Fix Conversational Awareness resuming media too early#601

Merged
d4rken merged 1 commit into
mainfrom
fix/conversational-awareness-stale-resume
May 31, 2026
Merged

Reaction: Fix Conversational Awareness resuming media too early#601
d4rken merged 1 commit into
mainfrom
fix/conversational-awareness-stale-resume

Conversation

@d4rken

@d4rken d4rken commented May 31, 2026

Copy link
Copy Markdown
Member

What changed

Fixed Conversational Awareness bringing your media back while you're still talking. Previously, during a longer stretch of talking the music/podcast would resume on its own after about 12 seconds and then fail to pause again when you kept speaking. Now it stays paused (or volume-lowered) for as long as you're actually talking, and only resumes when you stop.

Technical Context

  • Root cause: the reaction treated a 12s gap in 0x4B frames as "speaking ended". But the pod does not stream keep-alives during sustained speech — on fw …6861 it sent an onset (1,2) then no frames for 21s while CA stayed engaged (it held ANC=transparency the whole time), so the stale-timeout fired mid-speech. The pod never re-sent an onset, so it never re-paused.
  • Disengage is now driven by the pod's explicit not-speaking frame instead of frame-silence. Status 5 is added to the terminal STOP set, since that firmware winds down 35 and never reaches 6/8/9; transitional/unknown statuses stay engaged.
  • The stale timeout is demoted from the primary disengage to a long 5-minute backstop for a fully-dropped terminal frame, and is kept longer than the 2-minute pause-resume window so a back-stopped pause is never auto-resumed (only a duck is restored). Timeout constants moved to Kotlin Duration.
  • Verified against two firmware captures (…6503 compressed 1,2,3,0xB,4,8,9 wind-down; …6861 sparse 1,2,…,3,5); a regression test reproduces the 20s-silence case.

The pod only signals CA start and end, not continuous keep-alives. On fw 6861 it held CA engaged for 21s with zero 0x4B frames while the wearer kept talking, so the 12s stale-timeout fired mid-speech and resumed media; the pod never re-sent a start frame, so it didn't re-pause.

Disengage now waits for the explicit not-speaking frame (status 5 added as a terminal STOP, since that firmware winds down 3->5 and never reaches 6/8/9). Transitional/unknown statuses stay engaged. The stale timer is demoted to a long 5min backstop for a fully-dropped terminal frame; constants moved to Kotlin Durations.
@d4rken d4rken added bug Something isn't working coms/AAP Uses Apples AirPod Protocol. Requires Android ROM with fixed L2CAP support on the Bluetooth sockets. labels May 31, 2026
@d4rken d4rken merged commit 5ee777b into main May 31, 2026
11 checks passed
@d4rken d4rken deleted the fix/conversational-awareness-stale-resume branch May 31, 2026 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working coms/AAP Uses Apples AirPod Protocol. Requires Android ROM with fixed L2CAP support on the Bluetooth sockets.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant