Silence Detection
Silence removal tells speech apart from pauses with voice activity detection rather than a volume threshold, so clicks and room noise do not count as speech. The model is Silero VAD (MIT, 1.3 MB, embedded in vv-vad) run by tract, which is pure Rust: there is no native ML runtime to ship.

vv-vad
- The model is frozen to 16 kHz by
scripts/freeze_silero_vad.py, because tract does not support the original'sIfbranches on the sample rate. Vad::pushtakes mono 16 kHz samples in pieces of any size and returns one speech probability per 512 samples (32 ms). Each chunk is preceded by a 64-sample context from the previous one, and the recurrent state is carried across chunks.- The optimized plan is built once per process (
OnceLock).
From probabilities to cuts (vv-session silence.rs)
| Stage | Rule |
|---|---|
media_speech | Decodes one stream downmixed to mono at 16 kHz, feeding the VAD and an RMS level per 32 ms window. Reports progress and can be cancelled. |
| Speech runs | Start at the threshold (default 0.5) and end 0.15 below it (hysteresis). Edges more than 12 dB below the run's median level are trimmed. Runs shorter than 0.1 s are dropped (a cough, a knock). |
clip_ranges | Media seconds to timeline frames, using clip speed, rounded inwards so a frame partly in speech is kept. |
timeline_cuts | A pause counts only where every analysed clip is silent, even across a cut between clips. Pauses shorter than the minimum silence (default 0.3 s) are kept. Head and tail (default 0.1 s each) are kept next to speech only. |
Applying
The dialog (vv-app/src/silence_dialog.rs) runs the analysis on a thread and caches it per (content hash, stream), so changing the parameters re-plans the cuts instantly. Apply removes the ranges with vv_core::edit::delete_ranges in ripple mode, as a single undo step. MCP agents use the same delete through the delete_ranges tool, with levels from get_audio_levels (analysis.rs).
No comments to display
No comments to display