use super::*;
use crate::inference::audio::encode_wav_pcm16;
use bytes::Bytes;
fn ort_spec() -> WindowSpec {
WindowSpec::new(16000 * 30, 16000 * 24, 16000 * 2)
}
fn signal(n: usize, seed: f32) -> Vec<f32> {
(0..n)
.map(|i| {
let t = i as f32;
0.4 * ((t * 0.017 + seed).sin() + 0.5 * (t * 0.0031 + seed).sin())
})
.collect()
}
fn stereo_wav_pcm16(left: &[f32], right: &[f32], rate: u32) -> Vec<u8> {
let frames = left.len().min(right.len());
let data_bytes = (frames * 2 * 2) as u32;
let byte_rate = rate * 2 * 2;
let mut w = Vec::with_capacity(44 + data_bytes as usize);
w.extend_from_slice(b"RIFF");
w.extend_from_slice(&(36 + data_bytes).to_le_bytes());
w.extend_from_slice(b"WAVE");
w.extend_from_slice(b"fmt ");
w.extend_from_slice(&16u32.to_le_bytes());
w.extend_from_slice(&1u16.to_le_bytes()); w.extend_from_slice(&2u16.to_le_bytes()); w.extend_from_slice(&rate.to_le_bytes());
w.extend_from_slice(&byte_rate.to_le_bytes());
w.extend_from_slice(&4u16.to_le_bytes()); w.extend_from_slice(&16u16.to_le_bytes()); w.extend_from_slice(b"data");
w.extend_from_slice(&data_bytes.to_le_bytes());
let q = |s: f32| (s.clamp(-1.0, 1.0) * i16::MAX as f32) as i16;
for i in 0..frames {
w.extend_from_slice(&q(left[i]).to_le_bytes());
w.extend_from_slice(&q(right[i]).to_le_bytes());
}
w
}
fn window_seq(mut fw: FileWindows) -> Vec<(usize, Vec<f32>)> {
let mut out = Vec::new();
while let Some(w) = fw.next_window().expect("window") {
out.push((w.start_sample, w.samples.to_vec()));
}
out
}
fn slice_seq(buf: &[f32], spec: WindowSpec) -> Vec<(usize, Vec<f32>)> {
let mut sw = SliceWindows::new(buf, spec);
let mut out = Vec::new();
while let Some(w) = sw.next_window().expect("slice window") {
out.push((w.start_sample, w.samples.to_vec()));
}
out
}
fn expected_seq(flat: &[f32], spec: WindowSpec) -> Vec<(usize, Vec<f32>)> {
if flat.len() <= spec.single_pass_max() {
vec![(0, flat.to_vec())]
} else {
slice_seq(flat, spec)
}
}
#[test]
fn test_file_windows_16k_geometry_matches_decode_words() {
let spec = ort_spec();
for &n in &[1usize, 8_000, 480_000, 480_001, 560_000, 900_000] {
let src = signal(n, 1.0);
let wav = encode_wav_pcm16(&src, 16000);
let flat = FileWindows::from_bytes(Bytes::copy_from_slice(&wav), spec, None)
.expect("open flat")
.drain_to_vec()
.expect("drain");
assert_eq!(flat.len(), n, "passthrough length changed at n={n}");
let got = window_seq(
FileWindows::from_bytes(Bytes::copy_from_slice(&wav), spec, None)
.expect("open windows"),
);
assert_eq!(got, expected_seq(&flat, spec), "geometry mismatch at n={n}");
}
}
#[test]
fn test_file_windows_48k_stereo_matches_slice_over_drain() {
let spec = ort_spec();
let n = 48_000 * 40;
let left = signal(n, 0.3);
let right = signal(n, 2.1);
let wav = stereo_wav_pcm16(&left, &right, 48_000);
let flat = FileWindows::from_bytes(Bytes::copy_from_slice(&wav), spec, None)
.expect("open flat")
.drain_to_vec()
.expect("drain");
assert!(
flat.len() > spec.single_pass_max(),
"expected the chunked regime, got {} samples",
flat.len()
);
let got = window_seq(
FileWindows::from_bytes(Bytes::copy_from_slice(&wav), spec, None).expect("open windows"),
);
assert_eq!(got, slice_seq(&flat, spec));
}
#[test]
fn test_file_windows_channel_select_matches_batch_per_channel_decode() {
for rate in [16_000u32, 48_000] {
let n = rate as usize * 3;
let left = signal(n, 0.3);
let right = signal(n, 2.1);
let wav = stereo_wav_pcm16(&left, &right, rate);
let batch = crate::inference::audio::decode_audio_bytes_shared_channels(
Bytes::copy_from_slice(&wav),
)
.expect("batch per-channel decode");
assert_eq!(batch.len(), 2, "expected a stereo decode at {rate}Hz");
assert_ne!(batch[0], batch[1]);
for (k, want) in batch.iter().enumerate() {
let streamed = FileWindows::from_bytes_channel(
Bytes::copy_from_slice(&wav),
WindowSpec::flat(),
None,
k,
)
.expect("open channel")
.drain_to_vec()
.expect("drain channel");
assert_eq!(&streamed, want, "rate={rate} channel={k}");
}
}
}
#[test]
fn test_file_windows_channel_select_out_of_range_is_empty() {
let src = signal(16_000, 1.0);
let wav = encode_wav_pcm16(&src, 16000); let streamed =
FileWindows::from_bytes_channel(Bytes::copy_from_slice(&wav), WindowSpec::flat(), None, 5)
.expect("open")
.drain_to_vec()
.expect("drain");
assert!(streamed.is_empty(), "got {} samples", streamed.len());
}
#[test]
fn test_file_windows_single_pass_yields_one_window() {
let spec = ort_spec();
let src = signal(10_000, 0.7);
let wav = encode_wav_pcm16(&src, 16000);
let got = window_seq(
FileWindows::from_bytes(Bytes::copy_from_slice(&wav), spec, None).expect("open"),
);
assert_eq!(got.len(), 1);
assert_eq!(got[0].0, 0);
assert_eq!(got[0].1.len(), 10_000);
}
#[test]
fn test_file_windows_total_16k_samples_is_exact_at_16k() {
let spec = ort_spec();
let n = 700_000; let src = signal(n, 1.3);
let wav = encode_wav_pcm16(&src, 16000);
let mut fw = FileWindows::from_bytes(Bytes::copy_from_slice(&wav), spec, None).expect("open");
while fw.next_window().expect("window").is_some() {}
assert_eq!(fw.total_16k_samples(), n);
}
#[test]
#[ignore = "decode-only peak-RSS instrument; drive with GIGASTT_PEAK_SECONDS under /usr/bin/time"]
fn zzz_streaming_decode_peak_instrument() {
let secs: usize = std::env::var("GIGASTT_PEAK_SECONDS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(5);
let path = std::env::temp_dir().join(format!("gigastt_peak_{secs}s.wav"));
{
use std::io::Write;
let rate = 48_000u32;
let frames = secs * rate as usize;
let data_bytes = (frames * 2 * 2) as u32;
let f = std::fs::File::create(&path).expect("create temp wav");
let mut w = std::io::BufWriter::new(f);
w.write_all(b"RIFF").unwrap();
w.write_all(&(36 + data_bytes).to_le_bytes()).unwrap();
w.write_all(b"WAVE").unwrap();
w.write_all(b"fmt ").unwrap();
w.write_all(&16u32.to_le_bytes()).unwrap();
w.write_all(&1u16.to_le_bytes()).unwrap();
w.write_all(&2u16.to_le_bytes()).unwrap();
w.write_all(&rate.to_le_bytes()).unwrap();
w.write_all(&(rate * 4).to_le_bytes()).unwrap();
w.write_all(&4u16.to_le_bytes()).unwrap();
w.write_all(&16u16.to_le_bytes()).unwrap();
w.write_all(b"data").unwrap();
w.write_all(&data_bytes.to_le_bytes()).unwrap();
for sec in 0..secs {
let base = (sec * rate as usize) as f32;
for i in 0..rate as usize {
let t = base + i as f32;
let s = (0.4 * (t * 0.02).sin() * i16::MAX as f32) as i16;
w.write_all(&s.to_le_bytes()).unwrap();
w.write_all(&s.to_le_bytes()).unwrap();
}
}
w.flush().unwrap();
}
let p = path.to_str().unwrap();
let total = if std::env::var("GIGASTT_PEAK_MODE").as_deref() == Ok("drain") {
FileWindows::decode_file(p, None).expect("drain").len()
} else {
let mut fw = FileWindows::open(p, ort_spec(), None).expect("open temp wav");
let mut counted = 0usize;
while let Some(win) = fw.next_window().expect("window") {
counted += win.samples.len();
}
assert!(counted >= fw.total_16k_samples());
fw.total_16k_samples()
};
let _ = std::fs::remove_file(&path);
let expected = secs * 16_000;
assert!(
(total as i64 - expected as i64).unsigned_abs() < 16_000,
"total {total} not within 1 s of {expected}"
);
}