diff --git a/src/main.rs b/src/main.rs index 4d1602a..84d607a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ extern crate hound; -fn float_sample_iterator<'a>(reader: &'a mut hound::WavReader>) +type FileReader = std::io::BufReader; + +fn float_sample_iterator<'a>(reader: &'a mut hound::WavReader) -> Box + 'a> { match reader.spec().sample_format { hound::SampleFormat::Float => Box::new(reader.samples::().map(|x| x.unwrap())), @@ -13,6 +15,119 @@ fn float_sample_iterator<'a>(reader: &'a mut hound::WavReader { + factor: u16, + state: u16, + iterator: Box + 'a> +} + +impl<'a> Upsampler<'a> { + fn from(iterator: I, factor: u16) -> Upsampler<'a> where I: Iterator + 'a { + Upsampler { + factor: factor, + state: 0, + iterator: Box::new(iterator) + } + } +} + +impl<'a> Iterator for Upsampler<'a> { + type Item = f32; + + fn next(&mut self) -> Option { + let result = if self.state == 0 { + self.iterator.next() + } + else { + Some(0.0) + }; + self.state = (self.state + 1) % self.factor; + + return result; + } +} + + + +struct Downsampler<'a> { + factor: u16, + iterator: Box + 'a> +} + +impl<'a> Downsampler<'a> { + fn from(iterator: I, factor: u16) -> Downsampler<'a> where I: Iterator + 'a { + Downsampler { + factor: factor, + iterator: Box::new(iterator) + } + } +} + +impl<'a> Iterator for Downsampler<'a> { + type Item = f32; + + fn next(&mut self) -> Option { + let mut result = 0.0; + for _ in 0..self.factor { + match self.iterator.next() { + Some(x) => result += x, + None => return None + } + } + result /= self.factor as f32; + + return Some(result); + } +} + + + +struct FIRFilter<'a> { + coeffs: Vec, + state: Vec, + pos: usize, + iterator: Box + 'a> +} + +impl<'a> FIRFilter<'a> { + fn from(iterator: I, coeffs: Vec) -> FIRFilter<'a> where I: Iterator + 'a { + let mut state = Vec::new(); + for _ in 0..coeffs.len() { + state.push(0.0); + } + + FIRFilter { + coeffs: coeffs, + state: state, + pos: 0, + iterator: Box::new(iterator) + } + } +} + +impl<'a> Iterator for FIRFilter<'a> { + type Item = f32; + + fn next(&mut self) -> Option { + let cur = match self.iterator.next() { + Some(x) => x, + None => return None + }; + + self.pos = (self.pos + 1) % self.coeffs.len(); + self.state[self.pos] = cur; + + let mut result = 0.0; + 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]; + }; + + Some(result) + } +} + + fn main() { let carrier_freq = 2400; @@ -29,9 +144,42 @@ fn main() { let sample_rate = reader.spec().sample_rate; println!("Samplerate: {}", sample_rate); - let mut samples = float_sample_iterator(&mut reader); + let samples = float_sample_iterator(&mut reader); - for sample in samples { - println!("Sample: {}", sample ) + let coeffs = vec![1.73203081e-03, 3.68489420e-03, -1.61573864e-03, -4.83850760e-03, + 1.26938317e-03, 6.13073242e-03, -6.37488600e-04, -7.54064630e-03, + -3.41166003e-04, 9.04137653e-03, 1.73642240e-03, -1.06008349e-02, + -3.63238422e-03, 1.21827130e-02, 6.13805128e-03, -1.37477000e-02, + -9.40748113e-03, 1.52548738e-02, 1.36795184e-02, -1.66632054e-02, + -1.93616657e-02, 1.79331113e-02, 2.72262912e-02, -1.90279842e-02, + -3.89431985e-02, 1.99156328e-02, 5.88894574e-02, -2.05695633e-02, + -1.03195587e-01, 2.09700453e-02, 3.17333203e-01, 4.78895090e-01, + 3.17333203e-01, 2.09700453e-02, -1.03195587e-01, -2.05695633e-02, + 5.88894574e-02, 1.99156328e-02, -3.89431985e-02, -1.90279842e-02, + 2.72262912e-02, 1.79331113e-02, -1.93616657e-02, -1.66632054e-02, + 1.36795184e-02, 1.52548738e-02, -9.40748113e-03, -1.37477000e-02, + 6.13805128e-03, 1.21827130e-02, -3.63238422e-03, -1.06008349e-02, + 1.73642240e-03, 9.04137653e-03, -3.41166003e-04, -7.54064630e-03, + -6.37488600e-04, 6.13073242e-03, 1.26938317e-03, -4.83850760e-03, + -1.61573864e-03, 3.68489420e-03, 1.73203081e-03]; + + + + let filter = FIRFilter::from(samples, coeffs); + + let spec = hound::WavSpec { + channels: 1, + sample_rate: 48000, + bits_per_sample: 32, + sample_format: hound::SampleFormat::Int, + }; + let mut writer = hound::WavWriter::create("lowpass.wav", spec).unwrap(); + + + for sample in filter { + println!("{}", sample); + + let amplitude = i32::max_value() as f32; + writer.write_sample((sample * amplitude) as i32).unwrap(); } }