use super::Fst4s60;
use crate::core::dsp::gfsk::{GfskCfg, synth_f32, synth_i16};
use crate::core::{FecCodec, FrameLayout, ModulationParams};
use crate::fec::Ldpc240_101;
pub const FST4_15_GFSK: GfskCfg = GfskCfg {
sample_rate: 12_000.0,
samples_per_symbol: 720,
bt: 2.0,
hmod: 1.0,
ramp_samples: 720 / 8,
};
pub const FST4_30_GFSK: GfskCfg = GfskCfg {
sample_rate: 12_000.0,
samples_per_symbol: 1_680,
bt: 2.0,
hmod: 1.0,
ramp_samples: 1_680 / 8,
};
pub const FST4_60A_GFSK: GfskCfg = GfskCfg {
sample_rate: 12_000.0,
samples_per_symbol: 3_888,
bt: 2.0,
hmod: 1.0,
ramp_samples: 3_888 / 8,
};
pub const FST4_120_GFSK: GfskCfg = GfskCfg {
sample_rate: 12_000.0,
samples_per_symbol: 8_200,
bt: 2.0,
hmod: 1.0,
ramp_samples: 8_200 / 8,
};
pub const FST4_300_GFSK: GfskCfg = GfskCfg {
sample_rate: 12_000.0,
samples_per_symbol: 21_504,
bt: 2.0,
hmod: 1.0,
ramp_samples: 21_504 / 8,
};
fn append_crc24(message77: &[u8; 77]) -> [u8; 101] {
let mut info = [0u8; 101];
info[..77].copy_from_slice(message77);
let mut with_zero = [0u8; 101];
with_zero[..77].copy_from_slice(message77);
let crc = crate::fec::ldpc240_101::crc24(&with_zero);
for i in 0..24 {
info[77 + i] = ((crc >> (23 - i)) & 1) as u8;
}
info
}
pub fn message_to_tones(message77: &[u8; 77]) -> Vec<u8> {
let mut scrambled = *message77;
for (b, &r) in scrambled.iter_mut().zip(super::FST4_RVEC.iter()) {
*b = (*b ^ r) & 1;
}
let info = append_crc24(&scrambled);
let codec = Ldpc240_101;
let mut cw = [0u8; 240];
codec.encode(&info, &mut cw);
crate::core::tx::codeword_to_itone::<Fst4s60>(&cw)
}
pub fn tones_to_f32_with_gfsk(itone: &[u8], f0: f32, amplitude: f32, cfg: &GfskCfg) -> Vec<f32> {
debug_assert_eq!(itone.len(), <Fst4s60 as FrameLayout>::N_SYMBOLS as usize);
synth_f32(itone, f0, amplitude, cfg)
}
pub fn tones_to_i16_with_gfsk(
itone: &[u8],
f0: f32,
amplitude_i16: i16,
cfg: &GfskCfg,
) -> Vec<i16> {
debug_assert_eq!(itone.len(), <Fst4s60 as FrameLayout>::N_SYMBOLS as usize);
synth_i16(itone, f0, amplitude_i16, cfg)
}
pub fn tones_to_f32(itone: &[u8], f0: f32, amplitude: f32) -> Vec<f32> {
tones_to_f32_with_gfsk(itone, f0, amplitude, &FST4_60A_GFSK)
}
pub fn tones_to_i16(itone: &[u8], f0: f32, amplitude_i16: i16) -> Vec<i16> {
tones_to_i16_with_gfsk(itone, f0, amplitude_i16, &FST4_60A_GFSK)
}
fn _silence() {
let _ = <Fst4s60 as ModulationParams>::NTONES;
}