use std::borrow::Cow;
use crate::{RnnModel, FRAME_SIZE, FREQ_SIZE, NB_BANDS};
#[derive(Clone)]
pub struct DenoiseState<'model> {
lastg: [f32; crate::NB_BANDS],
rnn: crate::rnn::RnnState<'model>,
feat: crate::features::DenoiseFeatures,
}
impl DenoiseState<'static> {
pub const FRAME_SIZE: usize = FRAME_SIZE;
pub(crate) fn default() -> Self {
DenoiseState::from_model_owned(Cow::Owned(RnnModel::default()))
}
pub fn new() -> Box<DenoiseState<'static>> {
Box::new(Self::default())
}
pub fn from_model(model: RnnModel) -> Box<DenoiseState<'static>> {
Box::new(DenoiseState::from_model_owned(Cow::Owned(model)))
}
}
impl<'model> DenoiseState<'model> {
pub fn with_model(model: &'model RnnModel) -> Box<DenoiseState<'model>> {
Box::new(DenoiseState::from_model_owned(Cow::Borrowed(model)))
}
pub(crate) fn from_model_owned(model: Cow<'model, RnnModel>) -> DenoiseState<'model> {
DenoiseState {
lastg: [0.0; NB_BANDS],
rnn: crate::rnn::RnnState::new(model),
feat: crate::features::DenoiseFeatures::new(),
}
}
pub fn process_frame(&mut self, output: &mut [f32], input: &[f32]) -> f32 {
let mut g = [0.0; NB_BANDS];
let mut gf = [1.0; FREQ_SIZE];
let mut vad_prob = [0.0];
self.feat.shift_and_filter_input(input);
let silence = self.feat.compute_frame_features();
if !silence {
self.rnn
.compute(&mut g[..], &mut vad_prob[..], self.feat.features());
self.feat.pitch_filter(&g);
for i in 0..NB_BANDS {
g[i] = g[i].max(0.6 * self.lastg[i]);
self.lastg[i] = g[i];
}
crate::interp_band_gain(&mut gf[..], &g[..]);
self.feat.apply_gain(&gf);
}
self.feat.frame_synthesis(output);
vad_prob[0]
}
}
#[cfg(test)]
mod tests {
use super::*;
extern crate static_assertions as sa;
sa::assert_impl_all!(DenoiseState: Send, Sync);
}