mod af_replaygain;
use af_replaygain::*;
pub struct ReplayGain {
sample_rate: usize,
ctx: ReplayGainContext,
buf: Vec<f32>,
}
impl ReplayGain {
pub fn new(sample_rate: usize) -> Option<ReplayGain>{
freq_to_info(sample_rate).map(|x| ReplayGain {
sample_rate,
ctx: init_context(&x),
buf: Vec::new(),
})
}
pub fn frame_size(&self) -> usize {
self.sample_rate / 20 * 2
}
pub fn process_frame(&mut self, frame: &[f32]) {
assert!(frame.len() == self.frame_size());
assert!(self.buf.is_empty());
filter_frame(&mut self.ctx, frame);
}
pub fn process_samples(&mut self, frame: &[f32]) {
let frame_size = self.frame_size();
let mut remainder = None;
if !self.buf.is_empty() {
let required = frame_size - self.buf.len();
let can_fill = frame.len() >= required;
let input = if can_fill { required } else { frame.len() };
self.buf.extend_from_slice(&frame[..input]);
if can_fill {
assert!(self.buf.len() == frame_size);
filter_frame(&mut self.ctx, &self.buf[..]);
self.buf.clear();
remainder = Some(&frame[input..]);
}
} else {
remainder = Some(frame);
}
for chunk in remainder.iter().flat_map(|x| x.chunks(frame_size)) {
if chunk.len() == frame_size {
assert!(self.buf.is_empty());
filter_frame(&mut self.ctx, chunk);
} else {
self.buf.extend_from_slice(chunk);
}
}
}
pub fn finish(mut self) -> (f32, f32) {
self.buf.resize(self.frame_size(), 0.0);
filter_frame(&mut self.ctx, &self.buf[..]);
self.buf.clear();
finish(&mut self.ctx)
}
}