pub struct LinearResampler {
src_rate: u32,
dst_rate: u32,
step: f64,
phase: f64,
last_input: f32,
}
impl LinearResampler {
pub fn new(src_rate: u32, dst_rate: u32) -> Self {
assert!(
src_rate > 0 && dst_rate > 0,
"sample rates must be non-zero"
);
Self {
src_rate,
dst_rate,
step: src_rate as f64 / dst_rate as f64,
phase: 0.0,
last_input: 0.0,
}
}
pub fn dst_rate(&self) -> u32 {
self.dst_rate
}
pub fn process(&mut self, input: &[f32], out: &mut Vec<f32>) {
out.clear();
if self.src_rate == self.dst_rate {
out.extend_from_slice(input);
if let Some(&last) = input.last() {
self.last_input = last;
}
return;
}
let len = input.len();
out.reserve((len as f64 / self.step) as usize + 2);
let step = self.step;
let mut pos = self.phase;
let last_index = len as isize - 1;
while (pos.floor() as isize) < last_index {
let i = pos.floor() as isize;
let frac = (pos - i as f64) as f32;
let a = if i < 0 {
self.last_input
} else {
input[i as usize]
};
let b = input[(i + 1) as usize];
out.push(a + frac * (b - a));
pos += step;
}
self.phase = pos - len as f64;
if let Some(&last) = input.last() {
self.last_input = last;
}
}
}
pub fn resample_offline(input: &[f32], src: u32, dst: u32) -> Vec<f32> {
let mut resampler = LinearResampler::new(src, dst);
let mut out = Vec::new();
resampler.process(input, &mut out);
out
}