diff --git a/src/livekit/NoiseGateProcessor.worklet.ts b/src/livekit/TenVadProcessor.worklet.ts similarity index 94% rename from src/livekit/NoiseGateProcessor.worklet.ts rename to src/livekit/TenVadProcessor.worklet.ts index 70d2d0db..dc4ab9d2 100644 --- a/src/livekit/NoiseGateProcessor.worklet.ts +++ b/src/livekit/TenVadProcessor.worklet.ts @@ -23,7 +23,7 @@ declare function registerProcessor( processorCtor: new (...args: any[]) => AudioWorkletProcessor, ): void; -interface NoiseGateParams { +interface TenVadParams { // TEN-VAD params vadEnabled: boolean; vadPositiveThreshold: number; // open gate when prob >= this (0–1) @@ -169,7 +169,7 @@ class TenVADRuntime { * Asymmetric ramp: 5 ms open (minimise speech onset masking), 20 ms close * (de-click on silence). */ -class NoiseGateProcessor extends AudioWorkletProcessor { +class TenVadProcessor extends AudioWorkletProcessor { // VAD gate state private vadGateOpen = true; // starts open; TEN-VAD closes it on first silent frame private vadAttenuation = 1.0; @@ -212,23 +212,23 @@ class NoiseGateProcessor extends AudioWorkletProcessor { this.tenVadRuntime = new TenVADRuntime(this.tenVadModule, 256, 0.5); this.port.postMessage({ type: "log", - msg: "[NoiseGate worklet] TEN-VAD runtime initialized, decRatio=" + this.decRatio, + msg: "[TenVad worklet] TEN-VAD runtime initialized, decRatio=" + this.decRatio, }); } catch (e) { this.port.postMessage({ type: "log", - msg: "[NoiseGate worklet] TEN-VAD init failed: " + String(e), + msg: "[TenVad worklet] TEN-VAD init failed: " + String(e), }); } } this.port.onmessage = ( - e: MessageEvent, + e: MessageEvent, ): void => { if ((e.data as VADGateMessage).type === "vad-gate") { this.vadGateOpen = (e.data as VADGateMessage).open; } else { - this.updateParams(e.data as NoiseGateParams); + this.updateParams(e.data as TenVadParams); } }; @@ -242,11 +242,11 @@ class NoiseGateProcessor extends AudioWorkletProcessor { this.port.postMessage({ type: "log", - msg: "[NoiseGate worklet] constructor called, sampleRate=" + sampleRate, + msg: "[TenVad worklet] constructor called, sampleRate=" + sampleRate, }); } - private updateParams(p: NoiseGateParams): void { + private updateParams(p: TenVadParams): void { this.vadEnabled = p.vadEnabled ?? false; this.vadPositiveThreshold = p.vadPositiveThreshold ?? 0.5; this.vadNegativeThreshold = p.vadNegativeThreshold ?? 0.3; @@ -273,7 +273,7 @@ class NoiseGateProcessor extends AudioWorkletProcessor { try { this.tenVadRuntime = new TenVADRuntime(this.tenVadModule, newHopSize, 0.5); } catch (e) { - this.port.postMessage({ type: "log", msg: "[NoiseGate worklet] TEN-VAD recreate failed: " + String(e) }); + this.port.postMessage({ type: "log", msg: "[TenVad worklet] TEN-VAD recreate failed: " + String(e) }); } } this.vadHopSize = newHopSize; @@ -287,7 +287,7 @@ class NoiseGateProcessor extends AudioWorkletProcessor { if (!this.vadEnabled) this.vadGateOpen = true; this.port.postMessage({ type: "log", - msg: "[NoiseGate worklet] params updated: vadEnabled=" + p.vadEnabled + msg: "[TenVad worklet] params updated: vadEnabled=" + p.vadEnabled + " vadPos=" + p.vadPositiveThreshold + " vadNeg=" + p.vadNegativeThreshold + " vadMode=" + newMode @@ -379,7 +379,7 @@ class NoiseGateProcessor extends AudioWorkletProcessor { if (this.logCounter % 375 === 0) { this.port.postMessage({ type: "log", - msg: "[NoiseGate worklet] vadOpen=" + this.vadGateOpen + msg: "[TenVad worklet] vadOpen=" + this.vadGateOpen + " vadAtten=" + this.vadAttenuation.toFixed(3), }); } @@ -388,4 +388,4 @@ class NoiseGateProcessor extends AudioWorkletProcessor { } } -registerProcessor("noise-gate-processor", NoiseGateProcessor); +registerProcessor("ten-vad-processor", TenVadProcessor); diff --git a/src/livekit/NoiseGateTransformer.ts b/src/livekit/TenVadTransformer.ts similarity index 92% rename from src/livekit/NoiseGateTransformer.ts rename to src/livekit/TenVadTransformer.ts index 52403af6..0f4525f6 100644 --- a/src/livekit/NoiseGateTransformer.ts +++ b/src/livekit/TenVadTransformer.ts @@ -9,11 +9,11 @@ import { type Track } from "livekit-client"; import { logger } from "matrix-js-sdk/lib/logger"; // ?worker&url tells Vite to compile the TypeScript worklet and return its URL. // Without this, Vite copies the .ts file verbatim and the browser rejects it. -import compiledWorkletUrl from "./NoiseGateProcessor.worklet.ts?worker&url"; +import compiledWorkletUrl from "./TenVadProcessor.worklet.ts?worker&url"; -const log = logger.getChild("[NoiseGateTransformer]"); +const log = logger.getChild("[TenVadTransformer]"); -export interface NoiseGateParams { +export interface TenVadParams { // TEN-VAD params — processed entirely inside the AudioWorklet vadEnabled: boolean; vadPositiveThreshold: number; // open gate when prob >= this (0–1) @@ -74,16 +74,16 @@ function getTenVADModule(): Promise { * Audio graph: sourceNode → workletNode → destinationNode * processedTrack is destinationNode.stream.getAudioTracks()[0] */ -export class NoiseGateTransformer implements AudioTrackProcessor { +export class TenVadTransformer implements AudioTrackProcessor { public readonly name = "noise-gate"; public processedTrack?: MediaStreamTrack; private workletNode?: AudioWorkletNode; private sourceNode?: MediaStreamAudioSourceNode; private destinationNode?: MediaStreamAudioDestinationNode; - private params: NoiseGateParams; + private params: TenVadParams; - public constructor(params: NoiseGateParams) { + public constructor(params: TenVadParams) { this.params = { ...params }; } @@ -107,7 +107,7 @@ export class NoiseGateTransformer implements AudioTrackProcessor { this.workletNode = new AudioWorkletNode( audioContext, - "noise-gate-processor", + "ten-vad-processor", { processorOptions: { tenVadModule, @@ -150,7 +150,7 @@ export class NoiseGateTransformer implements AudioTrackProcessor { } /** Push updated gate/VAD parameters to the running worklet. */ - public updateParams(params: NoiseGateParams): void { + public updateParams(params: TenVadParams): void { this.params = { ...params }; this.sendParams(); } diff --git a/src/settings/SettingsModal.module.css b/src/settings/SettingsModal.module.css index 5e391727..83193595 100644 --- a/src/settings/SettingsModal.module.css +++ b/src/settings/SettingsModal.module.css @@ -35,16 +35,16 @@ Please see LICENSE in the repository root for full details. color: var(--cpd-color-text-secondary); } -.noiseGateSection { +.vadSection { margin-block-start: var(--cpd-space-6x); } -.noiseGateHeading { +.vadHeading { color: var(--cpd-color-text-secondary); margin-block: var(--cpd-space-3x) 0; } -.noiseGateSeparator { +.vadSeparator { margin-block: 6px var(--cpd-space-4x); } diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index 2911af2e..e66e71b1 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -201,17 +201,17 @@ export const SettingsModal: FC = ({ /> -
+
Voice Activity Detection - +
{ + const currentParams = (): TenVadParams => { const isAdvanced = vadAdvancedEnabled.getValue(); if (isAdvanced) { return { @@ -464,23 +464,23 @@ export class Publisher { const shouldAttach = vadActive; if (shouldAttach && !audioTrack.getProcessor()) { const params = currentParams(); - this.logger.info("[NoiseGate] attaching processor, params:", params); - transformer = new NoiseGateTransformer(params); + this.logger.info("[TenVad] attaching processor, params:", params); + transformer = new TenVadTransformer(params); audioCtx = new AudioContext(); - this.logger.info("[NoiseGate] AudioContext state before resume:", audioCtx.state); + this.logger.info("[TenVad] AudioContext state before resume:", audioCtx.state); // eslint-disable-next-line @typescript-eslint/no-explicit-any (audioTrack as any).setAudioContext(audioCtx); audioCtx.resume().then(async () => { - this.logger.info("[NoiseGate] AudioContext state after resume:", audioCtx?.state); + this.logger.info("[TenVad] AudioContext state after resume:", audioCtx?.state); // eslint-disable-next-line @typescript-eslint/no-explicit-any return audioTrack.setProcessor(transformer as any); }).then(() => { - this.logger.info("[NoiseGate] setProcessor resolved"); + this.logger.info("[TenVad] setProcessor resolved"); }).catch((e: unknown) => { - this.logger.error("[NoiseGate] setProcessor failed", e); + this.logger.error("[TenVad] setProcessor failed", e); }); } else if (!shouldAttach && audioTrack.getProcessor()) { - this.logger.info("[NoiseGate] removing processor"); + this.logger.info("[TenVad] removing processor"); void audioTrack.stopProcessor(); void audioCtx?.close(); audioCtx = null; @@ -488,11 +488,11 @@ export class Publisher { // eslint-disable-next-line @typescript-eslint/no-explicit-any (audioTrack as any).setAudioContext(undefined); } else if (shouldAttach && audioTrack.getProcessor()) { - // Processor already attached — push updated params (e.g. noiseGateActive toggled) + // Processor already attached — push updated params (e.g. vadActive toggled) transformer?.updateParams(currentParams()); } else { this.logger.info( - "[NoiseGate] tick — vadActive:", vadActive, + "[TenVad] tick — vadActive:", vadActive, "hasProcessor:", !!audioTrack.getProcessor(), ); }