The Problem
Real-time voice activity detection (VAD) is a prerequisite for speech pipelines, but most VAD models are either too heavy for edge devices or introduce unacceptable latency. TEN VAD targets that gap: a lightweight, low-latency VAD that runs on CPU across mobile, desktop, and web platforms without a GPU dependency.
What This Does
TEN VAD is a VAD engine with a C++ core (src/) and a public C API (include/ten_vad.h). The repo ships prebuilt binaries for Android, iOS, macOS, Windows, Linux, and WebAssembly under lib/, so you can integrate without compiling the core. The README highlights ONNX model support (the model and preprocessing code were open-sourced in June 2025), enabling deployment on "any platform and any hardware architecture."
This is a portfolio of five self-contained projects, not a single codebase: the core C++ library (src/, include/), language bindings (Python, Go, Java, JavaScript), platform-specific examples (examples/, examples_onnx/), prebuilt binaries (lib/), and CI workflows (.github/workflows/test-platforms.yml). The substantial pieces are the C++ core, the ONNX inference path, and the WebAssembly build.
How It Is Wired
No internal call graph was mapped, so the wiring is not fully traced. The entry points are examples/main.c (C), examples/go-tenvad/main.go (Go), and setup.py (Python). A typical path: the example reads a WAV file (examples/s0724-s0730.wav), feeds frames to the VAD via the C API, and receives speech/non-speech decisions. The ONNX path (examples_onnx/) runs the model through ONNX Runtime, with Python bindings in examples_onnx/python/ten_vad_python.cc. The WebAssembly build (lib/Web/ten_vad.js) exposes the same API to browsers.
The Go binding (examples/go-tenvad/vad.go) wraps the prebuilt .so/.dll via cgo. The Java binding (include/TenVad.java) uses JNI. The lib/ folder holds the actual binaries, so language bindings are thin wrappers over the C API.
How To Use It
Setup: Clone and build the C library:
git clone https://github.com/moses-y/ten-vad
cd ten-vad
mkdir build && cd build
cmake .. && make
Configuration: No environment variables are required. The VAD accepts a sample rate and hop size; the README documents supported rates (typically 16 kHz) and hop sizes.
Running it: Use the C example:
cd examples
./build-and-deploy-linux.sh # builds the demo
./ten_vad_demo s0724-s0730.wav
For Python with ONNX:
cd examples_onnx/python
pip install -r requirements.txt
python ten_vad_demo.py
Real-World Use
In a real-time ASR pipeline (e.g., a voice assistant), TEN VAD sits between the audio capture and the speech recognizer. It segments the audio stream, passing only speech frames to the ASR engine, cutting cost and latency. The WebAssembly build enables browser-based voice UIs without a server round-trip.
Code Health & Issues
Static analysis found 25 issues (14 high, 11 medium) across the repo:
- High – Deep nesting in
include/ten_vad.hand its iOS/macOS copies (max indentation depth 8). Control flow is hard to follow. - High – Duplicated code blocks: 123 repeated 6-line blocks across 21 files, mostly in
build-and-deploy-*.shscripts. - High – Oversized files:
src/fftw.c(3477 lines),src/aed.cc,src/pitch_est.cc— changes ripple widely. - Medium – Empty
catch {}inlib/Web/ten_vad.jssilently discards errors. - Medium – High branching density in
examples/go-tenvad/vad.go(38 branch points over 118 lines).
The code health audit adds: High – no test suite despite 14 source files; Medium – GITHUB_TOKEN lacks least-privilege permissions in .github/workflows/test-platforms.yml; Medium – no Dependabot/Renovate; Medium – no dependency vulnerability scan in CI; Medium – persist-credentials not disabled on checkout; Low – no job timeouts; Low – missing .editorconfig and .gitattributes.
The Bottom Line
TEN VAD is a solid, production-ready VAD with broad platform coverage and a clean C API. The prebuilt binaries and multiple language bindings make integration fast, but the core lacks tests and the build scripts are heavily duplicated. Use it if you need a lightweight, cross-platform VAD and can tolerate the maintenance debt in the supporting scripts.