use crate::silk::decoder_structs::{SilkDecoderControl, SilkDecoderState};
use crate::silk::define::*;
use crate::silk::gain_quant::silk_gains_dequant;
use crate::silk::nlsf::silk_nlsf2a;
use crate::silk::nlsf_decode::silk_nlsf_decode;
use crate::silk::sigproc_fix::silk_bwexpander;
use crate::silk::tables::SILK_LTP_SCALES_TABLE_Q14;
use crate::silk::tables::SILK_LTP_VQ_PTRS_Q7;
const BWE_AFTER_LOSS_Q16: i32 = 64738;
fn silk_decode_pitch(
lag_index: i16,
contour_index: i8,
pitch_l: &mut [i32],
fs_khz: i32,
nb_subfr: i32,
) {
let min_lag = PITCH_EST_MIN_LAG_MS * fs_khz;
let max_lag = PITCH_EST_MAX_LAG_MS * fs_khz;
let lag = min_lag + lag_index as i32;
let contour_index = contour_index as usize;
for k in 0..nb_subfr as usize {
let delta = if fs_khz == 8 {
if nb_subfr == PE_MAX_NB_SUBFR as i32 {
crate::silk::tables::SILK_CB_LAGS_STAGE2[k % 4]
[contour_index % PE_NB_CBKS_STAGE2_EXT] as i32
} else {
crate::silk::tables::SILK_CB_LAGS_STAGE2_10_MS[k % 2]
[contour_index % PE_NB_CBKS_STAGE2_10MS] as i32
}
} else if nb_subfr == PE_MAX_NB_SUBFR as i32 {
crate::silk::tables::SILK_CB_LAGS_STAGE3[k % 4][contour_index % PE_NB_CBKS_STAGE3_MAX]
as i32
} else {
crate::silk::tables::SILK_CB_LAGS_STAGE3_10_MS[k % 2]
[contour_index % PE_NB_CBKS_STAGE3_10MS] as i32
};
pitch_l[k] = (lag + delta).max(min_lag).min(max_lag);
}
}
pub fn silk_decode_parameters(
ps_dec: &mut SilkDecoderState,
ps_dec_ctrl: &mut SilkDecoderControl,
cond_coding: i32,
) {
let mut p_nlsf_q15: [i16; MAX_LPC_ORDER] = [0; MAX_LPC_ORDER];
let mut p_nlsf0_q15: [i16; MAX_LPC_ORDER] = [0; MAX_LPC_ORDER];
silk_gains_dequant(
&mut ps_dec_ctrl.gains_q16,
&ps_dec.indices.gains_indices,
&mut ps_dec.last_gain_index,
if cond_coding == CODE_CONDITIONALLY {
1
} else {
0
},
ps_dec.nb_subfr as usize,
);
silk_nlsf_decode(
&mut p_nlsf_q15,
&ps_dec.indices.nlsf_indices,
ps_dec.ps_nlsf_cb.unwrap(),
);
silk_nlsf2a(
&mut ps_dec_ctrl.pred_coef_q12[1],
&p_nlsf_q15,
ps_dec.lpc_order as usize,
);
if ps_dec.first_frame_after_reset == 1 {
ps_dec.indices.nlsf_interp_coef_q2 = 4;
}
if ps_dec.indices.nlsf_interp_coef_q2 < 4 {
for i in 0..ps_dec.lpc_order as usize {
p_nlsf0_q15[i] = ps_dec.prev_nlsf_q15[i]
+ (((ps_dec.indices.nlsf_interp_coef_q2 as i32)
* (p_nlsf_q15[i] as i32 - ps_dec.prev_nlsf_q15[i] as i32))
>> 2) as i16;
}
silk_nlsf2a(
&mut ps_dec_ctrl.pred_coef_q12[0],
&p_nlsf0_q15,
ps_dec.lpc_order as usize,
);
} else {
ps_dec_ctrl.pred_coef_q12[0] = ps_dec_ctrl.pred_coef_q12[1];
}
ps_dec.prev_nlsf_q15.copy_from_slice(&p_nlsf_q15);
if ps_dec.loss_cnt > 0 {
silk_bwexpander(
&mut ps_dec_ctrl.pred_coef_q12[0],
ps_dec.lpc_order as usize,
BWE_AFTER_LOSS_Q16,
);
silk_bwexpander(
&mut ps_dec_ctrl.pred_coef_q12[1],
ps_dec.lpc_order as usize,
BWE_AFTER_LOSS_Q16,
);
}
if ps_dec.indices.signal_type == TYPE_VOICED as i8 {
silk_decode_pitch(
ps_dec.indices.lag_index,
ps_dec.indices.contour_index,
&mut ps_dec_ctrl.pitch_l,
ps_dec.fs_khz,
ps_dec.nb_subfr,
);
let cbk_ptr_q7 = SILK_LTP_VQ_PTRS_Q7[ps_dec.indices.per_index as usize];
for k in 0..ps_dec.nb_subfr as usize {
let ix = ps_dec.indices.ltp_index[k] as usize;
for i in 0..LTP_ORDER {
ps_dec_ctrl.ltp_coef_q14[k * LTP_ORDER + i] =
((cbk_ptr_q7[ix][i] as i32) << 7) as i16;
}
}
let ix = ps_dec.indices.ltp_scale_index as usize;
ps_dec_ctrl.ltp_scale_q14 = SILK_LTP_SCALES_TABLE_Q14[ix] as i32;
} else {
for i in 0..ps_dec.nb_subfr as usize {
ps_dec_ctrl.pitch_l[i] = 0;
}
for i in 0..(LTP_ORDER * ps_dec.nb_subfr as usize) {
ps_dec_ctrl.ltp_coef_q14[i] = 0;
}
ps_dec.indices.per_index = 0;
ps_dec_ctrl.ltp_scale_q14 = 0;
}
}