Skip to main content

rusty_opus/silk/
nlsf_encode.rs

1use crate::silk::define::MAX_LPC_ORDER;
2use crate::silk::lin2log::silk_lin2log;
3use crate::silk::macros::{silk_div32_varq, silk_rshift, silk_smlabb, silk_smulbb};
4use crate::silk::nlsf::{silk_nlsf_stabilize, silk_nlsf_vq};
5use crate::silk::nlsf_decode::silk_nlsf_decode;
6use crate::silk::nlsf_del_dec_quant::silk_nlsf_del_dec_quant;
7use crate::silk::nlsf_unpack::silk_nlsf_unpack;
8use crate::silk::sort::silk_insertion_sort_increasing;
9use crate::silk::structs::NLSFCodebook;
10
11pub fn silk_nlsf_encode(
12    nlsf_indices: &mut [i8],
13    p_nlsf_q15: &mut [i16],
14    ps_nlsf_cb: &NLSFCodebook,
15    p_w_q2: &[i16],
16    nlsf_mu_q20: i32,
17    n_survivors: usize,
18    signal_type: i32,
19) -> i32 {
20    let order = ps_nlsf_cb.order as usize;
21
22    let mut err_q24 = [0i32; 32];
23    let mut temp_indices1 = [0i32; 16];
24    let mut rd_q25 = [0i32; 16];
25    let mut temp_indices2 = [0i8; 16 * MAX_LPC_ORDER];
26
27    let mut res_q10 = [0i16; MAX_LPC_ORDER];
28    let mut nlsf_tmp_q15: [i16; MAX_LPC_ORDER] = [0; MAX_LPC_ORDER];
29    let mut w_adj_q5 = [0i16; MAX_LPC_ORDER];
30    let mut pred_q8 = [0u8; MAX_LPC_ORDER];
31    let mut ec_ix = [0i16; MAX_LPC_ORDER];
32
33    silk_nlsf_stabilize(
34        p_nlsf_q15,
35        ps_nlsf_cb.delta_min_q15,
36        ps_nlsf_cb.order as usize,
37    );
38
39    silk_nlsf_vq(
40        &mut err_q24,
41        p_nlsf_q15,
42        ps_nlsf_cb.cb1_nlsf_q8,
43        ps_nlsf_cb.cb1_wght_q9,
44        ps_nlsf_cb.n_vectors as usize,
45        ps_nlsf_cb.order as usize,
46    );
47
48    silk_insertion_sort_increasing(
49        &mut err_q24,
50        &mut temp_indices1,
51        ps_nlsf_cb.n_vectors as usize,
52        n_survivors,
53    );
54
55    for s in 0..n_survivors {
56        let ind1 = temp_indices1[s] as usize;
57
58        let p_cb_element = &ps_nlsf_cb.cb1_nlsf_q8[ind1 * order..];
59        let p_cb_wght_q9 = &ps_nlsf_cb.cb1_wght_q9[ind1 * order..];
60        for i in 0..order {
61            nlsf_tmp_q15[i] = (p_cb_element[i] as i16) << 7;
62            let w_tmp_q9 = p_cb_wght_q9[i] as i32;
63            res_q10[i] =
64                (silk_smulbb(p_nlsf_q15[i] as i32 - nlsf_tmp_q15[i] as i32, w_tmp_q9) >> 14) as i16;
65            w_adj_q5[i] = silk_div32_varq(p_w_q2[i] as i32, w_tmp_q9 * w_tmp_q9, 21) as i16;
66        }
67
68        silk_nlsf_unpack(&mut ec_ix, &mut pred_q8, ps_nlsf_cb, ind1);
69
70        rd_q25[s] = silk_nlsf_del_dec_quant(
71            &mut temp_indices2[s * MAX_LPC_ORDER..(s + 1) * MAX_LPC_ORDER],
72            &res_q10,
73            &w_adj_q5,
74            &pred_q8,
75            &ec_ix,
76            ps_nlsf_cb.ec_rates_q5,
77            ps_nlsf_cb.quant_step_size_q16,
78            ps_nlsf_cb.inv_quant_step_size_q6,
79            nlsf_mu_q20,
80            ps_nlsf_cb.order,
81        );
82
83        let i_cdf_ptr =
84            &ps_nlsf_cb.cb1_icdf[((signal_type >> 1) as usize) * ps_nlsf_cb.n_vectors as usize..];
85        let prob_q8 = if ind1 == 0 {
86            256 - i_cdf_ptr[ind1] as i32
87        } else {
88            i_cdf_ptr[ind1 - 1] as i32 - i_cdf_ptr[ind1] as i32
89        };
90        let bits_q7 = (8 << 7) - silk_lin2log(prob_q8);
91        rd_q25[s] = silk_smlabb(rd_q25[s], bits_q7, silk_rshift(nlsf_mu_q20, 2));
92    }
93
94    let mut best_index = [0i32; 1];
95    silk_insertion_sort_increasing(&mut rd_q25, &mut best_index, n_survivors, 1);
96    let best_idx = best_index[0] as usize;
97
98    nlsf_indices[0] = temp_indices1[best_idx] as i8;
99    nlsf_indices[1..1 + order].copy_from_slice(
100        &temp_indices2[best_idx * MAX_LPC_ORDER..best_idx * MAX_LPC_ORDER + order],
101    );
102
103    silk_nlsf_decode(p_nlsf_q15, nlsf_indices, ps_nlsf_cb);
104
105    rd_q25[0]
106}