use crate::g729::basic_operations::*;
use crate::g729::codebooks::*;
use crate::g729::gain_quantization::{compute_gain_prediction_error, ma_code_gain_prediction};
pub fn init_decode_gains(previous_gain_prediction_error: &mut [Word16; 4]) {
previous_gain_prediction_error[0] = -14336;
previous_gain_prediction_error[1] = -14336;
previous_gain_prediction_error[2] = -14336;
previous_gain_prediction_error[3] = -14336;
}
pub fn decode_gains(
previous_gain_prediction_error: &mut [Word16; 4],
mut ga: u16,
mut gb: u16,
fixed_codebook_vector: &[Word16],
frame_erasure_flag: u8,
adaptative_codebook_gain: &mut Word16,
fixed_codebook_gain: &mut Word16,
) {
let predicted_fixed_codebook_gain: Word32;
let fixed_codebook_gain_correction_factor: Word16;
if frame_erasure_flag != 0 {
let mut current_gain_prediction_error: Word32 = 0;
if *adaptative_codebook_gain < 16384 {
*adaptative_codebook_gain =
mult16_16_q15(*adaptative_codebook_gain, 29491 as Word16) as Word16;
} else {
*adaptative_codebook_gain = 14746;
}
*fixed_codebook_gain = mult16_16_q15(*fixed_codebook_gain, 32113 as Word16) as Word16;
for i in 0..4 {
current_gain_prediction_error = add32(
current_gain_prediction_error,
previous_gain_prediction_error[i] as Word32,
);
}
current_gain_prediction_error = pshr(current_gain_prediction_error, 2);
if current_gain_prediction_error < -10240 {
current_gain_prediction_error = -14336;
} else {
current_gain_prediction_error = sub32(current_gain_prediction_error, 4096);
}
previous_gain_prediction_error[3] = previous_gain_prediction_error[2];
previous_gain_prediction_error[2] = previous_gain_prediction_error[1];
previous_gain_prediction_error[1] = previous_gain_prediction_error[0];
previous_gain_prediction_error[0] = current_gain_prediction_error as Word16;
return;
}
ga = REVERSE_INDEX_MAPPING_GA[ga as usize];
gb = REVERSE_INDEX_MAPPING_GB[gb as usize];
*adaptative_codebook_gain = add16(GA_CODEBOOK[ga as usize][0], GB_CODEBOOK[gb as usize][0]);
predicted_fixed_codebook_gain =
ma_code_gain_prediction(previous_gain_prediction_error, fixed_codebook_vector);
fixed_codebook_gain_correction_factor =
add16(GA_CODEBOOK[ga as usize][1], GB_CODEBOOK[gb as usize][1]);
*fixed_codebook_gain = pshr(
mult16_32_q12(
fixed_codebook_gain_correction_factor,
predicted_fixed_codebook_gain,
),
15,
) as Word16;
compute_gain_prediction_error(
fixed_codebook_gain_correction_factor,
previous_gain_prediction_error,
);
}