use super::{FRAME_LENGTH_SAMPLES, INT16_SCALE, LOG_FLOOR, NUM_MEL_BINS, PRE_EMPHASIS};
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn pcm_scale_extend(pcm: &[f32], out: &mut [f32]) {
debug_assert_eq!(pcm.len(), out.len());
for (dst, &src) in out.iter_mut().zip(pcm.iter()) {
*dst = if src.is_finite() {
src * INT16_SCALE
} else {
0.0
};
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn dc_remove(window: &[f32], out: &mut [f32]) {
debug_assert_eq!(window.len(), FRAME_LENGTH_SAMPLES);
debug_assert_eq!(out.len(), FRAME_LENGTH_SAMPLES);
let mean: f32 = window.iter().copied().sum::<f32>() / FRAME_LENGTH_SAMPLES as f32;
for (o, &w) in out.iter_mut().zip(window.iter()) {
*o = w - mean;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn pre_emphasis(samples: &mut [f32]) {
debug_assert_eq!(samples.len(), FRAME_LENGTH_SAMPLES);
for i in (1..FRAME_LENGTH_SAMPLES).rev() {
samples[i] -= PRE_EMPHASIS * samples[i - 1];
}
samples[0] -= PRE_EMPHASIS * samples[0];
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn window_apply(samples: &mut [f32], window: &[f32]) {
debug_assert_eq!(samples.len(), FRAME_LENGTH_SAMPLES);
debug_assert_eq!(window.len(), FRAME_LENGTH_SAMPLES);
for (s, &w) in samples.iter_mut().zip(window.iter()) {
*s *= w;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn power_spectrum(complex: &[rustfft::num_complex::Complex<f32>], out: &mut [f32]) {
debug_assert_eq!(complex.len(), out.len());
for (p, c) in out.iter_mut().zip(complex.iter()) {
*p = c.re * c.re + c.im * c.im;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn cmvn_apply(feature: &mut [f32], means: &[f32], istd: &[f32]) {
debug_assert_eq!(feature.len(), NUM_MEL_BINS);
debug_assert_eq!(means.len(), NUM_MEL_BINS);
debug_assert_eq!(istd.len(), NUM_MEL_BINS);
for ((f, &m), &i) in feature.iter_mut().zip(means.iter()).zip(istd.iter()) {
*f = (*f - m) * i;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn mel_dot_log(power_slice: &[f32], weights: &[f32]) -> f32 {
debug_assert_eq!(power_slice.len(), weights.len());
let mut energy = 0.0f32;
for (b, w) in power_slice.iter().zip(weights.iter()) {
energy += b * w;
}
energy.max(LOG_FLOOR).ln()
}