nx_vad.nx
buildroot/runtime/nx_vad.nx
about
nx_vad.nx -- voice activity detection. Phase 4a piece 4/5.
Returns a sealed per-frame verdict so the encoder can SKIP
transmitting silent frames (save ~30% of typical-call bandwidth)
or transmit only a "comfort noise" descriptor (a few bytes vs a
full-rate payload).
Features used (all integer):
1. Short-time energy: sum of squared samples in the frame.
2. Zero-crossing rate: count of sign flips; voice has lower ZCR
than unvoiced (whisper, breath, hiss).
3. Stability: smoothed energy of previous 3 frames vs current.
We DON'T use spectral features (FFT) at this layer -- they're
available via nx_fft but would couple this primitive to that one;
substrate cardinal "compose; don't couple" keeps VAD self-contained
and Tier-0 friendly.
genealogy_id: rabiner_sambur_1975_voiced_unvoiced + opus_silk_vad +
webrtc_vad_2011
lineage_id: nishi_vad_q10
dependencies 1 imports · 1 importers
imports: nx_syscalls.nx
imported by: nx_voice_codec.nx
structs
| 40 | struct VadState |
consts
| 32 | const NX_VAD_VERDICT_UNKNOWN: i64 = 0 |
| 33 | const NX_VAD_VERDICT_SILENCE: i64 = 1 |
| 34 | const NX_VAD_VERDICT_TRANSITION: i64 = 2 // start/end of an utterance |
| 35 | const NX_VAD_VERDICT_VOICE: i64 = 3 |
| 36 | const NX_VAD_VERDICT_NOISE: i64 = 4 // non-voice sound (e.g. typing) |
| 37 | const NX_VAD_VERDICT_N: i64 = 5 |
functions
| 50 | func nx_vad_energy(samples: *i64, n: i64) -> i64 |
| 67 | func nx_vad_zero_crossings(samples: *i64, n: i64) -> i64 called by 1: nx_vad_classify |
| 80 | func nx_vad_init(s: *VadState) -> i64 |
| 95 | func nx_vad_classify(s: *VadState, samples: *i64, n: i64) -> i64 |
| 153 | func nx_vad_verdict_is_valid(v: i64) -> i64 |