use crate::g729::basic_operations::*;
use crate::g729::codebooks::B30;
use crate::g729::ld8k::*;
pub fn init_decode_adaptative_code_vector(previous_int_pitch_delay: &mut i16) {
*previous_int_pitch_delay = 60;
}
fn compute_adaptative_codebook_vector(
excitation_vector: &mut [Word16],
mut frac_pitch_delay: i16,
int_pitch_delay: i16,
current_subframe_offset: usize,
) {
let excitation_vector_minus_k_idx: usize;
if frac_pitch_delay == 1 {
excitation_vector_minus_k_idx = current_subframe_offset - (int_pitch_delay + 1) as usize;
frac_pitch_delay = 2;
} else {
frac_pitch_delay = -frac_pitch_delay;
excitation_vector_minus_k_idx = current_subframe_offset - int_pitch_delay as usize;
}
for n in 0..L_SUBFRAME {
let excitation_vector_n_minus_k_idx = excitation_vector_minus_k_idx + n;
let excitation_vector_n_minus_k_plus_one_idx = excitation_vector_minus_k_idx + n + 1;
let b301_idx = frac_pitch_delay as usize;
let b302_idx = (3 - frac_pitch_delay) as usize;
let mut acc: Word32 = 0;
let mut j = 0;
for i in 0..10 {
acc = mac16_16(
acc,
excitation_vector[excitation_vector_n_minus_k_idx - i],
B30[b301_idx + j],
);
acc = mac16_16(
acc,
excitation_vector[excitation_vector_n_minus_k_plus_one_idx + i],
B30[b302_idx + j],
);
j += 3;
}
excitation_vector[current_subframe_offset + n] =
saturate(pshr(acc, 15), MAX_INT16 as Word32) as Word16;
}
}
pub fn decode_adaptative_code_vector(
previous_int_pitch_delay: &mut i16,
sub_frame_index: usize,
adaptative_codebook_index: u16,
parity_flag: u8,
frame_erasure_flag: u8,
int_pitch_delay: &mut i16,
excitation_vector: &mut [Word16],
) {
let frac_pitch_delay: i16;
if sub_frame_index == 0 {
if (parity_flag | frame_erasure_flag) != 0 {
*int_pitch_delay = *previous_int_pitch_delay;
frac_pitch_delay = 0;
*previous_int_pitch_delay += 1;
if *previous_int_pitch_delay > MAXIMUM_INT_PITCH_DELAY as i16 {
*previous_int_pitch_delay = MAXIMUM_INT_PITCH_DELAY as i16;
}
} else {
if adaptative_codebook_index < 197 {
*int_pitch_delay = add16(
mult16_16_q15(add16(adaptative_codebook_index as i16, 2), 10923 as Word16)
as Word16,
19,
);
frac_pitch_delay = add16(
sub16(
adaptative_codebook_index as i16,
mult16_16(*int_pitch_delay, 3) as Word16,
),
58,
);
} else {
*int_pitch_delay = sub16(adaptative_codebook_index as i16, 112);
frac_pitch_delay = 0;
}
*previous_int_pitch_delay = *int_pitch_delay;
}
} else {
if frame_erasure_flag != 0 {
*int_pitch_delay = *previous_int_pitch_delay;
frac_pitch_delay = 0;
*previous_int_pitch_delay += 1;
if *previous_int_pitch_delay > MAXIMUM_INT_PITCH_DELAY as i16 {
*previous_int_pitch_delay = MAXIMUM_INT_PITCH_DELAY as i16;
}
} else {
let mut t_min = sub16(*int_pitch_delay, 5);
if t_min < 20 {
t_min = 20;
}
if t_min > 134 {
t_min = 134;
}
*int_pitch_delay = sub16(
mult16_16_q15(add16(adaptative_codebook_index as i16, 2), 10923 as Word16)
as Word16,
1,
);
frac_pitch_delay = sub16(
sub16(
adaptative_codebook_index as i16,
mult16_16(*int_pitch_delay, 3) as Word16,
),
2,
);
*int_pitch_delay = add16(*int_pitch_delay, t_min);
*previous_int_pitch_delay = *int_pitch_delay;
}
}
compute_adaptative_codebook_vector(
excitation_vector,
frac_pitch_delay,
*int_pitch_delay,
L_PAST_EXCITATION + sub_frame_index,
);
}