//! Criterion bench for [`SpectrogramComputer::compute_aggregate`] — the //! hot per-chunk path. Guards the zero-alloc-after-construction property: //! a future change that reintroduces allocation into this loop should //! show up here as a clear regression. #![allow(clippy::expect_used, clippy::unwrap_used)] use std::hint::black_box; use clawaudio_dsp::{SpectrogramComputer, SpectrogramConfig}; use criterion::{Criterion, criterion_group, criterion_main}; fn sine(freq: f32, sample_rate: u32, n: usize) -> Vec { (0..n) .map(|i| (std::f32::consts::TAU * freq * i as f32 / sample_rate as f32).sin()) .collect() } fn bench_compute_aggregate(c: &mut Criterion) { let cfg = SpectrogramConfig { sample_rate: 16_000, fft_size: 512, hop_size: 256, mel_bins: 16, f_low_hz: 80.0, f_high_hz: 8_000.0, }; let mut sc = SpectrogramComputer::new(cfg).expect("valid config"); // ~0.5s chunk at 16kHz, a realistic single-chunk size. let mono = sine(440.0, 16_000, 8_000); let mut out = vec![0.0f32; sc.mel_bins()]; let mut group = c.benchmark_group("dsp"); group.bench_function("compute_aggregate_16khz_500ms_16mel", |b| { b.iter(|| { sc.compute_aggregate(black_box(&mono), black_box(&mut out)) .expect("compute_aggregate"); black_box(&out); }); }); group.finish(); } criterion_group!(benches, bench_compute_aggregate); criterion_main!(benches);