xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_usac_ec.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 #include <string.h>
21 #include <ixheaac_type_def.h>
22 #include <ixheaac_constants.h>
23 #include <ixheaac_basic_ops32.h>
24 #include <ixheaac_basic_ops16.h>
25 #include <ixheaac_basic_ops40.h>
26 #include "ixheaacd_sbr_common.h"
27 #include "ixheaacd_intrinsics.h"
28 #include "ixheaacd_common_rom.h"
29 #include "ixheaacd_sbrdecsettings.h"
30 #include "ixheaacd_bitbuffer.h"
31 #include "ixheaacd_defines.h"
32 #include "ixheaacd_pns.h"
33 #include <ixheaacd_aac_rom.h>
34 #include "ixheaacd_pulsedata.h"
35 #include "ixheaacd_lt_predict.h"
36 #include "ixheaacd_cnst.h"
37 #include "ixheaacd_drc_data_struct.h"
38 #include "ixheaacd_ec_defines.h"
39 #include "ixheaacd_ec_rom.h"
40 #include "ixheaacd_ec_struct_def.h"
41 #include "ixheaacd_channelinfo.h"
42 #include "ixheaacd_interface.h"
43 #include "ixheaacd_acelp_info.h"
44 #include "ixheaacd_tns_usac.h"
45 #include "ixheaacd_info.h"
46 #include "ixheaacd_drc_dec.h"
47 #include "ixheaacd_sbrdecoder.h"
48 #include "ixheaacd_mps_polyphase.h"
49 #include "ixheaac_sbr_const.h"
50 #include "ixheaacd_ec_defines.h"
51 #include "ixheaacd_ec_struct_def.h"
52 #include "ixheaacd_main.h"
53 #include "ixheaacd_acelp_com.h"
54 
ixheaacd_usac_ec_get_win_seq(WORD32 prev_win_seq)55 static WORD32 ixheaacd_usac_ec_get_win_seq(WORD32 prev_win_seq) {
56   if (prev_win_seq == LONG_START_SEQUENCE || prev_win_seq == EIGHT_SHORT_SEQUENCE) {
57     return LONG_STOP_SEQUENCE;
58   } else {
59     return ONLY_LONG_SEQUENCE;
60   }
61 }
62 
ixheaacd_usac_flip_spec_sign(WORD32 * ptr_spec_coeff,WORD32 samples_per_frame,UWORD32 * seed_value)63 static VOID ixheaacd_usac_flip_spec_sign(WORD32 *ptr_spec_coeff, WORD32 samples_per_frame,
64                                          UWORD32 *seed_value) {
65   WORD32 i;
66   for (i = 0; i < samples_per_frame; i++) {
67     ptr_spec_coeff[i] = ixheaac_mult32x16in32_sat(ptr_spec_coeff[i],
68                             (WORD16)ixheaacd_randomsign(seed_value));
69   }
70 }
71 
iexheaace_ec_sfb_nrg_q(WORD32 * ptr_spectrum,ia_ec_sfb_str * pstr_ec_sfb,WORD32 win_seq,WORD32 win_trans,WORD32 * ptr_sfb_enrg)72 static VOID iexheaace_ec_sfb_nrg_q(WORD32 *ptr_spectrum, ia_ec_sfb_str *pstr_ec_sfb,
73                                    WORD32 win_seq, WORD32 win_trans, WORD32 *ptr_sfb_enrg) {
74   WORD16 *ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long;
75   WORD32 l = 0, sfb, num_sfb = pstr_ec_sfb->num_sfb_long;
76   switch (win_seq) {
77     case EIGHT_SHORT_SEQUENCE:
78       if (win_trans == NO_TRANSITION) {
79         num_sfb = pstr_ec_sfb->num_sfb_short;
80         ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_short;
81         for (sfb = 0; sfb < num_sfb; sfb++) {
82           WORD64 accu = (WORD64)1;
83           WORD32 q_nrg = (sizeof(accu) << 3) -
84                          ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
85           for (; l < ptr_sfb_offset[sfb + 1]; l++) {
86             accu += ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg);
87           }
88           ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
89         }
90       } else {
91         num_sfb = pstr_ec_sfb->num_sfb_long;
92         ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long;
93 
94         for (sfb = 0; sfb < num_sfb; sfb++) {
95           WORD64 accu = (WORD64)1;
96           WORD32 q_nrg = (sizeof(accu) << 3) -
97                          ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
98           for (; l < ptr_sfb_offset[sfb + 1]; l++) {
99             accu += ixheaac_mul32_sh(ptr_spectrum[(l >> 3)], ptr_spectrum[(l >> 3)], q_nrg);
100           }
101           ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
102         }
103       }
104       break;
105     case ONLY_LONG_SEQUENCE:
106     case LONG_START_SEQUENCE:
107     case LONG_STOP_SEQUENCE:
108       if (win_trans == NO_TRANSITION) {
109         num_sfb = pstr_ec_sfb->num_sfb_long;
110         ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long;
111 
112         for (sfb = 0; sfb < num_sfb; sfb++) {
113           WORD64 accu = (WORD64)1;
114           WORD32 q_nrg = (sizeof(accu) << 3) -
115                          ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
116           for (; l < ptr_sfb_offset[sfb + 1]; l++) {
117             accu += ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg);
118           }
119           ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
120         }
121       } else {
122         num_sfb = pstr_ec_sfb->num_sfb_short;
123         ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_short;
124 
125         for (sfb = 0; sfb < num_sfb; sfb++) {
126           WORD64 accu = (WORD64)1;
127           WORD32 q_nrg = (sizeof(accu) << 3) -
128                          ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
129           for (; l < ptr_sfb_offset[sfb + 1] << 3; l++) {
130             accu += (accu + (ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg))) >> 3;
131           }
132           ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
133         }
134       }
135       break;
136   }
137 }
138 
ixheaacd_usac_ec_interpolate(WORD32 * ptr_spectrum,WORD16 * pq_spec_coeff_prev,WORD16 * pq_spec_coeff_act,WORD16 * pq_spec_coeff_out,WORD32 * ptr_nrg_prev,WORD32 * ptr_nrg_act,WORD32 num_sfb,WORD16 * ptr_sfb_offset)139 static VOID ixheaacd_usac_ec_interpolate(WORD32 *ptr_spectrum, WORD16 *pq_spec_coeff_prev,
140                                          WORD16 *pq_spec_coeff_act, WORD16 *pq_spec_coeff_out,
141                                          WORD32 *ptr_nrg_prev, WORD32 *ptr_nrg_act,
142                                          WORD32 num_sfb, WORD16 *ptr_sfb_offset) {
143   WORD32 sfb, l = 0;
144   WORD32 fac_shift;
145   WORD32 fac_mod;
146 
147   for (sfb = 0; sfb < num_sfb; sfb++) {
148     fac_shift =
149         ptr_nrg_prev[sfb] - ptr_nrg_act[sfb] + ((*pq_spec_coeff_act - *pq_spec_coeff_prev) << 1);
150     fac_mod = fac_shift & 3;
151     fac_shift = (fac_shift >> 2) + 1;
152     fac_shift += *pq_spec_coeff_prev - ixheaac_max16(*pq_spec_coeff_prev, *pq_spec_coeff_act);
153     fac_shift = ixheaac_max32(ixheaac_min32(fac_shift, INT_BITS - 1), -(INT_BITS - 1));
154 
155     for (; l < ptr_sfb_offset[sfb + 1]; l++) {
156       WORD32 accu = ixheaac_shl32_sat(
157           ixheaac_mult32x32in32(ptr_spectrum[l], (WORD32)(ia_ec_interpolation_fac[fac_mod])), 1);
158       ptr_spectrum[l] = ixheaac_shl32_dir_sat((WORD32)accu, fac_shift);
159     }
160   }
161   *pq_spec_coeff_out = ixheaac_max16(*pq_spec_coeff_prev, *pq_spec_coeff_act);
162 }
163 
ixheaacd_usac_ec_interpolate_frame(ia_usac_data_struct * pstr_usac_data,ia_ec_state_str * pstr_ec_state,const ia_usac_samp_rate_info * pstr_samp_rate_info,WORD32 frame_ok,WORD32 chn)164 static VOID ixheaacd_usac_ec_interpolate_frame(ia_usac_data_struct *pstr_usac_data,
165                                                ia_ec_state_str *pstr_ec_state,
166                                                const ia_usac_samp_rate_info *pstr_samp_rate_info,
167                                                WORD32 frame_ok, WORD32 chn) {
168   WORD32 frame_length = pstr_usac_data->ccfl;
169   WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[chn];
170   WORD16 *ptr_spec_sf = pstr_usac_data->spec_scale[chn];
171 
172   WORD32 i;
173   ia_ec_scratch_str *pstr_ec_scratch = pstr_ec_state->pstr_ec_scratch;
174   WORD16 num_sfb_long;
175   WORD16 *ptr_sfb_long = NULL;
176   WORD16 num_sfb_short;
177   WORD16 *ptr_sfb_short = NULL;
178 
179   if (pstr_usac_data->core_mode == CORE_MODE_FD) {
180     num_sfb_long = pstr_samp_rate_info->num_sfb_1024;
181     ptr_sfb_long = (WORD16 *)pstr_samp_rate_info->ptr_sfb_1024;
182     num_sfb_short = pstr_samp_rate_info->num_sfb_128;
183     ptr_sfb_short = (WORD16 *)pstr_samp_rate_info->ptr_sfb_128;
184     if (pstr_usac_data->ccfl == WIN_LEN_768) {
185       num_sfb_long = pstr_samp_rate_info->num_sfb_768;
186       ptr_sfb_long = (WORD16 *)pstr_samp_rate_info->ptr_sfb_768;
187       num_sfb_short = pstr_samp_rate_info->num_sfb_96;
188       ptr_sfb_short = (WORD16 *)pstr_samp_rate_info->ptr_sfb_96;
189     }
190     pstr_ec_state->str_ec_sfb.num_sfb_long = num_sfb_long;
191     pstr_ec_state->str_ec_sfb.num_sfb_long = num_sfb_long;
192     pstr_ec_state->str_ec_sfb.ptr_sfb_long = ptr_sfb_long;
193     pstr_ec_state->str_ec_sfb.ptr_sfb_long = ptr_sfb_long;
194 
195     memset(pstr_ec_scratch->prev_sfb_nrg, 0, sizeof(pstr_ec_scratch->prev_sfb_nrg));
196     memset(pstr_ec_scratch->pres_sfb_nrg, 0, sizeof(pstr_ec_scratch->pres_sfb_nrg));
197 
198     if (!frame_ok) {
199       pstr_usac_data->window_shape[chn] = pstr_ec_state->win_shape;
200       pstr_usac_data->window_sequence[chn] = pstr_ec_state->win_seq;
201       memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff,
202              sizeof(*ptr_spec_coeff) * frame_length);
203       memcpy(ptr_spec_sf, pstr_ec_state->q_spec_coeff, sizeof(pstr_ec_state->q_spec_coeff));
204     }
205   }
206 
207   if (!pstr_ec_state->prev_frame_ok[1]) {
208     if (frame_ok && pstr_ec_state->prev_frame_ok[0] &&
209         pstr_usac_data->core_mode == CORE_MODE_FD) {
210       if (pstr_usac_data->window_sequence[chn] == EIGHT_SHORT_SEQUENCE) {
211         WORD32 wnd;
212 
213         if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) {
214           WORD32 num_sfb = num_sfb_short;
215           WORD16 *ptr_sfb_offset = ptr_sfb_short;
216           pstr_usac_data->window_shape[chn] = 1;
217           pstr_usac_data->window_sequence[chn] = EIGHT_SHORT_SEQUENCE;
218 
219           for (wnd = 0; wnd < 8; wnd++) {
220             iexheaace_ec_sfb_nrg_q(&ptr_spec_coeff[wnd * (frame_length >> 3)],
221                                    &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE,
222                                    NO_TRANSITION, pstr_ec_scratch->prev_sfb_nrg);
223 
224             iexheaace_ec_sfb_nrg_q(&pstr_ec_state->spectral_coeff[wnd * (frame_length >> 3)],
225                                    &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE,
226                                    NO_TRANSITION, pstr_ec_scratch->pres_sfb_nrg);
227 
228             ixheaacd_usac_ec_interpolate(&ptr_spec_coeff[wnd * (frame_length / 8)],
229                                          &ptr_spec_sf[wnd], &pstr_ec_state->q_spec_coeff[wnd],
230                                          &ptr_spec_sf[wnd], pstr_ec_scratch->prev_sfb_nrg,
231                                          pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset);
232           }
233         } else {
234           WORD32 num_sfb = num_sfb_long;
235           WORD16 *ptr_sfb_offset = ptr_sfb_long;
236           WORD16 q_spec_coeff_out;
237 
238           iexheaace_ec_sfb_nrg_q(&ptr_spec_coeff[frame_length - (frame_length >> 3)],
239                                  &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE,
240                                  TRANS_SHORT_LONG, pstr_ec_scratch->pres_sfb_nrg);
241 
242           iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb,
243                                  ONLY_LONG_SEQUENCE, NO_TRANSITION,
244                                  pstr_ec_scratch->prev_sfb_nrg);
245 
246           pstr_usac_data->window_shape[chn] = 0;
247           pstr_usac_data->window_sequence[chn] = LONG_STOP_SEQUENCE;
248           memcpy(&ptr_spec_coeff[0], pstr_ec_state->spectral_coeff,
249                  frame_length * sizeof(ptr_spec_coeff[0]));
250 
251           for (i = 0; i < 8; i++) {
252             if (ptr_spec_sf[i] > ptr_spec_sf[0]) {
253               ptr_spec_sf[0] = ptr_spec_sf[i];
254             }
255           }
256 
257           ixheaacd_usac_ec_interpolate(ptr_spec_coeff, &pstr_ec_state->q_spec_coeff[0],
258                                        &ptr_spec_sf[0], &q_spec_coeff_out,
259                                        pstr_ec_scratch->prev_sfb_nrg,
260                                        pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset);
261 
262           ptr_spec_sf[0] = q_spec_coeff_out;
263         }
264       } else {
265         WORD32 num_sfb = num_sfb_long;
266         WORD16 *ptr_sfb_offset = ptr_sfb_long;
267         WORD16 q_spec_coeff_act = pstr_ec_state->q_spec_coeff[0];
268 
269         iexheaace_ec_sfb_nrg_q(ptr_spec_coeff, &pstr_ec_state->str_ec_sfb, ONLY_LONG_SEQUENCE,
270                                NO_TRANSITION, pstr_ec_scratch->prev_sfb_nrg);
271 
272         if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) {
273           pstr_usac_data->window_shape[chn] = 1;
274           pstr_usac_data->window_sequence[chn] = LONG_START_SEQUENCE;
275 
276           for (i = 1; i < 8; i++) {
277             if (pstr_ec_state->q_spec_coeff[i] > q_spec_coeff_act) {
278               q_spec_coeff_act = pstr_ec_state->q_spec_coeff[i];
279             }
280           }
281 
282           iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb,
283                                  EIGHT_SHORT_SEQUENCE, TRANS_SHORT_LONG,
284                                  pstr_ec_scratch->pres_sfb_nrg);
285         } else {
286           pstr_usac_data->window_shape[chn] = 0;
287           pstr_usac_data->window_sequence[chn] = ONLY_LONG_SEQUENCE;
288           iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb,
289                                  ONLY_LONG_SEQUENCE, NO_TRANSITION,
290                                  pstr_ec_scratch->pres_sfb_nrg);
291         }
292         ixheaacd_usac_ec_interpolate(ptr_spec_coeff, &ptr_spec_sf[0], &q_spec_coeff_act,
293                                      &ptr_spec_sf[0], pstr_ec_scratch->prev_sfb_nrg,
294                                      pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset);
295       }
296     }
297     ixheaacd_usac_flip_spec_sign(ptr_spec_coeff, frame_length, &pstr_usac_data->seed_value[chn]);
298   }
299 
300   if (FRAME_MUTE == pstr_ec_state->conceal_state) {
301     pstr_usac_data->window_shape[chn] = pstr_ec_state->win_shape;
302     pstr_usac_data->window_sequence[chn] = ixheaacd_usac_ec_get_win_seq(pstr_ec_state->win_seq);
303     pstr_ec_state->win_seq = pstr_usac_data->window_sequence[chn];
304     memset(ptr_spec_coeff, 0, frame_length * sizeof(ptr_spec_coeff[0]));
305   }
306 
307   return;
308 }
309 
ixheaacd_usac_lpc_ec_state(ia_ec_state_str * pstr_ec_state,WORD32 frame_ok)310 static VOID ixheaacd_usac_lpc_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_ok) {
311   if (frame_ok == 0) {
312     if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) {
313       pstr_ec_state->fade_idx++;
314     }
315     pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE;
316   } else {
317     if (pstr_ec_state->fade_idx > 0) {
318       pstr_ec_state->fade_idx--;
319     }
320     pstr_ec_state->conceal_state = FRAME_OKAY;
321   }
322   if (pstr_ec_state->fade_idx >= MAX_FADE_FRAMES) {
323     pstr_ec_state->fade_idx = MAX_FADE_FRAMES;
324     pstr_ec_state->conceal_state = FRAME_MUTE;
325   }
326   if (pstr_ec_state->fade_idx < 0) {
327     pstr_ec_state->fade_idx = 0;
328   }
329   return;
330 }
331 
ixheaacd_usac_ec_state(ia_ec_state_str * pstr_ec_state,WORD32 frame_ok)332 static VOID ixheaacd_usac_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_ok) {
333   WORD32 ec_state_val = (pstr_ec_state->prev_frame_ok[0] << 2) +
334                         (pstr_ec_state->prev_frame_ok[1] << 1) + (frame_ok);
335 
336   switch (ec_state_val) {
337     case 0:
338     case 4:
339       if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) {
340         pstr_ec_state->fade_idx++;
341       }
342       pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE;
343       break;
344     case 1:
345     case 2:
346       if (pstr_ec_state->fade_idx > 0) {
347         pstr_ec_state->fade_idx--;
348       }
349       pstr_ec_state->conceal_state = FRAME_FADE;
350       break;
351     case 5:
352       if (pstr_ec_state->fade_idx > 0) {
353         pstr_ec_state->fade_idx--;
354       }
355       pstr_ec_state->conceal_state = FRAME_OKAY;
356       break;
357       break;
358     case 3:
359     case 6:
360     case 7:
361       if (pstr_ec_state->fade_idx > 0) {
362         pstr_ec_state->fade_idx--;
363       }
364       pstr_ec_state->conceal_state = FRAME_OKAY;
365       break;
366     default:
367       pstr_ec_state->conceal_state = FRAME_OKAY;
368   }
369   if (pstr_ec_state->fade_idx > MAX_FADE_FRAMES) {
370     pstr_ec_state->fade_idx = MAX_FADE_FRAMES;
371   }
372   if (pstr_ec_state->fade_idx == MAX_FADE_FRAMES) {
373     pstr_ec_state->conceal_state = FRAME_MUTE;
374   }
375   if (pstr_ec_state->fade_idx < 0) {
376     pstr_ec_state->fade_idx = 0;
377   }
378 }
379 
ixheaacd_usac_ec_init(ia_ec_state_str * pstr_ec_state,WORD32 core_coder_mode)380 VOID ixheaacd_usac_ec_init(ia_ec_state_str *pstr_ec_state, WORD32 core_coder_mode) {
381   pstr_ec_state->win_shape = 1;
382   pstr_ec_state->win_seq = ONLY_LONG_SEQUENCE;
383   pstr_ec_state->prev_win_group_len = 1;
384 
385   pstr_ec_state->conceal_state = FRAME_OKAY;
386 
387   memset(pstr_ec_state->spectral_coeff, 0, sizeof(pstr_ec_state->spectral_coeff));
388   memset(pstr_ec_state->q_spec_coeff, 0, sizeof(pstr_ec_state->q_spec_coeff));
389 
390   pstr_ec_state->prev_frame_ok[0] = 1;
391   pstr_ec_state->prev_frame_ok[1] = 1;
392 
393   pstr_ec_state->fade_idx = 0;
394 
395   pstr_ec_state->prev_core_mode = core_coder_mode;
396 }
397 
ixheaacd_usac_lpc_ec(FLOAT32 lsp[][ORDER],FLOAT32 * lpc4_lsf,FLOAT32 * lsf_adaptive_mean,const WORD32 first_lpd_flag)398 VOID ixheaacd_usac_lpc_ec(FLOAT32 lsp[][ORDER], FLOAT32 *lpc4_lsf, FLOAT32 *lsf_adaptive_mean,
399                           const WORD32 first_lpd_flag) {
400   WORD32 i, j;
401 
402   if (first_lpd_flag) {
403     memcpy(lsp[0], lsf_init, sizeof(lsf_init));
404     memcpy(lpc4_lsf, lsf_init, sizeof(lsf_init));
405   } else {
406     memcpy(lsp[0], lpc4_lsf, ORDER * sizeof(lpc4_lsf[0]));
407   }
408 
409   for (i = 0; i < ORDER; i++) {
410     FLOAT32 lsf_mean = (BETA * lsf_init[i]) + (ONE_BETA * lsf_adaptive_mean[i]);
411     lsp[1][i] = (BFI_FAC * lpc4_lsf[i]) + (ONE_BFI_FAC * lsf_mean);
412   }
413 
414   for (j = 2; j <= 4; j++) {
415     for (i = 0; i < ORDER; i++) {
416       FLOAT32 lsf_mean = ((BETA + (j * ONE_BFI_FAC)) * lsf_init[i]) +
417                          ((ONE_BETA - (j * ONE_BFI_FAC)) * lsf_adaptive_mean[i]);
418       lsp[j][i] = (BFI_FAC * lsp[j - 1][i]) + (ONE_BFI_FAC * lsf_mean);
419     }
420   }
421 
422   memcpy(lpc4_lsf, lsp[4], ORDER * sizeof(lpc4_lsf[0]));
423 }
424 
ixheaacd_usac_ec_save_states(ia_ec_state_str * pstr_ec_state,ia_usac_data_struct * pstr_usac_data,WORD32 ch)425 VOID ixheaacd_usac_ec_save_states(ia_ec_state_str *pstr_ec_state,
426                                   ia_usac_data_struct *pstr_usac_data, WORD32 ch) {
427   if (pstr_usac_data->core_mode == CORE_MODE_FD &&
428       (pstr_usac_data->frame_ok == 1 && pstr_ec_state->prev_frame_ok[1] == 1)) {
429     WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[ch];
430     WORD16 *ptr_spec_scale = pstr_usac_data->spec_scale[ch];
431     WORD16 q_spec_coeff[MAX_SPEC_SCALE_LEN_EC];
432     UWORD8 win_shape = pstr_ec_state->win_shape;
433     UWORD8 win_shape_prev = pstr_ec_state->win_shape_prev;
434     WORD32 win_seq = pstr_ec_state->win_seq;
435     WORD32 td_frame_prev = pstr_ec_state->td_frame_prev;
436     WORD32 fac_data_present = pstr_ec_state->fac_data_present;
437 
438     ia_sfb_info_struct *sfb_info =
439         pstr_usac_data->pstr_usac_winmap[pstr_usac_data->window_sequence[ch]];
440     WORD32 *ptr_scratch_buf = &pstr_ec_state->pstr_ec_scratch->spec_coeff[0];
441 
442     memcpy(q_spec_coeff, pstr_ec_state->q_spec_coeff, sizeof(q_spec_coeff));
443     pstr_ec_state->win_seq = pstr_usac_data->window_sequence[ch];
444     pstr_ec_state->win_shape = pstr_usac_data->window_shape[ch];
445     pstr_ec_state->td_frame_prev = pstr_usac_data->td_frame_prev[ch];
446     pstr_ec_state->fac_data_present = pstr_usac_data->fac_data_present[ch];
447     pstr_ec_state->win_shape_prev = pstr_usac_data->window_shape_prev[ch];
448     pstr_ec_state->prev_win_group_len = (WORD32)sfb_info->group_len[sfb_info->num_groups - 1];
449 
450     memcpy(pstr_ec_state->q_spec_coeff, ptr_spec_scale, sizeof(pstr_ec_state->q_spec_coeff));
451 
452     memcpy(ptr_scratch_buf, ptr_spec_coeff, pstr_usac_data->ccfl * sizeof(ptr_scratch_buf[0]));
453     memcpy(ptr_spec_coeff, &pstr_ec_state->spectral_coeff[0],
454            pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
455     memcpy(&pstr_ec_state->spectral_coeff[0], ptr_scratch_buf,
456            pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
457 
458     if (!pstr_usac_data->first_frame) {
459       pstr_usac_data->window_sequence[ch] = win_seq;
460       pstr_usac_data->window_shape[ch] = win_shape;
461       pstr_usac_data->td_frame_prev_ec[ch] = td_frame_prev;
462       pstr_usac_data->fac_data_present[ch] = fac_data_present;
463       pstr_usac_data->window_shape_prev[ch] = win_shape_prev;
464     }
465 
466     memcpy(ptr_spec_scale, q_spec_coeff, sizeof(q_spec_coeff));
467   }
468 }
469 
ixheaacd_usac_apply_ec(ia_usac_data_struct * pstr_usac_data,const ia_usac_samp_rate_info * pstr_samp_rate_info,WORD32 ch)470 VOID ixheaacd_usac_apply_ec(ia_usac_data_struct *pstr_usac_data,
471                             const ia_usac_samp_rate_info *pstr_samp_rate_info, WORD32 ch) {
472   WORD32 frame_ok = pstr_usac_data->frame_ok;
473   ia_ec_state_str *pstr_ec_state = &pstr_usac_data->str_error_concealment[ch];
474 
475   if (pstr_usac_data->core_mode == CORE_MODE_FD) {
476     if (pstr_ec_state->win_shape == (UWORD8)-1) {
477       pstr_ec_state->win_shape = pstr_usac_data->window_shape[ch];
478     }
479 
480     ixheaacd_usac_ec_state(pstr_ec_state, frame_ok);
481 
482     if (pstr_ec_state->conceal_state == FRAME_OKAY) {
483       pstr_ec_state->prev_core_mode = pstr_usac_data->core_mode;
484       ixheaacd_usac_ec_save_states(pstr_ec_state, pstr_usac_data, ch);
485     } else if (pstr_ec_state->conceal_state == FRAME_CONCEAL_SINGLE) {
486       ixheaacd_usac_ec_interpolate_frame(pstr_usac_data, pstr_ec_state, pstr_samp_rate_info,
487                                          frame_ok, ch);
488     } else {
489     }
490     if (!frame_ok) {
491       WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[ch];
492       WORD16 *ptr_spec_scale = pstr_usac_data->spec_scale[ch];
493 
494       pstr_usac_data->window_sequence[ch] = pstr_ec_state->win_seq;
495       pstr_usac_data->window_shape[ch] = pstr_ec_state->win_shape;
496 
497       if (pstr_ec_state->conceal_state != FRAME_MUTE) {
498         memcpy(ptr_spec_scale, pstr_ec_state->q_spec_coeff, sizeof(pstr_ec_state->q_spec_coeff));
499         memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff,
500                sizeof(pstr_ec_state->spectral_coeff));
501       } else {
502         memset(ptr_spec_scale, 0, MAX_SPEC_SCALE_LEN * sizeof(ptr_spec_scale[0]));
503         memset(ptr_spec_coeff, 0, pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
504       }
505     }
506   } else {
507     ixheaacd_usac_lpc_ec_state(pstr_ec_state, frame_ok);
508 
509     if (pstr_ec_state->conceal_state == FRAME_OKAY) {
510       memcpy(pstr_ec_state->lsf4, pstr_usac_data->lpc4_lsf, sizeof(pstr_ec_state->lsf4));
511     } else if (pstr_ec_state->conceal_state == FRAME_CONCEAL_SINGLE) {
512       WORD32 frame_length = pstr_usac_data->ccfl;
513       WORD32 *ptr_spec_coeff = pstr_usac_data->tcx_spec_coeffs[ch];
514 
515       ixheaacd_usac_flip_spec_sign(ptr_spec_coeff, frame_length,
516                                    &pstr_usac_data->seed_value[ch]);
517     } else {
518       WORD32 *ptr_spec_coeff = pstr_usac_data->tcx_spec_coeffs[ch];
519       memset(ptr_spec_coeff, 0, pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
520     }
521     if (!frame_ok) {
522       memcpy(pstr_usac_data->lpc4_lsf, pstr_ec_state->lsf4, sizeof(pstr_usac_data->lpc4_lsf));
523     }
524   }
525 
526   pstr_ec_state->prev_frame_ok[0] = pstr_ec_state->prev_frame_ok[1];
527   pstr_ec_state->prev_frame_ok[1] = frame_ok;
528 
529   return;
530 }
531 
ixheaacd_lpc_wt_tool(FLOAT32 a[],WORD32 l)532 static VOID ixheaacd_lpc_wt_tool(FLOAT32 a[], WORD32 l) {
533   WORD32 i;
534 
535   for (i = 0; i < l; i++) {
536     a[i] = a[i] * ixheaacd_gamma_table[i];
537   }
538 
539   return;
540 }
ixheaacd_lpc_coef_gen_ec(FLOAT32 lsf_old[],FLOAT32 lsf_new[],FLOAT32 a[],WORD32 m)541 static VOID ixheaacd_lpc_coef_gen_ec(FLOAT32 lsf_old[], FLOAT32 lsf_new[], FLOAT32 a[],
542                                      WORD32 m) {
543   FLOAT32 lsf[ORDER], *ptr_a;
544   FLOAT32 inc, fnew, fold;
545   WORD32 i;
546 
547   ptr_a = a;
548 
549   inc = 1.0f / (FLOAT32)m;
550   fnew = 0.5f - (0.5f * inc);
551   fold = 1.0f - fnew;
552 
553   for (i = 0; i < ORDER; i++) {
554     lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew);
555   }
556   ixheaacd_lsp_to_lp_conversion(lsf, ptr_a);
557 
558   return;
559 }
560 
ixheaacd_usac_tcx_ec(ia_usac_data_struct * pstr_usac_data,ia_usac_lpd_decoder_handle st,FLOAT32 * ptr_lsp_curr,WORD32 frame_idx,FLOAT32 * lp_flt_coff_a)561 VOID ixheaacd_usac_tcx_ec(ia_usac_data_struct *pstr_usac_data, ia_usac_lpd_decoder_handle st,
562                           FLOAT32 *ptr_lsp_curr, WORD32 frame_idx, FLOAT32 *lp_flt_coff_a) {
563   WORD32 ch = pstr_usac_data->present_chan;
564   FLOAT32 synth_buf[ORDER + LEN_FRAME], temp;
565   FLOAT32 exc_buf[MAX_PITCH + ORDER + 1 + LEN_FRAME];
566   FLOAT32 *ptr_syn = synth_buf + ORDER;
567   FLOAT32 *ptr_exc = exc_buf + MAX_PITCH + ORDER + 1;
568   FLOAT32 est_fac_est = 0.1f;
569   WORD32 i, sf_idx;
570   FLOAT32 synth_sig_buf[LEN_SUBFR + 1];
571   FLOAT32 *synth_signal = synth_sig_buf + 1;
572   WORD32 num_lost_frames = pstr_usac_data->num_lost_lpd_frames[ch];
573   WORD32 len_subfrm = pstr_usac_data->len_subfrm;
574   FLOAT32 past_tcx_gain = pstr_usac_data->past_gain_tcx[ch];
575   WORD32 l_div_part = MAX_PITCH + ORDER + 1 - len_subfrm;
576   FLOAT32 *synth = pstr_usac_data->synth_buf + MAX_PITCH - LEN_SUBFR;
577   FLOAT32 *ptr_synth = &synth[512 + frame_idx * len_subfrm];
578   FLOAT32 syn_buf[MAX_PITCH + ORDER + 1];
579   FLOAT32 *ptr_syn_buf = &syn_buf[ORDER];
580 
581   memcpy(syn_buf, &ptr_synth[-(MAX_PITCH + ORDER + 1)],
582          sizeof(syn_buf));
583   memcpy(st->synth_prev_ec, &syn_buf[MAX_PITCH + 1], sizeof(st->synth_prev_ec));
584   ixheaacd_residual_tool_float(pstr_usac_data->lp_flt_coff_a_ec, ptr_syn_buf, st->xcitation_prev,
585                                pstr_usac_data->len_subfrm, 1);
586   ixheaacd_residual_tool_float(lp_flt_coff_a, &syn_buf[l_div_part],
587                                st->xcitation_prev + l_div_part, pstr_usac_data->len_subfrm, 1);
588   if (st->last_tcx_pitch > MAX_PITCH) {
589     st->last_tcx_pitch = MAX_PITCH;
590   }
591 
592   memcpy(synth_buf, st->synth_prev_ec, ORDER * sizeof(FLOAT32));
593   memcpy(exc_buf, st->xcitation_prev, (MAX_PITCH + ORDER + 1) * sizeof(FLOAT32));
594 
595   if (num_lost_frames <= 8) {
596     est_fac_est = ixheaacd_exc_fade_fac[num_lost_frames - 1];
597   }
598 
599   for (i = 0; i < len_subfrm; i++) {
600     ptr_exc[i] = est_fac_est * ptr_exc[i - st->last_tcx_pitch];
601   }
602   synth_signal[-1] = ptr_exc[-1];
603 
604   for (sf_idx = 0; sf_idx < len_subfrm; sf_idx += LEN_SUBFR) {
605     FLOAT32 lp_coef[ORDER + 1];
606 
607     ixheaacd_lpc_coef_gen_ec(st->lspold, ptr_lsp_curr, lp_coef, len_subfrm / LEN_SUBFR);
608 
609     ixheaacd_synthesis_tool_float(lp_coef, &ptr_exc[sf_idx], &ptr_syn[sf_idx], LEN_SUBFR,
610                                   synth_buf);
611 
612     ixheaacd_lpc_wt_tool(lp_coef, ORDER);
613 
614     ixheaacd_residual_tool_float(lp_coef, &ptr_syn[sf_idx], synth_signal, LEN_SUBFR, 1);
615 
616     ixheaacd_deemphsis_tool(synth_signal, LEN_SUBFR, synth_signal[-1]);
617 
618     temp = (est_fac_est * past_tcx_gain);
619 
620     for (i = 0; i < LEN_SUBFR; i++) {
621       if (synth_signal[i] > temp) {
622         synth_signal[i] = temp;
623       } else {
624         if (synth_signal[i] < -temp) {
625           synth_signal[i] = -temp;
626         }
627       }
628     }
629 
630     for (i = LEN_SUBFR - 1; i >= 0; i--) {
631       synth_signal[i] = (synth_signal[i] - (PREEMPH_FILT_FAC * synth_signal[i - 1]));
632     }
633     ixheaacd_synthesis_tool_float(lp_coef, synth_signal, &ptr_syn[sf_idx], LEN_SUBFR, synth_buf);
634 
635     memmove(&ptr_synth[sf_idx], &ptr_syn[sf_idx], LEN_SUBFR * sizeof(FLOAT32));
636   }
637 
638   memcpy(st->xcitation_prev, ptr_exc + len_subfrm - (MAX_PITCH + ORDER + 1),
639          sizeof(FLOAT32) * (MAX_PITCH + ORDER + 1));
640   memcpy(st->synth_prev_ec, synth_buf + len_subfrm, sizeof(FLOAT32) * ORDER);
641   return;
642 }
643