use crate::*; #[derive(Debug, Default)] pub enum MeteringMode { #[default] Rms, Log10, } #[derive(Debug, Default, Clone)] pub struct Log10Meter(pub f32); impl Layout for Log10Meter {} impl Draw 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 for RmsMeter {} impl Draw 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 + '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 + use<'_> { let left = format!("L/{:>+9.3}", values[0]); let right = format!("R/{:>+9.3}", values[1]); Bsp::s(left, right) }