xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_acelp_decode.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 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 #include <float.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <string.h>
25 
26 #include "ixheaac_type_def.h"
27 
28 #include "ixheaacd_bitbuffer.h"
29 
30 #include "ixheaacd_interface.h"
31 
32 #include "ixheaacd_tns_usac.h"
33 #include "ixheaacd_cnst.h"
34 
35 #include "ixheaacd_acelp_info.h"
36 
37 #include "ixheaacd_td_mdct.h"
38 
39 #include "ixheaacd_sbrdecsettings.h"
40 #include "ixheaacd_info.h"
41 #include "ixheaacd_sbr_common.h"
42 #include "ixheaacd_drc_data_struct.h"
43 #include "ixheaacd_drc_dec.h"
44 #include "ixheaacd_sbrdecoder.h"
45 #include "ixheaacd_mps_polyphase.h"
46 #include "ixheaac_sbr_const.h"
47 #include "ixheaacd_ec_defines.h"
48 #include "ixheaacd_ec_struct_def.h"
49 #include "ixheaacd_main.h"
50 #include "ixheaacd_arith_dec.h"
51 #include "ixheaacd_func_def.h"
52 
53 #include "ixheaacd_acelp_com.h"
54 
55 #define F_PIT_SHARP 0.85F
56 #define MEAN_ENER 30
57 
58 extern const FLOAT32 ixheaacd_interpol_filt[INTER_LP_FIL_LEN];
59 
ixheaacd_acelp_pitch_sharpening(FLOAT32 * x,WORD32 pit_lag)60 VOID ixheaacd_acelp_pitch_sharpening(FLOAT32 *x, WORD32 pit_lag) {
61   WORD32 i;
62   for (i = pit_lag; i < LEN_SUBFR; i++) {
63     x[i] += x[i - pit_lag] * F_PIT_SHARP;
64   }
65   return;
66 }
67 
ixheaacd_acelp_decode_1sp_per_track(WORD32 idx_1p,WORD32 M,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])68 static VOID ixheaacd_acelp_decode_1sp_per_track(WORD32 idx_1p, WORD32 M,
69                                                 WORD32 ixheaacd_drc_offset,
70                                                 WORD32 track,
71                                                 FLOAT32 code_vec[]) {
72   WORD32 sign_index, mask, m;
73   WORD32 sp_pos;
74   mask = ((1 << M) - 1);
75 
76   sp_pos = (idx_1p & mask) + ixheaacd_drc_offset;
77   sign_index = ((idx_1p >> M) & 1);
78 
79   m = (sp_pos << 2) + track;
80   if (sign_index == 1)
81     code_vec[m] = (code_vec[m] - 1.0f);
82   else
83     code_vec[m] = (code_vec[m] + 1.0f);
84 
85   return;
86 }
87 
ixheaacd_acelp_decode_2sp_per_track(WORD32 idx_2p,WORD32 M,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])88 static VOID ixheaacd_acelp_decode_2sp_per_track(WORD32 idx_2p, WORD32 M,
89                                                 WORD32 ixheaacd_drc_offset,
90                                                 WORD32 track,
91                                                 FLOAT32 code_vec[]) {
92   WORD32 sign_index;
93   WORD32 mask, m0, m1;
94   WORD32 sp_pos[2];
95   mask = ((1 << M) - 1);
96 
97   sp_pos[0] = (((idx_2p >> M) & mask) + ixheaacd_drc_offset);
98   sp_pos[1] = ((idx_2p & mask) + ixheaacd_drc_offset);
99 
100   sign_index = (idx_2p >> 2 * M) & 1;
101 
102   m0 = (sp_pos[0] << 2) + track;
103   m1 = (sp_pos[1] << 2) + track;
104 
105   if ((sp_pos[1] - sp_pos[0]) < 0) {
106     if (sign_index == 1) {
107       code_vec[m0] = (code_vec[m0] - 1.0f);
108       code_vec[m1] = (code_vec[m1] + 1.0f);
109     } else {
110       code_vec[m0] = (code_vec[m0] + 1.0f);
111       code_vec[m1] = (code_vec[m1] - 1.0f);
112     }
113   } else {
114     if (sign_index == 1) {
115       code_vec[m0] = (code_vec[m0] - 1.0f);
116       code_vec[m1] = (code_vec[m1] - 1.0f);
117     } else {
118       code_vec[m0] = (code_vec[m0] + 1.0f);
119       code_vec[m1] = (code_vec[m1] + 1.0f);
120     }
121   }
122   return;
123 }
124 
ixheaacd_acelp_decode_3sp_per_track(WORD32 idx_3p,WORD32 M,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])125 static VOID ixheaacd_acelp_decode_3sp_per_track(WORD32 idx_3p, WORD32 M,
126                                                 WORD32 ixheaacd_drc_offset,
127                                                 WORD32 track,
128                                                 FLOAT32 code_vec[]) {
129   WORD32 j, mask, idx_2p, idx_1p;
130 
131   mask = ((1 << (2 * M - 1)) - 1);
132   idx_2p = idx_3p & mask;
133   j = ixheaacd_drc_offset;
134   if (((idx_3p >> ((2 * M) - 1)) & 1) == 1) {
135     j += (1 << (M - 1));
136   }
137   ixheaacd_acelp_decode_2sp_per_track(idx_2p, M - 1, j, track, code_vec);
138   mask = ((1 << (M + 1)) - 1);
139   idx_1p = (idx_3p >> 2 * M) & mask;
140   ixheaacd_acelp_decode_1sp_per_track(idx_1p, M, ixheaacd_drc_offset, track,
141                                       code_vec);
142   return;
143 }
144 
ixheaacd_d_acelp_decode_4sp_per_track_section(WORD32 index,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])145 static VOID ixheaacd_d_acelp_decode_4sp_per_track_section(
146     WORD32 index, WORD32 ixheaacd_drc_offset, WORD32 track,
147     FLOAT32 code_vec[]) {
148   WORD32 j, idx_2p;
149 
150   idx_2p = index & 31;
151   j = ixheaacd_drc_offset;
152   if (((index >> 5) & 1) == 1) {
153     j += 4;
154   }
155   ixheaacd_acelp_decode_2sp_per_track(idx_2p, 2, j, track, code_vec);
156   idx_2p = (index >> 6) & 127;
157   ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, ixheaacd_drc_offset, track,
158                                       code_vec);
159   return;
160 }
161 
ixheaacd_acelp_decode_4sp_per_track(WORD32 idx_4p,WORD32 track,FLOAT32 code_vec[])162 static VOID ixheaacd_acelp_decode_4sp_per_track(WORD32 idx_4p, WORD32 track,
163                                                 FLOAT32 code_vec[]) {
164   WORD32 idx_1p, idx_2p, idx_3p;
165 
166   switch ((idx_4p >> 14) & 3) {
167     case 0:
168       if (((idx_4p >> 13) & 1) == 0)
169         ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 0, track,
170                                                       code_vec);
171       else
172         ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 8, track,
173                                                       code_vec);
174       break;
175     case 1:
176       idx_1p = idx_4p >> 10;
177       ixheaacd_acelp_decode_1sp_per_track(idx_1p, 3, 0, track, code_vec);
178       ixheaacd_acelp_decode_3sp_per_track(idx_4p, 3, 8, track, code_vec);
179       break;
180     case 2:
181       idx_2p = idx_4p >> 7;
182       ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, 0, track, code_vec);
183       ixheaacd_acelp_decode_2sp_per_track(idx_4p, 3, 8, track, code_vec);
184       break;
185     case 3:
186       idx_3p = idx_4p >> 4;
187       ixheaacd_acelp_decode_3sp_per_track(idx_3p, 3, 0, track, code_vec);
188       ixheaacd_acelp_decode_1sp_per_track(idx_4p, 3, 8, track, code_vec);
189       break;
190   }
191   return;
192 }
193 
ixheaacd_d_acelp_add_pulse(WORD32 pos[],WORD32 nb_pulse,WORD32 track,FLOAT32 code[])194 static VOID ixheaacd_d_acelp_add_pulse(WORD32 pos[], WORD32 nb_pulse,
195                                        WORD32 track, FLOAT32 code[]) {
196   WORD32 i, k;
197   for (k = 0; k < nb_pulse; k++) {
198     i = ((pos[k] & (16 - 1)) << 2) + track;
199     if ((pos[k] & 16) == 0) {
200       code[i] = (WORD16)(code[i] + 1.0f);
201     } else {
202       code[i] = (WORD16)(code[i] - 1.0f);
203     }
204   }
205   return;
206 }
207 
ixheaacd_d_acelp_decode_1p_n1(WORD32 index,WORD32 N,WORD32 ixheaacd_drc_offset,WORD32 pos[])208 static VOID ixheaacd_d_acelp_decode_1p_n1(WORD32 index, WORD32 N,
209                                           WORD32 ixheaacd_drc_offset,
210                                           WORD32 pos[]) {
211   WORD32 i, pos1, mask;
212   mask = ((1 << N) - 1);
213 
214   pos1 = ((index & mask) + ixheaacd_drc_offset);
215   i = ((index >> N) & 1);
216   if (i == 1) {
217     pos1 += 16;
218   }
219   pos[0] = pos1;
220   return;
221 }
222 
ixheaacd_acelp_decode_pulses_per_track(WORD32 cb_index[],const WORD16 code_bits,FLOAT32 code_vec[])223 VOID ixheaacd_acelp_decode_pulses_per_track(WORD32 cb_index[],
224                                             const WORD16 code_bits,
225                                             FLOAT32 code_vec[]) {
226   WORD32 track_idx, index, ixheaacd_drc_offset, pos[6], i;
227   memset(code_vec, 0, 64 * sizeof(FLOAT32));
228 
229   if (code_bits == 12) {
230     for (track_idx = 0; track_idx < 4; track_idx += 2) {
231       ixheaacd_drc_offset = cb_index[2 * (track_idx / 2)];
232       index = cb_index[2 * (track_idx / 2) + 1];
233       ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos);
234       ixheaacd_d_acelp_add_pulse(
235           pos, 1, 2 * ixheaacd_drc_offset + track_idx / 2, code_vec);
236     }
237   } else if (code_bits == 16) {
238     i = 0;
239     ixheaacd_drc_offset = cb_index[i++];
240     ixheaacd_drc_offset = (ixheaacd_drc_offset == 0) ? 1 : 3;
241     for (track_idx = 0; track_idx < 4; track_idx++) {
242       if (track_idx != ixheaacd_drc_offset) {
243         index = cb_index[i++];
244         ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos);
245         ixheaacd_d_acelp_add_pulse(pos, 1, track_idx, code_vec);
246       }
247     }
248   } else if (code_bits == 20) {
249     for (track_idx = 0; track_idx < 4; track_idx++) {
250       index = cb_index[track_idx];
251       ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec);
252     }
253   } else if (code_bits == 28) {
254     for (track_idx = 0; track_idx < 2; track_idx++) {
255       index = cb_index[track_idx];
256       ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec);
257     }
258     for (track_idx = 2; track_idx < 4; track_idx++) {
259       index = cb_index[track_idx];
260       ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec);
261     }
262   } else if (code_bits == 36) {
263     for (track_idx = 0; track_idx < 4; track_idx++) {
264       index = cb_index[track_idx];
265       ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec);
266     }
267   } else if (code_bits == 44) {
268     for (track_idx = 0; track_idx < 2; track_idx++) {
269       index = cb_index[track_idx];
270       ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec);
271     }
272     for (track_idx = 2; track_idx < 4; track_idx++) {
273       index = cb_index[track_idx];
274       ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec);
275     }
276   } else if (code_bits == 52) {
277     for (track_idx = 0; track_idx < 4; track_idx++) {
278       index = cb_index[track_idx];
279       ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec);
280     }
281   } else if (code_bits == 64) {
282     for (track_idx = 0; track_idx < 4; track_idx++) {
283       index = ((cb_index[track_idx] << 14) + cb_index[track_idx + 4]);
284       ixheaacd_acelp_decode_4sp_per_track(index, track_idx, code_vec);
285     }
286   }
287   return;
288 }
289 
ixheaacd_acelp_decode_gains(WORD32 index,FLOAT32 code_vec[],FLOAT32 * pitch_gain,FLOAT32 * codebook_gain,FLOAT32 mean_exc_energy,FLOAT32 * energy)290 static void ixheaacd_acelp_decode_gains(WORD32 index, FLOAT32 code_vec[],
291                                         FLOAT32 *pitch_gain,
292                                         FLOAT32 *codebook_gain,
293                                         FLOAT32 mean_exc_energy,
294                                         FLOAT32 *energy) {
295   WORD32 i;
296   FLOAT32 avg_innov_energy, est_gain;
297   const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table;
298 
299   avg_innov_energy = 0.01f;
300   for (i = 0; i < LEN_SUBFR; i++) {
301     avg_innov_energy += code_vec[i] * code_vec[i];
302   }
303   *energy = avg_innov_energy;
304 
305   avg_innov_energy =
306       (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR));
307 
308   est_gain = mean_exc_energy - avg_innov_energy;
309 
310   est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain);
311   *pitch_gain = gain_table[index * 2];
312 
313   *codebook_gain = gain_table[index * 2 + 1] * est_gain;
314 
315   return;
316 }
317 
ixheaacd_acelp_decode_gains_with_ec(WORD32 index,FLOAT32 code_vec[],FLOAT32 * pitch_gain,FLOAT32 * codebook_gain,FLOAT32 mean_exc_energy,FLOAT32 * energy,FLOAT32 * past_pitch_gain,FLOAT32 * past_gain_code,WORD32 bfi)318 static VOID ixheaacd_acelp_decode_gains_with_ec(WORD32 index, FLOAT32 code_vec[],
319                                                 FLOAT32 *pitch_gain, FLOAT32 *codebook_gain,
320                                                 FLOAT32 mean_exc_energy, FLOAT32 *energy,
321                                                 FLOAT32 *past_pitch_gain, FLOAT32 *past_gain_code,
322                                                 WORD32 bfi) {
323   WORD32 i;
324   FLOAT32 avg_innov_energy, est_gain, gain_inov;
325   const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table;
326 
327   avg_innov_energy = 0.01f;
328   for (i = 0; i < LEN_SUBFR; i++) {
329     avg_innov_energy += code_vec[i] * code_vec[i];
330   }
331   *energy = avg_innov_energy;
332   gain_inov = (FLOAT32)(1 / sqrt(avg_innov_energy / LEN_SUBFR));
333 
334   if (bfi) {
335     FLOAT32 tgpit = (*past_pitch_gain);
336 
337     if (tgpit > 0.95f) {
338       tgpit = 0.95f;
339     } else if (tgpit < 0.5f) {
340       tgpit = 0.5f;
341     }
342     *pitch_gain = (FLOAT32)tgpit;
343     tgpit = tgpit * 0.95f;
344     *past_pitch_gain = (FLOAT32)tgpit;
345 
346     tgpit = 1.4f - tgpit;
347     tgpit = *past_gain_code * tgpit;
348     *codebook_gain = tgpit * gain_inov;
349 
350     *past_gain_code = tgpit;
351     return;
352   }
353 
354   avg_innov_energy = (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR));
355   est_gain = mean_exc_energy - avg_innov_energy;
356 
357   est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain);
358   if (!bfi) {
359     *pitch_gain = gain_table[index * 2];
360     *past_pitch_gain = *pitch_gain;
361   }
362 
363   *codebook_gain = gain_table[index * 2 + 1] * est_gain;
364   *past_gain_code = (*codebook_gain) / gain_inov;
365 
366   return;
367 }
368 
ixheaacd_cb_exc_calc(FLOAT32 xcitation_curr[],WORD32 pitch_lag,WORD32 frac)369 static VOID ixheaacd_cb_exc_calc(FLOAT32 xcitation_curr[], WORD32 pitch_lag,
370                                  WORD32 frac) {
371   WORD32 i, j;
372   FLOAT32 s, *x0, *x1, *x2;
373   const FLOAT32 *c1, *c2;
374 
375   x0 = &xcitation_curr[-pitch_lag];
376   frac = -frac;
377   if (frac < 0) {
378     frac += UP_SAMP;
379     x0--;
380   }
381   for (j = 0; j < LEN_SUBFR + 1; j++) {
382     x1 = x0++;
383     x2 = x1 + 1;
384     c1 = &ixheaacd_interpol_filt[frac];
385     c2 = &ixheaacd_interpol_filt[UP_SAMP - frac];
386     s = 0.0;
387     for (i = 0; i < INTER_LP_FIL_ORDER; i++, c1 += UP_SAMP, c2 += UP_SAMP) {
388       s += (*x1--) * (*c1) + (*x2++) * (*c2);
389     }
390     xcitation_curr[j] = s;
391   }
392   return;
393 }
394 
ixheaacd_acelp_alias_cnx(ia_usac_data_struct * usac_data,ia_td_frame_data_struct * pstr_td_frame_data,WORD32 k,FLOAT32 lp_filt_coeff[],FLOAT32 stability_factor,ia_usac_lpd_decoder_handle st)395 VOID ixheaacd_acelp_alias_cnx(ia_usac_data_struct *usac_data,
396                               ia_td_frame_data_struct *pstr_td_frame_data, WORD32 k,
397                               FLOAT32 lp_filt_coeff[], FLOAT32 stability_factor,
398                               ia_usac_lpd_decoder_handle st) {
399   WORD32 i, subfr_idx;
400   WORD32 pitch_lag = 0, pitch_lag_frac = 0, index, pitch_flag, pitch_lag_max;
401   WORD32 pitch_lag_min = 0;
402   FLOAT32 tmp, pitch_gain, gain_code, voicing_factor, r_v, innov_energy,
403       pitch_energy, mean_ener_code;
404   FLOAT32 gain_smooth, gain_code0, cpe;
405   FLOAT32 code[LEN_SUBFR] = {0}, synth_temp[128 + 16] = {0};
406   FLOAT32 post_process_exc[LEN_SUBFR] = {0};
407   FLOAT32 gain_smooth_factor;
408   FLOAT32 *ptr_lp_filt_coeff;
409   WORD32 pitch_min;
410   WORD32 pitch_fr2;
411   WORD32 pitch_fr1;
412   WORD32 pitch_max;
413   WORD32 subfr_nb = 0;
414   const WORD16 num_codebits_table[8] = {20, 28, 36, 44, 52, 64, 12, 16};
415   FLOAT32 x[FAC_LENGTH] = {0}, xn2[2 * FAC_LENGTH + 16] = {0};
416   WORD32 int_x[FAC_LENGTH] = {0};
417   WORD32 TTT;
418   WORD32 len_subfr = usac_data->len_subfrm;
419   WORD32 fac_length;
420   WORD8 shiftp;
421   WORD32 preshift;
422   WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
423   WORD32 *int_xn2 = &usac_data->x_ac_dec[0];
424   WORD32 loop_count = 0;
425   WORD32 core_mode = pstr_td_frame_data->acelp_core_mode;
426   FLOAT32 *synth_signal =
427       &usac_data->synth_buf[len_subfr * k + MAX_PITCH +
428                             (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1) *
429                                 LEN_SUBFR];
430   FLOAT32 *xcitation_curr =
431       &usac_data->exc_buf[len_subfr * k + MAX_PITCH + (INTER_LP_FIL_ORDER + 1)];
432   FLOAT32 *ptr_pitch_gain =
433       &usac_data->pitch_gain[k * usac_data->num_subfrm +
434                              (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)];
435   WORD32 *ptr_pitch =
436       &usac_data->pitch[k * usac_data->num_subfrm +
437                         (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)];
438   fac_length = len_subfr / 2;
439 
440   WORD32 bfi = (usac_data->num_lost_lpd_frames[usac_data->present_chan] > 0) ? 1 : 0;
441   WORD32 i_offset =
442       (usac_data->str_tddec[usac_data->present_chan]->fscale * TMIN + (FSCALE_DENOM / 2)) /
443           FSCALE_DENOM -
444       TMIN;
445   const WORD32 pitch_max_val = TMAX + (6 * i_offset);
446   WORD16 code_t[LEN_SUBFR];
447 
448   if (st->mode_prev > 0) {
449     for (i = 0; i < fac_length / 2; i++) {
450       x[i] = st->fac_gain * pstr_td_frame_data->fac[k * FAC_LENGTH + 2 * i];
451       x[fac_length / 2 + i] =
452           st->fac_gain *
453           pstr_td_frame_data->fac[k * FAC_LENGTH + fac_length - 2 * i - 1];
454     }
455     for (i = 0; i < fac_length / 8; i++) {
456       x[i] *= st->fac_fd_data[2 * i];
457       x[fac_length - i - 1] *= st->fac_fd_data[2 * i + 1];
458     }
459 
460     preshift = 0;
461     shiftp = ixheaacd_float2fix(x, int_x, fac_length);
462 
463     ixheaacd_acelp_mdct(int_x, int_xn2, &preshift, fac_length, ptr_scratch);
464 
465     ixheaacd_fix2float(int_xn2, xn2 + fac_length, fac_length, &shiftp,
466                        &preshift);
467 
468     ixheaacd_vec_cnst_mul((2.0f / (FLOAT32)fac_length), xn2 + fac_length,
469                           xn2 + fac_length, fac_length);
470 
471     memset(xn2, 0, fac_length * sizeof(FLOAT32));
472 
473     ixheaacd_lpc_wt_synthesis_tool(st->lp_flt_coeff_a_prev, xn2 + fac_length,
474                                    fac_length);
475 
476     for (i = 0; i < 2 * fac_length; i++)
477       xn2[i] += synth_signal[i - (2 * fac_length)];
478 
479     memcpy(synth_signal - fac_length, xn2 + fac_length,
480            fac_length * sizeof(FLOAT32));
481 
482     tmp = 0.0;
483     ixheaacd_preemphsis_tool_float(xn2, PREEMPH_FILT_FAC, 2 * fac_length, tmp);
484 
485     ptr_lp_filt_coeff = st->lp_flt_coeff_a_prev;
486     TTT = fac_length % LEN_SUBFR;
487     if (TTT != 0) {
488       ixheaacd_residual_tool_float(
489           ptr_lp_filt_coeff, &xn2[fac_length],
490           &xcitation_curr[fac_length - (2 * fac_length)], TTT, 1);
491       ptr_lp_filt_coeff += (ORDER + 1);
492     }
493 
494     loop_count = (fac_length + TTT) / LEN_SUBFR;
495     ixheaacd_residual_tool_float(ptr_lp_filt_coeff, &xn2[fac_length + TTT],
496                                  &xcitation_curr[TTT - fac_length], LEN_SUBFR,
497                                  loop_count);
498   }
499 
500   for (i = 0; i < ORDER; i++)
501     synth_temp[i] = synth_signal[i - ORDER] -
502                     (PREEMPH_FILT_FAC * synth_signal[i - ORDER - 1]);
503 
504   i = (((st->fscale * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN;
505   pitch_min = TMIN + i;
506   pitch_fr2 = TFR2 - i;
507   pitch_fr1 = TFR1;
508   pitch_max = TMAX + (6 * i);
509 
510   ptr_lp_filt_coeff = lp_filt_coeff;
511   for (subfr_idx = 0; subfr_idx < len_subfr; subfr_idx += LEN_SUBFR) {
512     pitch_flag = subfr_idx;
513     if ((len_subfr == 256) && (subfr_idx == (2 * LEN_SUBFR))) {
514       pitch_flag = 0;
515     }
516     index = pstr_td_frame_data->acb_index[k * 4 + subfr_nb];
517 
518     if (pitch_flag == 0) {
519       if (index < (pitch_fr2 - pitch_min) * 4) {
520         pitch_lag = pitch_min + (index / 4);
521         pitch_lag_frac = index - (pitch_lag - pitch_min) * 4;
522       } else if (index <
523                  ((pitch_fr2 - pitch_min) * 4 + (pitch_fr1 - pitch_fr2) * 2)) {
524         index -= (pitch_fr2 - pitch_min) * 4;
525         pitch_lag = pitch_fr2 + (index / 2);
526         pitch_lag_frac = index - (pitch_lag - pitch_fr2) * 2;
527         pitch_lag_frac *= 2;
528       } else {
529         pitch_lag = index + pitch_fr1 - ((pitch_fr2 - pitch_min) * 4) -
530                     ((pitch_fr1 - pitch_fr2) * 2);
531         pitch_lag_frac = 0;
532       }
533       pitch_lag_min = pitch_lag - 8;
534       if (pitch_lag_min < pitch_min) pitch_lag_min = pitch_min;
535 
536       pitch_lag_max = pitch_lag_min + 15;
537       if (pitch_lag_max > pitch_max) {
538         pitch_lag_max = pitch_max;
539         pitch_lag_min = pitch_lag_max - 15;
540       }
541     } else {
542       pitch_lag = pitch_lag_min + index / 4;
543       pitch_lag_frac = index - (pitch_lag - pitch_lag_min) * 4;
544     }
545 
546     if (usac_data->ec_flag) {
547       if (bfi) {
548         if (usac_data->pitch_lag_old >= pitch_max_val) {
549           usac_data->pitch_lag_old = (pitch_max_val - 5);
550         }
551         pitch_lag = usac_data->pitch_lag_old;
552         pitch_lag_frac = usac_data->pitch_lag_frac_old;
553       }
554     }
555     ixheaacd_cb_exc_calc(&xcitation_curr[subfr_idx], pitch_lag, pitch_lag_frac);
556 
557     mean_ener_code =
558         (((FLOAT32)pstr_td_frame_data->mean_energy[k]) * 12.0f) + 18.0f;
559 
560     if (pstr_td_frame_data->ltp_filtering_flag[k * 4 + subfr_nb] == 0) {
561       for (i = 0; i < LEN_SUBFR; i++)
562         code[i] = (FLOAT32)(0.18 * xcitation_curr[i - 1 + subfr_idx] +
563                             0.64 * xcitation_curr[i + subfr_idx] +
564                             0.18 * xcitation_curr[i + 1 + subfr_idx]);
565 
566       ixheaacd_mem_cpy(code, &xcitation_curr[subfr_idx], LEN_SUBFR);
567     }
568     if (usac_data->frame_ok == 1) {
569       ixheaacd_acelp_decode_pulses_per_track(
570           &(pstr_td_frame_data->icb_index[k * 4 + subfr_nb][0]), num_codebits_table[core_mode],
571           code);
572     } else {
573       if (usac_data->ec_flag) {
574         WORD32 idx;
575         if (bfi) {
576           for (idx = 0; idx < LEN_SUBFR; idx++) {
577             usac_data->seed_ace = ((((WORD32)usac_data->seed_ace * 31821) >> 1) + 13849);
578             code_t[idx] = (WORD16)((usac_data->seed_ace) >> 4);
579             code[idx] = ((FLOAT32)code_t[idx] / 512);
580           }
581         }
582       }
583     }
584 
585     tmp = 0.0;
586     ixheaacd_preemphsis_tool_float(code, TILT_CODE, LEN_SUBFR, tmp);
587     i = pitch_lag;
588     if (pitch_lag_frac > 2) i++;
589     if (i >= 0) ixheaacd_acelp_pitch_sharpening(code, i);
590 
591     index = pstr_td_frame_data->gains[k * 4 + subfr_nb];
592     if (usac_data->ec_flag) {
593       ixheaacd_acelp_decode_gains_with_ec(index, code, &pitch_gain, &gain_code, mean_ener_code,
594                                           &innov_energy, &usac_data->past_pitch_gain,
595                                           &usac_data->past_gain_code, bfi);
596     } else {
597       ixheaacd_acelp_decode_gains(index, code, &pitch_gain, &gain_code, mean_ener_code,
598                                   &innov_energy);
599     }
600 
601     pitch_energy = 0.0;
602     for (i = 0; i < LEN_SUBFR; i++)
603       pitch_energy +=
604           xcitation_curr[i + subfr_idx] * xcitation_curr[i + subfr_idx];
605 
606     pitch_energy *= (pitch_gain * pitch_gain);
607 
608     innov_energy *= gain_code * gain_code;
609 
610     r_v = (FLOAT32)((pitch_energy - innov_energy) /
611                     (pitch_energy + innov_energy));
612 
613     for (i = 0; i < LEN_SUBFR; i++)
614       post_process_exc[i] = pitch_gain * xcitation_curr[i + subfr_idx];
615 
616     for (i = 0; i < LEN_SUBFR; i++)
617       xcitation_curr[i + subfr_idx] =
618           pitch_gain * xcitation_curr[i + subfr_idx] + gain_code * code[i];
619 
620     i = pitch_lag;
621     if (pitch_lag_frac > 2) i++;
622 
623     if (i > pitch_max) i = pitch_max;
624 
625     *ptr_pitch++ = i;
626     *ptr_pitch_gain++ = pitch_gain;
627 
628     voicing_factor = (FLOAT32)(0.5 * (1.0 - r_v));
629     gain_smooth_factor = stability_factor * voicing_factor;
630     gain_code0 = gain_code;
631     if (gain_code0 < st->gain_threshold) {
632       gain_code0 = (FLOAT32)(gain_code0 * 1.19);
633       if (gain_code0 > st->gain_threshold) gain_code0 = st->gain_threshold;
634     } else {
635       gain_code0 = (FLOAT32)(gain_code0 / 1.19);
636       if (gain_code0 < st->gain_threshold) gain_code0 = st->gain_threshold;
637     }
638     st->gain_threshold = gain_code0;
639     gain_smooth = (FLOAT32)((gain_smooth_factor * gain_code0) +
640                             ((1.0 - gain_smooth_factor) * gain_code));
641     for (i = 0; i < LEN_SUBFR; i++) code[i] *= gain_smooth;
642 
643     cpe = (FLOAT32)(0.125 * (1.0 + r_v));
644 
645     post_process_exc[0] += code[0] - (cpe * code[1]);
646 
647     for (i = 1; i < LEN_SUBFR - 1; i++)
648       post_process_exc[i] += code[i] - (cpe * (code[i - 1] + code[i + 1]));
649 
650     post_process_exc[LEN_SUBFR - 1] +=
651         code[LEN_SUBFR - 1] - (cpe * code[LEN_SUBFR - 2]);
652 
653     ixheaacd_synthesis_tool_float(ptr_lp_filt_coeff, post_process_exc,
654                                   &synth_signal[subfr_idx], LEN_SUBFR,
655                                   synth_temp);
656     memcpy(synth_temp, &synth_signal[subfr_idx + LEN_SUBFR - ORDER],
657            ORDER * sizeof(FLOAT32));
658 
659     ptr_lp_filt_coeff += (ORDER + 1);
660     subfr_nb++;
661   }
662 
663   ixheaacd_deemphsis_tool(synth_signal, len_subfr, synth_signal[-1]);
664 
665   memset(synth_temp + 16, 0, 128 * sizeof(FLOAT32));
666   ixheaacd_synthesis_tool_float1(ptr_lp_filt_coeff, synth_temp + 16, 128);
667 
668   ptr_lp_filt_coeff -= (2 * (ORDER + 1));
669   memcpy(st->lp_flt_coeff_a_prev, ptr_lp_filt_coeff,
670          (2 * (ORDER + 1)) * sizeof(FLOAT32));
671 
672   memcpy(st->exc_prev, synth_signal + len_subfr - (1 + fac_length),
673          (1 + fac_length) * sizeof(FLOAT32));
674 
675   memcpy(st->exc_prev + 1 + fac_length, synth_temp + 16,
676          fac_length * sizeof(FLOAT32));
677   ixheaacd_deemphsis_tool(st->exc_prev + 1 + fac_length, fac_length,
678                           synth_signal[len_subfr - 1]);
679 
680   if (usac_data->ec_flag) {
681     usac_data->pitch_lag_old = pitch_lag;
682     usac_data->pitch_lag_frac_old = pitch_lag_frac;
683   }
684   return;
685 }
686