use crate::Frame;
#[derive(Debug, Copy, Clone, PartialEq, Default)]
struct ResamplerFrame {
frame: Frame,
index: usize,
}
#[derive(Debug, Copy, Clone, PartialEq, Default)]
pub struct Resampler {
frames: [ResamplerFrame; 4],
}
#[inline] pub fn interpolate_frame(
previous: Frame,
current: Frame,
next: Frame,
next_next: Frame,
fraction: f32,
) -> Frame {
let c0 = current;
let c1 = (next - previous) * 0.5;
let c2 = previous - current * 2.5 + next * 2.0 - next_next * 0.5;
let c3 = (next_next - previous) * 0.5 + (current - next) * 1.5;
((c3 * fraction + c2) * fraction + c1) * fraction + c0
}
impl Resampler {
#[inline]
pub const fn new(starting_index: usize) -> Self {
Self {
frames: [ResamplerFrame {
frame: Frame::ZERO,
index: starting_index,
}; 4],
}
}
#[inline]
pub fn push_frame(&mut self, frame: Frame, frame_index: usize) {
for i in 0..self.frames.len() - 1 {
self.frames[i] = self.frames[i + 1];
}
self.frames[self.frames.len() - 1] = ResamplerFrame {
frame,
index: frame_index,
};
}
#[inline]
pub fn get(&self, fraction: f32) -> Frame {
interpolate_frame(
self.frames[0].frame,
self.frames[1].frame,
self.frames[2].frame,
self.frames[3].frame,
fraction,
)
}
#[inline]
pub const fn current_frame_index(&self) -> usize {
self.frames[1].index
}
#[inline]
pub fn outputting_silence(&self) -> bool {
self.frames
.iter()
.all(|ResamplerFrame { frame, .. }| *frame == Frame::ZERO)
}
}