use super::fft::FftBlock;
use crate::core::Block;
use num_complex::Complex32 as C32;
#[derive(Clone)]
pub struct SymbolFft {
n_fft: usize,
cp_len: usize,
backoff: usize,
fft: FftBlock,
time: Vec<C32>,
freq: Vec<C32>,
}
impl SymbolFft {
pub fn new(n_fft: usize, cp_len: usize) -> Self {
Self {
n_fft,
cp_len,
backoff: 0,
fft: FftBlock::new(n_fft),
time: vec![C32::default(); n_fft],
freq: vec![C32::default(); n_fft],
}
}
pub fn with_window_backoff(mut self, backoff: usize) -> Self {
self.backoff = backoff.min(self.cp_len);
self
}
pub fn max_pilot_safe_backoff(n_fft: usize, pilot_spacing: usize) -> usize {
n_fft / (2 * pilot_spacing.max(1))
}
pub fn n_fft(&self) -> usize {
self.n_fft
}
pub fn window_backoff(&self) -> usize {
self.backoff
}
pub fn symbol_len(&self) -> usize {
self.n_fft + self.cp_len
}
pub fn demod_symbol(&mut self, input: &[C32]) -> Option<&[C32]> {
let n = self.n_fft;
if input.len() < self.symbol_len() {
return None;
}
let start = self.cp_len - self.backoff;
self.time.copy_from_slice(&input[start..start + n]);
if self.fft.process(&self.time, &mut self.freq).out_written != n {
return None;
}
Some(&self.freq)
}
}