#![cfg_attr(feature = "nightly", feature(test))]
#[cfg(all(test, feature = "nightly"))]
extern crate test;
mod error;
mod resample_type;
mod resampler;
#[cfg(test)]
mod sanity_test;
pub use crate::error::Error;
pub use crate::error::ErrorKind;
pub use crate::resample_type::ResampleType;
pub use crate::resampler::Processed;
pub use crate::resampler::Resampler;
pub fn convert(
type_: ResampleType,
channels: u8,
from_rate: u32,
to_rate: u32,
input: &[f32],
) -> Result<Vec<f32>, Error> {
let input_len = input.len();
let input_frames = input_len / usize::from(channels);
let output_frames = (input_frames * to_rate as usize).div_ceil(from_rate as usize);
let mut output = vec![0.0; output_frames * usize::from(channels)];
let mut resampler = Resampler::new(type_, channels, from_rate, to_rate)?;
let mut total = Processed::default();
loop {
let in_buf = &input[total.read..];
let out_buf = &mut output[total.written..];
let processed = resampler.finalize(in_buf, out_buf)?;
total.read += processed.read;
total.written += processed.written;
if total.read >= input.len() {
break
}
let () = output.resize(output.len() + 64 * usize::from(channels), 0.0);
}
debug_assert_eq!(total.read, input.len());
let () = output.resize(total.written, 0.0);
Ok(output)
}
#[cfg(test)]
#[cfg(feature = "nightly")]
mod tests {
use super::*;
use test::Bencher;
fn bench_resample_impl(b: &mut Bencher, type_: ResampleType) {
use std::f32::consts::PI;
let freq = PI * 880f32 / 44100f32;
let input = (0..44100)
.map(|i| (freq * i as f32).sin())
.collect::<Vec<_>>();
let () = b.iter(|| {
let resampled = convert(type_, 1, 44100, 48000, &input).unwrap();
assert!((48000..=48001).contains(&resampled.len()));
});
}
#[bench]
fn bench_resample_sinc_best(b: &mut Bencher) {
let () = bench_resample_impl(b, ResampleType::SincBestQuality);
}
#[bench]
fn bench_resample_sinc_medium(b: &mut Bencher) {
let () = bench_resample_impl(b, ResampleType::SincMediumQuality);
}
#[bench]
fn bench_resample_sinc_fast(b: &mut Bencher) {
let () = bench_resample_impl(b, ResampleType::SincFastest);
}
#[bench]
fn bench_resample_zero_order_hold(b: &mut Bencher) {
let () = bench_resample_impl(b, ResampleType::ZeroOrderHold);
}
#[bench]
fn bench_resample_linear(b: &mut Bencher) {
let () = bench_resample_impl(b, ResampleType::Linear);
}
}