summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs322
1 files changed, 307 insertions, 15 deletions
diff --git a/src/main.rs b/src/main.rs
index b01dc9f..6e247c9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,35 +2,299 @@ use cpal::traits::HostTrait;
use cpal::traits::DeviceTrait;
use cpal::traits::StreamTrait;
+use eframe;
+use eframe::egui;
+use egui::plot::*;
+
+use std::io::Write;
+
+use std::time::{Duration, Instant};
+use rustfft::num_complex::Complex32;
+
+use fftw::array::AlignedVec;
+use fftw::plan::*;
+use fftw::types::*;
+use std::f64::consts::PI;
+
use std::time;
use std::thread;
use std::sync::mpsc;
+use std::fs::File;
+use std::path::Path;
+
+
+struct App {
+ val: bool,
+ it: u32,
+}
+
+impl Default for App {
+ fn default() -> Self {
+ Self {
+ val: false,
+ it: 0,
+ }
+ }
+}
+
+impl eframe::App for App {
+ fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
+ egui::SidePanel::left("side_panel").show(ctx, |ui| {
+ let sin: PlotPoints = (0..1000).map(|i| {
+ let x = i as f64 * 0.01;
+ [x, x.sin() * (self.it as f64 * 0.01).cos()]
+ }).collect();
+
+
+
+ if self.val {
+ ui.ctx().request_repaint();
+ self.it += 1;
+ }
+
+ let line = Line::new(sin);
+
+ Plot::new("plot").view_aspect(2.0).center_y_axis(true).show(ui, |plui| plui.line(line));
+
+ ui.checkbox(&mut self.val, "Animate");
+ println!("{}", &self.val);
+
+ // std::thread::sleep(std::time::Duration::from_millis(1))
+ });
+
+ egui::TopBottomPanel::top("top").show(ctx, |_ui| {
+ _ui.label("lol");
+
+ });
+ }
+}
+
+
+
+struct SamplePacket {
+ sample_rate: u32,
+ data: Box<[Complex32]>
+}
+
+impl SamplePacket {
+ fn new(sample_rate: u32, data: Box<[Complex32]>) -> Self {
+ Self {
+ sample_rate: sample_rate,
+ data: data
+ }
+ }
+}
+
+trait Process {
+ fn process(&mut self, src: SamplePacket) -> SamplePacket;
+}
+
+struct PipelineBuilder {
+ input: mpsc::SyncSender<SamplePacket>,
+ output: mpsc::Receiver<SamplePacket>
+}
+
+impl PipelineBuilder {
+ fn new() -> Self {
+ let (input, output) = mpsc::sync_channel(1);
+
+ Self {
+ input: input,
+ output: output
+ }
+ }
+
+ fn pipe<T>(mut self, mut proc: T) -> Self
+ where
+ T: Process + Send + 'static
+ {
+ let (proc_out, output) = mpsc::sync_channel(1);
+
+ let proc_in = std::mem::replace(&mut self.output, output);
+
+ thread::spawn(move || {
+ loop {
+ let src = match proc_in.recv() {
+ Ok(s) => s,
+ Err(_) => break,
+ };
+
+ let dst = proc.process(src);
+
+ if proc_out.send(dst).is_err() {
+ break;
+ }
+ }
+ });
+
+ self
+ }
+
+ fn finish(self) -> (mpsc::SyncSender<SamplePacket>, mpsc::Receiver<SamplePacket>) {
+ (self.input, self.output)
+ }
+}
+
+struct Squarer;
+impl Process for Squarer {
+ fn process(&mut self, mut src: SamplePacket) -> SamplePacket {
+ for sample in src.data.iter_mut() {
+ sample.re = (sample.re * 10.0) as i32 as f32 / 10.0;
+ sample.im = (sample.im * 10.0) as i32 as f32 / 10.0;
+ }
+
+ src
+ }
+}
+
+struct BandFilter {
+ wrap_around: Box<[f32]>,
+ window_filter: Box<[f32]>,
+ test: usize,
+ agc: f32,
+ phase: f32
+}
+
+impl BandFilter {
+ fn new(window_size: usize) -> Self {
+ let mut window_filter = vec![0.0f32; window_size].into_boxed_slice();
+
+
+ Self {
+ wrap_around: vec![0.0f32; window_size - 1].into_boxed_slice(),
+ window_filter: window_filter,
+ test: 0,
+ agc: 1.0,
+ phase: 0.0
+ }
+ }
+}
+
+impl Process for BandFilter {
+ fn process(&mut self, mut src: SamplePacket) -> SamplePacket {
+ if src.data.len() != 250000 {
+ println!("smh {}", src.data.len());
+ return src;
+ }
+
+ use rustfft::{Fft, FftDirection, algorithm::Radix4};
+ use rustfft::num_complex::Complex32;
+
+ let mut fft_planner = rustfft::FftPlannerAvx::new().unwrap();
+
+ let len = 250000;
+ let fft = fft_planner.plan_fft_forward(len);
+ let ifft = fft_planner.plan_fft_inverse(len);
+
+ src.data.iter_mut().enumerate().for_each(|(i, c)| {
+ let phase = i as f32 / len as f32 * 2.0 * 3.14159265359 * 0.0;
+
+ *c *= Complex32 { re: phase.cos(), im: phase.sin() };
+ });
+
+
+ fft.process(&mut src.data);
+
+ src.data[100000..len-100000].iter_mut().for_each(|c| *c = Complex32::default());
+
+ ifft.process(&mut src.data);
+
+ src.data.iter_mut().enumerate().for_each(|(i, c)| {
+ *c /= len as f32;
+
+ //let (_, phase) = c.to_polar();
+ let (_, phase) = c.to_polar();
+
+ let mut diff = phase - self.phase;
+
+ if diff > 3.141592 {
+ diff -= 2.0 * 3.141592;
+ } else if diff <= -3.141592 {
+ diff += 2.0 * 3.141592;
+ }
+
+ let deriv = diff * 250000.0 / 1000000.0;
+ self.phase = phase;
+
+ c.re = deriv;
+ c.im = 0.0;
+
+ let bytes = unsafe { std::mem::transmute::<Complex32, [u8;8]>(*c) };
+
+ // std::io::stdout().write(&bytes);
+ });
+
+ src
+ }
+}
+
+struct Resampler {
+ output_rate: u32,
+}
+
+impl Resampler {
+ fn new(output_rate: u32) -> Self {
+ Self {
+ output_rate: output_rate,
+ }
+ }
+}
+
+impl Process for Resampler {
+ fn process(&mut self, src: SamplePacket) -> SamplePacket {
+ if src.sample_rate == self.output_rate {
+ return src;
+ }
+
+ let skip = src.sample_rate as f32 / self.output_rate as f32;
+ let length = (src.data.len() as f32 / skip) as usize;
+
+ let mut dst = vec![Complex32::default();length].into_boxed_slice();
+
+ //dst.copy_from_slice(&src.data);
+ let mut idx = 0.0f32;
+ let mut isrc = idx as usize;
+ let mut idst = 0;
+ while idst < dst.len() && isrc < src.data.len() {
+ dst[idst] = src.data[isrc];
+
+ idx += skip;
+ isrc = idx as usize;
+ idst += 1;
+ }
+
+ SamplePacket::new(self.output_rate, dst)
+ }
+}
+
struct AudioSink {
- recv: mpsc::Receiver<Box<[f32]>>,
- buffer: Option<Box<[f32]>>,
+ recv: mpsc::Receiver<SamplePacket>,
+ buffer: Option<SamplePacket>,
idx: usize
}
impl AudioSink {
- fn new(recv: mpsc::Receiver<Box<[f32]>>) -> Self {
+ fn new(recv: mpsc::Receiver<SamplePacket>) -> Self {
Self {
recv: recv,
buffer: None,
- idx: 0
+ idx: 0,
}
}
- fn pour(&mut self, mut dst: &mut [f32], i: usize) {
+ fn pour(&mut self, mut dst: &mut [f32]) {
loop {
match self.buffer.as_ref() {
Some(src) => {
+ let src = &src.data;
let src_new = &src[self.idx..];
let count = std::cmp::min(src_new.len(), dst.len());
let src_new = &src_new[..count];
let dst_new = &mut dst[..count];
- dst_new.copy_from_slice(&src_new);
+ dst_new.iter_mut().zip(src_new.iter())
+ .for_each(|(d, s)| *d = s.re);
self.idx += count;
@@ -55,6 +319,12 @@ impl AudioSink {
}
fn main() {
+ eframe::run_native(
+ "λ",
+ eframe::NativeOptions::default(),
+ Box::new(|_cc| Box::new(App::default()))
+ );
+
let host = cpal::default_host();
let dev = host.default_output_device().expect("no audio device found");
@@ -63,17 +333,33 @@ fn main() {
.next()
.expect("bogus device")
.with_max_sample_rate().into();
+ let sample_rate = cfg.sample_rate.0 * cfg.channels as u32;
let denom = cfg.sample_rate.0 as f32 * cfg.channels as f32;
+ //println!("sample_rate{}", sample_rate);
+
+ let mut inp_file = File::open(Path::new("baseband_100100000Hz_19-35-33_03-11-2022.wav")).unwrap();
+ let (header, data) = wav::read(&mut inp_file).unwrap();
+ let data = match data {
+ wav::BitDepth::ThirtyTwoFloat(d) => d,
+ wav::BitDepth::TwentyFour(s) => s.into_iter().map(|m: i32| m as f32 / (1<<23) as f32).collect::<Vec<f32>>(),
+ wav::BitDepth::Sixteen(s) => s.into_iter().map(|m: i16| m as f32 / i16::MAX as f32).collect::<Vec<f32>>(),
+ _ => panic!("unsupported bit depth")
+ };
+
+
+ let (send, recv) = PipelineBuilder::new()
+ .pipe(BandFilter::new(1024))
+ .pipe(Resampler::new(sample_rate))
+ .finish();
- let (send, recv) = mpsc::sync_channel(1);
let mut snk = AudioSink::new(recv);
let mut snum: f32 = 0.0;
let stream = dev.build_output_stream(
&cfg,
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
- snk.pour(data, 0);
+ snk.pour(data);
},
move |err| {
println!("err: {}", err);
@@ -83,15 +369,21 @@ fn main() {
stream.play().unwrap();
let mut snum: usize = 0;
+
+
+ //println!("{}", header.channel_count);
+
+ let sampling_rate = header.sampling_rate as usize;
+ let channel_count = header.channel_count as usize;
- loop {
- let mut samples = vec![0.0f32;1024].into_boxed_slice();
+ let mut i = 0;
+ while i + sampling_rate*channel_count < data.len() {
+ let mut samples = vec![Complex32::default();sampling_rate].into_boxed_slice();
- for s in samples.iter_mut() {
- *s += (snum as f32 / denom * 2.0 * 3.141592 * 200.0 as f32).sin();
- snum = snum.wrapping_add(1);
- }
+ samples.iter_mut().zip(data[i..i + sampling_rate*channel_count].chunks(2))
+ .for_each(|(a, b)| *a = Complex32 { re: b[0], im: b[1] });
- send.send(samples).unwrap();
+ send.send(SamplePacket::new(header.sampling_rate, samples)).unwrap();
+ i += sampling_rate*channel_count;
}
}