xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_ext_ch_ele.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 <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <setjmp.h>
24 
25 #include "ixheaac_type_def.h"
26 
27 #include "ixheaacd_cnst.h"
28 
29 #include "ixheaacd_bitbuffer.h"
30 
31 #include "ixheaacd_interface.h"
32 #include "ixheaacd_acelp_info.h"
33 
34 #include "ixheaacd_tns_usac.h"
35 #include "ixheaacd_acelp_info.h"
36 
37 #include "ixheaacd_sbrdecsettings.h"
38 #include "ixheaacd_info.h"
39 #include "ixheaacd_sbr_common.h"
40 #include "ixheaacd_drc_data_struct.h"
41 #include "ixheaacd_drc_dec.h"
42 
43 #include "ixheaacd_sbrdecoder.h"
44 #include "ixheaacd_mps_polyphase.h"
45 #include "ixheaac_sbr_const.h"
46 
47 #include "ixheaacd_ec_defines.h"
48 #include "ixheaacd_ec_rom.h"
49 #include "ixheaacd_ec_struct_def.h"
50 #include "ixheaacd_main.h"
51 #include "ixheaacd_arith_dec.h"
52 #include "ixheaacd_tns_usac.h"
53 
54 #include "ixheaacd_bit_extract.h"
55 
56 #include "ixheaac_constants.h"
57 #include "ixheaac_basic_ops32.h"
58 #include "ixheaac_basic_ops40.h"
59 
60 #include "ixheaacd_func_def.h"
61 
62 #include "ixheaacd_defines.h"
63 #include "ixheaacd_windows.h"
64 
65 #include "ixheaacd_vec_baisc_ops.h"
66 #include "ixheaacd_config.h"
67 #include "ixheaacd_defines.h"
68 #include "ixheaacd_aac_rom.h"
69 #include "ixheaacd_pulsedata.h"
70 #include "ixheaacd_pns.h"
71 #include "ixheaacd_channelinfo.h"
72 #include "ixheaacd_ec.h"
73 #include "ixheaacd_error_codes.h"
74 
75 const WORD16 ixheaacd_mdst_fcoeff_long_sin[] = {0, 0, -16384, 0, 16384, 0, 0};
76 const WORD16 ixheaacd_mdst_fcoeff_long_kbd[] = {-2998, 0, -19052, 0,
77                                                 19052, 0, 2998};
78 const WORD16 ixheaacd_mdst_fcoeff_long_sin_kbd[] = {-1499, -1876, -17718, 0,
79                                                     17718, 1876,  1499};
80 const WORD16 ixheaacd_mdst_fcoeff_long_kbd_sin[] = {-1499, 1876,  -17718, 0,
81                                                     17718, -1876, 1499};
82 
83 const WORD16 *const ixheaacd_mdst_fcoeff_longshort_curr[2][2] = {
84     {ixheaacd_mdst_fcoeff_long_sin, ixheaacd_mdst_fcoeff_long_sin_kbd},
85     {ixheaacd_mdst_fcoeff_long_kbd_sin, ixheaacd_mdst_fcoeff_long_kbd}};
86 
87 const WORD16 ixheaacd_mdst_fcoeff_start_sin[] = {-3364, -3401, -18584, 0,
88                                                  18584, 3401,  3364};
89 const WORD16 ixheaacd_mdst_fcoeff_start_kbd[] = {-4932, -1572, -19942, 0,
90                                                  19942, 1572,  4932};
91 const WORD16 ixheaacd_mdst_fcoeff_start_sin_kbd[] = {-3433, -3447, -18608, 0,
92                                                      18608, 3447,  3433};
93 const WORD16 ixheaacd_mdst_fcoeff_start_kbd_sin[] = {-4863, -1525, -19918, 0,
94                                                      19918, 1525,  4863};
95 
96 const WORD16 *const ixheaacd_mdst_fcoeff_start_curr[2][2] = {
97     {ixheaacd_mdst_fcoeff_start_sin, ixheaacd_mdst_fcoeff_start_sin_kbd},
98     {ixheaacd_mdst_fcoeff_start_kbd_sin, ixheaacd_mdst_fcoeff_start_kbd}};
99 
100 const WORD16 ixheaacd_mdst_fcoeff_stop_sin[] = {-3364, 3401,  -18584, 0,
101                                                 18584, -3401, 3364};
102 const WORD16 ixheaacd_mdst_fcoeff_stop_kbd[] = {-4932, 1572,  -19942, 0,
103                                                 19942, -1572, 4932};
104 const WORD16 ixheaacd_mdst_fcoeff_stop_sin_kbd[] = {-4863, 1525,  -19918, 0,
105                                                     19918, -1525, 4863};
106 const WORD16 ixheaacd_mdst_fcoeff_stop_kbd_sin[] = {-3433, 3447,  -18608, 0,
107                                                     18608, -3447, 3433};
108 
109 const WORD16 *const ixheaacd_mdst_fcoeff_stop_cur[2][2] = {
110     {ixheaacd_mdst_fcoeff_stop_sin, ixheaacd_mdst_fcoeff_stop_sin_kbd},
111     {ixheaacd_mdst_fcoeff_stop_kbd_sin, ixheaacd_mdst_fcoeff_stop_kbd}};
112 
113 const WORD16 ixheaacd_mdst_fcoeff_stopstart_sin[] = {-6728, 0, -20785, 0,
114                                                      20785, 0, 6728};
115 const WORD16 ixheaacd_mdst_fcoeff_stopstart_kbd[] = {-6866, -0, -20831, 0,
116                                                      20831, 0,  6866};
117 const WORD16 ixheaacd_mdst_fcoeff_stopstart_sin_kbd[] = {-6797, -46, -20808, 0,
118                                                          20808, 46,  6797};
119 const WORD16 ixheaacd_mdst_fcoeff_stopstart_kbd_sin[] = {-6797, 46, -20808, 0,
120                                                          20808, 46, 6797};
121 
122 const WORD16 *const ixheaacd_mdst_fcoeff_stopstart_cur[2][2] = {
123     {ixheaacd_mdst_fcoeff_stopstart_sin,
124      ixheaacd_mdst_fcoeff_stopstart_sin_kbd},
125     {ixheaacd_mdst_fcoeff_stopstart_kbd_sin,
126      ixheaacd_mdst_fcoeff_stopstart_kbd}};
127 
128 const WORD16 ixheaacd_mdst_fcoeff_l_s_start_left_sin[] = {
129     -0, 3477, 8192, 10430, 8192, 3477, -0};
130 const WORD16 ixheaacd_mdst_fcoeff_l_s_start_left_kbd[] = {
131     1950, 4054, 6114, 6982, 6114, 4054, 1950};
132 
133 const WORD16 ixheaacd_mdst_fcoeff_stop_stopstart_left_sin[] = {
134     1262, 1285, 1299, 1304, 1299, 1285, 1262};
135 const WORD16 ixheaacd_mdst_fcoeff_stop_stopstart_left_kbd[] = {
136     857, 866, 871, 873, 871, 866, 857};
137 
138 const WORD16 *const ixheaacd_mdst_fcoeff_l_s_start_left_prev[2] = {
139     ixheaacd_mdst_fcoeff_l_s_start_left_sin,
140     ixheaacd_mdst_fcoeff_l_s_start_left_kbd};
141 const WORD16 *const ixheaacd_mdst_fcoeff_stop_stopstart_left_prev[2] = {
142     ixheaacd_mdst_fcoeff_stop_stopstart_left_sin,
143     ixheaacd_mdst_fcoeff_stop_stopstart_left_kbd};
144 
145 #define ONE_BY_TWO_POW_14 0.00006103515625
146 #define ONE_BY_TWO_POW_15 0.000030517578125
147 
ixheaacd_usac_cplx_save_prev(ia_sfb_info_struct * info,WORD32 * l_spec,WORD32 * r_spec,WORD32 * l_spec_prev,WORD32 * r_spec_prev)148 void ixheaacd_usac_cplx_save_prev(ia_sfb_info_struct *info, WORD32 *l_spec,
149                                   WORD32 *r_spec, WORD32 *l_spec_prev,
150                                   WORD32 *r_spec_prev) {
151   WORD32 ixheaacd_drc_offset;
152 
153   ixheaacd_drc_offset = info->samp_per_bk - info->bins_per_sbk;
154 
155   memcpy(l_spec_prev + ixheaacd_drc_offset, l_spec + ixheaacd_drc_offset,
156          sizeof(WORD32) * info->bins_per_sbk);
157   memcpy(r_spec_prev + ixheaacd_drc_offset, r_spec + ixheaacd_drc_offset,
158          sizeof(WORD32) * info->bins_per_sbk);
159 }
160 
ixheaacd_cplx_pred_data(ia_usac_data_struct * usac_data,ia_usac_tmp_core_coder_struct * pstr_core_coder,WORD32 num_window_groups,ia_bit_buf_struct * it_bit_buff)161 static VOID ixheaacd_cplx_pred_data(
162     ia_usac_data_struct *usac_data,
163     ia_usac_tmp_core_coder_struct *pstr_core_coder, WORD32 num_window_groups,
164     ia_bit_buf_struct *it_bit_buff) {
165   ia_huff_code_book_struct *ptr_huff_code_book = &ixheaacd_book;
166   const ia_huff_code_word_struct *ptr_huff_code_word =
167       ptr_huff_code_book->pstr_huff_code_word;
168   WORD32 cplx_pred_all;
169   WORD32 delta_code_time;
170   WORD32 g, sfb;
171   WORD32 dpcm_alpha, last_alpha_q_re, last_alpha_q_im;
172   UWORD8 max_sfb_ste = pstr_core_coder->max_sfb_ste;
173 
174   WORD32(*alpha_q_re)[SFB_NUM_MAX] = usac_data->alpha_q_re;
175   WORD32(*alpha_q_im)[SFB_NUM_MAX] = usac_data->alpha_q_im;
176   WORD32 *alpha_q_re_prev = usac_data->alpha_q_re_prev;
177   WORD32 *alpha_q_im_prev = usac_data->alpha_q_im_prev;
178   UWORD8(*cplx_pred_used)[SFB_NUM_MAX] = usac_data->cplx_pred_used;
179 
180   cplx_pred_all = ixheaacd_read_bits_buf(it_bit_buff, 1);
181 
182   if (cplx_pred_all == 0) {
183     for (g = 0; g < num_window_groups; g++) {
184       for (sfb = 0; sfb < max_sfb_ste; sfb += SFB_PER_PRED_BAND) {
185         cplx_pred_used[g][sfb] = ixheaacd_read_bits_buf(it_bit_buff, 1);
186 
187         if (sfb + 1 < max_sfb_ste)
188           cplx_pred_used[g][sfb + 1] = cplx_pred_used[g][sfb];
189       }
190       for (sfb = max_sfb_ste; sfb < SFB_NUM_MAX; sfb++)
191         cplx_pred_used[g][sfb] = 0;
192     }
193   } else {
194     for (g = 0; g < num_window_groups; g++) {
195       for (sfb = 0; sfb < max_sfb_ste; sfb++) cplx_pred_used[g][sfb] = 1;
196 
197       for (sfb = max_sfb_ste; sfb < SFB_NUM_MAX; sfb++)
198         cplx_pred_used[g][sfb] = 0;
199     }
200   }
201 
202   pstr_core_coder->pred_dir = ixheaacd_read_bits_buf(it_bit_buff, 1);
203 
204   pstr_core_coder->complex_coef = ixheaacd_read_bits_buf(it_bit_buff, 1);
205 
206   if (pstr_core_coder->complex_coef) {
207     if (usac_data->usac_independency_flg)
208       pstr_core_coder->use_prev_frame = 0;
209     else
210       pstr_core_coder->use_prev_frame = ixheaacd_read_bits_buf(it_bit_buff, 1);
211   }
212 
213   if (usac_data->usac_independency_flg)
214     delta_code_time = 0;
215   else
216     delta_code_time = ixheaacd_read_bits_buf(it_bit_buff, 1);
217 
218   for (g = 0; g < num_window_groups; g++) {
219     for (sfb = 0; sfb < max_sfb_ste; sfb += SFB_PER_PRED_BAND) {
220       if (delta_code_time == 1) {
221         last_alpha_q_re = alpha_q_re_prev[sfb];
222         last_alpha_q_im = alpha_q_im_prev[sfb];
223       } else {
224         if (sfb > 0) {
225           last_alpha_q_re = alpha_q_re[g][sfb - 1];
226           last_alpha_q_im = alpha_q_im[g][sfb - 1];
227         } else {
228           last_alpha_q_re = last_alpha_q_im = 0;
229         }
230       }
231 
232       if (cplx_pred_used[g][sfb] == 1) {
233         dpcm_alpha =
234             -ixheaacd_huff_codeword(ptr_huff_code_word, 0, it_bit_buff) + 60;
235         alpha_q_re[g][sfb] = dpcm_alpha + last_alpha_q_re;
236 
237         if (pstr_core_coder->complex_coef) {
238           dpcm_alpha =
239               -ixheaacd_huff_codeword(ptr_huff_code_word, 0, it_bit_buff) + 60;
240           alpha_q_im[g][sfb] = dpcm_alpha + last_alpha_q_im;
241         } else {
242           alpha_q_im[g][sfb] = 0;
243         }
244       } else {
245         alpha_q_re[g][sfb] = 0;
246         alpha_q_im[g][sfb] = 0;
247       }
248 
249       if ((sfb + 1) < max_sfb_ste) {
250         alpha_q_re[g][sfb + 1] = alpha_q_re[g][sfb];
251         alpha_q_im[g][sfb + 1] = alpha_q_im[g][sfb];
252       }
253 
254       alpha_q_re_prev[sfb] = alpha_q_re[g][sfb];
255       alpha_q_im_prev[sfb] = alpha_q_im[g][sfb];
256     }
257     for (sfb = max_sfb_ste; sfb < SFB_NUM_MAX; sfb++) {
258       alpha_q_re[g][sfb] = 0;
259       alpha_q_im[g][sfb] = 0;
260       alpha_q_re_prev[sfb] = 0;
261       alpha_q_im_prev[sfb] = 0;
262     }
263   }
264 
265   return;
266 }
267 
ixheaacd_read_ms_mask(ia_usac_data_struct * usac_data,ia_usac_tmp_core_coder_struct * pstr_core_coder,ia_bit_buf_struct * it_bit_buff,WORD32 chn)268 static WORD32 ixheaacd_read_ms_mask(
269     ia_usac_data_struct *usac_data,
270     ia_usac_tmp_core_coder_struct *pstr_core_coder,
271     ia_bit_buf_struct *it_bit_buff, WORD32 chn) {
272   WORD32 g, sfb;
273   WORD32 ms_mask_present;
274 
275   UWORD8 *sfb_group = usac_data->group_dis[chn];
276   UWORD8 max_sfb = pstr_core_coder->max_sfb_ste;
277   UWORD8 *ms_used = usac_data->ms_used[chn];
278   ia_sfb_info_struct *info = usac_data->pstr_sfb_info[chn];
279 
280   ms_mask_present = ixheaacd_read_bits_buf(it_bit_buff, 2);
281 
282   switch (ms_mask_present) {
283     case 0:
284 
285       break;
286 
287     case 1:
288       for (g = 0; g < info->max_win_len; g = *sfb_group++) {
289         for (sfb = 0; sfb < max_sfb; sfb++) {
290           *ms_used = ixheaacd_read_bits_buf(it_bit_buff, 1);
291           ms_used++;
292         }
293         for (; sfb < info->sfb_per_sbk; sfb++) {
294           *ms_used = 0;
295           ms_used++;
296         }
297       }
298 
299       break;
300     case 2:
301       for (g = 0; g < info->max_win_len; g = *sfb_group++)
302         for (sfb = 0; sfb < info->sfb_per_sbk; sfb++) *ms_used++ = 1;
303       break;
304 
305     case 3:
306 
307       ixheaacd_cplx_pred_data(usac_data, pstr_core_coder, info->num_groups,
308                               it_bit_buff);
309       return 3;
310   }
311 
312   for (sfb = 0; sfb < SFB_NUM_MAX; sfb++) {
313     usac_data->alpha_q_re_prev[sfb] = 0;
314     usac_data->alpha_q_im_prev[sfb] = 0;
315   }
316   return ms_mask_present;
317 }
318 
ixheaacd_ms_stereo(ia_usac_data_struct * usac_data,WORD32 * r_spec,WORD32 * l_spec,WORD32 chn,WORD32 nband)319 VOID ixheaacd_ms_stereo(ia_usac_data_struct *usac_data, WORD32 *r_spec,
320                         WORD32 *l_spec, WORD32 chn, WORD32 nband) {
321   WORD32 temp_r, temp_l;
322   WORD32 sfb, k, grp, grp_len;
323   ia_sfb_info_struct *ptr_sfb_info = usac_data->pstr_sfb_info[chn];
324   UWORD8 *ms_used = usac_data->ms_used[chn];
325   WORD32 ixheaacd_drc_offset = 0;
326 
327   for (grp = 0; grp < ptr_sfb_info->num_groups; grp++) {
328     for (grp_len = 0; grp_len < ptr_sfb_info->group_len[grp]; grp_len++) {
329       ixheaacd_drc_offset = 0;
330       for (sfb = 0; sfb < nband; sfb++) {
331         ixheaacd_drc_offset += ptr_sfb_info->sfb_width[sfb];
332         if (ms_used[sfb]) {
333           for (k = 0; k < ptr_sfb_info->sfb_width[sfb]; k++) {
334             temp_r = *r_spec;
335             temp_l = *l_spec;
336             *l_spec = ixheaac_add32_sat(temp_r, temp_l);
337             *r_spec = ixheaac_sub32_sat(temp_l, temp_r);
338             r_spec++;
339             l_spec++;
340           }
341         } else {
342           r_spec += ptr_sfb_info->sfb_width[sfb];
343           l_spec += ptr_sfb_info->sfb_width[sfb];
344         }
345       }
346 
347       l_spec = l_spec + ptr_sfb_info->bins_per_sbk - ixheaacd_drc_offset;
348       r_spec = r_spec + ptr_sfb_info->bins_per_sbk - ixheaacd_drc_offset;
349     }
350 
351     ms_used += ptr_sfb_info->sfb_per_sbk;
352   }
353 }
354 
ixheaacd_filter_and_add(const WORD32 * in,const WORD32 length,const WORD16 * filter,WORD32 * out,const WORD32 factor_even,const WORD32 factor_odd)355 static VOID ixheaacd_filter_and_add(const WORD32 *in, const WORD32 length,
356                                     const WORD16 *filter, WORD32 *out,
357                                     const WORD32 factor_even,
358                                     const WORD32 factor_odd) {
359   WORD32 i;
360   WORD64 sum;
361 
362   sum = ixheaac_mult32x32in64(in[2], filter[0]);
363   sum = ixheaac_mac32x32in64(sum, in[1], filter[1]);
364   sum = ixheaac_mac32x32in64(sum, in[0], filter[2]);
365   sum = ixheaac_mac32x32in64_n(sum, &in[0], &filter[3], 4);
366   *out = ixheaac_add32_sat(
367       *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_even) >> 15)));
368   out++;
369 
370   sum = ixheaac_mult32x32in64(in[1], filter[0]);
371   sum = ixheaac_mac32x32in64(sum, in[0], filter[1]);
372   sum = ixheaac_mac32x32in64_n(sum, &in[0], &filter[2], 5);
373   *out = ixheaac_add32_sat(
374       *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_odd) >> 15)));
375   out++;
376 
377   sum = ixheaac_mult32x32in64(in[0], filter[0]);
378   sum = ixheaac_mac32x32in64_n(sum, &in[0], &filter[1], 6);
379   *out = ixheaac_add32_sat(
380       *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_even) >> 15)));
381   out++;
382 
383   for (i = 3; i < length - 4; i += 2) {
384     sum = 0;
385     sum = ixheaac_mac32x32in64_7(&in[i - 3], filter);
386     *out = ixheaac_add32_sat(
387         *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_odd) >> 15)));
388     out++;
389 
390     sum = 0;
391     sum = ixheaac_mac32x32in64_7(&in[i - 2], filter);
392     *out = ixheaac_add32_sat(
393         *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_even) >> 15)));
394     out++;
395   }
396   i = length - 3;
397   sum = 0;
398   sum = ixheaac_mac32x32in64_n(sum, &in[i - 3], filter, 6);
399   sum = ixheaac_mac32x32in64(sum, in[i + 2], filter[6]);
400   *out = ixheaac_add32_sat(
401       *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_odd) >> 15)));
402 
403   out++;
404   i = length - 2;
405   sum = 0;
406   sum = ixheaac_mac32x32in64_n(sum, &in[i - 3], filter, 5);
407   sum = ixheaac_mac32x32in64(sum, in[i + 1], filter[5]);
408   sum = ixheaac_mac32x32in64(sum, in[i], filter[6]);
409 
410   *out = ixheaac_add32_sat(
411       *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_even) >> 15)));
412   out++;
413 
414   i = length - 1;
415   sum = 0;
416   sum = ixheaac_mac32x32in64_n(sum, &in[i - 3], filter, 4);
417   sum = ixheaac_mac32x32in64(sum, in[i], filter[4]);
418   sum = ixheaac_mac32x32in64(sum, in[i - 1], filter[5]);
419   sum = ixheaac_mac32x32in64(sum, in[i - 2], filter[6]);
420 
421   *out = ixheaac_add32_sat(
422       *out, ixheaac_sat64_32((((WORD64)sum * (WORD64)factor_odd) >> 15)));
423 }
424 
ixheaacd_estimate_dmx_im(const WORD32 * dmx_re,const WORD32 * dmx_re_prev,WORD32 * dmx_im,ia_sfb_info_struct * pstr_sfb_info,WORD32 window,const WORD32 w_shape,const WORD32 prev_w_shape)425 static VOID ixheaacd_estimate_dmx_im(const WORD32 *dmx_re,
426                                      const WORD32 *dmx_re_prev, WORD32 *dmx_im,
427                                      ia_sfb_info_struct *pstr_sfb_info,
428                                      WORD32 window, const WORD32 w_shape,
429                                      const WORD32 prev_w_shape) {
430   WORD32 i;
431   const WORD16 *mdst_fcoeff_curr, *mdst_fcoeff_prev;
432 
433   switch (window) {
434     case ONLY_LONG_SEQUENCE:
435     case EIGHT_SHORT_SEQUENCE:
436       mdst_fcoeff_curr =
437           ixheaacd_mdst_fcoeff_longshort_curr[prev_w_shape][w_shape];
438       mdst_fcoeff_prev = ixheaacd_mdst_fcoeff_l_s_start_left_prev[prev_w_shape];
439       break;
440     case LONG_START_SEQUENCE:
441       mdst_fcoeff_curr = ixheaacd_mdst_fcoeff_start_curr[prev_w_shape][w_shape];
442       mdst_fcoeff_prev = ixheaacd_mdst_fcoeff_l_s_start_left_prev[prev_w_shape];
443       break;
444     case LONG_STOP_SEQUENCE:
445       mdst_fcoeff_curr = ixheaacd_mdst_fcoeff_stop_cur[prev_w_shape][w_shape];
446       mdst_fcoeff_prev =
447           ixheaacd_mdst_fcoeff_stop_stopstart_left_prev[prev_w_shape];
448       break;
449     case STOP_START_SEQUENCE:
450       mdst_fcoeff_curr =
451           ixheaacd_mdst_fcoeff_stopstart_cur[prev_w_shape][w_shape];
452       mdst_fcoeff_prev =
453           ixheaacd_mdst_fcoeff_stop_stopstart_left_prev[prev_w_shape];
454       break;
455     default:
456       mdst_fcoeff_curr =
457           ixheaacd_mdst_fcoeff_stopstart_cur[prev_w_shape][w_shape];
458       mdst_fcoeff_prev =
459           ixheaacd_mdst_fcoeff_stop_stopstart_left_prev[prev_w_shape];
460       break;
461   }
462 
463   for (i = 0; i < pstr_sfb_info->max_win_len; i++) {
464     ixheaacd_filter_and_add(dmx_re, pstr_sfb_info->bins_per_sbk,
465                             mdst_fcoeff_curr, dmx_im, 1, 1);
466 
467     if (dmx_re_prev)
468       ixheaacd_filter_and_add(dmx_re_prev, pstr_sfb_info->bins_per_sbk,
469                               mdst_fcoeff_prev, dmx_im, -1, 1);
470 
471     dmx_re_prev = dmx_re;
472     dmx_re += pstr_sfb_info->bins_per_sbk;
473     dmx_im += pstr_sfb_info->bins_per_sbk;
474   }
475   return;
476 }
477 
ixheaacd_cplx_pred_upmixing(ia_usac_data_struct * usac_data,WORD32 * l_spec,WORD32 * r_spec,ia_usac_tmp_core_coder_struct * pstr_core_coder,WORD32 chn)478 static VOID ixheaacd_cplx_pred_upmixing(
479     ia_usac_data_struct *usac_data, WORD32 *l_spec, WORD32 *r_spec,
480     ia_usac_tmp_core_coder_struct *pstr_core_coder, WORD32 chn) {
481   ia_sfb_info_struct *pstr_sfb_info = usac_data->pstr_sfb_info[chn];
482   WORD32 *dmx_re = &usac_data->scratch_buffer[0];
483   WORD32 *dmx_im = &usac_data->x_ac_dec[0];
484 
485   WORD32 grp, sfb, grp_len, i = 0, k;
486   WORD32 *dmx_re_prev = usac_data->dmx_re_prev;
487   WORD32(*alpha_q_re)[SFB_NUM_MAX] = usac_data->alpha_q_re;
488   WORD32(*alpha_q_im)[SFB_NUM_MAX] = usac_data->alpha_q_im;
489 
490   UWORD8(*cplx_pred_used)[SFB_NUM_MAX] = usac_data->cplx_pred_used;
491 
492   WORD32 alpha_q_re_temp;
493   WORD32 alpha_q_im_temp;
494   WORD32 factor = 1;
495 
496   if (pstr_core_coder->pred_dir) factor = -1;
497 
498   for (grp = 0; grp < pstr_sfb_info->num_groups; grp++) {
499     for (grp_len = 0; grp_len < pstr_sfb_info->group_len[grp]; grp_len++) {
500       for (sfb = 0; sfb < pstr_sfb_info->sfb_per_sbk; sfb++) {
501         if (cplx_pred_used[grp][sfb] == 1) {
502           memcpy(&dmx_re[i], &l_spec[i],
503                  pstr_sfb_info->sfb_width[sfb] * sizeof(WORD32));
504           i += pstr_sfb_info->sfb_width[sfb];
505         }
506 
507         else {
508           for (k = 0; k < pstr_sfb_info->sfb_width[sfb]; k++, i++) {
509             dmx_re[i] = (WORD32)(
510                 ((WORD64)l_spec[i] + ((WORD64)factor * (WORD64)r_spec[i])) >>
511                 1);
512           }
513         }
514       }
515     }
516   }
517 
518   memset(dmx_im, 0, sizeof(WORD32) * BLOCK_LEN_LONG);
519 
520   if (pstr_core_coder->complex_coef) {
521     WORD32 *p_dmx_re_prev =
522         pstr_core_coder->use_prev_frame ? dmx_re_prev : NULL;
523     ixheaacd_estimate_dmx_im(dmx_re, p_dmx_re_prev, dmx_im, pstr_sfb_info,
524                              usac_data->window_sequence[chn],
525                              usac_data->window_shape[chn],
526                              usac_data->window_shape_prev[chn]);
527 
528     for (grp = 0, i = 0; grp < pstr_sfb_info->num_groups; grp++) {
529       for (grp_len = 0; grp_len < pstr_sfb_info->group_len[grp]; grp_len++) {
530         for (sfb = 0; sfb < pstr_sfb_info->sfb_per_sbk; sfb++) {
531           alpha_q_re_temp = ixheaac_sat64_32(ixheaac_mult32x32in64(alpha_q_re[grp][sfb], 1677722));
532           alpha_q_im_temp = ixheaac_sat64_32(ixheaac_mult32x32in64(alpha_q_im[grp][sfb], 1677722));
533           if (cplx_pred_used[grp][sfb]) {
534             for (k = 0; k < pstr_sfb_info->sfb_width[sfb]; k++, i++) {
535               WORD32 mid_side = ixheaac_sub32_sat(
536                   ixheaac_sub32_sat(r_spec[i],
537                                      (WORD32)((WORD64)ixheaac_mult32x32in64(
538                                                   alpha_q_re_temp, l_spec[i]) >>
539                                               24)),
540                   (WORD32)((WORD64)ixheaac_mult32x32in64(alpha_q_im_temp,
541                                                           dmx_im[i]) >>
542                            24));
543               r_spec[i] = ixheaac_sat64_32((WORD64)factor) *
544                           (WORD64)(ixheaac_sub32_sat(l_spec[i], mid_side));
545               l_spec[i] = ixheaac_add32_sat(l_spec[i], mid_side);
546             }
547           } else {
548             i += pstr_sfb_info->sfb_width[sfb];
549           }
550         }
551       }
552     }
553   } else {
554     for (grp = 0, i = 0; grp < pstr_sfb_info->num_groups; grp++) {
555       for (grp_len = 0; grp_len < pstr_sfb_info->group_len[grp]; grp_len++) {
556         for (sfb = 0; sfb < pstr_sfb_info->sfb_per_sbk; sfb++) {
557           alpha_q_re_temp = ixheaac_sat64_32(ixheaac_mult32x32in64(alpha_q_re[grp][sfb], 1677722));
558           if (cplx_pred_used[grp][sfb]) {
559             for (k = 0; k < pstr_sfb_info->sfb_width[sfb]; k++, i++) {
560               WORD32 mid_side = ixheaac_sub32_sat(
561                   r_spec[i], (WORD32)((WORD64)ixheaac_mult32x32in64(
562                                           alpha_q_re_temp, l_spec[i]) >>
563                                       24));
564 
565               r_spec[i] = ixheaac_sat64_32((WORD64)factor) *
566                           (WORD64)(ixheaac_sub32_sat(l_spec[i], mid_side));
567               l_spec[i] = ixheaac_add32_sat(l_spec[i], mid_side);
568             }
569           } else {
570             i += pstr_sfb_info->sfb_width[sfb];
571           }
572         }
573       }
574     }
575   }
576 
577   return;
578 }
579 
ixheaacd_cplx_prev_mdct_dmx(ia_sfb_info_struct * pstr_sfb_info,WORD32 * l_spec,WORD32 * r_spec,WORD32 * dmx_re_prev,WORD32 pred_dir)580 static VOID ixheaacd_cplx_prev_mdct_dmx(ia_sfb_info_struct *pstr_sfb_info,
581                                         WORD32 *l_spec, WORD32 *r_spec,
582                                         WORD32 *dmx_re_prev, WORD32 pred_dir) {
583   WORD32 offs, i;
584   WORD32 factor = 1;
585   if (pred_dir) factor = -1;
586 
587   offs = pstr_sfb_info->samp_per_bk - pstr_sfb_info->bins_per_sbk;
588 
589   for (i = 0; i < pstr_sfb_info->bins_per_sbk; i++)
590     dmx_re_prev[i] = (WORD32)(((WORD64)l_spec[i + offs] +
591                                ((WORD64)factor * (WORD64)r_spec[i + offs])) >>
592                               1);
593 }
594 
ixheaacd_ics_info(ia_usac_data_struct * usac_data,WORD32 chn,UWORD8 * max_sfb,ia_bit_buf_struct * it_bit_buff,WORD32 window_sequence_last)595 WORD32 ixheaacd_ics_info(ia_usac_data_struct *usac_data, WORD32 chn,
596                          UWORD8 *max_sfb, ia_bit_buf_struct *it_bit_buff,
597                          WORD32 window_sequence_last
598 
599                          )
600 
601 {
602   WORD32 win;
603   WORD32 mask = 0x40;
604 
605   UWORD8 *scf_group_ptr = usac_data->group_dis[chn];
606 
607   win = ixheaacd_read_bits_buf(it_bit_buff, 2);
608 
609   win = usac_data->window_sequence[chn] =
610       ixheaacd_win_seq_select(win, window_sequence_last);
611   if (win == -1) return -1;
612 
613   usac_data->pstr_sfb_info[chn] =
614       usac_data->pstr_usac_winmap[usac_data->window_sequence[chn]];
615 
616   usac_data->window_shape[chn] = ixheaacd_read_bits_buf(it_bit_buff, 1);
617 
618   if (usac_data->pstr_usac_winmap[win]->islong) {
619     *max_sfb = ixheaacd_read_bits_buf(it_bit_buff, 6);
620     *scf_group_ptr = 1;
621   } else {
622     WORD32 i, scale_factor_grouping;
623 
624     *max_sfb = ixheaacd_read_bits_buf(it_bit_buff, 4);
625 
626     scale_factor_grouping = ixheaacd_read_bits_buf(it_bit_buff, 7);
627 
628     for (i = 1; i < 8; i++) {
629       if (!(scale_factor_grouping & mask)) *scf_group_ptr++ = i;
630 
631       mask = mask >> 1;
632     }
633     *scf_group_ptr++ = i;
634 
635     ixheaacd_calc_grp_offset(usac_data->pstr_usac_winmap[win],
636                              &usac_data->group_dis[chn][0]);
637   }
638 
639   if (*max_sfb > usac_data->pstr_sfb_info[chn]->sfb_per_sbk) {
640     *max_sfb = usac_data->pstr_sfb_info[chn]->sfb_per_sbk;
641     return -1;
642   }
643 
644   return 0;
645 }
646 
ixheaacd_core_coder_data(WORD32 id,ia_usac_data_struct * usac_data,WORD32 elem_idx,WORD32 chan_offset,ia_bit_buf_struct * it_bit_buff,WORD32 nr_core_coder_channels)647 WORD32 ixheaacd_core_coder_data(WORD32 id, ia_usac_data_struct *usac_data,
648                                 WORD32 elem_idx, WORD32 chan_offset,
649                                 ia_bit_buf_struct *it_bit_buff,
650                                 WORD32 nr_core_coder_channels) {
651   WORD32 err_code = 0;
652   WORD32 k = 0, ch = 0, chn = 0, left = 0, right = 0;
653 
654   ia_usac_tmp_core_coder_struct str_tmp_core_coder = {0};
655   ia_usac_tmp_core_coder_struct *pstr_core_coder = &str_tmp_core_coder;
656   ia_td_frame_data_struct td_frame;
657   jmp_buf local;
658 
659   if (usac_data->ec_flag) {
660     err_code = setjmp(local);
661     it_bit_buff->xaac_jmp_buf = &local;
662   }
663   if (err_code == 0 &&
664       ((usac_data->ec_flag == 0) || (usac_data->frame_ok == 1 && usac_data->ec_flag == 1))) {
665     memset(&td_frame, 0, sizeof(td_frame));
666     pstr_core_coder->tns_on_lr = 0;
667     pstr_core_coder->pred_dir = 0;
668     if (id != ID_USAC_LFE) {
669       for (ch = 0; ch < nr_core_coder_channels; ch++)
670         pstr_core_coder->core_mode[ch] = ixheaacd_read_bits_buf(it_bit_buff, 1);
671     } else {
672       for (ch = 0; ch < nr_core_coder_channels; ch++) pstr_core_coder->core_mode[ch] = 0;
673     }
674 
675     if (nr_core_coder_channels == 2 && pstr_core_coder->core_mode[0] == 0 &&
676         pstr_core_coder->core_mode[1] == 0) {
677       pstr_core_coder->tns_active = ixheaacd_read_bits_buf(it_bit_buff, 1);
678       pstr_core_coder->common_window = ixheaacd_read_bits_buf(it_bit_buff, 1);
679 
680       if (pstr_core_coder->common_window) {
681         left = chan_offset;
682         right = chan_offset + 1;
683 
684         err_code = ixheaacd_ics_info(usac_data, left, &pstr_core_coder->max_sfb[left],
685                                      it_bit_buff, usac_data->window_sequence_last[left]);
686 
687         if (err_code == -1) {
688           if (usac_data->ec_flag) {
689             memcpy(usac_data->max_sfb, pstr_core_coder->max_sfb,
690                    sizeof(pstr_core_coder->max_sfb));
691             longjmp(*(it_bit_buff->xaac_jmp_buf),
692                     IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES);
693           } else {
694             return err_code;
695           }
696         }
697 
698         pstr_core_coder->common_max_sfb = ixheaacd_read_bits_buf(it_bit_buff, 1);
699 
700         if (pstr_core_coder->common_max_sfb == 0) {
701           if (usac_data->window_sequence[left] == EIGHT_SHORT_SEQUENCE)
702             pstr_core_coder->max_sfb[right] = ixheaacd_read_bits_buf(it_bit_buff, 4);
703           else
704             pstr_core_coder->max_sfb[right] = ixheaacd_read_bits_buf(it_bit_buff, 6);
705         } else {
706           pstr_core_coder->max_sfb[right] = pstr_core_coder->max_sfb[left];
707         }
708 
709         pstr_core_coder->max_sfb_ste =
710             max(pstr_core_coder->max_sfb[left], pstr_core_coder->max_sfb[right]);
711 
712         usac_data->window_sequence[right] = usac_data->window_sequence[left];
713         usac_data->window_shape[right] = usac_data->window_shape[left];
714         memcpy(&usac_data->group_dis[right][0], &usac_data->group_dis[left][0], 8);
715         usac_data->pstr_sfb_info[right] = usac_data->pstr_sfb_info[left];
716         if (pstr_core_coder->max_sfb[right] > usac_data->pstr_sfb_info[right]->sfb_per_sbk)
717           pstr_core_coder->max_sfb[right] = usac_data->pstr_sfb_info[right]->sfb_per_sbk;
718 
719         pstr_core_coder->ms_mask_present[0] =
720             ixheaacd_read_ms_mask(usac_data, pstr_core_coder, it_bit_buff, left);
721       } else {
722         left = chan_offset;
723         right = chan_offset + 1;
724 
725         pstr_core_coder->ms_mask_present[0] = 0;
726         pstr_core_coder->ms_mask_present[1] = 0;
727 
728         for (k = 0; k < SFB_NUM_MAX; k++) {
729           usac_data->alpha_q_re_prev[k] = 0;
730           usac_data->alpha_q_im_prev[k] = 0;
731         }
732       }
733 
734       if (usac_data->tw_mdct[elem_idx] == 1) {
735         pstr_core_coder->common_tw = ixheaacd_read_bits_buf(it_bit_buff, 1);
736 
737         if (pstr_core_coder->common_tw == 1) {
738           usac_data->tw_data_present[left] = ixheaacd_read_bits_buf(it_bit_buff, 1);
739           usac_data->tw_data_present[right] = usac_data->tw_data_present[left];
740           if (usac_data->tw_data_present[left]) {
741             for (k = 0; k < NUM_TW_NODES; k++) {
742               usac_data->tw_ratio[left][k] = ixheaacd_read_bits_buf(it_bit_buff, 3);
743               usac_data->tw_ratio[right][k] = usac_data->tw_ratio[left][k];
744             }
745           }
746         }
747       }
748 
749       if (pstr_core_coder->tns_active) {
750         if (pstr_core_coder->common_window) {
751           pstr_core_coder->common_tns = ixheaacd_read_bits_buf(it_bit_buff, 1);
752 
753         } else {
754           pstr_core_coder->common_tns = 0;
755         }
756 
757         pstr_core_coder->tns_on_lr = ixheaacd_read_bits_buf(it_bit_buff, 1);
758 
759         if (pstr_core_coder->common_tns) {
760           ixheaacd_read_tns_u(usac_data->pstr_sfb_info[0], &usac_data->pstr_tns[left][0],
761                               it_bit_buff);
762           memcpy(&usac_data->pstr_tns[right][0], &usac_data->pstr_tns[left][0],
763                  sizeof(ia_tns_frame_info_struct));
764 
765           pstr_core_coder->tns_data_present[0] = 2;
766           pstr_core_coder->tns_data_present[1] = 2;
767         } else {
768           pstr_core_coder->tns_present_both = ixheaacd_read_bits_buf(it_bit_buff, 1);
769 
770           if (pstr_core_coder->tns_present_both) {
771             pstr_core_coder->tns_data_present[0] = 1;
772             pstr_core_coder->tns_data_present[1] = 1;
773           } else {
774             pstr_core_coder->tns_data_present[1] = ixheaacd_read_bits_buf(it_bit_buff, 1);
775             pstr_core_coder->tns_data_present[0] = 1 - pstr_core_coder->tns_data_present[1];
776           }
777         }
778       } else {
779         pstr_core_coder->common_tns = 0;
780         pstr_core_coder->tns_data_present[0] = 0;
781         pstr_core_coder->tns_data_present[1] = 0;
782       }
783 
784     } else {
785       pstr_core_coder->common_window = 0;
786       pstr_core_coder->common_tw = 0;
787       left = chan_offset;
788       right = chan_offset;
789       if (nr_core_coder_channels == 2) right = chan_offset + 1;
790     }
791 
792     for (ch = 0, chn = chan_offset; ch < nr_core_coder_channels; ch++, chn++) {
793       if (pstr_core_coder->core_mode[chn] == CORE_MODE_LPD &&
794           usac_data->td_frame_prev[chn] == CORE_MODE_FD && usac_data->ec_flag) {
795         memcpy(usac_data->coef_fix[chn], usac_data->str_error_concealment[chn].spectral_coeff,
796                sizeof(usac_data->str_error_concealment[chn].spectral_coeff));
797         memcpy(usac_data->spec_scale[chn], usac_data->str_error_concealment[chn].q_spec_coeff,
798                sizeof(usac_data->spec_scale[chn]));
799         err_code = ixheaacd_fd_frm_dec(usac_data, chn);
800         if (err_code == -1) return err_code;
801         for (k = 0; k < usac_data->ccfl; k++) {
802           usac_data->time_sample_vector[chn][k] = (FLOAT32)(
803               (FLOAT32)usac_data->output_data_ptr[chn][k] * (FLOAT32)(ONE_BY_TWO_POW_15));
804         }
805         memcpy(usac_data->time_sample_vector_prev[chn], usac_data->time_sample_vector[chn],
806                usac_data->ccfl * sizeof(usac_data->time_sample_vector_prev[chn][0]));
807 
808         usac_data->window_sequence[ch] = usac_data->str_error_concealment[ch].win_seq;
809         usac_data->window_shape[ch] = usac_data->str_error_concealment[ch].win_shape;
810         usac_data->window_shape_prev[ch] = usac_data->window_shape[ch];
811         usac_data->window_sequence_last[ch] = usac_data->window_sequence[ch];
812       }
813       if (pstr_core_coder->core_mode[ch] == 1) {
814         err_code = ixheaacd_tw_buff_update(usac_data, chn, usac_data->str_tddec[chn]);
815         if (err_code == -1) return err_code;
816 
817         if (!usac_data->td_frame_prev[chn]) {
818           ixheaacd_fix2flt_data(usac_data, usac_data->str_tddec[chn], chn);
819         }
820 
821         for (k = 0; k < usac_data->ccfl; k++) {
822           usac_data->time_sample_vector[chn][k] = (FLOAT32)(
823               (FLOAT32)usac_data->output_data_ptr[chn][k] * (FLOAT32)(ONE_BY_TWO_POW_15));
824         }
825         usac_data->present_chan = chn;
826         err_code = ixheaacd_lpd_channel_stream(usac_data, &td_frame, it_bit_buff,
827                                                usac_data->time_sample_vector[chn]);
828         if (err_code == -1) return err_code;
829         if (usac_data->ec_flag) {
830           it_bit_buff->xaac_jmp_buf = &local;
831         }
832         if (usac_data->ec_flag && usac_data->frame_ok) {
833           memcpy(&usac_data->td_frame_data_prev[chn], &td_frame, sizeof(td_frame));
834           usac_data->core_mode = CORE_MODE_LPD;
835         }
836         for (k = 0; k < usac_data->ccfl; k++) {
837           usac_data->output_data_ptr[chn][k] =
838               (WORD32)(usac_data->time_sample_vector[chn][k] * (FLOAT32)((WORD64)1 << 15));
839         }
840 
841         usac_data->window_shape[chn] = WIN_SEL_0;
842 
843         ixheaacd_td_frm_dec(usac_data, chn, td_frame.mod[0]);
844 
845         usac_data->window_shape_prev[chn] = usac_data->window_shape[chn];
846         usac_data->window_sequence_last[chn] = EIGHT_SHORT_SEQUENCE;
847 
848       } else {
849         memset(usac_data->coef_fix[chn], 0, LN2 * sizeof(*usac_data->coef_fix[0]));
850 
851         if (usac_data->str_tddec[chn] && usac_data->td_frame_prev[chn]) {
852           if (usac_data->ec_flag) {
853             memcpy(usac_data->time_sample_vector[chn], usac_data->time_sample_vector_prev[chn],
854                    usac_data->ccfl * sizeof(usac_data->time_sample_vector[chn][0]));
855           }
856           ixheaacd_lpd_dec_update(usac_data->str_tddec[chn], usac_data, chn);
857         }
858 
859         if (id != ID_USAC_LFE) {
860           if ((nr_core_coder_channels == 1) ||
861               (pstr_core_coder->core_mode[0] != pstr_core_coder->core_mode[1]))
862             pstr_core_coder->tns_data_present[ch] = ixheaacd_read_bits_buf(it_bit_buff, 1);
863         }
864 
865         err_code = ixheaacd_fd_channel_stream(
866             usac_data, pstr_core_coder, &pstr_core_coder->max_sfb[ch],
867             usac_data->window_sequence_last[chn], chn, usac_data->noise_filling_config[elem_idx],
868             ch, it_bit_buff);
869         if (err_code == -1) return err_code;
870       }
871     }
872 
873     if (pstr_core_coder->core_mode[0] == CORE_MODE_FD &&
874         pstr_core_coder->core_mode[1] == CORE_MODE_FD && nr_core_coder_channels == 2) {
875       ixheaacd_cplx_prev_mdct_dmx(usac_data->pstr_sfb_info[left], usac_data->coef_save[left],
876                                   usac_data->coef_save[right], usac_data->dmx_re_prev,
877                                   pstr_core_coder->pred_dir);
878     }
879 
880     if (pstr_core_coder->tns_on_lr == 0 && (id != ID_USAC_LFE)) {
881       for (ch = 0, chn = left; chn <= right; ch++, chn++) {
882         if (pstr_core_coder->core_mode[ch] == CORE_MODE_FD) {
883           err_code = ixheaacd_tns_apply(usac_data, usac_data->coef_fix[chn],
884                                         pstr_core_coder->max_sfb[ch],
885                                         usac_data->pstr_sfb_info[chn], usac_data->pstr_tns[chn]);
886           if (err_code) return err_code;
887         }
888       }
889     }
890 
891     if (nr_core_coder_channels == 2 && pstr_core_coder->core_mode[0] == 0 &&
892         pstr_core_coder->core_mode[1] == 0) {
893       if (pstr_core_coder->ms_mask_present[0] == 3) {
894         ixheaacd_cplx_pred_upmixing(usac_data, usac_data->coef_fix[left],
895                                     usac_data->coef_fix[right], pstr_core_coder, left);
896 
897       } else if (pstr_core_coder->ms_mask_present[0] > 0) {
898         ixheaacd_ms_stereo(usac_data, usac_data->coef_fix[right], usac_data->coef_fix[left], left,
899                            pstr_core_coder->max_sfb[right] > pstr_core_coder->max_sfb[left]
900                                ? pstr_core_coder->max_sfb[right]
901                                : pstr_core_coder->max_sfb[left]);
902       }
903 
904       if (pstr_core_coder->tns_on_lr) {
905         for (ch = 0, chn = left; chn <= right; ch++, chn++) {
906           if (pstr_core_coder->core_mode[ch] == CORE_MODE_FD) {
907             err_code = ixheaacd_tns_apply(
908                 usac_data, usac_data->coef_fix[chn], pstr_core_coder->max_sfb[ch],
909                 usac_data->pstr_sfb_info[chn], usac_data->pstr_tns[chn]);
910             if (err_code) return err_code;
911           }
912         }
913       }
914 
915       ixheaacd_usac_cplx_save_prev(usac_data->pstr_sfb_info[left], usac_data->coef_fix[left],
916                                    usac_data->coef_fix[right], usac_data->coef_save[left],
917                                    usac_data->coef_save[right]);
918     }
919     if (usac_data->ec_flag) {
920       for (chn = left; chn <= right; chn++) {
921         if (pstr_core_coder->core_mode[chn] == CORE_MODE_FD &&
922             usac_data->td_frame_prev[chn] == CORE_MODE_LPD) {
923           memcpy(usac_data->str_error_concealment[chn].spectral_coeff, usac_data->coef_fix[chn],
924                  sizeof(usac_data->str_error_concealment[chn].spectral_coeff));
925           memcpy(usac_data->str_error_concealment[chn].q_spec_coeff, usac_data->spec_scale[chn],
926                  sizeof(usac_data->spec_scale[chn]));
927           usac_data->str_error_concealment[chn].win_seq = usac_data->window_sequence[chn];
928           usac_data->str_error_concealment[chn].win_shape = usac_data->window_shape[chn];
929           usac_data->str_error_concealment[chn].win_shape_prev =
930               usac_data->window_shape_prev[chn];
931           usac_data->str_error_concealment[chn].td_frame_prev = usac_data->td_frame_prev[chn];
932           usac_data->str_error_concealment[chn].fac_data_present =
933               usac_data->fac_data_present[chn];
934         }
935       }
936       if (usac_data->frame_ok && usac_data->ec_flag) {
937         memcpy(usac_data->max_sfb, pstr_core_coder->max_sfb, sizeof(pstr_core_coder->max_sfb));
938       }
939     }
940   } else {
941     left = chan_offset;
942     right = chan_offset;
943     if (nr_core_coder_channels == 2) right = chan_offset + 1;
944     if (usac_data->ec_flag == 1) {
945       WORD32 err = 0;
946       usac_data->frame_ok = 0;
947       for (ch = left; ch <= right; ch++) {
948         if (usac_data->td_frame_prev[ch] == CORE_MODE_LPD) {
949           usac_data->fac_data_present[ch] = 0;
950           usac_data->str_error_concealment[ch].pstr_ec_scratch =
951               (ia_ec_scratch_str *)&usac_data->str_error_concealment[ch].str_ec_scratch;
952           usac_data->core_mode = usac_data->td_frame_prev[ch];
953           usac_data->present_chan = ch;
954           ixheaacd_usac_apply_ec(usac_data, NULL, ch);
955           err = ixheaacd_lpd_dec(usac_data, usac_data->str_tddec[ch],
956                                  &usac_data->td_frame_data_prev[ch],
957                                  usac_data->time_sample_vector[ch], usac_data->first_lpd_flag, 0,
958                                  usac_data->bpf_control_info);
959 
960           if (err) return err;
961 
962           for (k = 0; k < usac_data->ccfl; k++) {
963             usac_data->output_data_ptr[ch][k] =
964                 (WORD32)(usac_data->time_sample_vector[ch][k] * (FLOAT32)((WORD64)1 << 15));
965           }
966 
967           usac_data->window_shape[ch] = WIN_SEL_0;
968           usac_data->window_shape_prev[ch] = usac_data->window_shape[ch];
969           usac_data->window_sequence_last[ch] = EIGHT_SHORT_SEQUENCE;
970         } else {
971           pstr_core_coder->core_mode[ch] = CORE_MODE_FD;
972         }
973       }
974     }
975   }
976 
977   for (ch = left; ch <= right; ch++) {
978     FLOAT32 *ptr_scratch =
979         (FLOAT32 *)usac_data->str_error_concealment[ch].str_ec_scratch.spec_coeff;
980     if ((pstr_core_coder->core_mode[ch] != CORE_MODE_LPD &&
981          usac_data->td_frame_prev[ch] != CORE_MODE_LPD && usac_data->ec_flag) ||
982         (pstr_core_coder->core_mode[ch] == CORE_MODE_FD && usac_data->ec_flag == 0)) {
983       if (usac_data->tw_mdct[elem_idx]) {
984         err_code = -1;
985         return err_code;
986 
987       } else {
988         if (usac_data->frame_ok == 0) {
989           usac_data->fac_data_present[ch] = 0;
990         }
991         err_code = ixheaacd_fd_frm_dec(usac_data, ch);
992         if (err_code == -1) return err_code;
993         if (usac_data->ec_flag) {
994           if (usac_data->str_error_concealment[ch].fade_idx < MAX_FADE_FRAMES) {
995             FLOAT32 fade_fac = (FLOAT32)(ONE_BY_TWO_POW_15)*ia_ec_fade_factors
996                 [usac_data->str_error_concealment[ch].fade_idx];
997             for (k = 0; k < usac_data->ccfl; k++) {
998               usac_data->time_sample_vector[ch][k] =
999                   (FLOAT32)((FLOAT32)usac_data->output_data_ptr[ch][k] * fade_fac);
1000             }
1001           } else {
1002             memset(&usac_data->time_sample_vector[ch][0], 0,
1003                    usac_data->ccfl * sizeof(usac_data->time_sample_vector[ch][0]));
1004           }
1005         } else {
1006           for (k = 0; k < usac_data->ccfl; k++) {
1007             usac_data->time_sample_vector[ch][k] =
1008                 (FLOAT32)((FLOAT32)usac_data->output_data_ptr[ch][k] *
1009                           (FLOAT32)(ONE_BY_TWO_POW_15));
1010           }
1011         }
1012       }
1013       usac_data->window_shape_prev[ch] = usac_data->window_shape[ch];
1014       usac_data->window_sequence_last[ch] = usac_data->window_sequence[ch];
1015     } else {
1016       if (usac_data->ec_flag) {
1017         usac_data->str_error_concealment[ch].prev_frame_ok[0] =
1018             usac_data->str_error_concealment[ch].prev_frame_ok[1];
1019         usac_data->str_error_concealment[ch].prev_frame_ok[1] = usac_data->frame_ok;
1020 
1021         if (usac_data->str_error_concealment[ch].fade_idx < MAX_FADE_FRAMES) {
1022           FLOAT32 fade_fac =
1023               (FLOAT32)(ONE_BY_TWO_POW_15)*ia_ec_fade_factors[usac_data->str_error_concealment[ch]
1024                                                                   .fade_idx];
1025           for (k = 0; k < usac_data->ccfl; k++) {
1026             usac_data->time_sample_vector[ch][k] =
1027                 (FLOAT32)((FLOAT32)usac_data->output_data_ptr[ch][k] * fade_fac);
1028           }
1029         } else {
1030           memset(&usac_data->time_sample_vector[ch][0], 0,
1031                  usac_data->ccfl * sizeof(usac_data->time_sample_vector[ch][0]));
1032         }
1033 
1034         memcpy(ptr_scratch, usac_data->time_sample_vector[ch],
1035                usac_data->ccfl * sizeof(ptr_scratch[0]));
1036         memcpy(usac_data->time_sample_vector[ch], usac_data->time_sample_vector_prev[ch],
1037                usac_data->ccfl * sizeof(usac_data->time_sample_vector[ch][0]));
1038         memcpy(usac_data->time_sample_vector_prev[ch], ptr_scratch,
1039                usac_data->ccfl * sizeof(ptr_scratch[0]));
1040       } else {
1041         for (k = 0; k < usac_data->ccfl; k++) {
1042           usac_data->time_sample_vector[ch][k] =
1043               (FLOAT32)((FLOAT32)usac_data->output_data_ptr[ch][k] *
1044                         (FLOAT32)(ONE_BY_TWO_POW_15));
1045         }
1046       }
1047     }
1048     if (usac_data->ec_flag) {
1049       usac_data->window_sequence[ch] = usac_data->str_error_concealment[ch].win_seq;
1050       usac_data->window_shape[ch] = usac_data->str_error_concealment[ch].win_shape;
1051       if (usac_data->first_frame == 0) {
1052         usac_data->window_shape_prev[ch] = usac_data->window_shape[ch];
1053         usac_data->window_sequence_last[ch] = usac_data->window_sequence[ch];
1054       }
1055     }
1056   }
1057   if (usac_data->ec_flag) {
1058     usac_data->first_frame = 0;
1059     if (usac_data->frame_ok == 1) {
1060       for (ch = 0, chn = left; chn <= right; chn++, ch++)
1061         usac_data->td_frame_prev[chn] = pstr_core_coder->core_mode[ch];
1062     }
1063   } else {
1064     for (ch = 0, chn = left; chn <= right; chn++, ch++)
1065       usac_data->td_frame_prev[chn] = pstr_core_coder->core_mode[ch];
1066   }
1067 
1068   return 0;
1069 }
1070