use super::decode::Spec;
use super::output::{remap_channels, Plan};
use super::resample::Resample;
pub struct Converter {
src: Spec,
plan: Plan,
speed: f64,
resampler: Option<Resample>,
scratch: Vec<f32>,
finished: bool,
}
impl Converter {
pub fn new(src: Spec, plan: Plan, speed: f64) -> Self {
let resampler = if plan.needs_resample(src) || speed != 1.0 {
Resample::new(src.rate, plan.rate, src.channels, speed)
} else {
None
};
Converter {
src,
plan,
speed,
resampler,
scratch: Vec::new(),
finished: false,
}
}
pub fn src(&self) -> Spec {
self.src
}
pub fn resampling(&self) -> bool {
self.resampler.is_some()
}
pub fn continues(&self, src: Spec, plan: Plan, speed: f64) -> bool {
!self.finished && self.src == src && self.plan == plan && self.speed == speed
}
pub fn push(&mut self, decoded: &[f32], sink: &mut Vec<f32>) {
let (src_ch, dst_ch) = (self.src.channels as usize, self.plan.channels as usize);
match self.resampler.as_mut() {
Some(r) => {
self.scratch.clear();
r.push(decoded, &mut self.scratch);
remap_channels(&self.scratch, src_ch, dst_ch, sink);
}
None => remap_channels(decoded, src_ch, dst_ch, sink),
}
}
pub fn finish(&mut self, sink: &mut Vec<f32>) {
if std::mem::replace(&mut self.finished, true) {
return;
}
if let Some(r) = self.resampler.as_mut() {
self.scratch.clear();
r.flush(&mut self.scratch);
let (src_ch, dst_ch) = (self.src.channels as usize, self.plan.channels as usize);
remap_channels(&self.scratch, src_ch, dst_ch, sink);
}
}
}