xref: /aosp_15_r20/external/libxaac/encoder/iusace_acelp_enc.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include <string.h>
22 #include <math.h>
23 #include "ixheaac_type_def.h"
24 #include "iusace_bitbuffer.h"
25 
26 /* DRC */
27 #include "impd_drc_common_enc.h"
28 #include "impd_drc_uni_drc.h"
29 #include "impd_drc_tables.h"
30 #include "impd_drc_api.h"
31 #include "impd_drc_uni_drc_eq.h"
32 #include "impd_drc_uni_drc_filter_bank.h"
33 #include "impd_drc_gain_enc.h"
34 #include "impd_drc_struct_def.h"
35 
36 #include "iusace_cnst.h"
37 #include "iusace_tns_usac.h"
38 #include "iusace_psy_mod.h"
39 #include "ixheaace_adjust_threshold_data.h"
40 #include "iusace_fd_qc_util.h"
41 #include "iusace_config.h"
42 #include "iusace_arith_enc.h"
43 #include "iusace_block_switch_const.h"
44 #include "iusace_block_switch_struct_def.h"
45 #include "iusace_lpd_rom.h"
46 #include "iusace_lpd.h"
47 
iusace_acelp_encode(FLOAT32 * lp_filt_coeff,FLOAT32 * quant_lp_filt_coeff,FLOAT32 * speech_in,FLOAT32 * wsig_in,FLOAT32 * synth_out,FLOAT32 * wsynth_out,WORD16 acelp_core_mode,ia_usac_lpd_state_struct * lpd_state,WORD32 len_subfrm,FLOAT32 norm_corr,FLOAT32 norm_corr2,WORD32 ol_pitch_lag1,WORD32 ol_pitch_lag2,WORD32 pit_adj,WORD32 * acelp_params,iusace_scratch_mem * pstr_scratch)48 VOID iusace_acelp_encode(FLOAT32 *lp_filt_coeff, FLOAT32 *quant_lp_filt_coeff, FLOAT32 *speech_in,
49                          FLOAT32 *wsig_in, FLOAT32 *synth_out, FLOAT32 *wsynth_out,
50                          WORD16 acelp_core_mode, ia_usac_lpd_state_struct *lpd_state,
51                          WORD32 len_subfrm, FLOAT32 norm_corr, FLOAT32 norm_corr2,
52                          WORD32 ol_pitch_lag1, WORD32 ol_pitch_lag2, WORD32 pit_adj,
53                          WORD32 *acelp_params, iusace_scratch_mem *pstr_scratch) {
54   WORD32 i, i_subfr, num_bits, t;
55   WORD32 t0, t0_min, t0_max, index, subfrm_flag;
56   WORD32 t0_frac;
57   FLOAT32 temp, energy, max_ener, mean_ener_code;
58   FLOAT32 pitch_gain, code_gain, gain1, gain2;
59   FLOAT32 tgt_cb_corr[5], tgt_cb_corr2[2];
60   FLOAT32 *p_lp_filt_coeff, *p_quant_lp_filt_coeff, weighted_lpc[ORDER + 1];
61   FLOAT32 imp_res[LEN_SUBFR];
62   FLOAT32 code[LEN_SUBFR];
63   WORD16 cb_exc[LEN_SUBFR];
64   FLOAT32 error[ORDER + LEN_SUBFR + 8];
65   FLOAT32 cn[LEN_SUBFR];
66   FLOAT32 xn[LEN_SUBFR];
67   FLOAT32 xn2[LEN_SUBFR];
68   FLOAT32 dn[LEN_SUBFR];
69   FLOAT32 y0[LEN_SUBFR];
70   FLOAT32 y1[LEN_SUBFR];
71   FLOAT32 y2[LEN_SUBFR];
72   WORD32 min_pitch_lag_res1_4;
73   WORD32 min_pitch_lag_res1_2;
74   WORD32 min_pitch_lag_res1;
75   WORD32 max_pitch_lag;
76   FLOAT32 *exc_buf = pstr_scratch->p_acelp_exc_buf;
77   FLOAT32 *exc;
78   FLOAT32 mem_txn, mem_txnq;
79   WORD32 fac_length = len_subfrm / 2;
80   if (lpd_state->mode > 0) {
81     for (i = 0; i < fac_length; i++) {
82       acelp_params[i] = lpd_state->avq_params[i];
83     }
84     acelp_params += fac_length;
85   }
86 
87   if (pit_adj == SR_MAX)
88     exc = exc_buf + (2 * len_subfrm) + 41;
89   else
90     exc = exc_buf + (2 * len_subfrm);
91 
92   memset(exc_buf, 0, (2 * len_subfrm) * sizeof(exc_buf[0]));
93   memcpy(exc_buf, lpd_state->acelp_exc, 2 * len_subfrm * sizeof(FLOAT32));
94   memcpy(synth_out - 128, &(lpd_state->synth[ORDER]), 128 * sizeof(FLOAT32));
95   memcpy(wsynth_out - 128, &(lpd_state->wsynth[1]), 128 * sizeof(FLOAT32));
96 
97   num_bits = ((iusace_acelp_core_numbits_1024[acelp_core_mode] - NBITS_MODE) / 4) - NBITS_LPC;
98 
99   if (pit_adj == 0) {
100     min_pitch_lag_res1_4 = TMIN;
101     min_pitch_lag_res1_2 = TFR2;
102     min_pitch_lag_res1 = TFR1;
103     max_pitch_lag = TMAX;
104   } else {
105     i = (((pit_adj * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN;
106     min_pitch_lag_res1_4 = TMIN + i;
107     min_pitch_lag_res1_2 = TFR2 - i;
108     min_pitch_lag_res1 = TFR1;
109     max_pitch_lag = TMAX + (6 * i);
110   }
111 
112   ol_pitch_lag1 *= OPL_DECIM;
113   ol_pitch_lag2 *= OPL_DECIM;
114 
115   t0_min = ol_pitch_lag1 - 8;
116 
117   t = MIN(ol_pitch_lag1, ol_pitch_lag2) - 4;
118   if (t0_min < t) t0_min = t;
119 
120   if (t0_min < min_pitch_lag_res1_4) {
121     t0_min = min_pitch_lag_res1_4;
122   }
123   t0_max = t0_min + 15;
124   t = MAX(ol_pitch_lag1, ol_pitch_lag2) + 4;
125   if (t0_max > t) t0_max = t;
126 
127   if (t0_max > max_pitch_lag) {
128     t0_max = max_pitch_lag;
129     t0_min = t0_max - 15;
130   }
131 
132   max_ener = 0.0;
133   mean_ener_code = 0.0;
134   p_quant_lp_filt_coeff = quant_lp_filt_coeff;
135   for (i_subfr = 0; i_subfr < len_subfrm; i_subfr += LEN_SUBFR) {
136     iusace_compute_lp_residual(p_quant_lp_filt_coeff, &speech_in[i_subfr], &exc[i_subfr],
137                                LEN_SUBFR);
138     energy = 0.01f;
139     for (i = 0; i < LEN_SUBFR; i++) {
140       energy += exc[i + i_subfr] * exc[i + i_subfr];
141     }
142     energy = 10.0f * (FLOAT32)log10(energy / ((FLOAT32)LEN_SUBFR));
143     if (energy < 0.0) {
144       energy = 0.0;
145     }
146     if (energy > max_ener) {
147       max_ener = energy;
148     }
149     mean_ener_code += 0.25f * energy;
150     p_quant_lp_filt_coeff += (ORDER + 1);
151   }
152 
153   mean_ener_code -= 5.0f * norm_corr;
154   mean_ener_code -= 5.0f * norm_corr2;
155 
156   temp = (mean_ener_code - 18.0f) / 12.0f;
157   index = (WORD32)floor(temp + 0.5);
158   if (index < 0) {
159     index = 0;
160   }
161   if (index > 3) {
162     index = 3;
163   }
164   mean_ener_code = (((FLOAT32)index) * 12.0f) + 18.0f;
165 
166   while ((mean_ener_code < (max_ener - 27.0)) && (index < 3)) {
167     index++;
168     mean_ener_code += 12.0;
169   }
170   *acelp_params = index;
171   acelp_params++;
172 
173   p_lp_filt_coeff = lp_filt_coeff;
174   p_quant_lp_filt_coeff = quant_lp_filt_coeff;
175   for (i_subfr = 0; i_subfr < len_subfrm; i_subfr += LEN_SUBFR) {
176     subfrm_flag = i_subfr;
177     if ((len_subfrm == 256) && (i_subfr == (2 * LEN_SUBFR))) {
178       subfrm_flag = 0;
179 
180       t0_min = ol_pitch_lag2 - 8;
181 
182       t = MIN(ol_pitch_lag1, ol_pitch_lag2) - 4;
183       if (t0_min < t) t0_min = t;
184 
185       if (t0_min < min_pitch_lag_res1_4) {
186         t0_min = min_pitch_lag_res1_4;
187       }
188       t0_max = t0_min + 15;
189 
190       t = MAX(ol_pitch_lag1, ol_pitch_lag2) + 4;
191       if (t0_max > t) t0_max = t;
192 
193       if (t0_max > max_pitch_lag) {
194         t0_max = max_pitch_lag;
195         t0_min = t0_max - 15;
196       }
197     }
198 
199     memcpy(xn, &wsig_in[i_subfr], LEN_SUBFR * sizeof(FLOAT32));
200 
201     memcpy(error, &synth_out[i_subfr - ORDER], ORDER * sizeof(FLOAT32));
202     memset(error + ORDER, 0, LEN_SUBFR * sizeof(FLOAT32));
203     iusace_synthesis_tool_float(p_quant_lp_filt_coeff, error + ORDER, error + ORDER, LEN_SUBFR,
204                                 error, pstr_scratch->p_buf_synthesis_tool);
205     iusace_get_weighted_lpc(p_lp_filt_coeff, weighted_lpc);
206     iusace_compute_lp_residual(weighted_lpc, error + ORDER, xn2, LEN_SUBFR);
207 
208     temp = wsynth_out[i_subfr - 1];
209     iusace_apply_deemph(xn2, TILT_FAC, LEN_SUBFR, &temp);
210     memcpy(y0, xn2, LEN_SUBFR * sizeof(FLOAT32));
211 
212     for (i = 0; i < LEN_SUBFR; i++) {
213       xn[i] -= xn2[i];
214     }
215     iusace_compute_lp_residual(p_quant_lp_filt_coeff, &speech_in[i_subfr], &exc[i_subfr],
216                                LEN_SUBFR);
217 
218     memset(&code[0], 0, ORDER * sizeof(code[0]));
219     memcpy(code + ORDER, xn, (LEN_SUBFR / 2) * sizeof(FLOAT32));
220     temp = 0.0;
221     iusace_apply_preemph(code + ORDER, TILT_FAC, LEN_SUBFR / 2, &temp);
222     iusace_get_weighted_lpc(p_lp_filt_coeff, weighted_lpc);
223     iusace_synthesis_tool_float(weighted_lpc, code + ORDER, code + ORDER, LEN_SUBFR / 2, code,
224                                 pstr_scratch->p_buf_synthesis_tool);
225     iusace_compute_lp_residual(p_quant_lp_filt_coeff, code + ORDER, cn, LEN_SUBFR / 2);
226     memcpy(cn + (LEN_SUBFR / 2), &exc[i_subfr + (LEN_SUBFR / 2)],
227            (LEN_SUBFR / 2) * sizeof(FLOAT32));
228 
229     iusace_get_weighted_lpc(p_lp_filt_coeff, weighted_lpc);
230     memset(imp_res, 0, LEN_SUBFR * sizeof(FLOAT32));
231     memcpy(imp_res, weighted_lpc, (ORDER + 1) * sizeof(FLOAT32));
232     iusace_synthesis_tool_float(p_quant_lp_filt_coeff, imp_res, imp_res, LEN_SUBFR,
233                                 &imp_res[ORDER + 1], pstr_scratch->p_buf_synthesis_tool);
234     temp = 0.0;
235     iusace_apply_deemph(imp_res, TILT_FAC, LEN_SUBFR, &temp);
236 
237     iusace_closed_loop_search(&exc[i_subfr], xn, imp_res, t0_min, t0_max, &t0_frac, subfrm_flag,
238                               min_pitch_lag_res1_2, min_pitch_lag_res1, &t0);
239 
240     if (subfrm_flag == 0) {
241       if (t0 < min_pitch_lag_res1_2) {
242         index = t0 * 4 + t0_frac - (min_pitch_lag_res1_4 * 4);
243       } else if (t0 < min_pitch_lag_res1) {
244         index = t0 * 2 + (t0_frac >> 1) - (min_pitch_lag_res1_2 * 2) +
245                 ((min_pitch_lag_res1_2 - min_pitch_lag_res1_4) * 4);
246       } else {
247         index = t0 - min_pitch_lag_res1 + ((min_pitch_lag_res1_2 - min_pitch_lag_res1_4) * 4) +
248                 ((min_pitch_lag_res1 - min_pitch_lag_res1_2) * 2);
249       }
250 
251       t0_min = t0 - 8;
252       if (t0_min < min_pitch_lag_res1_4) {
253         t0_min = min_pitch_lag_res1_4;
254       }
255       t0_max = t0_min + 15;
256       if (t0_max > max_pitch_lag) {
257         t0_max = max_pitch_lag;
258         t0_min = t0_max - 15;
259       }
260     } else {
261       i = t0 - t0_min;
262       index = i * 4 + t0_frac;
263     }
264     *acelp_params = index;
265     acelp_params++;
266 
267     iusace_acelp_ltpred_cb_exc(&exc[i_subfr], t0, t0_frac, LEN_SUBFR + 1);
268     iusace_convolve(&exc[i_subfr], imp_res, y1);
269     gain1 = iusace_acelp_tgt_cb_corr2(xn, y1, tgt_cb_corr);
270     iusace_acelp_cb_target_update(xn, xn2, y1, gain1);
271     energy = 0.0;
272     for (i = 0; i < LEN_SUBFR; i++) {
273       energy += xn2[i] * xn2[i];
274     }
275 
276     for (i = 0; i < LEN_SUBFR; i++) {
277       code[i] = (FLOAT32)(0.18 * exc[i - 1 + i_subfr] + 0.64 * exc[i + i_subfr] +
278                           0.18 * exc[i + 1 + i_subfr]);
279     }
280     iusace_convolve(code, imp_res, y2);
281     gain2 = iusace_acelp_tgt_cb_corr2(xn, y2, tgt_cb_corr2);
282 
283     iusace_acelp_cb_target_update(xn, xn2, y2, gain2);
284     temp = 0.0;
285     for (i = 0; i < LEN_SUBFR; i++) {
286       temp += xn2[i] * xn2[i];
287     }
288 
289     if (temp < energy) {
290       *acelp_params = 0;
291       memcpy(&exc[i_subfr], code, LEN_SUBFR * sizeof(FLOAT32));
292       memcpy(y1, y2, LEN_SUBFR * sizeof(FLOAT32));
293       pitch_gain = gain2;
294       tgt_cb_corr[0] = tgt_cb_corr2[0];
295       tgt_cb_corr[1] = tgt_cb_corr2[1];
296     } else {
297       *acelp_params = 1;
298       pitch_gain = gain1;
299     }
300     acelp_params++;
301 
302     iusace_acelp_cb_target_update(xn, xn2, y1, pitch_gain);
303     iusace_acelp_cb_target_update(cn, cn, &exc[i_subfr], pitch_gain);
304 
305     temp = 0.0;
306     iusace_apply_preemph(imp_res, TILT_CODE, LEN_SUBFR, &temp);
307     if (t0_frac > 2) {
308       t0++;
309     }
310 
311     for (i = t0; i < LEN_SUBFR; i++) {
312       imp_res[i] += imp_res[i - t0] * PIT_SHARP;
313     }
314 
315     iusace_acelp_tgt_ir_corr(xn2, imp_res, dn);
316 
317     if (acelp_core_mode == ACELP_CORE_MODE_9k6) {
318       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_20, acelp_params,
319                           pstr_scratch->p_acelp_ir_buf);
320       acelp_params += 4;
321     } else if (acelp_core_mode == ACELP_CORE_MODE_11k2) {
322       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_28, acelp_params,
323                           pstr_scratch->p_acelp_ir_buf);
324       acelp_params += 4;
325     } else if (acelp_core_mode == ACELP_CORE_MODE_12k8) {
326       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_36, acelp_params,
327                           pstr_scratch->p_acelp_ir_buf);
328       acelp_params += 4;
329     } else if (acelp_core_mode == ACELP_CORE_MODE_14k4) {
330       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_44, acelp_params,
331                           pstr_scratch->p_acelp_ir_buf);
332       acelp_params += 4;
333     } else if (acelp_core_mode == ACELP_CORE_MODE_16k) {
334       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_52, acelp_params,
335                           pstr_scratch->p_acelp_ir_buf);
336       acelp_params += 4;
337     } else if (acelp_core_mode == ACELP_CORE_MODE_18k4) {
338       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_64, acelp_params,
339                           pstr_scratch->p_acelp_ir_buf);
340       acelp_params += 8;
341     } else {
342       iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_64, acelp_params,
343                           pstr_scratch->p_acelp_ir_buf);
344       acelp_params += 8;
345     }
346 
347     for (i = 0; i < LEN_SUBFR; i++) {
348       code[i] = (FLOAT32)(cb_exc[i] / 512);
349     }
350 
351     temp = 0.0;
352     iusace_apply_preemph(code, TILT_CODE, LEN_SUBFR, &temp);
353     for (i = t0; i < LEN_SUBFR; i++) {
354       code[i] += code[i - t0] * PIT_SHARP;
355     }
356 
357     iusace_acelp_tgt_cb_corr1(xn, y1, y2, tgt_cb_corr);
358     iusace_acelp_quant_gain(code, &pitch_gain, &code_gain, tgt_cb_corr, mean_ener_code,
359                             acelp_params);
360     acelp_params++;
361 
362     temp = 0.0;
363     for (i = 0; i < LEN_SUBFR; i++) {
364       temp += code[i] * code[i];
365     }
366     temp *= code_gain * code_gain;
367 
368     for (i = 0; i < LEN_SUBFR; i++) {
369       wsynth_out[i + i_subfr] = y0[i] + (pitch_gain * y1[i]) + (code_gain * y2[i]);
370     }
371 
372     for (i = 0; i < LEN_SUBFR; i++) {
373       exc[i + i_subfr] = pitch_gain * exc[i + i_subfr] + code_gain * code[i];
374     }
375 
376     iusace_synthesis_tool_float(p_quant_lp_filt_coeff, &exc[i_subfr], &synth_out[i_subfr],
377                                 LEN_SUBFR, &synth_out[i_subfr - ORDER],
378                                 pstr_scratch->p_buf_synthesis_tool);
379     p_lp_filt_coeff += (ORDER + 1);
380     p_quant_lp_filt_coeff += (ORDER + 1);
381   }
382 
383   memcpy(lpd_state->acelp_exc, exc - len_subfrm, 2 * len_subfrm * sizeof(FLOAT32));
384   memcpy(lpd_state->synth, synth_out + len_subfrm - (ORDER + 128),
385          (ORDER + 128) * sizeof(FLOAT32));
386   memcpy(lpd_state->wsynth, wsynth_out + len_subfrm - (1 + 128), (1 + 128) * sizeof(FLOAT32));
387   memcpy(lpd_state->lpc_coeffs_quant, p_quant_lp_filt_coeff - (2 * (ORDER + 1)),
388          (2 * (ORDER + 1)) * sizeof(FLOAT32));
389   memcpy(lpd_state->lpc_coeffs, p_lp_filt_coeff - (2 * (ORDER + 1)),
390          (2 * (ORDER + 1)) * sizeof(FLOAT32));
391 
392   mem_txn = lpd_state->tcx_mem[128 - 1];
393   mem_txnq = lpd_state->tcx_fac;
394 
395   p_quant_lp_filt_coeff = quant_lp_filt_coeff;
396   for (i_subfr = 0; i_subfr < (len_subfrm - 2 * LEN_SUBFR); i_subfr += LEN_SUBFR) {
397     iusace_get_weighted_lpc(p_quant_lp_filt_coeff, weighted_lpc);
398 
399     memcpy(error, &speech_in[i_subfr], LEN_SUBFR * sizeof(FLOAT32));
400     iusace_apply_deemph(error, TILT_FAC, LEN_SUBFR, &mem_txn);
401 
402     memcpy(error, &synth_out[i_subfr], LEN_SUBFR * sizeof(FLOAT32));
403     iusace_apply_deemph(error, TILT_FAC, LEN_SUBFR, &mem_txnq);
404 
405     p_quant_lp_filt_coeff += (ORDER + 1);
406   }
407 
408   lpd_state->tcx_quant[0] = mem_txnq;
409   for (i_subfr = 0; i_subfr < (2 * LEN_SUBFR); i_subfr += LEN_SUBFR) {
410     iusace_get_weighted_lpc(p_quant_lp_filt_coeff, weighted_lpc);
411 
412     memcpy(&(lpd_state->tcx_mem[i_subfr]), &speech_in[i_subfr + (len_subfrm - 2 * LEN_SUBFR)],
413            LEN_SUBFR * sizeof(FLOAT32));
414     iusace_apply_deemph(&(lpd_state->tcx_mem[i_subfr]), TILT_FAC, LEN_SUBFR, &mem_txn);
415 
416     memcpy(&(lpd_state->tcx_quant[1 + i_subfr]),
417            &synth_out[i_subfr + (len_subfrm - 2 * LEN_SUBFR)], LEN_SUBFR * sizeof(FLOAT32));
418     iusace_apply_deemph(&(lpd_state->tcx_quant[1 + i_subfr]), TILT_FAC, LEN_SUBFR, &mem_txnq);
419     p_quant_lp_filt_coeff += (ORDER + 1);
420   }
421   lpd_state->tcx_fac = mem_txnq;
422 
423   iusace_get_weighted_lpc(p_quant_lp_filt_coeff, weighted_lpc);
424 
425   memcpy(error, &synth_out[len_subfrm - ORDER], ORDER * sizeof(FLOAT32));
426   for (i_subfr = (2 * LEN_SUBFR); i_subfr < (4 * LEN_SUBFR); i_subfr += LEN_SUBFR) {
427     memset(error + ORDER, 0, LEN_SUBFR * sizeof(FLOAT32));
428 
429     iusace_synthesis_tool_float(p_quant_lp_filt_coeff, error + ORDER, error + ORDER, LEN_SUBFR,
430                                 error, pstr_scratch->p_buf_synthesis_tool);
431     memcpy(&(lpd_state->tcx_quant[1 + i_subfr]), error + ORDER, LEN_SUBFR * sizeof(FLOAT32));
432     iusace_apply_deemph(&(lpd_state->tcx_quant[1 + i_subfr]), TILT_FAC, LEN_SUBFR, &mem_txnq);
433     memcpy(error, error + LEN_SUBFR, ORDER * sizeof(FLOAT32));
434   }
435 
436   lpd_state->mode = 0;
437 
438   lpd_state->num_bits = num_bits;
439 }
440