use crate::bitmath::silog2;
pub fn compute_residual(signal: &[i64], order: usize, qlp_coeff: &[i32], shift: i32) -> Vec<i32> {
let data_len = signal.len() - order;
let mut residual = vec![0i32; data_len];
for i in 0..data_len {
let mut sum = 0i64;
for j in 0..order {
sum += qlp_coeff[j] as i64 * signal[order + i - 1 - j];
}
residual[i] = (signal[order + i] - (sum >> shift)) as i32;
}
residual
}
pub fn compute_residual_limit(
signal: &[i64],
order: usize,
qlp_coeff: &[i32],
shift: i32,
) -> Option<Vec<i32>> {
let data_len = signal.len() - order;
let mut residual = vec![0i32; data_len];
for i in 0..data_len {
let mut sum = 0i64;
for j in 0..order {
sum += qlp_coeff[j] as i64 * signal[order + i - 1 - j];
}
let r = signal[order + i] - (sum >> shift);
if r <= i32::MIN as i64 || r > i32::MAX as i64 {
return None;
}
residual[i] = r as i32;
}
Some(residual)
}
pub fn max_prediction_before_shift_bps(subframe_bps: u32, qlp_coeff: &[i32], order: usize) -> u32 {
let mut abs_sum = 0i32;
for &c in &qlp_coeff[..order] {
abs_sum += c.abs();
}
if abs_sum == 0 {
abs_sum = 1;
}
subframe_bps + silog2(abs_sum as i64)
}
pub fn max_residual_bps(
subframe_bps: u32,
qlp_coeff: &[i32],
order: usize,
lp_quantization: i32,
) -> u32 {
let predictor_sum_bps =
max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) as i32 - lp_quantization;
if subframe_bps as i32 > predictor_sum_bps {
subframe_bps + 1
} else {
(predictor_sum_bps + 1) as u32
}
}