dspfrivs/src/skew.rs

80 lines
1.6 KiB
Rust

#![allow(unused_parens)]
use std::io::prelude::*;
use std::fs::File;
use std::env::args;
fn main()
{
let argv = args().collect::<Vec<String>>();
if argv.len() != 4
{
eprintln!("usage: skew <offset‰> <mismatch‰> <target.dat>");
return;
}
// offset: permil phase offset in transmission from receiver
// mismatch: permil frequency error in transmission sample rate from receiver sample rate
let offset =
(
argv[1]
.parse::<f32>()
.unwrap()
/ 1000.0
);
let mismatch =
(
argv[2]
.parse::<f32>()
.unwrap()
.max(-999.0) // no closer to 0 than 1 permil
/ 1000.0
);
let mut input = File::open(&argv[3]).unwrap();
let mut data:Vec<f32> = Vec::new();
loop
{
let mut buffer:[u8;4] = [0x00;4];
match input.read_exact(&mut buffer)
{
Ok(_) => (),
Err(_) => break,
};
data.push(f32::from_be_bytes(buffer));
}
let output_length =
(
(
data.len() as f32
/
(1.0 + mismatch)
)
as usize
);
let mut result:Vec<f32> = Vec::with_capacity(output_length);
for i in 0..output_length
{
let skew = offset + (i as f32) * mismatch;
let shift = skew.floor() as usize;
let upper_misalign = skew.fract();
let lower_misalign = 1.0 - skew.fract();
result.push(
upper_misalign * data[(i + shift + 1) % data.len()]
+
lower_misalign * data[(i + shift + 0) % data.len()]
);
}
let mut output = File::create(&argv[3]).unwrap();
let mut output_buffer:Vec<u8> = Vec::with_capacity(data.len() * 4);
for &point in result.iter()
{
output_buffer.extend_from_slice(&point.to_be_bytes());
}
output.write_all(&output_buffer).unwrap();
}