rusty_opus/silk/
nlsf_encode.rs1use 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}