mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
85 lines
2.7 KiB
Rust
85 lines
2.7 KiB
Rust
use crate::*;
|
|
|
|
#[derive(Debug, Default)]
|
|
pub enum MeteringMode {
|
|
#[default]
|
|
Rms,
|
|
Log10,
|
|
}
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
pub struct Log10Meter(pub f32);
|
|
impl Layout<TuiOut> for Log10Meter {}
|
|
impl Draw<TuiOut> for Log10Meter {
|
|
fn draw (&self, to: &mut TuiOut) {
|
|
let [x, y, w, h] = to.area();
|
|
let signal = 100.0 - f32::max(0.0, f32::min(100.0, self.0.abs()));
|
|
let v = (signal * h as f32 / 100.0).ceil() as u16;
|
|
let y2 = y + h;
|
|
//to.blit(&format!("\r{v} {} {signal}", self.0), x * 20, y, None);
|
|
for y in y..(y + v) {
|
|
for x in x..(x + w) {
|
|
to.blit(&"▌", x, y2 - y, Some(Style::default().green()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn to_log10 (samples: &[f32]) -> f32 {
|
|
let total: f32 = samples.iter().map(|x|x.abs()).sum();
|
|
let count = samples.len() as f32;
|
|
10. * (total / count).log10()
|
|
}
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
pub struct RmsMeter(pub f32);
|
|
impl Layout<TuiOut> for RmsMeter {}
|
|
impl Draw<TuiOut> for RmsMeter {
|
|
fn draw (&self, to: &mut TuiOut) {
|
|
let [x, y, w, h] = to.area();
|
|
let signal = f32::max(0.0, f32::min(100.0, self.0.abs()));
|
|
let v = (signal * h as f32).ceil() as u16;
|
|
let y2 = y + h;
|
|
//to.blit(&format!("\r{v} {} {signal}", self.0), x * 30, y, Some(Style::default()));
|
|
for y in y..(y + v) {
|
|
for x in x..(x + w) {
|
|
to.blit(&"▌", x, y2.saturating_sub(y), Some(Style::default().green()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn to_rms (samples: &[f32]) -> f32 {
|
|
let sum = samples.iter()
|
|
.map(|s|*s)
|
|
.reduce(|sum, sample|sum + sample.abs())
|
|
.unwrap_or(0.0);
|
|
(sum / samples.len() as f32).sqrt()
|
|
}
|
|
|
|
pub fn view_meter <'a> (label: &'a str, value: f32) -> impl Content<TuiOut> + 'a {
|
|
col!(
|
|
FieldH(ItemTheme::G[128], label, format!("{:>+9.3}", value)),
|
|
Fixed::XY(if value >= 0.0 { 13 }
|
|
else if value >= -1.0 { 12 }
|
|
else if value >= -2.0 { 11 }
|
|
else if value >= -3.0 { 10 }
|
|
else if value >= -4.0 { 9 }
|
|
else if value >= -6.0 { 8 }
|
|
else if value >= -9.0 { 7 }
|
|
else if value >= -12.0 { 6 }
|
|
else if value >= -15.0 { 5 }
|
|
else if value >= -20.0 { 4 }
|
|
else if value >= -25.0 { 3 }
|
|
else if value >= -30.0 { 2 }
|
|
else if value >= -40.0 { 1 }
|
|
else { 0 }, 1, Tui::bg(if value >= 0.0 { Red }
|
|
else if value >= -3.0 { Yellow }
|
|
else { Green }, ())))
|
|
}
|
|
|
|
pub fn view_meters (values: &[f32;2]) -> impl Content<TuiOut> + use<'_> {
|
|
let left = format!("L/{:>+9.3}", values[0]);
|
|
let right = format!("R/{:>+9.3}", values[1]);
|
|
Bsp::s(left, right)
|
|
}
|