First try at implementing filters

This commit is contained in:
Sebastian 2016-11-24 02:05:10 +01:00
parent 1126e570e8
commit 5a31e4ff4e
1 changed files with 152 additions and 4 deletions

View File

@ -1,6 +1,8 @@
extern crate hound;
fn float_sample_iterator<'a>(reader: &'a mut hound::WavReader<std::io::BufReader<std::fs::File>>)
type FileReader = std::io::BufReader<std::fs::File>;
fn float_sample_iterator<'a>(reader: &'a mut hound::WavReader<FileReader>)
-> Box<Iterator<Item=f32> + 'a> {
match reader.spec().sample_format {
hound::SampleFormat::Float => Box::new(reader.samples::<f32>().map(|x| x.unwrap())),
@ -13,6 +15,119 @@ fn float_sample_iterator<'a>(reader: &'a mut hound::WavReader<std::io::BufReader
}
}
struct Upsampler<'a> {
factor: u16,
state: u16,
iterator: Box<Iterator<Item=f32> + 'a>
}
impl<'a> Upsampler<'a> {
fn from<I>(iterator: I, factor: u16) -> Upsampler<'a> where I: Iterator<Item=f32> + 'a {
Upsampler {
factor: factor,
state: 0,
iterator: Box::new(iterator)
}
}
}
impl<'a> Iterator for Upsampler<'a> {
type Item = f32;
fn next(&mut self) -> Option<Self::Item> {
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<Iterator<Item=f32> + 'a>
}
impl<'a> Downsampler<'a> {
fn from<I>(iterator: I, factor: u16) -> Downsampler<'a> where I: Iterator<Item=f32> + 'a {
Downsampler {
factor: factor,
iterator: Box::new(iterator)
}
}
}
impl<'a> Iterator for Downsampler<'a> {
type Item = f32;
fn next(&mut self) -> Option<Self::Item> {
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<f32>,
state: Vec<f32>,
pos: usize,
iterator: Box<Iterator<Item=f32> + 'a>
}
impl<'a> FIRFilter<'a> {
fn from<I>(iterator: I, coeffs: Vec<f32>) -> FIRFilter<'a> where I: Iterator<Item=f32> + '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<Self::Item> {
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();
}
}