feat(audio): live mic meter with draggable noise gate

Adds a mic input meter to Settings for gate calibration, replacing the
blind noise-gate slider with a unified Discord/OBS-style control: the bar
shows the live mic level and a draggable handle sets the gate threshold on
the same axis. Fill is green above the gate (transmitting), dim below it
(muted), with a live status word; the handle is bright red with a dark
edge so it stays legible when the green level sweeps past it.

Two level sources:
- In-call: the capture thread peak-holds the raw (pre-gate, pre-mute)
  frame level and emits UiEvent::MicLevel ~10/sec.
- Off-call: a "Test mic" toggle runs CoreCommand::SetMicMonitor, spinning
  up a standalone capture-only stream feeding run_mic_monitor. It shares
  the backend's single capture stream, so Join tears it down first and
  leaving Settings releases it; ignored while a session is active.

The gate handle drags live via NoiseGateDragging (no disk write per pixel)
and persists once on release via NoiseGateChanged. Meter axis is 0..0.3 so
a normal voice doesn't peg. Enables the iced "canvas" feature for the
custom GateMeter widget.

Build + clippy clean, tests pass. Field-verified on desktop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 15:46:38 -04:00
co-authored by Claude Opus 4.8
parent a15c70623d
commit b4d0f2db7b
5 changed files with 394 additions and 6 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ async-trait = "0.1.89"
base64 = "0.22.1"
bytes = "1.11.1"
dirs = "6.0.0"
iced = "0.14.0"
iced = { version = "0.14.0", features = ["canvas"] }
iroh = "1.0.0-rc.0"
iroh-gossip = "0.99.0"
opus = "0.3.1"