diff --git a/src/main.rs b/src/main.rs index 57eb8c6..6e5347f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,17 @@ mod windows; use egui_plot::{Legend, Line, Plot}; use hound::WavWriter; -use rand::{rand_core::le, seq::index::sample, Rng}; -use std::{cell::{Cell, RefCell}, collections::VecDeque, env::{self, args}, fs::File, io::{stdout, BufWriter, Sink, Write}, ops::DerefMut, sync::Arc, time::Duration}; +use rand::{Rng, rand_core::le, seq::index::sample}; +use std::{ + cell::{Cell, RefCell}, + collections::VecDeque, + env::{self, args}, + fs::File, + io::{BufWriter, Sink, Write, stdout}, + ops::DerefMut, + sync::Arc, + time::Duration, +}; use tokio::{join, net::UdpSocket, select, time::timeout}; use crate::{ @@ -26,7 +35,8 @@ use crate::{ ted::elg::ELGate, units::frequency::hz_to_rad_per_sample, }; -use eframe::{egui::{self, mutex::{Mutex, RwLock}, panel::Side, CentralPanel, Color32, SidePanel}, glow::SAMPLE_MASK_VALUE}; +use eframe::egui::{self, CentralPanel, Color32}; +use tokio::sync::RwLock; use tokio::sync::mpsc::{Receiver, Sender, channel}; const BAUD_RATE: u32 = 1000; @@ -36,108 +46,23 @@ const SAMPLE_RATE: u32 = 48000; const CENTER_FREQ: f32 = 1700.; const DEVIATION: f32 = 500.; - pub trait SampleSender { async fn open_link(&mut self); async fn send_sample(&mut self, sample: f32); async fn close_link(&mut self); } -pub struct ChannelSampleSender -{ - pub sender: Sender, - pub open: Arc>, +struct WavSampleSender { + writer: Option>>, } -impl SampleSender for ChannelSampleSender -{ - async fn open_link(&mut self) - { - *self.open.write() = true; - } - - async fn send_sample(&mut self, sample: f32) { - self.sender.send(sample).await.unwrap(); - } - - async fn close_link(&mut self) - { - *self.open.write() = false; - } -} - -fn create_dummy_channel() -> ((Receiver, ChannelSampleSender), (Receiver, ChannelSampleSender)) -{ - let a_open = Arc::new(RwLock::new(false)); - let b_open = Arc::new(RwLock::new(false)); - let a_open_cln = a_open.clone(); - let b_open_cln = b_open.clone(); - - // Up link - let (a_up_tx, mut a_up_rx) = channel::(1024); - let (b_up_tx, mut b_up_rx) = channel::(1024); - - // Down link - let (a_down_tx, a_down_rx) = channel::(1024); - let (b_down_tx, b_down_rx) = channel::(1024); - - tokio::spawn(async move { - loop - { - let sample = select! - { - Some(x) = a_up_rx.recv() => x, - Some(x) = b_up_rx.recv() => x - }; - - if !(*a_open_cln.read()) - { - a_down_tx.send(sample).await.unwrap(); - } - - if !(*b_open_cln.read()) - { - b_down_tx.send(sample).await.unwrap(); - } - } - }); - - - ( - ( - a_down_rx, - ChannelSampleSender - { - open: a_open, - sender: a_up_tx - } - ), - ( - b_down_rx, - ChannelSampleSender - { - open: b_open, - sender: b_up_tx - } - ) - ) - -} - -struct WavSampleSender -{ - writer: Option>> -} - -impl Default for WavSampleSender -{ +impl Default for WavSampleSender { fn default() -> Self { Self { writer: None } } } -impl SampleSender for WavSampleSender -{ +impl SampleSender for WavSampleSender { async fn open_link(&mut self) { let spec = hound::WavSpec { channels: 1, @@ -149,9 +74,12 @@ impl SampleSender for WavSampleSender } async fn send_sample(&mut self, sample: f32) { - - let out_sample = (sample * i16::MAX as f32) as i16; - self.writer.as_mut().unwrap().write_sample(out_sample).unwrap(); + let out_sample = (sample * i16::MAX as f32) as i16; + self.writer + .as_mut() + .unwrap() + .write_sample(out_sample) + .unwrap(); } async fn close_link(&mut self) { @@ -167,7 +95,7 @@ impl Transceiver { mut tx_stream: Receiver>, mut rx_stream: Sender>, mut sample_sender: T, - mut eye_sender: Sender> + mut eye_sender: Sender>, ) { let mut resend: Option> = None; loop { @@ -179,6 +107,8 @@ impl Transceiver { { x = Self::receive(&mut sample_stream, &mut eye_sender) => { + // Flush channel + while sample_stream.recv().await.is_some() {}; match x { Err(()) => {continue;}, @@ -188,7 +118,8 @@ impl Transceiver { } Ok(Frame::Data(data)) => { - rx_stream.send(data).await.unwrap(); + let _ = rx_stream.send(data).await; + tokio::time::sleep(Duration::from_secs(1)).await; Self::transmit(Frame::Ack, &mut sample_sender).await; } } @@ -214,7 +145,6 @@ impl Transceiver { { if let Some(data) = data_opt { - println!("Sending data"); Self::transmit(Frame::Data(data.clone()), &mut sample_sender).await; resend = Some(data); } @@ -262,7 +192,10 @@ impl Transceiver { samples_sender.close_link().await; } - async fn receive(sample_stream: &mut Receiver, eye_sender: &mut Sender>) -> Result { + async fn receive( + sample_stream: &mut Receiver, + eye_sender: &mut Sender>, + ) -> Result { let mut iq_sampler = IQSampler::new(hz_to_rad_per_sample(CENTER_FREQ, SAMPLE_RATE as f32)); let samples_per_symbol = (SAMPLE_RATE as f32) / (BAUD_RATE as f32); @@ -283,8 +216,10 @@ impl Transceiver { pos_correllator.normalize_freq(hz_to_rad_per_sample(DEVIATION, SAMPLE_RATE as f32)); neg_correllator.normalize_freq(hz_to_rad_per_sample(-DEVIATION, SAMPLE_RATE as f32)); - let mut matched_lowpass = - FIRFilter::new(&vec![Complex32::new(1., 0.); samples_per_symbol as usize / 2]); + let mut matched_lowpass = FIRFilter::new(&vec![ + Complex32::new(1., 0.); + samples_per_symbol as usize / 2 + ]); matched_lowpass.normalize_freq(hz_to_rad_per_sample(DEVIATION, SAMPLE_RATE as f32)); //let mut dc_block = DCBlocker::new(0.999); let mut dc_block = DCBlocker::new(1.); @@ -292,7 +227,7 @@ impl Transceiver { let loop_i = 0.0; let loop_p = 0.1; let mut loop_ir = vec![Complex32::new(loop_i, 0.); samples_per_symbol as usize]; - loop_ir.push(Complex32::new(loop_p, 0.)); + loop_ir.push(Complex32::new(loop_p, 0.)); let mut elg = ELGate::new(samples_per_symbol, FIRFilter::new(&loop_ir)); // Frame reconstruction @@ -302,11 +237,10 @@ impl Transceiver { while let Some(sample) = sample_stream.recv().await { let iq = iq_sampler.sample(sample); let matched = - matched_lowpass.next_real( - dc_block.next_real( - pos_correllator.next(iq).mag() - neg_correllator.next(iq).mag(), - ) - ); + matched_lowpass + .next_real(dc_block.next_real( + pos_correllator.next(iq).mag() - neg_correllator.next(iq).mag(), + )); if let Some((bit_sample, eye)) = elg.next_eye(matched) { let _ = eye_sender.send(eye).await; last_byte >>= 1; @@ -315,7 +249,8 @@ impl Transceiver { //last_byte |= ((bit_sample < 0.) as u8); bit_count = bit_count.map(|x| x + 1); - if let None = bit_count && last_byte == 0xD8 + if let None = bit_count + && last_byte == 0xD8 { // Potential frame starts last_byte = 0; @@ -362,7 +297,7 @@ pub struct FrameConstructor { frame: Vec, frame_countdown: Option, checksum: u8, - started: bool + started: bool, } impl FrameConstructor { @@ -371,7 +306,7 @@ impl FrameConstructor { frame: Vec::new(), frame_countdown: None, checksum: 0u8, - started: false + started: false, } } @@ -382,12 +317,12 @@ impl FrameConstructor { return Err(()); } - if self.frame.is_empty() && byte == 0xC4 && !self.started{ + if self.frame.is_empty() && byte == 0xC4 && !self.started { self.started = true; return Ok(Some(Frame::Ack)); } - if self.frame.is_empty() && byte == 0x4C && !self.started{ + if self.frame.is_empty() && byte == 0x4C && !self.started { self.started = true; return Ok(None); } @@ -465,7 +400,7 @@ impl Frame { #[tokio::main] async fn main() { //Transceiver::transmit(Frame::Data("Skibditoilet".repeat(100).bytes().collect::>()), &mut WavSampleSender{}).await; - Transceiver::transmit(Frame::Ack, &mut WavSampleSender::default()).await; + //Transceiver::transmit(Frame::Ack, &mut WavSampleSender::default()).await; //return; let native_options = eframe::NativeOptions::default(); @@ -488,132 +423,26 @@ impl SampleSender for DummySampleSender { struct EguiApp { eye_receiver_a: Receiver>, - eye_receiver_b: Receiver>, eyes_a: VecDeque>, - eyes_b: VecDeque>, - up_a_tx: Sender> } impl EguiApp { fn new(_cc: &eframe::CreationContext<'_>) -> Self { - let (eye_a_tx, mut eye_a_rx) = channel::>(1024); - let (eye_b_tx, mut eye_b_rx) = channel::>(1024); - - let (eye_a_red_tx, eye_a_red_rx) = channel::>(1024); - let (eye_b_red_tx, eye_b_red_rx) = channel::>(1024); - let ctx = _cc.egui_ctx.clone(); - tokio::spawn(async move - { - loop - { - let _ = select! - { - Some(eye) = eye_a_rx.recv() => {eye_a_red_tx.send(eye).await.unwrap()} - Some(eye) = eye_b_rx.recv() => {eye_b_red_tx.send(eye).await.unwrap()} - }; - ctx.request_repaint(); - } - } - ); - - let ((sample_down_a, sample_up_a), (sample_down_b, sample_up_b)) = create_dummy_channel(); - let (up_a_tx, up_a_rx) = channel::>(1024); - let (down_a_tx, down_a_rx) = channel::>(1024); - - let (up_b_tx, up_b_rx) = channel::>(1024); - let (down_b_tx, down_b_rx) = channel::>(1024); - - tokio::spawn(Transceiver::start(sample_down_a, up_a_rx, down_a_tx, sample_up_a, eye_a_tx)); - tokio::spawn(Transceiver::start(sample_down_b, up_b_rx, down_b_tx, sample_up_b, eye_b_tx)); - - // tokio::spawn(async move { - // loop - // { - // let bytes = receive_rx.recv().await.unwrap(); - // let str = String::from_utf8(bytes).unwrap(); - // println!("{}", str); - // - // } - // }); - // - - - Self { - eye_receiver_a: eye_a_red_rx, - eye_receiver_b: eye_b_red_rx, - eyes_a: VecDeque::with_capacity(100), - eyes_b: VecDeque::with_capacity(100), - - up_a_tx, - } + EguiApp {} } } impl eframe::App for EguiApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - egui::CentralPanel::default() - .show(ctx, |ui| { + egui::CentralPanel::default().show(ctx, |ui| { let max_eyes = 100; while let Ok(eye) = self.eye_receiver_a.try_recv() { self.eyes_a.push_back(eye); } - - while let Ok(eye) = self.eye_receiver_b.try_recv() { - self.eyes_b.push_back(eye); - } - while self.eyes_a.len() > max_eyes { self.eyes_a.pop_front(); } - - while self.eyes_b.len() > max_eyes { - self.eyes_b.pop_front(); - } - - ui.columns(2, |uis| { - Plot::new("EyeA") - .legend(Legend::default()) - .show(&mut uis[0], |plot_ui| { - //plot_ui.set_auto_bounds(Vec2b { x: false, y: false }); - for eye in self.eyes_a.iter() { - let line = Line::new( - "EyeA", - eye.iter() - .enumerate() - .map(|(i, x)| [i as f64, *x as f64]) - .collect::>(), - ) - .color(Color32::LIGHT_GREEN); - plot_ui.line(line); - } - }); - - if uis[0].button("Start").clicked() - { - let snd = self.up_a_tx.clone(); - tokio::spawn(async move { - let _ = snd.send("Skibditoilet".repeat(100).as_bytes().to_vec()).await; - }); - } - - Plot::new("EyeB") - .legend(Legend::default()) - .show(&mut uis[1], |plot_ui| { - //plot_ui.set_auto_bounds(Vec2b { x: false, y: false }); - for eye in self.eyes_b.iter() { - let line = Line::new( - "EyeB", - eye.iter() - .enumerate() - .map(|(i, x)| [i as f64, *x as f64]) - .collect::>(), - ) - .color(Color32::LIGHT_GREEN); - plot_ui.line(line); - } - }); - }); - }); + }); } }