use crate::core::{DecodeContext, FecCodec, FecOpts, MessageCodec};
use crate::fec::ConvFano232;
use crate::msg::{Jt72Codec, Jt72Message};
use super::Jt9Decode;
use super::softsym::{AudioFft, FSAMPLE_DOWN, afc_simple, llrs_from_c5, peakdt9, twkfreq_const};
const SYNC_GATE: f32 = 1.5;
pub fn decode_at_baseband_with_fft(big_fft: &AudioFft, freq_hz: f32) -> Option<Jt9Decode> {
if freq_hz <= 0.0 {
return None;
}
let c2 = big_fft.downsam9(freq_hz);
let (lagpk, sync_score, mut c3) = peakdt9(&c2);
if !sync_score.is_finite() || sync_score < SYNC_GATE {
return None;
}
let df = afc_simple(&c3);
twkfreq_const(&mut c3, df);
let llrs = llrs_from_c5(&c3);
let res = ConvFano232.decode_soft(&llrs, &FecOpts::default())?;
let mut payload = [0u8; 72];
payload.copy_from_slice(&res.info);
let msg = Jt72Codec::default().unpack(&payload, &DecodeContext::default())?;
match &msg {
Jt72Message::Standard { .. } => {}
_ => return None,
}
let start_sample = lag_to_audio_sample(lagpk);
let freq_corrected = freq_hz - df;
Some(Jt9Decode {
message: msg,
freq_hz: freq_corrected,
start_sample,
})
}
#[cfg(test)]
#[allow(dead_code)]
pub fn decode_at_baseband(
audio: &[f32],
_sample_rate: u32,
_start_sample: usize,
freq_hz: f32,
) -> Option<Jt9Decode> {
let big = AudioFft::build(audio);
decode_at_baseband_with_fft(&big, freq_hz)
}
fn lag_to_audio_sample(lagpk: i64) -> usize {
let i0 = 5 * 16i64;
let nspsd = 16i64;
let ndown = 432i64;
let c2_offset = lagpk - i0 - nspsd + 1;
let sample = c2_offset.max(0) * ndown;
let _ = FSAMPLE_DOWN; sample as usize
}