use crate::core::{Block, WorkReport};
use num_complex::Complex32 as C32;
#[derive(Debug, Clone)]
pub struct SymbolWindow {
symbol_len: usize,
roll_off: usize,
ramp: Vec<f32>,
}
impl SymbolWindow {
pub fn new(symbol_len: usize, roll_off: usize) -> Self {
let roll_off = roll_off.min(symbol_len / 2);
let ramp = (0..roll_off)
.map(|i| {
let x = core::f32::consts::PI * (i as f32 + 0.5) / roll_off as f32;
0.5 * (1.0 - x.cos())
})
.collect();
Self {
symbol_len,
roll_off,
ramp,
}
}
pub fn symbol_len(&self) -> usize {
self.symbol_len
}
pub fn roll_off(&self) -> usize {
self.roll_off
}
}
impl Block for SymbolWindow {
type In = C32;
type Out = C32;
fn process(&mut self, input: &[C32], output: &mut [C32]) -> WorkReport {
let n = self.symbol_len;
if input.len() < n || output.len() < n {
return WorkReport::default();
}
output[..n].copy_from_slice(&input[..n]);
let l = self.roll_off;
for i in 0..l {
let w = self.ramp[i];
output[i] = scale(output[i], w);
output[n - 1 - i] = scale(output[n - 1 - i], w);
}
WorkReport {
in_read: n,
out_written: n,
}
}
}
#[inline]
fn scale(c: C32, w: f32) -> C32 {
C32::new(c.re * w, c.im * w)
}