dspfrivs/src/sfilter.rs

94 lines
1.8 KiB
Rust

#![allow(unused_parens)]
use std::io::prelude::*;
use std::fs::File;
use std::env::args;
use std::f32::consts::PI;
fn sinc
(
x: f32,
) ->
f32
{
if x.abs() > std::f32::MIN_POSITIVE
{
(PI*x).sin() / (PI*x)
} else {
1.0
}
}
fn main()
{
let argv = args().collect::<Vec<String>>();
if argv.len() != 3
{
eprintln!("usage: sfilter <frequency> <target.dat>");
return;
}
/*
frequency (f32):
the frequency of the sinc function from 0.0 to 1000.0, where 0.0 is zero and 1000.0 is half the sample rate (the Nyquist limit).
*/
let filter_frequency =
(
argv[1]
.parse::<f32>()
.unwrap()
/ 2000.0 // later on, this will need to be normalized so that 1.0 equals the sample rate, so we divide by 2000 so that an input of 1000 becomes 0.5
);
let mut input_file = File::open(&argv[2]).unwrap();
let mut input_buffer:Vec<u8> = Vec::new();
input_file.read_to_end(&mut input_buffer).unwrap();
let mut data:Vec<f32> = Vec::new();
for chunk in input_buffer.chunks_exact(4)
{
let mut new_value:[u8;4] = [0x00;4];
new_value.copy_from_slice(chunk);
data.push(f32::from_be_bytes(new_value));
}
let mut filtered_data:Vec<f32> = Vec::with_capacity(data.len());
for shift in 0..data.len()
{
let s = shift as f32;
let mut convol_value:f32 = 0.0;
for x in 0..data.len()
{
let t = x as f32;
convol_value +=
(
data[x]
*
2.0
*
filter_frequency
*
sinc(
2.0
*
filter_frequency
*
(t - s)
)
);
}
filtered_data.push(convol_value);
}
let mut output_file = File::create(&argv[2]).unwrap();
let mut output_buffer:Vec<u8> = Vec::with_capacity(filtered_data.len() * 4);
for &point in filtered_data.iter()
{
output_buffer.extend_from_slice(&point.to_be_bytes());
}
output_file.write_all(&output_buffer).unwrap();
}