#![allow(clippy::needless_range_loop)]
use crate::analyzer::MAX_CHANNELS;
pub(crate) const MOMENTARY_BLOCKS: usize = 4;
pub(crate) const SHORT_TERM_BLOCKS: usize = 30;
#[derive(Debug)]
pub(crate) struct BlockAccumulator {
n_channels: usize,
samples_per_block: u32,
samples_in_current: u32,
sum_sq: [f64; MAX_CHANNELS],
}
impl BlockAccumulator {
pub(crate) fn new(n_channels: usize, samples_per_block: u32) -> Self {
Self {
n_channels,
samples_per_block,
samples_in_current: 0,
sum_sq: [0.0; MAX_CHANNELS],
}
}
#[inline]
pub(crate) fn push_frame(&mut self, frame: &[f32]) -> bool {
for (i, &s) in frame.iter().enumerate() {
self.sum_sq[i] += (s as f64) * (s as f64);
}
self.samples_in_current += 1;
self.samples_in_current >= self.samples_per_block
}
#[inline]
pub(crate) fn take_block(&mut self) -> [f32; MAX_CHANNELS] {
let mut out = [0.0f32; MAX_CHANNELS];
let n = self.samples_per_block.max(1) as f64;
for i in 0..self.n_channels {
out[i] = (self.sum_sq[i] / n) as f32;
self.sum_sq[i] = 0.0;
}
self.samples_in_current = 0;
out
}
pub(crate) fn reset(&mut self) {
self.sum_sq = [0.0; MAX_CHANNELS];
self.samples_in_current = 0;
}
}