use num::traits::{Num, NumCast}; use std::iter::FromIterator; pub struct Upsampler<'a, NumType> where NumType: Num + Clone, { factor: u16, state: u16, sample: Option, iterator: Box + 'a>, } impl<'a, NumType> Upsampler<'a, NumType> where NumType: Num + Clone, { pub fn from(iterator: I, factor: u16) -> Upsampler<'a, NumType> where I: Iterator + 'a, { Upsampler { factor: factor, state: 0, sample: Some(NumType::zero()), iterator: Box::new(iterator), } } } impl<'a, NumType> Iterator for Upsampler<'a, NumType> where NumType: Num + Clone, { type Item = NumType; fn next(&mut self) -> Option { if self.state == 0 { self.sample = self.iterator.next(); } self.state = (self.state + 1) % self.factor; return self.sample.clone(); } } pub struct Downsampler<'a, NumType> where NumType: Num + Clone + NumCast, { factor: u16, iterator: Box + 'a>, } impl<'a, NumType> Downsampler<'a, NumType> where NumType: Num + Clone + NumCast, { pub fn from(iterator: I, factor: u16) -> Downsampler<'a, NumType> where I: Iterator + 'a, { Downsampler { factor: factor, iterator: Box::new(iterator), } } } impl<'a, NumType> Iterator for Downsampler<'a, NumType> where NumType: Num + Clone + NumCast, { type Item = NumType; fn next(&mut self) -> Option { let mut result = NumType::zero(); for _ in 0..self.factor { match self.iterator.next() { Some(x) => result = result + x, None => return None, } } result = result / NumType::from(self.factor).unwrap(); return Some(result); } } #[cfg(test)] mod tests { use super::*; #[test] fn upsampler_test() { let test_data = vec![1_f32, 2_f32, 3_f32, 4_f32, 5_f32]; let upsampler = Upsampler::from(test_data.into_iter(), 2); let result_data = Vec::from_iter(upsampler); assert_eq!(result_data.len(), 10); assert_eq!( result_data, [1_f32, 1_f32, 2_f32, 2_f32, 3_f32, 3_f32, 4_f32, 4_f32, 5_f32, 5_f32] ); } #[test] fn downsampler_test() { let test_data = vec![ 1_f32, 1_f32, 2_f32, 2_f32, 3_f32, 3_f32, 4_f32, 4_f32, 5_f32, 5_f32, ]; let downsampler = Downsampler::from(test_data.into_iter(), 2); let result_data = Vec::from_iter(downsampler); assert_eq!(result_data.len(), 5); assert_eq!(result_data, [1_f32, 2_f32, 3_f32, 4_f32, 5_f32]); } }