dynamic fft scaling
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Has been cancelled

This commit is contained in:
Max Känner 2025-01-14 10:48:28 +01:00
parent 2f60fb8ba3
commit 5f374a9bc9

View File

@ -51,6 +51,8 @@ fn main() -> color_eyre::Result<()> {
let fft = planner.plan_fft_forward(buffer_size as usize); let fft = planner.plan_fft_forward(buffer_size as usize);
let mut fft_input = fft.make_input_vec(); let mut fft_input = fft.make_input_vec();
let mut fft_output = fft.make_output_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 (sender, receiver) = mpsc::channel();
let stream = device.build_input_stream( let stream = device.build_input_stream(
@ -61,6 +63,8 @@ fn main() -> color_eyre::Result<()> {
&mut fft_input, &mut fft_input,
&mut fft_output, &mut fft_output,
config.sample_rate.0, config.sample_rate.0,
&mut previous_sample_smth,
&mut previous_magnitude,
) { ) {
Ok(packet) => { Ok(packet) => {
if let Err(e) = sender.send(packet) { if let Err(e) = sender.send(packet) {
@ -79,7 +83,6 @@ fn main() -> color_eyre::Result<()> {
stream.play()?; stream.play()?;
let mut previous_sample_smth = 0.0;
loop { loop {
let mut data = receiver.recv()?; let mut data = receiver.recv()?;
data.sample_smth = 0.8f32.mul_add(previous_sample_smth, 0.2 * data.sample_raw); 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_input: &mut [f32],
fft_output: &mut [Complex32], fft_output: &mut [Complex32],
sample_rate: u32, sample_rate: u32,
previous_sample_smth: &mut f32,
previous_magnitude: &mut f32,
) -> Result<Self> { ) -> Result<Self> {
// take the absolute value of the audio data // take the absolute value of the audio data
let abs_data: Vec<_> = data.iter().map(|sample| sample.abs()).collect(); let abs_data: Vec<_> = data.iter().map(|sample| sample.abs()).collect();
@ -215,24 +220,27 @@ impl AudioSyncPacket {
// scale the fft values to u8 // scale the fft values to u8
let mut fft_values_u8 = [0u8; 16]; let mut fft_values_u8 = [0u8; 16];
let mut fft_max = fft_values let fft_max = fft_values
.iter() .iter()
.max_by(|lhs, rhs| lhs.partial_cmp(rhs).unwrap_or(Ordering::Equal)) .max_by(|lhs, rhs| lhs.partial_cmp(rhs).unwrap_or(Ordering::Equal))
.copied() .copied()
.unwrap_or(1.0); .unwrap_or(1.0)
if fft_max == 0.0 { .max(1.0);
fft_max = 1.0; let magnitude = fft_max.max(*previous_magnitude * 0.99);
} *previous_magnitude = magnitude;
for i in 0..fft_values.len() { 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 // calculate fft magnitude sum
let fft_magnitude_sum = real_fft_output.iter().sum::<f32>(); let fft_magnitude_sum = real_fft_output.iter().sum::<f32>();
let sample_smth = 0.8f32.mul_add(*previous_sample_smth, 0.2 * raw_level);
*previous_sample_smth = sample_smth;
Ok(Self::new( Ok(Self::new(
raw_level, raw_level,
0.0, sample_smth,
peak_level, peak_level,
fft_values_u8, fft_values_u8,
fft_magnitude_sum, fft_magnitude_sum,