use super::App;
use ratatui::{
Frame,
prelude::*,
style::Color,
widgets::{
Block, Borders,
canvas::{Canvas, Line as CanvasLine},
},
};
const MIN_PEAK: f32 = 0.001;
pub fn draw_mono_output(f: &mut Frame, area: Rect, app: &App) {
let block = Block::default().borders(Borders::ALL).title(" Output ");
let capture = app.capture.lock();
let samples: Vec<f32> = capture.mono_output().iter().copied().collect();
drop(capture);
if samples.is_empty() {
f.render_widget(block, area);
return;
}
let mean: f32 = samples.iter().sum::<f32>() / samples.len() as f32;
let centered: Vec<f32> = samples.iter().map(|&s| s - mean).collect();
let peak = centered.iter().map(|&s| s.abs()).fold(MIN_PEAK, f32::max);
let canvas = Canvas::default()
.block(block)
.x_bounds([0.0, 100.0])
.y_bounds([-1.0, 1.0])
.paint(|ctx| {
ctx.draw(&CanvasLine {
x1: 0.0,
y1: 0.0,
x2: 100.0,
y2: 0.0,
color: Color::DarkGray,
});
let len = centered.len();
let step = 100.0 / len as f64;
for i in 1..len {
let x1 = (i - 1) as f64 * step;
let x2 = i as f64 * step;
let y1 = (centered[i - 1] / peak) as f64 * 0.9;
let y2 = (centered[i] / peak) as f64 * 0.9;
ctx.draw(&CanvasLine {
x1,
y1,
x2,
y2,
color: Color::White,
});
}
});
f.render_widget(canvas, area);
}