xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_lpc.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 <assert.h>
21 #include <float.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <string.h>
26 
27 #include "ixheaac_type_def.h"
28 #include "ixheaacd_bitbuffer.h"
29 #include "ixheaacd_interface.h"
30 #include "ixheaacd_defines.h"
31 #include "ixheaacd_aac_rom.h"
32 #include "ixheaacd_tns_usac.h"
33 #include "ixheaacd_cnst.h"
34 #include "ixheaacd_acelp_info.h"
35 
36 #include "ixheaacd_sbrdecsettings.h"
37 #include "ixheaacd_info.h"
38 #include "ixheaacd_sbr_common.h"
39 #include "ixheaacd_drc_data_struct.h"
40 #include "ixheaacd_drc_dec.h"
41 #include "ixheaacd_sbrdecoder.h"
42 #include "ixheaacd_mps_polyphase.h"
43 #include "ixheaac_sbr_const.h"
44 
45 #include "ixheaacd_pulsedata.h"
46 #include "ixheaacd_pns.h"
47 #include "ixheaacd_lt_predict.h"
48 #include "ixheaacd_ec_defines.h"
49 #include "ixheaacd_ec_struct_def.h"
50 #include "ixheaacd_main.h"
51 #include "ixheaacd_channelinfo.h"
52 #include "ixheaacd_ec.h"
53 #include "ixheaacd_arith_dec.h"
54 
55 #include "ixheaacd_func_def.h"
56 #include "ixheaacd_windows.h"
57 #include "ixheaacd_acelp_com.h"
58 #include "ixheaac_constants.h"
59 #include "ixheaac_basic_ops32.h"
60 #include "ixheaac_basic_ops40.h"
61 
62 #define LSF_GAP_F 50.0f
63 #define FREQ_MAX_F 6400.0f
64 #define FREQ_DIV_F 400.0f
65 
66 extern const FLOAT32 ixheaacd_fir_lp_filt[1 + FILTER_DELAY];
67 
68 const WORD32 ixheaacd_pow_10_i_by_128[128] = {
69     16384,     17788,     19312,     20968,     22765,     24716,     26835,
70     29135,     31632,     34343,     37287,     40483,     43953,     47720,
71     51810,     56251,     61072,     66307,     71990,     78161,     84860,
72     92134,     100030,    108604,    117913,    128019,    138992,    150905,
73     163840,    177882,    193129,    209682,    227654,    247167,    268352,
74     291353,    316325,    343438,    372874,    404834,    439532,    477205,
75     518107,    562515,    610728,    663075,    719908,    781612,    848605,
76     921340,    1000309,   1086046,   1179133,   1280197,   1389925,   1509057,
77     1638400,   1778829,   1931294,   2096827,   2276549,   2471675,   2683525,
78     2913532,   3163255,   3434381,   3728745,   4048340,   4395328,   4772057,
79     5181075,   5625151,   6107289,   6630752,   7199081,   7816122,   8486051,
80     9213400,   10003091,  10860467,  11791330,  12801978,  13899250,  15090570,
81     16384000,  17788290,  19312945,  20968279,  22765494,  24716750,  26835250,
82     29135329,  31632551,  34343813,  37287459,  40483409,  43953287,  47720573,
83     51810757,  56251515,  61072895,  66307521,  71990813,  78161226,  84860513,
84     92134002,  100030911, 108604672, 117913300, 128019781, 138992500, 150905703,
85     163840000, 177882909, 193129453, 209682794, 227654941, 247167501, 268352504,
86     291353298, 316325515, 343438130, 372874596, 404834095, 439532879, 477205734,
87     518107571, 562515151};
88 
89 VOID ixheaacd_lsf_weight_2st_flt(float *lsfq, float *w, WORD32 mode);
90 
ixheaacd_mult32_m(WORD32 a,WORD32 b)91 static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
92   WORD32 result;
93   WORD64 temp_result;
94 
95   temp_result = (WORD64)a * (WORD64)b;
96   result = (WORD32)(temp_result >> 31);
97 
98   return (result);
99 }
100 
ixheaacd_reset_acelp_data_fix(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st,WORD32 * ptr_overlap_buf,WORD32 was_last_short,WORD32 tw_mdct)101 void ixheaacd_reset_acelp_data_fix(ia_usac_data_struct *usac_data,
102                                    ia_usac_lpd_decoder_handle st,
103                                    WORD32 *ptr_overlap_buf,
104                                    WORD32 was_last_short, WORD32 tw_mdct) {
105   WORD32 i;
106 
107   if (was_last_short == 1) {
108     st->mode_prev = -2;
109   } else {
110     st->mode_prev = -1;
111   }
112 
113   for (i = 0; i < NUM_SUBFR_SUPERFRAME_BY2 - 1; i++) {
114     st->pitch_prev[i] = 64;
115     st->gain_prev[i] = 0;
116   }
117 
118   st->bpf_active_prev = 0;
119 
120   if (ptr_overlap_buf != NULL && !tw_mdct) {
121     const WORD32 *ptr_window_coeff;
122     WORD32 fac_length;
123     if (was_last_short) {
124       fac_length = (usac_data->ccfl) / 16;
125     } else {
126       fac_length = (usac_data->len_subfrm) / 2;
127     }
128 
129     if (fac_length == 48) {
130       ptr_window_coeff = ixheaacd_sine_win_96;
131     } else if (fac_length == 64) {
132       ptr_window_coeff = ixheaacd_sine_win_128;
133     } else if (fac_length == 96) {
134       ptr_window_coeff = ixheaacd_sine_win_192;
135     } else {
136       ptr_window_coeff = ixheaacd_sine_win_256;
137     }
138 
139     for (i = 0; i < 2 * fac_length; i++) {
140       ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i] =
141           ixheaacd_mult32_m(
142               ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i],
143               ptr_window_coeff[2 * fac_length - 1 - i]);
144     }
145     for (i = 0; i < (usac_data->ccfl) / 2 - fac_length; i++) {
146       ptr_overlap_buf[(usac_data->ccfl) / 2 + fac_length + i] = 0;
147     }
148 
149     if (ptr_overlap_buf != NULL) {
150       for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
151         st->exc_prev[i] = 0.0f;
152       }
153       for (i = 0; i < 2 * fac_length + 1; i++) {
154         st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] =
155             ptr_overlap_buf[i + usac_data->ccfl / 2 - fac_length - 1] /
156             (float)(16384);
157       }
158     } else {
159       ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
160     }
161   }
162 
163   return;
164 }
165 
ixheaacd_fix2flt_data(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st,WORD32 k)166 VOID ixheaacd_fix2flt_data(ia_usac_data_struct *usac_data,
167                            ia_usac_lpd_decoder_handle st, WORD32 k) {
168   WORD32 i;
169   WORD32 fac_length;
170   WORD32 window_sequence_last = usac_data->window_sequence_last[k];
171   WORD32 *p_ola_buffer = usac_data->overlap_data_ptr[k];
172   if (window_sequence_last == EIGHT_SHORT_SEQUENCE) {
173     fac_length = (usac_data->ccfl) / 16;
174   } else {
175     fac_length = (usac_data->len_subfrm) / 2;
176   }
177 
178   ixheaacd_memset(st->lp_flt_coeff_a_prev, 2 * (ORDER + 1));
179   ixheaacd_memset(st->xcitation_prev, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
180   ixheaacd_memset(st->synth_prev, MAX_PITCH + SYNTH_DELAY_LMAX);
181   ixheaacd_memset(st->bpf_prev, FILTER_DELAY + LEN_SUBFR);
182 
183   st->gain_threshold = 0.0f;
184 
185   if (p_ola_buffer != NULL) {
186     for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
187       st->exc_prev[i] = 0;
188     }
189     for (i = 0; i < 2 * fac_length + 1; i++) {
190       st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] = (FLOAT32)(
191           p_ola_buffer[i + usac_data->ccfl / 2 - fac_length - 1] / 16384.0);
192     }
193   } else {
194     ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
195   }
196 
197   return;
198 }
199 
ixheaacd_init_acelp_data(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st)200 void ixheaacd_init_acelp_data(ia_usac_data_struct *usac_data,
201                               ia_usac_lpd_decoder_handle st) {
202   ixheaacd_reset_acelp_data_fix(usac_data, st, NULL, 0, 0);
203 }
204 
205 #define PI_BY_6400 (PI / 6400.0)
206 #define SCALE1 (6400.0 / PI)
207 
ixheaacd_lsp_2_lsf_conversion(float lsp[],float lsf[],WORD32 m)208 void ixheaacd_lsp_2_lsf_conversion(float lsp[], float lsf[], WORD32 m) {
209   short i;
210   for (i = 0; i < m; i++) {
211     lsf[i] = (float)(acos(lsp[i]) * SCALE1);
212   }
213   return;
214 }
215 
ixheaacd_lsf_2_lsp_conversion_float(FLOAT32 lsf[],FLOAT32 lsp[],WORD32 m)216 static VOID ixheaacd_lsf_2_lsp_conversion_float(FLOAT32 lsf[], FLOAT32 lsp[],
217                                                 WORD32 m) {
218   WORD32 i;
219   for (i = 0; i < m; i++)
220     lsp[i] = (FLOAT32)cos((double)lsf[i] * (double)PI_BY_6400);
221 
222   return;
223 }
224 
ixheaacd_bass_post_filter(FLOAT32 * synth_sig,WORD32 * pitch,FLOAT32 * pitch_gain,FLOAT32 * synth_out,WORD32 len_fr,WORD32 len2,FLOAT32 bpf_prev[],WORD32 ec_flag)225 static WORD32 ixheaacd_bass_post_filter(FLOAT32 *synth_sig, WORD32 *pitch, FLOAT32 *pitch_gain,
226                                         FLOAT32 *synth_out, WORD32 len_fr, WORD32 len2,
227                                         FLOAT32 bpf_prev[], WORD32 ec_flag) {
228   WORD32 i, j, sf, num_subfr, pitch_lag, lg;
229   FLOAT32 x_energy, xy_corr, y_energy, norm_corr, energy, gain, tmp, alpha;
230   FLOAT32 noise_buf[FILTER_DELAY + (2 * LEN_SUBFR)], *noise_tmp1, *noise_tmp2,
231       *x, *y;
232 
233   noise_tmp1 = noise_buf + FILTER_DELAY;
234   noise_tmp2 = noise_buf + FILTER_DELAY + LEN_SUBFR;
235 
236   memcpy(synth_out, synth_sig - LEN_SUBFR, len_fr * sizeof(FLOAT32));
237 
238   if (len_fr % 64)
239     memset(synth_out + len_fr, 0, (LEN_SUBFR - len_fr % 64) * sizeof(FLOAT32));
240 
241   sf = 0;
242   for (num_subfr = 0; num_subfr < len_fr; num_subfr += LEN_SUBFR, sf++) {
243     pitch_lag = pitch[sf];
244     gain = pitch_gain[sf];
245     if (((pitch_lag >> 1) + 96 - num_subfr) > MAX_PITCH) {
246       if (ec_flag) {
247         pitch_lag = (MAX_PITCH + num_subfr - 96) << 1;
248       } else {
249         return -1;
250       }
251     }
252     if (gain > 1.0f) gain = 1.0f;
253     if (gain < 0.0f) gain = 0.0f;
254 
255     x = &synth_sig[num_subfr - 96];
256     y = &synth_sig[num_subfr - pitch_lag / 2 - 96];
257 
258     x_energy = 0.01f;
259     xy_corr = 0.01f;
260     y_energy = 0.01f;
261     for (i = 0; i < LEN_SUBFR + 96; i++) {
262       x_energy += x[i] * x[i];
263       xy_corr += x[i] * y[i];
264       y_energy += y[i] * y[i];
265     }
266 
267     norm_corr = xy_corr / (FLOAT32)sqrt(x_energy * y_energy);
268 
269     if (norm_corr > 0.95f) pitch_lag >>= 1;
270 
271     lg = len_fr + len2 - pitch_lag - num_subfr;
272     if (lg < 0) lg = 0;
273     if (lg > LEN_SUBFR) lg = LEN_SUBFR;
274 
275     if (pitch_lag > MAX_PITCH) {
276       if (ec_flag) {
277         pitch_lag = MAX_PITCH;
278       } else {
279         return -1;
280       }
281     }
282 
283     if (gain > 0) {
284       if (lg > 0) {
285         tmp = 0.01f;
286         for (i = 0; i < lg; i++) {
287           tmp += synth_sig[i + num_subfr] * synth_sig[i + num_subfr];
288         }
289         energy = 0.01f;
290         for (i = 0; i < lg; i++) {
291           energy += synth_sig[i + num_subfr + pitch_lag] *
292                     synth_sig[i + num_subfr + pitch_lag];
293         }
294         tmp = (FLOAT32)sqrt(tmp / energy);
295         if (tmp < gain) gain = tmp;
296       }
297 
298       alpha = 0.5f * gain;
299       for (i = 0; i < lg; i++) {
300         noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
301                                  0.5f * synth_sig[i + num_subfr - pitch_lag] -
302                                  0.5f * synth_sig[i + num_subfr + pitch_lag]);
303       }
304       for (i = lg; i < LEN_SUBFR; i++) {
305         noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
306                                  synth_sig[i + num_subfr - pitch_lag]);
307       }
308     } else {
309       memset(noise_tmp2, 0, LEN_SUBFR * sizeof(FLOAT32));
310     }
311 
312     memcpy(noise_buf, bpf_prev, (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
313     memcpy(bpf_prev, noise_buf + LEN_SUBFR,
314            (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
315 
316     for (i = 0; i < LEN_SUBFR; i++) {
317       tmp = ixheaacd_fir_lp_filt[0] * noise_tmp1[i];
318       for (j = 1; j <= FILTER_DELAY; j++) {
319         tmp +=
320             ixheaacd_fir_lp_filt[j] * (noise_tmp1[i - j] + noise_tmp1[i + j]);
321       }
322       synth_out[i + num_subfr] -= tmp;
323     }
324   }
325 
326   return 0;
327 }
328 
ixheaacd_reorder_lsf(float * lsf,float min_dist,int n)329 void ixheaacd_reorder_lsf(float *lsf, float min_dist, int n) {
330   int i;
331   float lsf_min;
332 
333   lsf_min = min_dist;
334   for (i = 0; i < n; i++) {
335     if (lsf[i] < lsf_min) lsf[i] = lsf_min;
336 
337     lsf_min = lsf[i] + min_dist;
338   }
339 
340   lsf_min = FREQ_MAX_F - min_dist;
341   for (i = n - 1; i >= 0; i--) {
342     if (lsf[i] > lsf_min) lsf[i] = lsf_min;
343 
344     lsf_min = lsf[i] - min_dist;
345   }
346 
347   return;
348 }
349 
ixheaacd_lpd_dec(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st,ia_td_frame_data_struct * pstr_td_frame_data,FLOAT32 fsynth[],WORD32 first_lpd_flag,WORD32 short_fac_flag,WORD32 bpf_control_info)350 WORD32 ixheaacd_lpd_dec(ia_usac_data_struct *usac_data,
351                         ia_usac_lpd_decoder_handle st,
352                         ia_td_frame_data_struct *pstr_td_frame_data,
353                         FLOAT32 fsynth[], WORD32 first_lpd_flag,
354                         WORD32 short_fac_flag, WORD32 bpf_control_info) {
355   FLOAT32 *synth_buf = usac_data->synth_buf;
356   FLOAT32 *xcitation_buff = usac_data->exc_buf;
357   FLOAT32 lsp_curr[ORDER];
358   FLOAT32 lsf_curr[ORDER];
359   FLOAT32 *lp_flt_coff_a = usac_data->lp_flt_coff;
360   FLOAT32 *synth, *xcitation_curr;
361   WORD32 *pitch = usac_data->pitch;
362   FLOAT32 *pitch_gain = usac_data->pitch_gain;
363   FLOAT32 lsf_flt[(2 * NUM_FRAMES + 1) * ORDER];
364 
365   WORD32 i, k, tp, mode;
366   WORD32 *mod;
367   FLOAT32 gain, stability_factor = 0.0f;
368   FLOAT32 tmp, synth_corr, synth_energy;
369 
370   WORD32 len_fr;
371   WORD32 len_subfrm;
372   WORD32 num_subfr;
373   WORD32 num_subfr_in_superfr;
374   WORD32 num_subfr_by2;
375   WORD32 synth_delay;
376   WORD32 num_samples = 0;
377 
378   WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
379 
380   WORD32 subfr_len = 0, n_subfr = 0;
381   WORD32 err = 0;
382   WORD32 ch = usac_data->present_chan;
383 
384   len_fr = usac_data->ccfl;
385   len_subfrm = usac_data->len_subfrm;
386   num_subfr = usac_data->num_subfrm;
387   num_subfr_in_superfr = NUM_FRAMES * num_subfr;
388   num_subfr_by2 = (num_subfr_in_superfr / 2) - 1;
389   synth_delay = num_subfr_by2 * LEN_SUBFR;
390 
391   synth = synth_buf + MAX_PITCH + synth_delay;
392   ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
393   ixheaacd_memset(synth, SYNTH_DELAY_LMAX + LEN_SUPERFRAME - synth_delay);
394 
395   xcitation_curr = xcitation_buff + MAX_PITCH + INTER_LP_FIL_ORDER + 1;
396   ixheaacd_mem_cpy(st->xcitation_prev, xcitation_buff,
397                    MAX_PITCH + INTER_LP_FIL_ORDER + 1);
398   memset(xcitation_curr, 0, sizeof(FLOAT32) * (LEN_SUPERFRAME + 1));
399 
400   mod = pstr_td_frame_data->mod;
401   if (usac_data->frame_ok == 1) {
402     usac_data->num_lost_lpd_frames[usac_data->present_chan] = 0;
403   }
404 
405   if (usac_data->ec_flag && usac_data->frame_ok == 0) {
406     ixheaacd_usac_lpc_ec(usac_data->lsp_coeff, usac_data->lpc4_lsf, usac_data->lsf_adaptive_mean,
407                          first_lpd_flag);
408   }
409   for (i = 0; i < num_subfr_by2; i++) {
410     pitch[i] = st->pitch_prev[i];
411     pitch_gain[i] = st->gain_prev[i];
412   }
413   for (i = 0; i < num_subfr_in_superfr; i++) {
414     pitch[i + num_subfr_by2] = 64;
415     pitch_gain[i + num_subfr_by2] = 0.0f;
416   }
417 
418   if (usac_data->frame_ok) {
419     if (!first_lpd_flag) {
420       ixheaacd_lsp_2_lsf_conversion(st->lspold, lsf_flt, ORDER);
421     }
422 
423     ixheaacd_alg_vec_dequant(pstr_td_frame_data, first_lpd_flag, lsf_flt, pstr_td_frame_data->mod,
424                              usac_data->ec_flag);
425   }
426   if (usac_data->ec_flag && !(usac_data->frame_ok)) {
427     for (i = 0; i < 5; i++) {
428       memcpy(&lsf_flt[i * ORDER], &usac_data->lsp_coeff[i], ORDER * sizeof(lsf_flt[0]));
429     }
430   }
431   if (first_lpd_flag) {
432     ixheaacd_mem_cpy(&lsf_flt[0], st->lsf_prev, ORDER);
433     ixheaacd_lsf_2_lsp_conversion_float(st->lsf_prev, st->lspold, ORDER);
434   }
435 
436   if ((first_lpd_flag && mod[0] == 0) || (first_lpd_flag && mod[1] == 0) ||
437       ((first_lpd_flag && mod[2] == 0 && len_subfrm != LEN_FRAME))) {
438     FLOAT32 lp_flt_coeff_a[9 * (ORDER + 1)];
439     FLOAT32 tmp_buf[3 * LEN_FRAME + ORDER];
440     FLOAT32 tmp_res_buf[3 * LEN_FRAME];
441     FLOAT32 *tmp = &(tmp_buf[LEN_FRAME]);
442     FLOAT32 *ptr_tmp = &(tmp_res_buf[LEN_FRAME]);
443     WORD32 tmp_start;
444     FLOAT32 mem = 0;
445     WORD32 gain;
446     WORD32 length;
447 
448     ixheaacd_interpolation_lsp_params(st->lspold, st->lspold, lp_flt_coeff_a,
449                                       8);
450 
451     memcpy(st->lp_flt_coeff_a_prev, lp_flt_coeff_a,
452            (ORDER + 1) * sizeof(FLOAT32));
453     memcpy(st->lp_flt_coeff_a_prev + ORDER + 1, lp_flt_coeff_a,
454            (ORDER + 1) * sizeof(FLOAT32));
455 
456     if (mod[0] == 0) {
457       WORD32 fac_length;
458       if (short_fac_flag) {
459         fac_length = (len_subfrm * NUM_FRAMES) / 16;
460       } else {
461         fac_length = len_subfrm / 2;
462       }
463 
464       if (usac_data->frame_ok == 0) {
465         memset(&pstr_td_frame_data->fac_data[0], 0, sizeof(pstr_td_frame_data->fac_data));
466       }
467       gain = ixheaacd_pow_10_i_by_128[pstr_td_frame_data->fac_data[0]];
468 
469       memcpy(ptr_scratch, &pstr_td_frame_data->fac_data[0],
470              129 * sizeof(WORD32));
471 
472       for (i = 0; i < fac_length / 2; i++) {
473         pstr_td_frame_data->fac_data[i] = ptr_scratch[2 * i + 1] << 16;
474         pstr_td_frame_data->fac_data[fac_length / 2 + i] =
475             ptr_scratch[fac_length - 2 * i] << 16;
476       }
477 
478       if (usac_data->ec_flag == 0) {
479         if (fac_length & (fac_length - 1)) {
480           if ((fac_length != 48) && (fac_length != 96) && (fac_length != 192) &&
481               (fac_length != 384) && (fac_length != 768)) {
482             return -1;
483           }
484         }
485       }
486 
487       ixheaacd_fwd_alias_cancel_tool(usac_data, pstr_td_frame_data, fac_length, lp_flt_coeff_a,
488                                      gain);
489 
490       memset(&usac_data->overlap_data_ptr[usac_data->present_chan][(len_fr / 2)], 0,
491              fac_length * sizeof(WORD32));
492     }
493 
494     for (i = 0; i < 2 * len_subfrm; i++)
495       st->fd_synth[ORDER + i] = (FLOAT32)(
496           (FLOAT32)usac_data->overlap_data_ptr[usac_data->present_chan][i] /
497           16384.0);
498     num_samples = min(2 * len_subfrm, MAX_PITCH + synth_delay);
499 
500     ixheaacd_mem_cpy(st->fd_synth + ORDER, synth - 2 * len_subfrm,
501                      2 * len_subfrm);
502 
503     ixheaacd_preemphsis_tool_float(st->fd_synth + ORDER, PREEMPH_FILT_FAC,
504                                    2 * len_subfrm, mem);
505 
506     ixheaacd_memset(tmp, ORDER);
507     ixheaacd_mem_cpy(st->fd_synth + ORDER, tmp + ORDER, 2 * len_subfrm);
508     tmp_start = 0;
509 
510     ixheaacd_memset(ptr_tmp - len_subfrm, 3 * len_subfrm);
511     memset(st->fd_synth, 0, ORDER * sizeof(WORD32));
512     length = (2 * len_subfrm - tmp_start) / LEN_SUBFR;
513 
514     ixheaacd_residual_tool_float1(lp_flt_coeff_a,
515                                   &st->fd_synth[ORDER + tmp_start],
516                                   &ptr_tmp[tmp_start], LEN_SUBFR, length);
517 
518     if (mod[0] != 0 && (len_subfrm == LEN_FRAME || mod[1] != 0)) {
519       num_samples = min(len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
520     } else {
521       num_samples = min(2 * len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
522     }
523     ixheaacd_mem_cpy(ptr_tmp + 2 * len_subfrm - num_samples,
524                      xcitation_curr - num_samples, num_samples);
525   }
526 
527   k = 0;
528 
529   while (k < 4) {
530     if (usac_data->ec_flag && usac_data->frame_ok == 0) {
531       if (mod[k] != 0 && usac_data->frame_ok == 0 &&
532           usac_data->str_error_concealment[ch].prev_frame_ok[0] == 0 && k == 0) {
533         memcpy(st->lspold, usac_data->lspold_ec, sizeof(st->lspold));
534       }
535       usac_data->num_lost_lpd_frames[usac_data->present_chan]++;
536     }
537 
538     mode = mod[k];
539     if ((st->mode_prev == 0) && (mode > 0) &&
540         (k != 0 || st->bpf_active_prev == 1)) {
541       i = (k * num_subfr) + num_subfr_by2;
542       pitch[i + 1] = pitch[i] = pitch[i - 1];
543       pitch_gain[i + 1] = pitch_gain[i] = pitch_gain[i - 1];
544     }
545     if (usac_data->frame_ok == 0) {
546       memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
547     } else {
548       if ((mode == 0) || (mode == 1))
549         memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
550       else if (mode == 2)
551         memcpy(lsf_curr, &lsf_flt[(k + 2) * ORDER], ORDER * sizeof(FLOAT32));
552       else
553         memcpy(lsf_curr, &lsf_flt[(k + 4) * ORDER], ORDER * sizeof(FLOAT32));
554     }
555 
556     ixheaacd_lsf_2_lsp_conversion_float(lsf_curr, lsp_curr, ORDER);
557     if (usac_data->frame_ok) {
558       tmp = 0.0f;
559       for (i = 0; i < ORDER; i++) {
560         tmp += (lsf_curr[i] - st->lsf_prev[i]) * (lsf_curr[i] - st->lsf_prev[i]);
561       }
562       stability_factor = (FLOAT32)(1.25f - (tmp / 400000.0f));
563       if (stability_factor > 1.0f) {
564         stability_factor = 1.0f;
565       }
566       if (stability_factor < 0.0f) {
567         stability_factor = 0.0f;
568       }
569       if (usac_data->ec_flag) {
570         usac_data->stability_factor_old = stability_factor;
571       }
572     }
573     if (usac_data->ec_flag && !(usac_data->frame_ok)) {
574       stability_factor = usac_data->stability_factor_old;
575     }
576     if (usac_data->frame_ok == 0) {
577       mode = st->mode_prev;
578     }
579     if ((usac_data->frame_ok == 1 && mode == 0) ||
580         (usac_data->frame_ok == 0 && (st->mode_prev == 0 || st->mode_prev == 1))) {
581       ixheaacd_interpolation_lsp_params(st->lspold, lsp_curr, lp_flt_coff_a, num_subfr);
582 
583       if (usac_data->frame_ok == 1 || (usac_data->frame_ok == 0 && st->mode_prev == 0)) {
584         ixheaacd_acelp_alias_cnx(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
585                                  stability_factor, st);
586       }
587 
588       if (usac_data->frame_ok == 0 && st->mode_prev == 1) {
589         ixheaacd_usac_tcx_ec(usac_data, st, lsp_curr, k, lp_flt_coff_a);
590       }
591 
592       if ((st->mode_prev != 0) && bpf_control_info) {
593         i = (k * num_subfr) + num_subfr_by2;
594         pitch[i - 1] = pitch[i];
595         pitch_gain[i - 1] = pitch_gain[i];
596         if (st->mode_prev != -2) {
597           pitch[i - 2] = pitch[i];
598           pitch_gain[i - 2] = pitch_gain[i];
599         }
600       }
601       k++;
602     } else {
603       if (mode == 1) {
604         subfr_len = len_subfrm;
605         n_subfr = num_subfr;
606       } else if (mode == 2) {
607         subfr_len = len_subfrm << 1;
608         n_subfr = num_subfr_in_superfr / 2;
609       } else if (mode == 3) {
610         subfr_len = len_subfrm << 2;
611         n_subfr = num_subfr_in_superfr;
612       } else {
613         if (usac_data->frame_ok == 0) {
614           mode = 3;
615           subfr_len = len_subfrm << 2;
616           n_subfr = num_subfr_in_superfr;
617         }
618       }
619 
620       ixheaacd_lpc_coef_gen(st->lspold, lsp_curr, lp_flt_coff_a, n_subfr,
621                             ORDER);
622 
623       err = ixheaacd_tcx_mdct(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
624                               subfr_len, st);
625       if (err) return err;
626       if (usac_data->frame_ok == 1 && k == 2) {
627         memcpy(usac_data->lp_flt_coff_a_ec, &lp_flt_coff_a[k * (ORDER + 1)],
628                sizeof(usac_data->lp_flt_coff_a_ec));
629       }
630       k += (1 << (mode - 1));
631     }
632 
633     st->mode_prev = mode;
634     if (usac_data->frame_ok == 0) {
635       memcpy(usac_data->lspold_ec, st->lspold, sizeof(st->lspold));
636     }
637     ixheaacd_mem_cpy(lsp_curr, st->lspold, ORDER);
638     ixheaacd_mem_cpy(lsf_curr, st->lsf_prev, ORDER);
639   }
640 
641   ixheaacd_mem_cpy(xcitation_buff + len_fr, st->xcitation_prev,
642                    MAX_PITCH + INTER_LP_FIL_ORDER + 1);
643 
644   ixheaacd_mem_cpy(synth_buf + len_fr, st->synth_prev, MAX_PITCH + synth_delay);
645 
646   if (!bpf_control_info) {
647     if (mod[0] != 0 && st->bpf_active_prev) {
648       for (i = 2; i < num_subfr_in_superfr; i++)
649         pitch_gain[num_subfr_by2 + i] = 0.0;
650     } else {
651       for (i = 0; i < num_subfr_in_superfr; i++)
652         pitch_gain[num_subfr_by2 + i] = 0.0;
653     }
654   }
655   st->bpf_active_prev = bpf_control_info;
656 
657   for (i = 0; i < num_subfr_by2; i++) {
658     st->pitch_prev[i] = pitch[num_subfr_in_superfr + i];
659     st->gain_prev[i] = pitch_gain[num_subfr_in_superfr + i];
660   }
661 
662   synth = synth_buf + MAX_PITCH;
663 
664   for (i = 0; i < num_subfr_in_superfr; i++) {
665     tp = pitch[i];
666     gain = pitch_gain[i];
667     if (gain > 0.0f) {
668       synth_corr = 0.0f, synth_energy = 1e-6f;
669       if ((((i * LEN_SUBFR) + LEN_SUBFR) > LEN_SUPERFRAME) ||
670           ((((i * LEN_SUBFR) + LEN_SUBFR) - tp) > LEN_SUPERFRAME)) {
671         if (usac_data->ec_flag) {
672           tp = LEN_SUPERFRAME - LEN_SUBFR - (i * LEN_SUBFR);
673         } else
674           return -1;
675       }
676       for (k = 0; k < LEN_SUBFR; k++) {
677         synth_corr +=
678             synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
679         synth_energy +=
680             synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
681       }
682       pitch_gain[i] = synth_corr / synth_energy;
683     }
684   }
685 
686   if (mod[3] == 0) {
687     err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr, synth_delay,
688                                     st->bpf_prev, usac_data->ec_flag);
689   } else {
690     err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr,
691                                     synth_delay - (len_subfrm / 2), st->bpf_prev,
692                                     usac_data->ec_flag);
693   }
694   if (err) return err;
695   if (usac_data->ec_flag && usac_data->frame_ok) {
696     memcpy(usac_data->lpc4_lsf, pstr_td_frame_data->lpc4_lsf, sizeof(usac_data->lpc4_lsf));
697     memcpy(usac_data->str_error_concealment[ch].lsf4, usac_data->lpc4_lsf,
698            sizeof(usac_data->lpc4_lsf));
699     memcpy(usac_data->lsf_adaptive_mean, pstr_td_frame_data->lsf_adaptive_mean_cand,
700            sizeof(usac_data->lsf_adaptive_mean));
701   }
702   return err;
703 }
704 
ixheaacd_lpd_dec_update(ia_usac_lpd_decoder_handle tddec,ia_usac_data_struct * usac_data,WORD32 i_ch)705 VOID ixheaacd_lpd_dec_update(ia_usac_lpd_decoder_handle tddec,
706                              ia_usac_data_struct *usac_data, WORD32 i_ch) {
707   WORD32 i, k;
708 
709   WORD32 *ptr_overlap = &usac_data->overlap_data_ptr[i_ch][0];
710   WORD32 len_fr, lpd_sbf_len, lpd_delay, num_subfr_by2, synth_delay, fac_length;
711 
712   if (usac_data->tw_mdct[0])
713     ptr_overlap = &usac_data->overlap_data_ptr[i_ch][usac_data->ccfl / 2];
714 
715   len_fr = usac_data->ccfl;
716   lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
717   lpd_delay = lpd_sbf_len * LEN_SUBFR;
718   num_subfr_by2 = lpd_sbf_len - 1;
719   synth_delay = num_subfr_by2 * LEN_SUBFR;
720   fac_length = (usac_data->len_subfrm) / 2;
721 
722   for (i = 0; i < LEN_SUBFR + synth_delay; i++)
723     ptr_overlap[i] = (WORD32)(
724         (FLOAT32)tddec->synth_prev[MAX_PITCH - (LEN_SUBFR) + i] * 16384.0);
725 
726   ptr_overlap += LEN_SUBFR + synth_delay - fac_length;
727 
728   for (k = 0; k < 2 * fac_length; k++)
729     ptr_overlap[k] = (WORD32)((FLOAT32)tddec->exc_prev[k + 1] * 16384.0);
730 
731   ptr_overlap = &usac_data->overlap_data_ptr[i_ch][lpd_delay + fac_length];
732 
733   for (i = 0; i < len_fr - lpd_delay - fac_length; i++) ptr_overlap[i] = 0;
734 
735   usac_data->window_shape[i_ch] = WIN_SEL_0;
736   usac_data->window_sequence_last[i_ch] = EIGHT_SHORT_SEQUENCE;
737   usac_data->td_frame_prev[i_ch] = 1;
738 
739   if (tddec->mode_prev == 0) {
740     memmove(usac_data->lpc_prev[i_ch], &tddec->lp_flt_coeff_a_prev[ORDER + 1],
741             (ORDER + 1) * sizeof(FLOAT32));
742     memmove(usac_data->acelp_in[i_ch], tddec->exc_prev,
743             (1 + (2 * FAC_LENGTH)) * sizeof(FLOAT32));
744   }
745 
746   return;
747 }
748 
ixheaacd_lpd_bpf_fix(ia_usac_data_struct * usac_data,WORD32 is_short_flag,FLOAT32 out_buffer[],ia_usac_lpd_decoder_handle st)749 WORD32 ixheaacd_lpd_bpf_fix(ia_usac_data_struct *usac_data,
750                             WORD32 is_short_flag, FLOAT32 out_buffer[],
751                             ia_usac_lpd_decoder_handle st) {
752   WORD32 i, tp, k;
753   float synth_buf[MAX_PITCH + SYNTH_DELAY_LMAX + LEN_SUPERFRAME];
754   float signal_out[LEN_SUPERFRAME];
755   float *synth, synth_corr, synth_energy;
756   WORD32 pitch[NUM_SUBFR_SUPERFRAME_BY2 + 3];
757   float pitch_gain[NUM_SUBFR_SUPERFRAME_BY2 + 3];
758   WORD32 len_fr, lpd_sbf_len, num_subfr_by2, synth_delay;
759   WORD32 err = 0;
760 
761   len_fr = usac_data->ccfl;
762   lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
763   num_subfr_by2 = lpd_sbf_len - 1;
764   synth_delay = num_subfr_by2 * LEN_SUBFR;
765 
766   ixheaacd_memset(synth_buf, MAX_PITCH + synth_delay + len_fr);
767   ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
768   ixheaacd_mem_cpy(out_buffer, synth_buf + MAX_PITCH - (LEN_SUBFR),
769                    synth_delay + len_fr + (LEN_SUBFR));
770 
771   for (i = 0; i < num_subfr_by2; i++) {
772     pitch[i] = st->pitch_prev[i];
773     pitch_gain[i] = st->gain_prev[i];
774   }
775   for (i = num_subfr_by2; i < lpd_sbf_len + 3; i++) {
776     pitch[i] = 64;
777     pitch_gain[i] = 0.0f;
778   }
779   if (st->mode_prev == 0) {
780     pitch[num_subfr_by2] = pitch[num_subfr_by2 - 1];
781     pitch_gain[num_subfr_by2] = pitch_gain[num_subfr_by2 - 1];
782     if (!is_short_flag) {
783       pitch[num_subfr_by2 + 1] = pitch[num_subfr_by2];
784       pitch_gain[num_subfr_by2 + 1] = pitch_gain[num_subfr_by2];
785     }
786   }
787 
788   synth = synth_buf + MAX_PITCH;
789 
790   for (i = 0; i < num_subfr_by2 + 2; i++) {
791     tp = pitch[i];
792     if ((i * LEN_SUBFR + MAX_PITCH) < tp) {
793       if (usac_data->ec_flag == 0)
794         return -1;
795       else {
796         tp = MAX_PITCH - (i * LEN_SUBFR);
797       }
798     } else if (((i * LEN_SUBFR + MAX_PITCH - tp) >= 1883) ||
799                (((i * LEN_SUBFR) + LEN_SUBFR) > LEN_SUPERFRAME) ||
800                ((((i * LEN_SUBFR) + LEN_SUBFR) - tp) > LEN_SUPERFRAME)) {
801       if (usac_data->ec_flag == 0)
802         return -1;
803       else {
804         tp = (i * LEN_SUBFR + MAX_PITCH - 1882);
805       }
806     }
807 
808     if (pitch_gain[i] > 0.0f) {
809       synth_corr = 0.0f, synth_energy = 1e-6f;
810       for (k = 0; k < LEN_SUBFR; k++) {
811         synth_corr +=
812             synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
813         synth_energy +=
814             synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
815       }
816       pitch_gain[i] = synth_corr / synth_energy;
817     }
818   }
819 
820   err = ixheaacd_bass_post_filter(
821       synth, pitch, pitch_gain, signal_out, (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR,
822       len_fr - (lpd_sbf_len + 4) * LEN_SUBFR, st->bpf_prev, usac_data->ec_flag);
823   if (err != 0) return err;
824 
825   ixheaacd_mem_cpy(signal_out, out_buffer,
826                    (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR);
827   return err;
828 }
829