extern crate rusty_dsp; use rusty_dsp::error::DspError; pub struct BitUpsampler<'a> { bit_length: f64, current_bit_length: usize, pos: usize, residual_error: f64, current_bit: bool, iterator: Box> + 'a>, } impl<'a> BitUpsampler<'a> { pub fn from(iterator: I, sampling_rate: f64, baud_rate: f64) -> BitUpsampler<'a> where I: Iterator> + 'a, { BitUpsampler { bit_length: sampling_rate / baud_rate, current_bit_length: 0, residual_error: 0.0, pos: 0, current_bit: false, iterator: Box::new(iterator), } } } impl<'a> Iterator for BitUpsampler<'a> { type Item = Result; fn next(&mut self) -> Option { if self.pos >= self.current_bit_length { self.current_bit = match self.iterator.next() { None => return None, Some(Err(e)) => return Some(Err(e)), Some(Ok(b)) => b, }; self.current_bit_length = self.bit_length.floor() as usize; self.residual_error += self.bit_length - self.bit_length.floor(); if self.residual_error >= 1.0 { self.residual_error -= 1.0; self.current_bit_length += 1; } self.pos = 0; } self.pos += 1; Some(Ok(self.current_bit)) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_baurate_error_correction() { let input = vec![true, false, true, false]; let upsampler = BitUpsampler::from(input.into_iter().map(|x| Ok(x)), 10.0, 4.0); let result_data: Result, DspError> = upsampler.collect(); assert_eq!( result_data, Ok(vec![ true, true, false, false, false, true, true, false, false, false ]) ); } }