use anyhow::Result;
use rubato::{InterpolationParameters, Resampler as _, SincFixedOut};
use crate::{SongSource, SourceError};
pub struct Resampler {
pub resampler: SincFixedOut<f32>,
pub source_buf: Vec<[f32; 2]>,
pub in_buf: Vec<Vec<f32>>,
pub out_buf: Vec<Vec<f32>>,
pub i: usize,
}
impl Resampler {
pub fn new(ratio: f64) -> Result<Self> {
let resampler = SincFixedOut::new(
ratio,
2.0,
InterpolationParameters {
sinc_len: 256,
f_cutoff: 0.95,
oversampling_factor: 128,
interpolation: rubato::InterpolationType::Linear,
window: rubato::WindowFunction::Blackman2,
},
512,
2,
)
.unwrap();
Ok(Self {
source_buf: vec![[0.0; 2]; resampler.input_frames_max()],
in_buf: resampler.input_buffer_allocate(),
out_buf: resampler.output_buffer_allocate(),
resampler,
i: 0,
})
}
pub fn process(&mut self, source: &mut SongSource) -> Result<(), SourceError> {
let in_len = self.resampler.input_frames_next();
source.signal.next(&mut self.source_buf[..in_len])?;
self.in_buf[0].clear();
self.in_buf[1].clear();
for i in 0..in_len {
self.in_buf[0].push(self.source_buf[i][0]);
self.in_buf[1].push(self.source_buf[i][1]);
}
self.out_buf[0].clear();
self.out_buf[1].clear();
self.resampler
.process_into_buffer(&self.in_buf, &mut self.out_buf, Some(&[true, true]))
.unwrap();
self.i = 0;
Ok(())
}
}