From 5f374a9bc979004e330e6a8b0d19e9f7911b7d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20K=C3=A4nner?= Date: Tue, 14 Jan 2025 10:48:28 +0100 Subject: [PATCH] dynamic fft scaling --- src/main.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index feae976..6af186e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,8 @@ fn main() -> color_eyre::Result<()> { let fft = planner.plan_fft_forward(buffer_size as usize); let mut fft_input = fft.make_input_vec(); let mut fft_output = fft.make_output_vec(); + let mut previous_sample_smth = 0.0; + let mut previous_magnitude = 1.0; let (sender, receiver) = mpsc::channel(); let stream = device.build_input_stream( @@ -61,6 +63,8 @@ fn main() -> color_eyre::Result<()> { &mut fft_input, &mut fft_output, config.sample_rate.0, + &mut previous_sample_smth, + &mut previous_magnitude, ) { Ok(packet) => { if let Err(e) = sender.send(packet) { @@ -79,7 +83,6 @@ fn main() -> color_eyre::Result<()> { stream.play()?; - let mut previous_sample_smth = 0.0; loop { let mut data = receiver.recv()?; data.sample_smth = 0.8f32.mul_add(previous_sample_smth, 0.2 * data.sample_raw); @@ -168,6 +171,8 @@ impl AudioSyncPacket { fft_input: &mut [f32], fft_output: &mut [Complex32], sample_rate: u32, + previous_sample_smth: &mut f32, + previous_magnitude: &mut f32, ) -> Result { // take the absolute value of the audio data let abs_data: Vec<_> = data.iter().map(|sample| sample.abs()).collect(); @@ -215,24 +220,27 @@ impl AudioSyncPacket { // scale the fft values to u8 let mut fft_values_u8 = [0u8; 16]; - let mut fft_max = fft_values + let fft_max = fft_values .iter() .max_by(|lhs, rhs| lhs.partial_cmp(rhs).unwrap_or(Ordering::Equal)) .copied() - .unwrap_or(1.0); - if fft_max == 0.0 { - fft_max = 1.0; - } + .unwrap_or(1.0) + .max(1.0); + let magnitude = fft_max.max(*previous_magnitude * 0.99); + *previous_magnitude = magnitude; for i in 0..fft_values.len() { - fft_values_u8[i] = (fft_values[i] * f32::from(u8::MAX) / fft_max).saturating_as(); + fft_values_u8[i] = (fft_values[i] * f32::from(u8::MAX) / magnitude).saturating_as(); } // calculate fft magnitude sum let fft_magnitude_sum = real_fft_output.iter().sum::(); + let sample_smth = 0.8f32.mul_add(*previous_sample_smth, 0.2 * raw_level); + *previous_sample_smth = sample_smth; + Ok(Self::new( raw_level, - 0.0, + sample_smth, peak_level, fft_values_u8, fft_magnitude_sum,