step3
This commit is contained in:
+19
-1
@@ -44,6 +44,20 @@ pub struct VadSettings {
|
||||
pub speech_pad_ms: u32,
|
||||
/// Speech required to fire the barge-in onset (`VAD_BARGE_IN_MIN_SPEECH_MS`).
|
||||
pub barge_in_min_speech_ms: u32,
|
||||
/// Drop an utterance shorter than this before transcription
|
||||
/// (`VAD_MIN_UTTERANCE_MS`, default 300). `0` disables the check. Filters
|
||||
/// the short VAD false-triggers (breaths, clicks, echo).
|
||||
pub min_utterance_ms: u32,
|
||||
/// Drop an utterance whose average speech probability is below this before
|
||||
/// transcription (`VAD_MIN_AVG_PROB`, default 0.25). `0.0` disables the
|
||||
/// check. Filters the soft/noisy segments that the STT would otherwise
|
||||
/// turn into hallucinated text. The average is taken over the **voiced
|
||||
/// windows only** (probability ≥ `neg_threshold`), so the trailing
|
||||
/// hangover silence (`min_silence_ms`) does not dilute short utterances
|
||||
/// like "uno" / "due". A genuine utterance still fluctuates around the
|
||||
/// speech threshold on its onset/release, so keep this well below
|
||||
/// `threshold` (default 0.5).
|
||||
pub min_avg_prob: f32,
|
||||
/// Feed the STT engine with VAD-segmented utterances instead of letting it
|
||||
/// run its own RMS segmentation (`VAD_SEGMENT_STT`).
|
||||
pub segment_stt: bool,
|
||||
@@ -62,9 +76,11 @@ impl Default for VadSettings {
|
||||
threshold: 0.5,
|
||||
neg_threshold: 0.35,
|
||||
min_speech_ms: 250,
|
||||
min_silence_ms: 300,
|
||||
min_silence_ms: 700,
|
||||
speech_pad_ms: 30,
|
||||
barge_in_min_speech_ms: 150,
|
||||
min_utterance_ms: 300,
|
||||
min_avg_prob: 0.25,
|
||||
segment_stt: true,
|
||||
barge_in: true,
|
||||
debug: false,
|
||||
@@ -91,6 +107,8 @@ impl VadSettings {
|
||||
s.min_silence_ms = env_u32("VAD_MIN_SILENCE_MS", s.min_silence_ms);
|
||||
s.speech_pad_ms = env_u32("VAD_SPEECH_PAD_MS", s.speech_pad_ms);
|
||||
s.barge_in_min_speech_ms = env_u32("VAD_BARGE_IN_MIN_SPEECH_MS", s.barge_in_min_speech_ms);
|
||||
s.min_utterance_ms = env_u32("VAD_MIN_UTTERANCE_MS", s.min_utterance_ms);
|
||||
s.min_avg_prob = env_f32("VAD_MIN_AVG_PROB", s.min_avg_prob);
|
||||
|
||||
// Hysteresis must stay below the speech threshold, and the fast
|
||||
// barge-in onset can never be slower than the utterance onset.
|
||||
|
||||
+11
-3
@@ -219,8 +219,10 @@ pub struct VadDetector {
|
||||
speech_run_ms: u32,
|
||||
/// Consecutive silence milliseconds while in speech.
|
||||
silence_run_ms: u32,
|
||||
/// Running probability average over the current utterance.
|
||||
/// Running sum of speech probabilities over the voiced windows of the
|
||||
/// current utterance.
|
||||
prob_sum: f32,
|
||||
/// Number of voiced windows contributing to `prob_sum`.
|
||||
speech_windows: u64,
|
||||
/// Windows analysed since the detector was created (for logging).
|
||||
window_count: u64,
|
||||
@@ -365,8 +367,14 @@ impl VadDetector {
|
||||
}
|
||||
|
||||
self.utterance.extend_from_slice(window);
|
||||
self.prob_sum += prob;
|
||||
self.speech_windows += 1;
|
||||
// Average only over the voiced windows. The trailing hangover (the
|
||||
// `min_silence_ms` of silence that closes the segment) must not dilute
|
||||
// the score: for a short word like "uno" it is most of the segment and
|
||||
// would drag the mean below any sane gate.
|
||||
if prob >= self.settings.neg_threshold {
|
||||
self.prob_sum += prob;
|
||||
self.speech_windows += 1;
|
||||
}
|
||||
|
||||
if prob < self.settings.neg_threshold {
|
||||
self.silence_run_ms = self.silence_run_ms.saturating_add(WINDOW_MS);
|
||||
|
||||
Reference in New Issue
Block a user