diff --git a/Cargo.toml b/Cargo.toml index 94cbd15..33fb213 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,8 @@ derive_more = "0.99.17" thiserror = "1.0.48" rustfft = "6.1.0" # for TUI backend -ratatui = { version = "0.23.0", features = ["all-widgets"], optional = true } -crossterm = { version = "0.25", optional = true } +ratatui = { version = "0.26", features = ["all-widgets"], optional = true } +crossterm = { version = "0.27", optional = true } # for pulseaudio libpulse-binding = { version = "2.0", optional = true } libpulse-simple-binding = { version = "2.25", optional = true } diff --git a/src/display/mod.rs b/src/display/mod.rs index 6be21f4..481c0d4 100644 --- a/src/display/mod.rs +++ b/src/display/mod.rs @@ -47,7 +47,7 @@ pub trait DisplayMode { } pub struct DataSet { - name: String, + name: Option, data: Vec<(f64, f64)>, marker_type: Marker, graph_type: GraphType, @@ -56,8 +56,11 @@ pub struct DataSet { impl<'a> From::<&'a DataSet> for Dataset<'a> { fn from(ds: &'a DataSet) -> Dataset<'a> { - Dataset::default() - .name(ds.name.clone()) + let mut out = Dataset::default(); // TODO creating a binding is kinda ugly, is it avoidable? + if let Some(name) = &ds.name { + out = out.name(name.clone()); + } + out .marker(ds.marker_type) .graph_type(ds.graph_type) .style(Style::default().fg(ds.color)) @@ -65,9 +68,10 @@ impl<'a> From::<&'a DataSet> for Dataset<'a> { } } +// TODO this is pretty ugly but I need datasets which own the data impl DataSet { pub fn new( - name: String, + name: Option, data: Vec<(f64, f64)>, marker_type: Marker, graph_type: GraphType, diff --git a/src/display/oscilloscope.rs b/src/display/oscilloscope.rs index c3facf0..99cb019 100644 --- a/src/display/oscilloscope.rs +++ b/src/display/oscilloscope.rs @@ -58,7 +58,7 @@ impl DisplayMode for Oscilloscope { fn references(&self, cfg: &GraphConfig) -> Vec { vec![ - DataSet::new("".into(), vec![(0.0, 0.0), (cfg.samples as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(0.0, 0.0), (cfg.samples as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color), ] } @@ -78,7 +78,7 @@ impl DisplayMode for Oscilloscope { } if self.triggering { - out.push(DataSet::new("T".into(), vec![(0.0, self.threshold)], cfg.marker_type, GraphType::Scatter, cfg.labels_color)); + out.push(DataSet::new(Some("T".into()), vec![(0.0, self.threshold)], cfg.marker_type, GraphType::Scatter, cfg.labels_color)); } for (n, channel) in data.iter().enumerate().rev() { @@ -94,7 +94,7 @@ impl DisplayMode for Oscilloscope { if self.peaks { out.push(DataSet::new( - "".into(), + None, vec![(0.0, min), (0.0, max)], cfg.marker_type, GraphType::Scatter, @@ -103,7 +103,7 @@ impl DisplayMode for Oscilloscope { } out.push(DataSet::new( - self.channel_name(n), + Some(self.channel_name(n)), tmp, cfg.marker_type, if cfg.scatter { GraphType::Scatter } else { GraphType::Line }, diff --git a/src/display/spectroscope.rs b/src/display/spectroscope.rs index 9e3815e..00280f0 100644 --- a/src/display/spectroscope.rs +++ b/src/display/spectroscope.rs @@ -115,11 +115,12 @@ impl DisplayMode for Spectroscope { if self.window { chunk = hann_window(chunk.as_slice()); } - let max_val = chunk.iter().max_by(|a, b| a.total_cmp(b)).expect("empty dataset?"); - let mut tmp : Vec> = chunk.iter().map(|x| Complex { re: *x / *max_val, im: 0.0 }).collect(); + let mut max_val = *chunk.iter().max_by(|a, b| a.total_cmp(b)).expect("empty dataset?"); + if max_val < 1. { max_val = 1.; } + let mut tmp : Vec> = chunk.iter().map(|x| Complex { re: *x / max_val, im: 0.0 }).collect(); fft.process(tmp.as_mut_slice()); out.push(DataSet::new( - self.channel_name(n), + Some(self.channel_name(n)), tmp[..=tmp.len() / 2] .iter() .enumerate() @@ -149,37 +150,37 @@ impl DisplayMode for Spectroscope { fn references(&self, cfg: &GraphConfig) -> Vec { let s = if self.log_y { (cfg.scale as f64 / 10.0).ln() } else { cfg.scale as f64 / 10.0 }; vec![ - DataSet::new("".into(), vec![(0.0, 0.0), ((cfg.samples as f64).ln(), 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(0.0, 0.0), ((cfg.samples as f64).ln(), 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color), // TODO can we auto generate these? lol... - DataSet::new("".into(), vec![(20.0f64.ln(), 0.0), (20.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(30.0f64.ln(), 0.0), (30.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(40.0f64.ln(), 0.0), (40.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(50.0f64.ln(), 0.0), (50.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(60.0f64.ln(), 0.0), (60.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(70.0f64.ln(), 0.0), (70.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(80.0f64.ln(), 0.0), (80.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(90.0f64.ln(), 0.0), (90.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(100.0f64.ln(), 0.0), (100.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(200.0f64.ln(), 0.0), (200.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(300.0f64.ln(), 0.0), (300.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(400.0f64.ln(), 0.0), (400.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(500.0f64.ln(), 0.0), (500.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(600.0f64.ln(), 0.0), (600.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(700.0f64.ln(), 0.0), (700.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(800.0f64.ln(), 0.0), (800.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(900.0f64.ln(), 0.0), (900.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(1000.0f64.ln(), 0.0), (1000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(2000.0f64.ln(), 0.0), (2000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(3000.0f64.ln(), 0.0), (3000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(4000.0f64.ln(), 0.0), (4000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(5000.0f64.ln(), 0.0), (5000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(6000.0f64.ln(), 0.0), (6000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(7000.0f64.ln(), 0.0), (7000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(8000.0f64.ln(), 0.0), (8000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(9000.0f64.ln(), 0.0), (9000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(10000.0f64.ln(), 0.0), (10000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(20000.0f64.ln(), 0.0), (20000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(20.0f64.ln(), 0.0), (20.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(30.0f64.ln(), 0.0), (30.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(40.0f64.ln(), 0.0), (40.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(50.0f64.ln(), 0.0), (50.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(60.0f64.ln(), 0.0), (60.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(70.0f64.ln(), 0.0), (70.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(80.0f64.ln(), 0.0), (80.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(90.0f64.ln(), 0.0), (90.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(100.0f64.ln(), 0.0), (100.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(200.0f64.ln(), 0.0), (200.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(300.0f64.ln(), 0.0), (300.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(400.0f64.ln(), 0.0), (400.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(500.0f64.ln(), 0.0), (500.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(600.0f64.ln(), 0.0), (600.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(700.0f64.ln(), 0.0), (700.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(800.0f64.ln(), 0.0), (800.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(900.0f64.ln(), 0.0), (900.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(1000.0f64.ln(), 0.0), (1000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(2000.0f64.ln(), 0.0), (2000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(3000.0f64.ln(), 0.0), (3000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(4000.0f64.ln(), 0.0), (4000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(5000.0f64.ln(), 0.0), (5000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(6000.0f64.ln(), 0.0), (6000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(7000.0f64.ln(), 0.0), (7000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(8000.0f64.ln(), 0.0), (8000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(9000.0f64.ln(), 0.0), (9000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(10000.0f64.ln(), 0.0), (10000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(20000.0f64.ln(), 0.0), (20000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color), ] } } diff --git a/src/display/vectorscope.rs b/src/display/vectorscope.rs index d7d9c87..c8c95a1 100644 --- a/src/display/vectorscope.rs +++ b/src/display/vectorscope.rs @@ -36,8 +36,8 @@ impl DisplayMode for Vectorscope { fn references(&self, cfg: &GraphConfig) -> Vec { vec![ - DataSet::new("".into(), vec![(-(cfg.scale as f64), 0.0), (cfg.scale as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color), - DataSet::new("".into(), vec![(0.0, -(cfg.scale as f64)), (0.0, cfg.scale as f64)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(-(cfg.scale as f64), 0.0), (cfg.scale as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color), + DataSet::new(None, vec![(0.0, -(cfg.scale as f64)), (0.0, cfg.scale as f64)], cfg.marker_type, GraphType::Line, cfg.axis_color), ] } @@ -65,14 +65,14 @@ impl DisplayMode for Vectorscope { // TODO configure splitting in multiple parts? let pivot = tmp.len() / 2; out.push(DataSet::new( - self.channel_name((n * 2) + 1), + Some(self.channel_name((n * 2) + 1)), tmp[pivot..].to_vec(), cfg.marker_type, if cfg.scatter { GraphType::Scatter } else { GraphType::Line }, cfg.palette((n * 2) + 1), )); out.push(DataSet::new( - self.channel_name(n * 2), + Some(self.channel_name(n * 2)), tmp[..pivot].to_vec(), cfg.marker_type, if cfg.scatter { GraphType::Scatter } else { GraphType::Line },