fix: rebuild wedged taps and adapt render to the output channel layout#29
Merged
Conversation
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>
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 #27. Two changes in the tap chain. Staleness: taps now record the resolved device object IDs next to the UIDs, and
reconcileTapRoutingalso 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 toTapMixso 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.The staleness path itself is HAL-bound and has no hostless test; it was verified by tracing the reconcile flow.