use svod_dtype::DType;
use svod_tensor::Tensor;
use crate::silero_vad::{CONTEXT_SIZE, HIDDEN, NUM_SAMPLES, SileroVad, VadInference};
#[test]
fn forward_chunk_zero_weights_shape() {
let vad = SileroVad::with_random_weights();
let chunk = Tensor::zeros(&[1, CONTEXT_SIZE + NUM_SAMPLES], DType::Float32).unwrap();
let state_h = Tensor::zeros(&[1, HIDDEN], DType::Float32).unwrap();
let state_c = Tensor::zeros(&[1, HIDDEN], DType::Float32).unwrap();
let out = vad.forward_chunk(&chunk, &state_h, &state_c).unwrap();
let shape: Vec<usize> = out
.shape()
.unwrap()
.iter()
.map(|s| s.as_const().or_else(|| s.vmax()).expect("concrete or symbolic-max shape"))
.collect();
assert_eq!(shape, vec![1, 1 + 2 * HIDDEN]);
}
#[test]
#[ignore = "heavy: full SileroVad JIT compile + execute on random weights"]
fn vad_inference_runs_on_random_weights() {
let vad = SileroVad::with_random_weights();
let mut inf = VadInference::new(vad).expect("prepare");
let waveform = vec![0.0_f32; 4 * NUM_SAMPLES];
let probs = inf.probs(&waveform).expect("probs");
assert_eq!(probs.len(), 4, "one prob per {NUM_SAMPLES}-sample chunk");
for p in &probs {
assert!(p.is_finite(), "non-finite VAD prob: {p}");
assert!((0.0..=1.0).contains(p), "VAD prob outside [0, 1]: {p}");
}
}
#[test]
#[ignore = "heavy: full VAD pipeline + chunker on random weights"]
fn vad_segment_random_weights_ranges_are_well_formed() {
let vad = SileroVad::with_random_weights();
let mut inf = VadInference::new(vad).expect("prepare");
let waveform = vec![0.0_f32; 16_000];
let ranges = inf.segment(&waveform, 0.5);
for (start, end) in &ranges {
assert!(start <= end, "inverted range: ({start}, {end})");
assert!(*end <= waveform.len(), "range past waveform end: ({start}, {end})");
}
}