use std::{error::Error, path::PathBuf};
use adaptif::filters::{LmsFilter, LmsOptions, ProcessingMode};
use adaptif::types::{InputSignal, NoiseReference};
use rand::{self, RngExt as _, SeedableRng as _, rngs::StdRng};
use rand_distr::StandardNormal;
fn main() -> Result<(), Box<dyn Error>> {
let mut lms = LmsFilter::new(
LmsOptions {
step_size: 0.1, window_size: 16, },
ProcessingMode::Sample,
)?;
let (noisy_signal, noise) = load_signals()?;
let input_signal = InputSignal::new(noisy_signal)?;
let noise_ref = NoiseReference::new(noise)?;
let _ = lms.adapt(&input_signal, &noise_ref)?;
let _cleaned_signal = lms.filter(&input_signal, &noise_ref)?;
Ok(())
}
#[allow(clippy::missing_errors_doc, reason = "Example")]
pub fn load_signals() -> Result<(Vec<f64>, Vec<f64>), Box<dyn Error>> {
let clean_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("integration")
.join("fixtures");
let wav_path = std::fs::read_dir(clean_dir)?
.next()
.ok_or("No WAV fixtures")??
.path();
let mut reader = hound::WavReader::open(wav_path)?;
let clean_signal: Vec<f64> = reader
.samples::<i16>()
.map(|s| Ok(f64::from(s?) / f64::from(i16::MAX)))
.collect::<Result<_, hound::Error>>()?;
let mut rng = StdRng::seed_from_u64(42);
let noise: Vec<f64> = std::iter::repeat_with(|| rng.sample(StandardNormal))
.take(clean_signal.len())
.collect();
let noisy_signal: Vec<f64> = clean_signal
.iter()
.zip(&noise)
.map(|(c, n)| c + n)
.collect();
Ok((noisy_signal, noise))
}