Ramp the microphone gate closed, so sentences stop ending in a click - #413
Merged
Merged
Conversation
With Mic Sensitivity on, the voice detector gates the microphone by writing gain.value: full level when it hears you, zero when it stops. The zero is the problem. At that moment the signal is still mid-decay, so cutting it is a step the size of whatever you were saying - a click in every other player's ears at the end of every sentence. You never hear it yourself, because it happens in the stream you send. Only the release is ramped, over 20 ms. The attack stays instant: at the start of speech the signal is close to silence, so there is nothing to smooth, and a fade-in would soften the first consonant of every word on top of the delay the detector already costs. Fast attack, ramped release, the way a noise gate is built. Opening the gate now also cancels a release still in flight. A plain value write does not, so speaking again inside the ramp window let the old ramp run on to zero and mute the word that had just re-opened it. MicrophoneSoundBar mirrors this gating for the settings level meter, and is deliberately left alone: its ScriptProcessorNode never writes its output buffer, so that graph is silent and has no click to remove - ramping it would only make the meter lag the gate it is there to show. Signed-off-by: Lucas Greuloch (greluc) <lucas.greuloch@gmail.com>
|
Download the artifacts for this pull request:
This service is provided by nightly.link. These artifacts will expire in 90 days and will not be available for download after that time. |
OhMyGuus
approved these changes
Sep 8, 2026
Owner
|
Thanks |
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.
The microphone half of the clicking, split out as promised in #412. Independent of it — I test-merged the two branches and they apply cleanly in either order.
The problem
With Mic Sensitivity on, the voice detector gates the microphone by writing
gain.valuedirectly:The zero is what hurts. At the moment the gate closes your signal is still mid-decay, so cutting it is a step the size of whatever you were saying — a click in every other player's ears at the end of every sentence you speak. You never hear it yourself; it happens in the stream you send, not the one you receive.
Scope is narrow, worth being clear about it: the gate only runs when
micSensitivityEnabledis on andautoGainControlis off. With the shipped defaults the gain node isn't even created, so most users have never had this.The change
Release ramped over 20 ms, attack left instant. Not symmetry for its own sake:
onVoiceStart. Word beginnings are the last thing to spend latency on.Fast attack, ramped release, the way a noise gate is built.
Opening the gate now also cancels a release still in flight. That is a real bug in the current code as much as a consequence of the ramp: scheduled automation outlives a plain
valuewrite, so without the cancel, speaking again inside the ramp window would let the old ramp run on to zero and mute the word that had just re-opened the gate.Why
MicrophoneSoundBaris not touchedIt mirrors the same gating for the settings level meter, so it looks like it needs the same fix. It doesn't: its
ScriptProcessorNodereadsinputBufferto compute an RMS and never writesoutputBuffer, so that graph outputs silence — theconnect(ctx.destination)on it is only there to keep the processor running. There is no click to remove, and ramping it would make the meter lag the gate it exists to display.Verification
npm run typecheck,npm run lintandnpm run format:checkpass.Not verified by ear — I don't have a lobby, and this one really wants an ear rather than a reviewer. Two things I'd want someone to check: that the click at the end of a sentence is actually gone, and that 20 ms of release doesn't audibly smear the last syllable. If it does, the constant is the only thing that needs moving.
🤖 Generated with Claude Code