From 7333743d879acc6306e9407b9bf45c7f469bb16f Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Tue, 17 Mar 2020 22:41:25 +0100 Subject: [PATCH] Made fir filter generic --- src/firfilter.rs | 56 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/firfilter.rs b/src/firfilter.rs index 39baae9..90b45fd 100644 --- a/src/firfilter.rs +++ b/src/firfilter.rs @@ -1,18 +1,25 @@ -pub struct FIRFilter<'a> { - coeffs: &'a [f32], - state: Vec, +use num::traits::Num; +use std::iter::FromIterator; + +pub struct FIRFilter<'a, NumType> +where + NumType: Num + Copy { + coeffs: &'a [NumType], + state: Vec, pos: usize, - iterator: Box + 'a>, + iterator: Box + 'a>, } -impl<'a> FIRFilter<'a> { - pub fn from(iterator: I, coeffs: &'a [f32]) -> FIRFilter<'a> +impl<'a, NumType> FIRFilter<'a, NumType> +where + NumType: Num + Copy { + pub fn from(iterator: I, coeffs: &'a [NumType]) -> FIRFilter<'a, NumType> where - I: Iterator + 'a, + I: Iterator + 'a, { let mut state = Vec::new(); for _ in 0..coeffs.len() { - state.push(0.0); + state.push(NumType::zero()); } FIRFilter { @@ -24,10 +31,12 @@ impl<'a> FIRFilter<'a> { } } -impl<'a> Iterator for FIRFilter<'a> { - type Item = f32; +impl<'a, NumType> Iterator for FIRFilter<'a, NumType> + where + NumType: Num + Copy { + type Item = NumType; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { let cur = match self.iterator.next() { Some(x) => x, None => return None, @@ -36,12 +45,33 @@ impl<'a> Iterator for FIRFilter<'a> { self.pos = (self.pos + 1) % self.coeffs.len(); self.state[self.pos] = cur; - let mut result = 0.0; + let mut result = NumType::zero(); for i in 0..self.coeffs.len() { let pos = (self.pos + self.coeffs.len() - i) % self.coeffs.len(); - result += self.state[pos] * self.coeffs[i]; + result = result + (self.state[pos] * self.coeffs[i].clone()); } Some(result) } } + + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn fir_avg_test() { + let test_data = vec![0_f32, 1_f32, 2_f32, 3_f32, 4_f32, 5_f32, 6_f32, 7_f32]; + + let upsampler = FIRFilter::from(test_data.into_iter(), &[0.5_f32, 0.5_f32]); + + let result_data = Vec::from_iter(upsampler); + assert_eq!(result_data.len(), 8); + assert_eq!( + result_data, + [0.0_f32, 0.5_f32, 1.5_f32, 2.5_f32, 3.5_f32, 4.5_f32, 5.5_f32, 6.5_f32] + ); + } +}