use crate::*; use std::ops::Deref; use ratatui::{prelude::Rect, widgets::{Widget, canvas::{Canvas, Points, Line}}}; const EMPTY: &[(f64, f64)] = &[(0., 0.), (1., 1.), (2., 2.), (0., 2.), (2., 0.)]; pub struct SampleViewer(pub Option>>); render!(|self: SampleViewer|render(|to|{ let [x, y, width, height] = to.area(); let area = Rect { x, y, width, height }; let min_db = -40.0; let (x_bounds, y_bounds, lines): ([f64;2], [f64;2], Vec) = if let Some(sample) = &self.0 { let sample = sample.read().unwrap(); let start = sample.start as f64; let end = sample.end as f64; let length = end - start; let step = length / width as f64; let mut t = start; let mut lines = vec![]; while t < end { let chunk = &sample.channels[0][t as usize..((t + step) as usize).min(sample.end)]; let total: f32 = chunk.iter().map(|x|x.abs()).sum(); let count = chunk.len() as f32; let meter = 10. * (total / count).log10(); let x = t as f64; let y = meter as f64; lines.push(Line::new(x, min_db, x, y, Color::Green)); t += step / 2.; } ( [sample.start as f64, sample.end as f64], [min_db, 0.], lines ) } else { ( [0.0, width as f64], [0.0, height as f64], vec![ Line::new(0.0, 0.0, width as f64, height as f64, Color::Red), Line::new(width as f64, 0.0, 0.0, height as f64, Color::Red), ] ) }; Canvas::default().x_bounds(x_bounds).y_bounds(y_bounds).paint(|ctx|{ for line in lines.iter() { ctx.draw(line) } }).render(area, &mut to.buffer); Ok(()) }));