use crate::*; #[derive(Debug, Default)] pub enum MixingMode { #[default] Summing, Average, } pub fn mix_summing ( buffer: &mut [Vec], gain: f32, frames: usize, mut next: impl FnMut()->Option<[f32;N]>, ) -> bool { let channels = buffer.len(); for index in 0..frames { if let Some(frame) = next() { for (channel, sample) in frame.iter().enumerate() { let channel = channel % channels; buffer[channel][index] += sample * gain; } } else { return false } } true } pub fn mix_average ( buffer: &mut [Vec], gain: f32, frames: usize, mut next: impl FnMut()->Option<[f32;N]>, ) -> bool { let channels = buffer.len(); for index in 0..frames { if let Some(frame) = next() { for (channel, sample) in frame.iter().enumerate() { let channel = channel % channels; let value = buffer[channel][index]; buffer[channel][index] = (value + sample * gain) / 2.0; } } else { return false } } true } #[derive(Debug, Default)] pub enum MeteringMode { #[default] Rms, Log10, } #[derive(Debug, Default, Clone)] pub struct Log10Meter(pub f32); #[derive(Debug, Default, Clone)] pub struct RmsMeter(pub f32); impl_draw!(|self: RmsMeter, to: Tui|{ let XYWH(x, y, w, h) = to.area().into(); 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())); } } Ok(Some(to.area().into())) }); impl_draw!(|self: Log10Meter, to: Tui| { let XYWH(x, y, w, h) = to.area().into(); 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())); } } Ok(Some(to.area().into())) }); 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() } 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() }