feat: add VAD threshold controls and smooth gate ramp

Replace the hard 0/1 VAD gate with a 20ms ramp in the worklet to prevent
clicks on open/close transitions. Expose positive and negative speech
probability thresholds as user-adjustable settings (defaults 0.5/0.35).
Sliders with restore-defaults button added to the VAD section of the
audio settings tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mk
2026-03-23 23:57:35 -03:00
parent 1ffee2d25e
commit 859db651e0
5 changed files with 101 additions and 21 deletions

View File

@@ -42,6 +42,8 @@ import {
transientThreshold,
transientRelease,
vadEnabled,
vadPositiveThreshold,
vadNegativeThreshold,
} from "../../../settings/settings.ts";
import {
type NoiseGateParams,
@@ -467,7 +469,10 @@ export class Publisher {
return;
}
const stream = new MediaStream([rawTrack]);
vadGate = new SileroVADGate(stream, ctx);
vadGate = new SileroVADGate(stream, ctx, {
positiveThreshold: vadPositiveThreshold.getValue(),
negativeThreshold: vadNegativeThreshold.getValue(),
});
vadGate.onOpen = (): void => transformer?.setVADOpen(true);
vadGate.onClose = (): void => transformer?.setVADOpen(false);
vadGate.start().catch((e: unknown) => {
@@ -525,6 +530,13 @@ export class Publisher {
}
});
// Push VAD threshold changes to the live gate without recreating it.
combineLatest([vadPositiveThreshold.value$, vadNegativeThreshold.value$])
.pipe(scope.bind())
.subscribe(([positiveThreshold, negativeThreshold]) => {
vadGate?.updateOptions({ positiveThreshold, negativeThreshold });
});
// Push param changes to the live worklet without recreating the processor.
combineLatest([
noiseGateThreshold.value$,