1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Voice Activity Detection trait.
//!
//! # No backend ships with this crate
//!
//! `adk-audio` defines the [`VadProcessor`] boundary but implements it nowhere.
//! Callers supply their own detector. The `vad` Cargo feature gates no code —
//! it once pulled `webrtc-vad`, which this crate never imported.
//!
//! # `&self` is the constraint on any streaming backend
//!
//! [`VadProcessor::is_speech`] takes `&self`, and the trait is `Send + Sync`, so
//! implementors are shared immutably (`Arc<dyn VadProcessor>` throughout
//! [`crate::pipeline`] and the desktop turn detector). Every serious streaming
//! VAD — Silero, TEN, Earshot — is *recurrent*: classifying a frame mutates
//! per-stream state. Such a detector cannot implement this trait without
//! interior mutability, and a `Mutex` in the per-frame path is exactly what a
//! real-time audio loop must not have.
//!
//! So a stateful backend cannot simply implement `VadProcessor`. It needs one
//! detector instance per stream, owned mutably by that stream, with an explicit
//! `reset()` at session boundaries — and a documented compatibility wrapper for
//! existing `Arc<dyn VadProcessor>` callers, not a silent lock.
//!
//! # This is a primitive, not a policy
//!
//! A `VadProcessor` reports whether audio contains speech. It carries no
//! call-control authority on its own: endpointing, answering-machine detection,
//! barge-in, and turn-taking are separate decisions layered above it. Provider
//! server VAD remains the conversational turn-taking authority unless an
//! application explicitly chooses otherwise.
/// A detected speech segment within an audio frame.
use crateAudioFrame;
/// Trait for Voice Activity Detection processors.
///
/// Used by the voice agent pipeline to gate STT inference
/// to speech-only segments.