almost there, i can smell it (input_dsp.rs)
This commit is contained in:
parent
22af4e0145
commit
e56b9ef454
2 changed files with 42 additions and 9 deletions
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue