tek/src/sampler/sample_viewer.rs

53 lines
1.9 KiB
Rust

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<Arc<RwLock<Sample>>>);
render!(<Tui>|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<Line>) =
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(())
}));