Made fir filter generic

This commit is contained in:
Sebastian 2020-03-17 22:41:25 +01:00
parent 2941890adf
commit 7333743d87
1 changed files with 43 additions and 13 deletions

View File

@ -1,18 +1,25 @@
pub struct FIRFilter<'a> { use num::traits::Num;
coeffs: &'a [f32], use std::iter::FromIterator;
state: Vec<f32>,
pub struct FIRFilter<'a, NumType>
where
NumType: Num + Copy {
coeffs: &'a [NumType],
state: Vec<NumType>,
pos: usize, pos: usize,
iterator: Box<dyn Iterator<Item = f32> + 'a>, iterator: Box<dyn Iterator<Item = NumType> + 'a>,
} }
impl<'a> FIRFilter<'a> { impl<'a, NumType> FIRFilter<'a, NumType>
pub fn from<I>(iterator: I, coeffs: &'a [f32]) -> FIRFilter<'a> where
NumType: Num + Copy {
pub fn from<I>(iterator: I, coeffs: &'a [NumType]) -> FIRFilter<'a, NumType>
where where
I: Iterator<Item = f32> + 'a, I: Iterator<Item = NumType> + 'a,
{ {
let mut state = Vec::new(); let mut state = Vec::new();
for _ in 0..coeffs.len() { for _ in 0..coeffs.len() {
state.push(0.0); state.push(NumType::zero());
} }
FIRFilter { FIRFilter {
@ -24,10 +31,12 @@ impl<'a> FIRFilter<'a> {
} }
} }
impl<'a> Iterator for FIRFilter<'a> { impl<'a, NumType> Iterator for FIRFilter<'a, NumType>
type Item = f32; where
NumType: Num + Copy {
type Item = NumType;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<NumType> {
let cur = match self.iterator.next() { let cur = match self.iterator.next() {
Some(x) => x, Some(x) => x,
None => return None, None => return None,
@ -36,12 +45,33 @@ impl<'a> Iterator for FIRFilter<'a> {
self.pos = (self.pos + 1) % self.coeffs.len(); self.pos = (self.pos + 1) % self.coeffs.len();
self.state[self.pos] = cur; self.state[self.pos] = cur;
let mut result = 0.0; let mut result = NumType::zero();
for i in 0..self.coeffs.len() { for i in 0..self.coeffs.len() {
let pos = (self.pos + self.coeffs.len() - i) % 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) 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]
);
}
}