almost there, i can smell it (input_dsp.rs)

This commit is contained in:
TerraMaster85 2025-01-15 12:42:14 -05:00
parent 22af4e0145
commit e56b9ef454
2 changed files with 42 additions and 9 deletions

View file

@ -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<T>(
}));
let mut fft_planner = FftPlanner::<f64>::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<Complex<f64>> = if fft_size < 8192 {
let mut frm =
@ -45,26 +47,56 @@ pub fn take_input_pcm<T>(
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 {

View file

@ -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)