Repository navigation
fix(streaming): keep gating dual-channel mixing on live channels after close_channel - #267
Closed
RaphaelFakhri wants to merge 1 commit into
Closed
RaphaelFakhri wants to merge 1 commit into
RaphaelFakhri wants to merge 1 commit into
Conversation
Author
|
Closing to keep the number of open PRs here manageable. Happy to reopen if it is still useful. |
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
With three or more channels,
ChannelStreamer.close_channel()(and the async equivalent) stops the mixer from aligning the channels that are still open. After any channel is closed, the mixer sends everything the longest buffer holds and pads the shorter live channels with silence. Audio that arrives later for a padded channel is then mixed at the wrong position, so it is shifted out of time against the other channels in the stream sent to the server and against the VAD timeline used for channel attribution.The mixer already intends closed channels to stop gating:
drain()builds a list of live channels for that purpose. That branch is unreachable, becausepad = force or bool(self._ended)switches to "pad to the longest buffer" as soon as any channel is closed. With two channels this is harmless, since one live channel is left. With three or more channels it isn't.Changes
_ChannelMixer.drain()gates on the shortest buffer among the channels that are still open. Closed channels never gate, and are zero-padded when they are shorter.forceflush, and once every channel is closed, all buffers are still padded up to the longest.drain()docstring describes this behavior.Behavior with two channels, and for
flush(), is unchanged.Testing
Added
test_mixer_close_channel_keeps_gating_on_live_channels. With channelsmic(100 ms),system(100 ms) androom(50 ms) buffered, closingmicand draining must send only the 800 samples that both live channels cover. Onmasterit sends 1600 samples, paddingroomwith 50 ms of silence.The full unit suite passes.