use dasp::frame::Frame;
use dasp::sample::Sample;
use dasp::signal::Signal;
use std::borrow::Cow;
use crate::{DenoiseState, RnnModel, FRAME_SIZE};
#[derive(Clone)]
pub struct DenoiseSignal<'model, S: Signal> {
input: S,
states: Vec<DenoiseState<'model>>,
in_bufs: Vec<[f32; FRAME_SIZE]>,
out_bufs: Vec<[f32; FRAME_SIZE]>,
out_idx: usize,
}
impl<'model, S: Signal> DenoiseSignal<'model, S> {
pub fn new(input: S) -> DenoiseSignal<'static, S> {
DenoiseSignal {
input,
states: vec![DenoiseState::default(); S::Frame::CHANNELS],
in_bufs: vec![[0.0; FRAME_SIZE]; S::Frame::CHANNELS],
out_bufs: vec![[0.0; FRAME_SIZE]; S::Frame::CHANNELS],
out_idx: 0,
}
.discard_first_frame()
}
pub fn with_model(input: S, model: &'model RnnModel) -> DenoiseSignal<'model, S> {
DenoiseSignal {
input,
states: vec![DenoiseState::from_model_owned(Cow::Borrowed(model)); S::Frame::CHANNELS],
in_bufs: vec![[0.0; FRAME_SIZE]; S::Frame::CHANNELS],
out_bufs: vec![[0.0; FRAME_SIZE]; S::Frame::CHANNELS],
out_idx: 0,
}
.discard_first_frame()
}
pub fn from_model(input: S, model: RnnModel) -> DenoiseSignal<'static, S> {
DenoiseSignal {
input,
states: vec![DenoiseState::from_model_owned(Cow::Owned(model)); S::Frame::CHANNELS],
in_bufs: vec![[0.0; FRAME_SIZE]; S::Frame::CHANNELS],
out_bufs: vec![[0.0; FRAME_SIZE]; S::Frame::CHANNELS],
out_idx: 0,
}
.discard_first_frame()
}
fn discard_first_frame(mut self) -> Self {
self.refill_out_bufs();
self.refill_out_bufs();
self
}
fn refill_out_bufs(&mut self) -> bool {
if self.input.is_exhausted() {
return false;
}
for i in 0..FRAME_SIZE {
for (ch, samp) in self.input.next().to_float_frame().channels().enumerate() {
self.in_bufs[ch][i] = samp.to_sample::<f32>() * 32768.0;
}
}
for ch in 0..S::Frame::CHANNELS {
self.states[ch].process_frame(&mut self.out_bufs[ch][..], &self.in_bufs[ch][..]);
}
!self.input.is_exhausted()
}
}
impl<'model, S: Signal> Signal for DenoiseSignal<'model, S> {
type Frame = <<S as Signal>::Frame as Frame>::Float;
fn is_exhausted(&self) -> bool {
self.out_idx >= FRAME_SIZE
}
fn next(&mut self) -> Self::Frame {
if self.out_idx >= FRAME_SIZE {
return Self::Frame::EQUILIBRIUM;
}
let idx = self.out_idx;
self.out_idx += 1;
let ret = Frame::from_fn(|ch| {
let samp = (self.out_bufs[ch][idx] / 32768.0).clamp(-1.0, 1.0);
samp.to_sample()
});
if self.out_idx >= FRAME_SIZE {
if self.refill_out_bufs() {
self.out_idx = 0;
}
}
ret
}
}