Skip to content
Permalink
Browse files
Add EbuR128::reset() for resetting the current state without realloca…
…tion
  • Loading branch information
sdroege committed Sep 1, 2020
1 parent 1bb7e0c commit f29d0b89c32fd34e74bd714935c9ddcc1207a140
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
@@ -570,6 +570,34 @@ impl EbuR128 {
Ok(())
}

/// Resets the current state.
pub fn reset(&mut self) {
// TODO: Use slice::fill() once stabilized
for v in &mut *self.audio_data {
*v = 0.0;
}

// the first block needs 400ms of audio data
self.needed_frames = self.samples_in_100ms * 4;
// start at the beginning of the buffer
self.audio_data_index = 0;
// reset short term frame counter
self.short_term_frame_counter = 0;

// TODO: Use slice::fill() once stabilized
for v in &mut *self.true_peak {
*v = 0.0;
}
// TODO: Use slice::fill() once stabilized
for v in &mut *self.sample_peak {
*v = 0.0;
}

self.filter.reset();
self.block_energy_history.reset();
self.short_term_block_energy_history.reset();
}

fn add_frames<T: crate::filter::AsF64>(&mut self, frames: &[T]) -> Result<(), Error> {
if frames.is_empty() {
return Ok(());
@@ -976,6 +1004,42 @@ mod tests {
-10.650000000000006,
abs <= 0.000001
);

ebu.reset();

assert_float_eq!(
ebu.loudness_global().unwrap(),
-std::f64::INFINITY,
abs <= 0.000001
);
assert_float_eq!(
ebu.loudness_momentary().unwrap(),
-std::f64::INFINITY,
abs <= 0.000001
);
assert_float_eq!(
ebu.loudness_shortterm().unwrap(),
-std::f64::INFINITY,
abs <= 0.000001
);
assert_float_eq!(
ebu.loudness_window(1).unwrap(),
-std::f64::INFINITY,
abs <= 0.000001
);
assert_float_eq!(ebu.loudness_range().unwrap(), 0.0, abs <= 0.000001);

assert_float_eq!(ebu.sample_peak(0).unwrap(), 0.0, abs <= 0.000001);
assert_float_eq!(ebu.sample_peak(1).unwrap(), 0.0, abs <= 0.000001);
assert_float_eq!(ebu.prev_sample_peak(0).unwrap(), 0.0, abs <= 0.000001);
assert_float_eq!(ebu.prev_sample_peak(1).unwrap(), 0.0, abs <= 0.000001);

assert_float_eq!(ebu.true_peak(0).unwrap(), 0.0, abs <= 0.000001);
assert_float_eq!(ebu.true_peak(1).unwrap(), 0.0, abs <= 0.000001);
assert_float_eq!(ebu.prev_true_peak(0).unwrap(), 0.0, abs <= 0.000001);
assert_float_eq!(ebu.prev_true_peak(1).unwrap(), 0.0, abs <= 0.000001);

assert_float_eq!(ebu.relative_threshold().unwrap(), -70.0, abs <= 0.000001);
}

#[test]
@@ -148,6 +148,21 @@ impl Filter {
}
}

pub fn reset(&mut self) {
self.reset_peaks();

for f in &mut *self.filter_state {
// TODO: Use slice::fill() once stabilized
for v in &mut *f {
*v = 0.0;
}
}

if let Some(ref mut tp) = self.tp {
tp.reset();
}
}

pub fn sample_peak(&self) -> &[f64] {
&*self.sample_peak
}
@@ -91,6 +91,13 @@ impl Histogram {
self.0[idx] += 1;
}

fn reset(&mut self) {
// TODO: Use slice::fill() once stabilized
for v in self.0.iter_mut() {
*v = 0;
}
}

fn calc_relative_threshold(&self) -> (u64, f64) {
let mut above_thresh_counter = 0;
let mut relative_threshold = 0.0;
@@ -190,6 +197,10 @@ impl Queue {
self.max = max;
}

fn reset(&mut self) {
self.queue.clear();
}

fn calc_relative_threshold(&self) -> (u64, f64) {
(self.queue.len() as u64, self.queue.iter().sum::<f64>())
}
@@ -266,6 +277,13 @@ impl History {
}
}

pub fn reset(&mut self) {
match self {
History::Histogram(ref mut h) => h.reset(),
History::Queue(ref mut q) => q.reset(),
}
}

fn calc_relative_threshold(&self) -> (u64, f64) {
match self {
History::Histogram(ref h) => h.calc_relative_threshold(),
@@ -109,6 +109,14 @@ impl Interp {
self.factor
}

pub fn reset(&mut self) {
// TODO: Use slice::fill() once stabilized
for v in &mut *self.z {
*v = 0.0;
}
self.zi = 0;
}

pub fn process(&mut self, src: &[f32], dst: &mut [f32]) {
assert!(src.len().checked_mul(self.factor) == Some(dst.len()));
assert!(self.z.len() == self.delay * self.channels as usize);
@@ -62,6 +62,10 @@ impl TruePeak {
})
}

pub fn reset(&mut self) {
self.interp.reset();
}

// FIXME: Use f32 for storage
pub fn check_true_peak<T: AsF32>(&mut self, src: &[T], peaks: &mut [f64]) {
assert!(src.len() <= self.buffer_input.len());

0 comments on commit f29d0b8

Please sign in to comment.