Skip to content

feat(web): add mic noise suppression and adaptive VAD#64

Merged
sonsangwoo1116 merged 1 commit into
mainfrom
feat/web-mic-noise-suppression
Jul 3, 2026
Merged

feat(web): add mic noise suppression and adaptive VAD#64
sonsangwoo1116 merged 1 commit into
mainfrom
feat/web-mic-noise-suppression

Conversation

@starz-woo

Copy link
Copy Markdown
Contributor

Summary

  • Adds browser-side (caller mic) noise robustness: high-pass filter (100Hz) + Speex denoiser (WASM AudioWorklet) on top of browser-native noiseSuppression, plus a noise-floor-adaptive client VAD.
  • Relay pipeline untouched: output format stays 16kHz PCM16 base64 100ms chunks; VAD state machine semantics unchanged. Server-side echo gating (paper Section 3) is not affected.

Changes

  • apps/web/lib/audio/web-recorder.ts — mic chain source → high-pass → Speex denoiser → capture; package dynamically imported (touches browser-only globals at module scope, breaks SSR otherwise); graceful fallback to native suppression if assets fail; wasm fetched once per page and reused across calls.
  • apps/web/lib/audio/vad.ts — thresholds adapt as max(fixed minimum, noiseFloor × ratio) with asymmetric EMA floor tracking (fast decay 0.3 / slow attack 0.05, cap 0.04); speech-level frames excluded from floor updates; degenerates to existing fixed thresholds in quiet rooms. Debug getters added.
  • apps/web/public/noise-suppressor/ — vendored speexWorklet.js + speex.wasm from @sapphi-red/web-noise-suppressor@0.3.5 dist (AudioWorklet modules must load by URL; SHA-256 verified against npm).
  • apps/web/package.json / package-lock.json — new dependency @sapphi-red/web-noise-suppressor@0.3.5 (MIT).

Quality Gate

  • Score: 83/100 (Grade B)
  • Status: PASS — no Critical findings; security check clean (vendored asset hashes match npm dist, lockfile integrity present)
  • Known fast-follows (non-blocking): pre-existing stop()-during-start() race window widened by new awaits; silent catch on denoiser fallback could use a console.warn

Test Plan

  • tsc --noEmit, eslint (touched files), next build all pass
  • Manual: noisy environment (fan/music) — speech onset detected, commit fires after speech ends
  • Manual: quiet environment — behavior identical to before
  • Manual: block /noise-suppressor/* in DevTools — recorder falls back gracefully

🤖 Generated with Claude Code (/auto-commit)

Caller-side (browser) noise robustness; relay pipeline untouched
(output stays 16kHz PCM16 base64 100ms chunks, VAD state machine
semantics unchanged).

- web-recorder.ts: mic chain source -> high-pass (100Hz) -> Speex
  denoiser (WASM AudioWorklet via @sapphi-red/web-noise-suppressor,
  dynamically imported to avoid SSR breakage) -> capture. Graceful
  fallback to browser-native noiseSuppression if assets fail.
- vad.ts: thresholds adapt to ambient noise floor via asymmetric
  EMA (fast decay / slow attack, capped); degenerates to existing
  fixed thresholds in quiet environments.
- Vendored speexWorklet.js + speex.wasm (v0.3.5 dist, SHA-256
  verified against npm) into public/noise-suppressor/ since
  AudioWorklet modules must load by URL.

Quality Score: 83/100
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
wigvo-web Ready Ready Preview, Comment Jul 3, 2026 5:19am

@sonsangwoo1116 sonsangwoo1116 merged commit bc54741 into main Jul 3, 2026
5 checks passed
sonsangwoo1116 added a commit that referenced this pull request Jul 3, 2026
revert(web): remove mic noise suppression and adaptive VAD (#64)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants