#![expect(clippy::too_many_arguments)]
use std::cmp::PartialOrd;
use std::f64::consts::PI;
use rstest::rstest;
use crate::ResampleType;
#[rustfmt::skip]
#[rstest(n, from_rate, to_rate, n_ch, bleed_size, in_bleed_eps, out_bleed_eps,
case(16384, 1, 2, 1, 512, 1e-6, 0.02),
case(16384, 1, 2, 2, 512, 1e-6, 0.02),
case(16384, 1, 2, 7, 512, 1e-6, 0.02),
case(44100, 44100, 48000, 1, 512, 1e-6, 0.001),
case(44100, 44100, 48000, 2, 512, 1e-6, 0.001),
case(44100, 44100, 48000, 7, 512, 1e-6, 0.001),
case(22050, 44100, 16000, 1, 512, 1e-6, 0.02),
case(22050, 44100, 16000, 2, 512, 1e-6, 0.02),
)]
fn simple_resample(
n: usize,
from_rate: usize,
to_rate: usize,
n_ch: u8,
#[values(
ResampleType::SincBestQuality,
ResampleType::SincMediumQuality,
ResampleType::SincFastest,
ResampleType::ZeroOrderHold,
ResampleType::Linear
)]
type_: ResampleType,
bleed_size: usize,
in_bleed_eps: f32,
out_bleed_eps: f32,
) {
let n_chs = usize::from(n_ch);
let sig_freq = 128.0f64;
let data = (0..n * n_chs)
.map(|i| (2.0 * PI * sig_freq * ((i / n_chs) as f64 / n as f64)).sin())
.map(|x| x as f32)
.collect::<Vec<f32>>();
let down_data = crate::convert(
type_,
n_ch,
from_rate as u32,
to_rate as u32,
&data,
)
.unwrap();
let up_data = crate::convert(
type_,
n_ch,
to_rate as u32,
from_rate as u32,
&down_data,
)
.unwrap();
if type_ == ResampleType::SincBestQuality {
assert_eq!(
up_data.len(),
((n * to_rate).div_ceil(from_rate) * from_rate).div_ceil(to_rate) * n_chs
);
let max_diff = data
.iter()
.enumerate()
.zip(up_data.iter())
.map(|((i, a), b)| (i, (a - b).abs()))
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
.unwrap();
let max_diff_bleed = data
.iter()
.take((n - bleed_size) * n_chs)
.enumerate()
.skip(bleed_size * n_chs)
.zip(up_data.iter().skip(bleed_size * n_chs))
.map(|((i, a), b)| (i, (a - b).abs()))
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
.unwrap();
assert!(max_diff_bleed.1 < in_bleed_eps);
assert!(max_diff.1 < out_bleed_eps);
} else {
let expected = ((n * to_rate).div_ceil(from_rate) * from_rate).div_ceil(to_rate) * n_chs;
let lower = expected - 3;
let upper = expected + 7;
assert!(up_data.len() >= lower, "{} | {lower}", up_data.len());
assert!(up_data.len() <= upper, "{} | {upper}", up_data.len());
}
}