From e56b9ef454d171ae76a8eaf0dac600e22b0ebb58 Mon Sep 17 00:00:00 2001 From: TerraMaster85 Date: Wed, 15 Jan 2025 12:42:14 -0500 Subject: [PATCH] almost there, i can smell it (input_dsp.rs) --- src/audio_receiver/input_dsp.rs | 50 +++++++++++++++++++++++++++------ src/main.rs | 1 + 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/audio_receiver/input_dsp.rs b/src/audio_receiver/input_dsp.rs index d1625a4..9c5b4f9 100644 --- a/src/audio_receiver/input_dsp.rs +++ b/src/audio_receiver/input_dsp.rs @@ -3,6 +3,8 @@ use std::io::Write; use cpal::{FromSample, Sample, SampleRate}; +use tracing::{debug, trace, warn}; + use rustfft::{num_complex::Complex, FftPlanner}; use super::ForeignTwoStateCarrier; @@ -25,14 +27,14 @@ pub fn take_input_pcm( })); let mut fft_planner = FftPlanner::::new(); - let fft_machine = fft_planner.plan_fft_forward(fft_size); // Zero-pad for a better freq resolution. 8192 fft should be fast enough let mut window_offset = 0; - let mut prev_phase = f64::NAN; + let mut prev_phase = f64::MAX; // window must not extend beyond pcm_buffer - while !carrier.acquired && window_offset + pcm_buffer.len() < fft_size { + while !carrier.acquired && window_offset + fft_size < pcm_buffer.len() { + trace!("carrier acq: trying, window offset {window_offset}"); let pcm_buffer_contiguous = pcm_buffer.make_contiguous(); let mut fft_frame: Vec> = if fft_size < 8192 { let mut frm = @@ -45,26 +47,56 @@ pub fn take_input_pcm( pcm_buffer_contiguous[window_offset..(fft_size+window_offset)] .to_vec() }; - + let fft_machine = fft_planner.plan_fft_forward(fft_frame.len()); fft_machine.process(&mut fft_frame); + let clock_freq_index = (fft_size as f64 * carrier.clock_hz / sample_rate.0 as f64) .round() as usize; if let Some(bin) = fft_frame.get(clock_freq_index) { - if bin.re + bin.im < 0.000000001 { break; } // too small to use. - // arbitrary number; - // tune as needed + // if too small to use. threshold is arbitrary and needs tuning + let threshold = 0.000000001; + if bin.re + bin.im < threshold { + trace!( + "carrier acq: nothing ({}) below cutoff threshold {}. stop", + bin.re + bin.im, + threshold, + ); + break; + } + let phase = f64::atan2(bin.im, bin.re); + let ampl = bin.norm(); // if the phase just passed 0, increasing: - if phase > 0.0 && phase - prev_phase > 0.0 { + if phase > 0.0 && prev_phase < 0.0 { carrier.acquired = true; + debug!("carrier acq: success!"); + debug!( + "carrier acq: drift {} matching {} ampl {}, nearest bin {}", + phase, + window_offset, + ampl, + sample_rate.0 as usize * clock_freq_index / fft_size, + ); } else { window_offset += 1; + if window_offset > fft_size { + trace!("carrier acq: can't find what i smell. stop"); + break; + } + trace!( + "carrier acq: carrier ampl {} but phase {}, spinning...", + ampl, + phase, + ); } prev_phase = phase; - } else { break; } + } else { + warn!("carrier acq: window overran FFT frame! report this!"); + break; + } } while carrier.acquired && pcm_buffer.len() >= fft_size { diff --git a/src/main.rs b/src/main.rs index c5ec3ee..822affb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +// Do not be complaining for these things while I develop #![cfg_attr( debug_assertions, allow(dead_code, unused_imports, unused_variables)