diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 322 |
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; } } |
