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 cpal::{FromSample, Sample, SampleRate};
|
||||||
|
|
||||||
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
use rustfft::{num_complex::Complex, FftPlanner};
|
use rustfft::{num_complex::Complex, FftPlanner};
|
||||||
|
|
||||||
use super::ForeignTwoStateCarrier;
|
use super::ForeignTwoStateCarrier;
|
||||||
|
@ -25,14 +27,14 @@ pub fn take_input_pcm<T>(
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut fft_planner = FftPlanner::<f64>::new();
|
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
|
// Zero-pad for a better freq resolution. 8192 fft should be fast enough
|
||||||
let mut window_offset = 0;
|
let mut window_offset = 0;
|
||||||
let mut prev_phase = f64::NAN;
|
let mut prev_phase = f64::MAX;
|
||||||
|
|
||||||
// window must not extend beyond pcm_buffer
|
// 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 pcm_buffer_contiguous = pcm_buffer.make_contiguous();
|
||||||
let mut fft_frame: Vec<Complex<f64>> = if fft_size < 8192 {
|
let mut fft_frame: Vec<Complex<f64>> = if fft_size < 8192 {
|
||||||
let mut frm =
|
let mut frm =
|
||||||
|
@ -45,26 +47,56 @@ pub fn take_input_pcm<T>(
|
||||||
pcm_buffer_contiguous[window_offset..(fft_size+window_offset)]
|
pcm_buffer_contiguous[window_offset..(fft_size+window_offset)]
|
||||||
.to_vec()
|
.to_vec()
|
||||||
};
|
};
|
||||||
|
let fft_machine = fft_planner.plan_fft_forward(fft_frame.len());
|
||||||
fft_machine.process(&mut fft_frame);
|
fft_machine.process(&mut fft_frame);
|
||||||
|
|
||||||
let clock_freq_index =
|
let clock_freq_index =
|
||||||
(fft_size as f64 * carrier.clock_hz / sample_rate.0 as f64)
|
(fft_size as f64 * carrier.clock_hz / sample_rate.0 as f64)
|
||||||
.round() as usize;
|
.round() as usize;
|
||||||
|
|
||||||
if let Some(bin) = fft_frame.get(clock_freq_index) {
|
if let Some(bin) = fft_frame.get(clock_freq_index) {
|
||||||
if bin.re + bin.im < 0.000000001 { break; } // too small to use.
|
// if too small to use. threshold is arbitrary and needs tuning
|
||||||
// arbitrary number;
|
let threshold = 0.000000001;
|
||||||
// tune as needed
|
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 phase = f64::atan2(bin.im, bin.re);
|
||||||
|
let ampl = bin.norm();
|
||||||
|
|
||||||
// if the phase just passed 0, increasing:
|
// 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;
|
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 {
|
} else {
|
||||||
window_offset += 1;
|
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;
|
prev_phase = phase;
|
||||||
} else { break; }
|
} else {
|
||||||
|
warn!("carrier acq: window overran FFT frame! report this!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while carrier.acquired && pcm_buffer.len() >= fft_size {
|
while carrier.acquired && pcm_buffer.len() >= fft_size {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Do not be complaining for these things while I develop
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
debug_assertions,
|
debug_assertions,
|
||||||
allow(dead_code, unused_imports, unused_variables)
|
allow(dead_code, unused_imports, unused_variables)
|
||||||
|
|
Loading…
Add table
Reference in a new issue