Skip to content

fix: rebuild wedged taps and adapt render to the output channel layout#29

Merged
pantafive merged 1 commit into
mainfrom
fix/tap-resilience
Jul 10, 2026
Merged

fix: rebuild wedged taps and adapt render to the output channel layout#29
pantafive merged 1 commit into
mainfrom
fix/tap-resilience

Conversation

@pantafive

Copy link
Copy Markdown
Owner

Summary

Fixes #27. Two changes in the tap chain. Staleness: taps now record the resolved device object IDs next to the UIDs, and reconcileTapRouting also checks the aggregate is still alive, dropping the tap when anything mismatches or the resolve fails — the app un-mutes at full volume instead of sitting silent, and the next sync re-taps it. Render: the mix (extracted to TapMix so the hostless tests can cover it) adapts the tap's stereo mixdown to the output's channel count per frame; mono outputs get the frame average, wider outputs repeat the last channel.

Test plan

  • make test: bug test reproduces the mono garble (stereo input into a mono output downmixes per frame instead of smearing across time), plus layout-matrix and ramp tests.
  • Manual: set an app volume, force device churn (toggle Bluetooth) mid-playback, confirm the app never stays silent; call on a Bluetooth headset with a tapped app, confirm clean audio in HFP.

The staleness path itself is HAL-bound and has no hostless test; it was verified by tracing the reconcile flow.

A tap's private aggregate can die under it during device churn, and a
device can die and re-publish under the same UID. The staleness check
compared UID strings only and swallowed resolve errors, so the tap
survived either way — and .mutedWhenTapped kept the app muted with
nobody re-rendering it: total silence until Fader restarted.

Record the resolved object IDs next to the UIDs, check the aggregate is
still alive on every reconcile, and drop the tap when the resolve fails
(briefly loud beats indefinitely silent; the next sync re-taps).

The render also assumed the output stream matches the tap's stereo
layout; a Bluetooth headset dropping to mono HFP mid-call got stereo
pairs written as consecutive mono frames — garbled, robotic audio. The
mix (extracted to TapMix for hostless tests) now adapts layouts per
frame: narrower outputs average the frame, wider ones repeat the last
channel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pantafive pantafive merged commit 25483da into main Jul 10, 2026
1 check passed
@pantafive pantafive deleted the fix/tap-resilience branch July 10, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wedged tap leaves an app silent; stereo render garbles mono outputs

1 participant