Repository navigation
A Drive that fails as it joins mid-Take gets no audio, so no false dropped frames (#544) - #944
Merged
Merged
Conversation
…opped frames (#544) A stop that landed between receive reading the join requests and adding them to capturing left the Copy fed: its ring overflowed after about 4 s and the Take reported drops that never happened. A stopped mask now masks capturing on every block, and the join block takes a Copy stopped since its request was read back out of capturing, so no stale bit is left for a rejoin. Real-time path (ADR 0002): atomics only. Assisted-by: Claude Code:claude-opus-5-5
Skeyelab
enabled auto-merge (squash)
October 23, 2026 03:23
3 tasks
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
Closes #544.
Real-time path (ADR 0002): human review of the diff. This changes
Capture.receive, which runs on the audio thread. The change is atomics only: no locks, no allocation, no blocking calls (checked by a Code Reviewer).The bug
receivereadsjoinRequests, then a few lines later ORs them intocapturing. AstopFeeding(the Drive failed or retired) that landed between the two left the Copy fed with no writer draining it. After about 4 s its ring overflowed and the Take reported dropped frames that never happened. #872 closed the rest of this; this window was left.The fix
stoppedFeedsmask, one bit per Copy.stopFeedingsets it first, before clearing the request and thecapturingbit.capturingwith~stoppedFeeds, so a stopped Copy gets at most the block in flight.capturing, so no stale bit is left for a later rejoin.attachMidTakeclears the Copy's stopped bit;startCapturingclears all of them.afterJoinRead(nil in the app), runs between reading the requests and acting on them. In the app it costs one nil check, only on a block with a join waiting.Tests
stopFeedingDuringJoinRead: the Copy is stopped from inside the hook. Red first: before the fix, the stopped Copy got 960 frames; now 0.rejoinAfterStopDuringJoinRead: a Copy that lost that race and joins again is fed only from its new join block, at its new join frame. Passed on its first run (it guards the stopped bit being cleared on rejoin).receive's two mask loads. The join-block clear above closes it; hitting it deterministically would need a second hook../scripts/verify.shpassed (spelling, vocabulary, package tests, macOS and iOS app builds).Device Take needed (before External testers)
Checked by tests only. Ship in an
[internal]tag (v1.1.16). Eric's Take from that TestFlight build: a Drive that fails as it joins mid-Take, with no false dropped frames in the report.Follow-up noted, not fixed
Older than this change:
joinRequests.bitwiseAnd(~requested)can wipe a new attach request that lands in the same block window, which needs a stop plus a reattach inside one block.