use super::super::enc_quant::MAX_GROUPS;
use super::super::filterbank::window_left;
use super::super::ics::WindowShape;
use super::super::mdct::mdct_into_f32;
use super::super::swb::{LONG_WINDOW_LEN, SHORT_WINDOW_LEN};
const SHORT_START: usize = (2 * LONG_WINDOW_LEN - 2 * SHORT_WINDOW_LEN) / 4;
const SHORT_HOP: usize = SHORT_WINDOW_LEN;
pub struct ShortWindows {
pub start: Box<[f32; 2 * LONG_WINDOW_LEN]>,
pub stop: Box<[f32; 2 * LONG_WINDOW_LEN]>,
pub short: Box<[f32; 2 * SHORT_WINDOW_LEN]>,
}
impl ShortWindows {
pub fn new() -> Self {
let long = window_left(2 * LONG_WINDOW_LEN, WindowShape::Kbd);
let short = window_left(2 * SHORT_WINDOW_LEN, WindowShape::Kbd);
let mut start = crate::engine::heap::heap_array::<f32, { 2 * LONG_WINDOW_LEN }>(0.0);
let mut stop = crate::engine::heap::heap_array::<f32, { 2 * LONG_WINDOW_LEN }>(0.0);
for i in 0..LONG_WINDOW_LEN {
start[i] = long[i] * 32768.0;
stop[LONG_WINDOW_LEN + i] = long[LONG_WINDOW_LEN - 1 - i] * 32768.0;
}
let flat = SHORT_START; for i in 0..flat {
start[LONG_WINDOW_LEN + i] = 32768.0;
stop[SHORT_START + SHORT_WINDOW_LEN + i] = 32768.0;
}
for m in 0..SHORT_WINDOW_LEN {
start[LONG_WINDOW_LEN + flat + m] = short[SHORT_WINDOW_LEN - 1 - m] * 32768.0;
stop[SHORT_START + m] = short[m] * 32768.0;
}
let mut sw = Box::new([0.0f32; 2 * SHORT_WINDOW_LEN]);
for i in 0..SHORT_WINDOW_LEN {
sw[i] = short[i] * 32768.0;
sw[2 * SHORT_WINDOW_LEN - 1 - i] = short[i] * 32768.0;
}
Self {
start,
stop,
short: sw,
}
}
}
pub fn spectra(
block: &[f32; 2 * LONG_WINDOW_LEN],
windows: &ShortWindows,
spec: &mut [f32; LONG_WINDOW_LEN],
) {
let mut seg = [0.0f32; 2 * SHORT_WINDOW_LEN];
for w in 0..MAX_GROUPS {
let base = SHORT_START + w * SHORT_HOP;
for (s, (&x, &win)) in seg.iter_mut().zip(
block[base..base + 2 * SHORT_WINDOW_LEN]
.iter()
.zip(windows.short.iter()),
) {
*s = x * win;
}
mdct_into_f32(
&seg,
&mut spec[w * SHORT_WINDOW_LEN..(w + 1) * SHORT_WINDOW_LEN],
);
}
}