use audio_samples::{AudioStatistics, sine_wave};
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use std::time::Duration;

fn bench_statistics_peak_rms(c: &mut Criterion) {
    let audio = sine_wave::<f32, f32>(440.0, Duration::from_secs_f32(0.8), 44100, 0.8);
    c.bench_function("statistics::peak", |b| b.iter(|| black_box(audio.peak())));
    c.bench_function("statistics::rms", |b| {
        b.iter(|| black_box(audio.rms::<f32>()))
    });
}

fn bench_statistics_min_max_mean_variance_std_zcr(c: &mut Criterion) {
    let audio = sine_wave::<f32, f32>(660.0, Duration::from_secs_f32(0.6), 44100, 0.6);
    c.bench_function("statistics::min_max", |b| {
        b.iter(|| black_box((audio.min_sample(), audio.max_sample())))
    });

    c.bench_function("statistics::mean_variance_std", |b| {
        b.iter(|| {
            black_box((
                audio.mean::<f32>(),
                audio.variance::<f32>(),
                audio.std_dev::<f32>(),
            ))
        })
    });

    c.bench_function("statistics::zcr", |b| {
        b.iter(|| black_box((audio.zero_crossings(), audio.zero_crossing_rate::<f32>())))
    });
}

fn bench_statistics_cross_correlation(c: &mut Criterion) {
    let a = sine_wave::<f32, f32>(440.0, Duration::from_secs_f32(0.5), 44100, 0.8);
    // slightly different frequency for correlation
    let b = sine_wave::<f32, f32>(442.0, Duration::from_secs_f32(0.5), 44100, 0.8);
    c.bench_function("statistics::cross_correlation", |ben| {
        ben.iter(|| black_box(a.cross_correlation::<f32>(&b, 128).unwrap()))
    });
}

criterion_group!(
    benches,
    bench_statistics_peak_rms,
    bench_statistics_min_max_mean_variance_std_zcr,
    bench_statistics_cross_correlation
);
criterion_main!(benches);
