Repository navigation
fix(recording): align mixed Instant audio sources to their capture times - #2647
Merged
Merged
Conversation
Mixer inputs were placed at the exact sample of every capture timestamp. Receipt-time stamps (Linux) jitter by milliseconds, so each late callback became inserted silence followed by dropped input. Packets within 2 ms of the source's sample cursor now continue it untouched; between 2 and 10 ms the cursor moves at most one sample per 256 (clock drift); from 10 ms a packet starts at its capture time as before.
A mixed audio source that took over 1 s to stop, or a mixer that had not closed 2 s later, failed the recording. Bluetooth inputs can take that long to tear down. Both now record a cleanup error and keep the audio drained so far, as a failed source stop already did.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ling An encoder that stopped draining the mixer's output past the stop deadline returned an error from finish(), which failed the recording. The mixer now stops delivering and keeps the audio already sent.
Member
Author
|
@greptileai review |
Sources were stopped one after another, so a microphone kept capturing while system audio tore down, and that audio after Stop reached the file through the mixer drain. All sources now stop together, the drain keeps only audio captured before Stop, and the source-stop and drain timeouts no longer record cleanup errors (Instant treats any cleanup error as a failed recording); the mixer closes its inputs at its own deadline.
Member
Author
|
@greptileai review this PR |
This comment has been minimized.
This comment has been minimized.
… time The source clock remap clamps a packet captured before the master clock's origin to the origin. The first real-capture microphone packet started 3.6 ms early, so it was stamped at the origin with all 480 samples and overlapped the next packet by 174 samples; the mixer then moved the microphone back over two seconds. The mixer now drops only the samples captured before the origin.
With mixer inputs aligned, system audio sits on the microphone's timeline (system minus mic 0 ms) and shares its gated offset, replacing the -60 ms and -6.7 ms mixer-mode entries.
The report test pinned the two removed mixer-mode entries; it now checks the single strict entry accepts system audio within 1 ms of the mic and rejects both old modes.
A source whose device teardown hangs held the pipeline stop forever. The stop now waits at most MIXER_STOP_TIMEOUT, logs, and drains what the mixer has; it records no cleanup error, which Instant treats as failure.
Member
Author
|
@greptileai review |
…ing their stop Pause and Resume now advance the wall-clock pause total at their own instants, so video removes the same pause time as mixed audio even when a static screen sends no frame through check() during the pause. A mixed source that misses the stop deadline is dropped without its cleanup scope, so the stop that hung is not spawned again as scope cleanup.
Member
Author
|
@greptileai review |
check() read the flag before taking the lock set_paused_at holds while it records a pause, so a frame holding a stale flag could end a pause that had just started and lose its time from the video total.
Member
Author
|
@greptileai review |
This branch was successfully deployed
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.
Instant recordings that mix the microphone with system audio could place system audio up to 60 ms before the microphone. Which offset a recording got depended on when the mixer thread first polled.
Cause
sequenceDiagram participant Mic participant System participant Mixer participant amix Mic->>Mixer: first sample captured at 200 ms System->>Mixer: first sample captured at 260 ms Note over Mixer: inputs reach amix without pts Mixer->>amix: mic samples become sample 0 Mixer->>amix: system samples also become sample 0 Note over amix: system is now 60 ms early (2,880 samples)amix, so the gap between the two sources' first samples was lost.start + samples_out / rate, so the offset stayed for the rest of the recording.Fix
Every mixer input now keeps a sample cursor on one shared timeline, which starts at the earliest captured sample (
crates/recording/src/sources/audio_mixer.rs).STARTUP_GRACE). After that it is filled with silence, and its first packet lands at its capture time.amix, so audio still queued in the mixer reaches the file. The drain keeps only audio captured before Stop. A mixer that has not closed 2 s later, or an encoder that stops draining it, costs the audio not yet delivered, never the recording.SharedWallClockPauserecords each pause interval, and frames that span a pause boundary are split (crates/recording/src/output_pipeline/core.rs). Recordings with one audio source keep the wall-clock pause path.Measured
Instant system-minus-mic offset, synthetic sources with known capture times:
AudioAnchor::FirstFrame) and is unchanged here.

Confidence Score: 5/5
The PR appears safe to merge; no blocking findings remain.Summary
The PR aligns mixed audio sources by capture time and preserves queued audio during Stop.
All four earlier, unnumbered findings are addressed. No new actionable issues were found.
Reviews (6) · Last reviewed commit: "fix: read the pause flag under the pause..." · Reviewed by Greptile