Made fir filter generic
This commit is contained in:
parent
2941890adf
commit
7333743d87
|
@ -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]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue