• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include "ixheaacd_type_def.h"
25 #include "ixheaacd_constants.h"
26 #include "ixheaacd_basic_ops32.h"
27 #include "ixheaacd_basic_ops16.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_basic_ops.h"
30 #include "ixheaacd_sbr_common.h"
31 #include "ixheaacd_error_standards.h"
32 
33 #include <ixheaacd_cnst.h>
34 #include "ixheaacd_constants.h"
35 #include "ixheaacd_intrinsics.h"
36 #include "ixheaacd_common_rom.h"
37 #include "ixheaacd_sbrdecsettings.h"
38 #include "ixheaacd_bitbuffer.h"
39 #include "ixheaacd_defines.h"
40 
41 #include "ixheaacd_pns.h"
42 
43 #include <ixheaacd_aac_rom.h>
44 #include "ixheaacd_pulsedata.h"
45 
46 #include "ixheaacd_drc_data_struct.h"
47 
48 #include "ixheaacd_interface.h"
49 #include "ixheaacd_info.h"
50 #include "ixheaacd_lt_predict.h"
51 #include "ixheaacd_ec_defines.h"
52 #include "ixheaacd_ec_rom.h"
53 #include "ixheaacd_ec_struct_def.h"
54 #include "ixheaacd_channelinfo.h"
55 #include "ixheaacd_error_standards.h"
56 
57 #include "ixheaacd_aac_rom.h"
58 
ixheaacd_aac_ec_get_win_seq(WORD32 prev_win_seq)59 static WORD32 ixheaacd_aac_ec_get_win_seq(WORD32 prev_win_seq) {
60   WORD32 new_win_seq = ONLY_LONG_SEQUENCE;
61 
62   if (prev_win_seq == LONG_START_SEQUENCE || prev_win_seq == EIGHT_SHORT_SEQUENCE) {
63     new_win_seq = LONG_STOP_SEQUENCE;
64   }
65 
66   return new_win_seq;
67 }
68 
ixheaacd_aac_ec_flip_spec_sign(WORD32 * ptr_spec_coeff,WORD32 num_samples)69 static VOID ixheaacd_aac_ec_flip_spec_sign(WORD32 *ptr_spec_coeff, WORD32 num_samples) {
70   WORD32 idx;
71   WORD32 random_value;
72 
73   for (idx = 0; idx < num_samples; idx++) {
74     random_value = ptr_spec_coeff[idx] ^ idx;
75     if ((random_value & 1) == 0) {
76       ptr_spec_coeff[idx] = ixheaacd_negate32_sat(ptr_spec_coeff[idx]);
77     }
78   }
79 }
80 
ixheaacd_aac_ec_store(ia_ec_state_str * pstr_ec_state,ia_aac_dec_channel_info_struct * pstr_aac_dec_channel_info,ia_ics_info_struct * pstr_ics_info)81 static VOID ixheaacd_aac_ec_store(ia_ec_state_str *pstr_ec_state,
82                                   ia_aac_dec_channel_info_struct *pstr_aac_dec_channel_info,
83                                   ia_ics_info_struct *pstr_ics_info) {
84   WORD32 *ptr_spec_coeff = pstr_aac_dec_channel_info->ptr_spec_coeff;
85   WORD16 *ptr_spec_scale = pstr_aac_dec_channel_info->ptr_scale_factor;
86   UWORD8 win_shape = pstr_ec_state->win_shape;
87   WORD32 win_seq = pstr_ec_state->win_seq;
88   WORD16 q_spec_scale[MAX_SPEC_SCALE_LEN];
89   WORD32 *ptr_temp_spec_coeff = &pstr_ec_state->str_ec_scratch.spec_coeff[0];
90 
91   memcpy(q_spec_scale, pstr_ec_state->q_spec_coeff, sizeof(q_spec_scale));
92 
93   pstr_ec_state->win_seq = pstr_ics_info->window_sequence;
94   pstr_ec_state->win_shape = (UWORD8)pstr_ics_info->window_shape;
95   pstr_ec_state->prev_win_group_len =
96       *(pstr_ics_info->window_group_length + pstr_ics_info->num_window_groups - 1);
97 
98   memcpy(pstr_ec_state->q_spec_coeff, ptr_spec_scale, sizeof(pstr_ec_state->q_spec_coeff));
99 
100   memcpy(ptr_temp_spec_coeff, ptr_spec_coeff, LEN_SUPERFRAME * sizeof(ptr_temp_spec_coeff[0]));
101   memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff,
102          LEN_SUPERFRAME * sizeof(ptr_spec_coeff[0]));
103   memcpy(pstr_ec_state->spectral_coeff, ptr_temp_spec_coeff,
104          sizeof(pstr_ec_state->spectral_coeff));
105   pstr_ics_info->window_sequence = win_seq;
106   pstr_ics_info->window_shape = win_shape;
107 
108   memcpy(ptr_spec_scale, q_spec_scale, MAX_SPEC_SCALE_LEN * sizeof(ptr_spec_scale[0]));
109 }
110 
ixheaacd_aac_ec_calc_sfb_nrg(WORD32 * ptr_spec_coeff,const ia_usac_samp_rate_info * pstr_samp_rate_info,const WORD32 win_seq,WORD32 win_trans,WORD32 * ptr_sfb_energy)111 static VOID ixheaacd_aac_ec_calc_sfb_nrg(WORD32 *ptr_spec_coeff,
112                                          const ia_usac_samp_rate_info *pstr_samp_rate_info,
113                                          const WORD32 win_seq, WORD32 win_trans,
114                                          WORD32 *ptr_sfb_energy) {
115   const WORD16 *ptr_sfb_offset;
116   WORD32 line = 0, sfb, total_scale_factor_bands = 0;
117 
118   switch (win_seq) {
119     case EIGHT_SHORT_SEQUENCE:
120 
121       if (win_trans == NO_TRANSITION) {
122         total_scale_factor_bands = pstr_samp_rate_info->num_sfb_128 - 1;
123         ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_128;
124 
125         for (sfb = 0; sfb < total_scale_factor_bands; sfb++) {
126           WORD32 accu = 1;
127           WORD32 q_nrg;
128           if (sfb == 0) {
129             q_nrg = (sizeof(accu) << 3) - ixheaacd_norm32(ptr_sfb_offset[sfb] - 0);
130             for (; line < ptr_sfb_offset[sfb]; line++) {
131               accu += ixheaacd_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg;
132             }
133             ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
134           }
135           q_nrg = (sizeof(accu) << 3) -
136                   ixheaacd_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
137           for (; line < ptr_sfb_offset[sfb + 1]; line++) {
138             accu += ixheaacd_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg;
139           }
140           ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
141         }
142       } else {
143         total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1;
144         ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024;
145 
146         for (sfb = 0; sfb < total_scale_factor_bands; sfb++) {
147           WORD32 accu = 1;
148           WORD32 q_nrg;
149           if (sfb == 0) {
150             q_nrg = (sizeof(accu) << 3) - ixheaacd_norm32(ptr_sfb_offset[sfb] - 0);
151             for (; line < ptr_sfb_offset[sfb]; line++) {
152               accu +=
153                   ixheaacd_mult32(ptr_spec_coeff[line >> 3], ptr_spec_coeff[line >> 3]) >> q_nrg;
154             }
155             ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
156           }
157           q_nrg = (sizeof(accu) << 3) -
158                   ixheaacd_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
159           for (; line < ptr_sfb_offset[sfb + 1]; line++) {
160             accu +=
161                 ixheaacd_mult32(ptr_spec_coeff[line >> 3], ptr_spec_coeff[line >> 3]) >> q_nrg;
162           }
163           ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
164         }
165       }
166       break;
167 
168     case ONLY_LONG_SEQUENCE:
169     case LONG_START_SEQUENCE:
170     case LONG_STOP_SEQUENCE:
171 
172       if (win_trans == NO_TRANSITION) {
173         total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1;
174         ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024;
175 
176         for (sfb = 0; sfb < total_scale_factor_bands; sfb++) {
177           WORD32 accu = 1;
178           WORD32 q_nrg;
179           if (sfb == 0) {
180             q_nrg = (sizeof(accu) << 3) - ixheaacd_norm32(ptr_sfb_offset[sfb] - 0);
181             for (; line < ptr_sfb_offset[sfb]; line++) {
182               accu += ixheaacd_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg;
183             }
184             ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
185           }
186           q_nrg = (sizeof(accu) << 3) -
187                   ixheaacd_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
188           for (; line < ptr_sfb_offset[sfb + 1]; line++) {
189             accu += ixheaacd_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg;
190           }
191           ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
192         }
193       } else {
194         total_scale_factor_bands = pstr_samp_rate_info->num_sfb_128 - 1;
195         ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_128;
196 
197         for (sfb = 0; sfb < total_scale_factor_bands; sfb++) {
198           WORD32 accu = 1;
199           WORD32 q_nrg;
200           if (sfb == 0) {
201             q_nrg = (sizeof(accu) << 3) - ixheaacd_norm32(ptr_sfb_offset[sfb] - 0);
202             for (; line < ptr_sfb_offset[sfb] << 3; line++) {
203               accu += (accu +
204                        (ixheaacd_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg)) >>
205                       3;
206             }
207             ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
208           }
209           q_nrg = (sizeof(accu) << 3) -
210                   ixheaacd_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
211           for (; line < ptr_sfb_offset[sfb + 1] << 3; line++) {
212             accu +=
213                 (accu + (ixheaacd_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg)) >>
214                 3;
215           }
216           ptr_sfb_energy[sfb] = ixheaacd_norm32(accu);
217         }
218       }
219       break;
220   }
221 }
222 
ixheaacd_aac_ec_interpolate(WORD32 * ptr_spec_coeff,WORD16 * ptr_spec_scale_prev,WORD16 * ptr_spec_scale_act,WORD16 * ptr_spec_scale_out,WORD32 * nrg_prev,WORD32 * nrg_act,WORD32 num_sfb,const WORD16 * ptr_sfb_offset)223 static VOID ixheaacd_aac_ec_interpolate(WORD32 *ptr_spec_coeff, WORD16 *ptr_spec_scale_prev,
224                                         WORD16 *ptr_spec_scale_act, WORD16 *ptr_spec_scale_out,
225                                         WORD32 *nrg_prev, WORD32 *nrg_act, WORD32 num_sfb,
226                                         const WORD16 *ptr_sfb_offset) {
227   WORD32 sfb, line = 0;
228   WORD32 fac_shift;
229   WORD32 fac_mod;
230 
231   for (sfb = 0; sfb < num_sfb; sfb++) {
232     fac_shift =
233         nrg_prev[sfb] - nrg_act[sfb] + ((*ptr_spec_scale_act - *ptr_spec_scale_prev) << 1);
234     fac_mod = fac_shift & 3;
235     fac_shift = (fac_shift >> 2) + 1;
236     fac_shift += *ptr_spec_scale_prev - max(*ptr_spec_scale_prev, *ptr_spec_scale_act);
237     fac_shift = max(min(fac_shift, INT_BITS - 1), -(INT_BITS - 1));
238 
239     for (; line < ptr_sfb_offset[sfb]; line++) {
240       WORD32 accu =
241           ixheaacd_mult32x16in32_shl(ptr_spec_coeff[line], ia_ec_interpolation_fac[fac_mod]);
242       ptr_spec_coeff[line] = ixheaacd_shl32_dir_sat(accu, fac_shift);
243     }
244   }
245   *ptr_spec_scale_out = max(*ptr_spec_scale_prev, *ptr_spec_scale_act);
246 }
247 
ixheaacd_aac_ec_state(ia_ec_state_str * pstr_ec_state,WORD32 frame_status)248 static VOID ixheaacd_aac_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_status) {
249   WORD32 ec_state_val = (pstr_ec_state->prev_frame_ok[0] << 2) +
250                         (pstr_ec_state->prev_frame_ok[1] << 1) + (frame_status);
251 
252   switch (ec_state_val) {
253     case 0:
254     case 4:
255       if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) {
256         pstr_ec_state->fade_idx++;
257       }
258       pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE;
259       break;
260     case 1:
261     case 2:
262       if (pstr_ec_state->fade_idx > 0) {
263         pstr_ec_state->fade_idx--;
264       }
265       pstr_ec_state->conceal_state = FRAME_FADE;
266       break;
267     case 5:
268       if (pstr_ec_state->fade_idx > 0) {
269         pstr_ec_state->fade_idx--;
270       }
271       pstr_ec_state->conceal_state = FRAME_OKAY;
272       break;
273       break;
274     case 3:
275     case 6:
276     case 7:
277       if (pstr_ec_state->fade_idx > 0) {
278         pstr_ec_state->fade_idx--;
279       }
280       pstr_ec_state->conceal_state = FRAME_OKAY;
281       break;
282     default:
283       pstr_ec_state->conceal_state = FRAME_OKAY;
284   }
285   if (pstr_ec_state->fade_idx > MAX_FADE_FRAMES) {
286     pstr_ec_state->fade_idx = MAX_FADE_FRAMES;
287   }
288   if (pstr_ec_state->fade_idx == MAX_FADE_FRAMES) {
289     pstr_ec_state->conceal_state = FRAME_MUTE;
290   }
291   if (pstr_ec_state->fade_idx < 0) {
292     pstr_ec_state->fade_idx = 0;
293   }
294 }
295 
ixheaacd_aac_ec_interpolate_frame(ia_ec_state_str * pstr_ec_state,ia_aac_dec_channel_info_struct * pstr_aac_dec_channel_info,const ia_usac_samp_rate_info * pstr_samp_rate_info,const WORD32 num_samples,const WORD32 frame_status,ia_ics_info_struct * pstr_ics_info)296 static VOID ixheaacd_aac_ec_interpolate_frame(
297     ia_ec_state_str *pstr_ec_state, ia_aac_dec_channel_info_struct *pstr_aac_dec_channel_info,
298     const ia_usac_samp_rate_info *pstr_samp_rate_info, const WORD32 num_samples,
299     const WORD32 frame_status, ia_ics_info_struct *pstr_ics_info) {
300   WORD32 *ptr_spec_coeff = pstr_aac_dec_channel_info->ptr_spec_coeff;
301   WORD16 *ptr_spec_scale = pstr_aac_dec_channel_info->ptr_scale_factor;
302 
303   WORD32 sfb_nrg_prev[WIN_LEN_64];
304   WORD32 sfb_nrg_act[WIN_LEN_64];
305 
306   WORD32 idx;
307 
308   memset(sfb_nrg_prev, 0, sizeof(sfb_nrg_prev));
309   memset(sfb_nrg_act, 0, sizeof(sfb_nrg_act));
310 
311   if (!frame_status) {
312     pstr_ics_info->window_shape = pstr_ec_state->win_shape;
313     pstr_ics_info->window_sequence = pstr_ec_state->win_seq;
314 
315     for (idx = 0; idx < num_samples; idx++) {
316       ptr_spec_coeff[idx] = pstr_ec_state->spectral_coeff[idx];
317     }
318 
319     memcpy(ptr_spec_scale, pstr_ec_state->q_spec_coeff, 8 * sizeof(ptr_spec_scale[0]));
320   }
321 
322   if (!pstr_ec_state->prev_frame_ok[1]) {
323     if (frame_status && pstr_ec_state->prev_frame_ok[0]) {
324       if (pstr_ics_info->window_sequence == EIGHT_SHORT_SEQUENCE) {
325         WORD32 window;
326         if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) {
327           WORD32 total_scale_factor_bands = pstr_samp_rate_info->num_sfb_128 - 1;
328           const WORD16 *ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_128;
329           pstr_ics_info->window_shape = 1;
330           pstr_ics_info->window_sequence = EIGHT_SHORT_SEQUENCE;
331 
332           for (window = 0; window < 8; window++) {
333             ixheaacd_aac_ec_calc_sfb_nrg(&ptr_spec_coeff[window * (num_samples / 8)],
334                                          pstr_samp_rate_info, EIGHT_SHORT_SEQUENCE, NO_TRANSITION,
335                                          sfb_nrg_prev);
336 
337             ixheaacd_aac_ec_calc_sfb_nrg(
338                 &pstr_ec_state->spectral_coeff[window * (num_samples / 8)], pstr_samp_rate_info,
339                 EIGHT_SHORT_SEQUENCE, NO_TRANSITION, sfb_nrg_act);
340 
341             ixheaacd_aac_ec_interpolate(
342                 &ptr_spec_coeff[window * (num_samples / 8)], &ptr_spec_scale[window],
343                 &pstr_ec_state->q_spec_coeff[window], &ptr_spec_scale[window], sfb_nrg_prev,
344                 sfb_nrg_act, total_scale_factor_bands, ptr_sfb_offset);
345           }
346         } else {
347           WORD32 total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1;
348           const WORD16 *ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024;
349           WORD16 spec_scale_out;
350 
351           ixheaacd_aac_ec_calc_sfb_nrg(&ptr_spec_coeff[num_samples - (num_samples / 8)],
352                                        pstr_samp_rate_info, EIGHT_SHORT_SEQUENCE,
353                                        TRANS_SHORT_LONG, sfb_nrg_act);
354 
355           ixheaacd_aac_ec_calc_sfb_nrg(pstr_ec_state->spectral_coeff, pstr_samp_rate_info,
356                                        ONLY_LONG_SEQUENCE, NO_TRANSITION, sfb_nrg_prev);
357 
358           pstr_ics_info->window_shape = 0;
359           pstr_ics_info->window_sequence = LONG_STOP_SEQUENCE;
360 
361           for (idx = 0; idx < num_samples; idx++) {
362             ptr_spec_coeff[idx] = pstr_ec_state->spectral_coeff[idx];
363           }
364 
365           for (idx = 0; idx < 8; idx++) {
366             if (ptr_spec_scale[idx] > ptr_spec_scale[0]) {
367               ptr_spec_scale[0] = ptr_spec_scale[idx];
368             }
369           }
370 
371           ixheaacd_aac_ec_interpolate(ptr_spec_coeff, &pstr_ec_state->q_spec_coeff[0],
372                                       &ptr_spec_scale[0], &spec_scale_out, sfb_nrg_prev,
373                                       sfb_nrg_act, total_scale_factor_bands, ptr_sfb_offset);
374 
375           ptr_spec_scale[0] = spec_scale_out;
376         }
377       } else {
378         WORD32 total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1;
379         const WORD16 *ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024;
380         WORD16 spec_scale_act = pstr_ec_state->q_spec_coeff[0];
381 
382         ixheaacd_aac_ec_calc_sfb_nrg(ptr_spec_coeff, pstr_samp_rate_info, ONLY_LONG_SEQUENCE,
383                                      NO_TRANSITION, sfb_nrg_prev);
384 
385         if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) {
386           pstr_ics_info->window_shape = 1;
387           pstr_ics_info->window_sequence = LONG_START_SEQUENCE;
388 
389           for (idx = 1; idx < 8; idx++) {
390             if (pstr_ec_state->q_spec_coeff[idx] > spec_scale_act) {
391               spec_scale_act = pstr_ec_state->q_spec_coeff[idx];
392             }
393           }
394 
395           ixheaacd_aac_ec_calc_sfb_nrg(pstr_ec_state->spectral_coeff, pstr_samp_rate_info,
396                                        EIGHT_SHORT_SEQUENCE, TRANS_SHORT_LONG, sfb_nrg_act);
397         } else {
398           pstr_ics_info->window_shape = 0;
399           pstr_ics_info->window_sequence = ONLY_LONG_SEQUENCE;
400 
401           ixheaacd_aac_ec_calc_sfb_nrg(pstr_ec_state->spectral_coeff, pstr_samp_rate_info,
402                                        ONLY_LONG_SEQUENCE, NO_TRANSITION, sfb_nrg_act);
403         }
404 
405         ixheaacd_aac_ec_interpolate(ptr_spec_coeff, &ptr_spec_scale[0], &spec_scale_act,
406                                     &ptr_spec_scale[0], sfb_nrg_prev, sfb_nrg_act,
407                                     total_scale_factor_bands, ptr_sfb_offset);
408       }
409     }
410 
411     ixheaacd_aac_ec_flip_spec_sign(ptr_spec_coeff, num_samples);
412   }
413 
414   if (FRAME_MUTE == pstr_ec_state->conceal_state) {
415     pstr_ics_info->window_shape = pstr_ec_state->win_shape;
416     pstr_ics_info->window_sequence = ixheaacd_aac_ec_get_win_seq(pstr_ec_state->win_seq);
417     pstr_ec_state->win_seq = pstr_ics_info->window_sequence;
418     memset(ptr_spec_coeff, 0, num_samples * sizeof(ptr_spec_coeff[0]));
419   }
420 }
421 
ixheaacd_aac_ec_init(ia_ec_state_str * pstr_ec_state)422 VOID ixheaacd_aac_ec_init(ia_ec_state_str *pstr_ec_state) {
423   pstr_ec_state->win_shape = CONCEAL_NOT_DEFINED;
424   pstr_ec_state->win_seq = ONLY_LONG_SEQUENCE;
425   pstr_ec_state->prev_win_group_len = 1;
426 
427   pstr_ec_state->conceal_state = FRAME_OKAY;
428 
429   memset(pstr_ec_state->spectral_coeff, 0, sizeof(pstr_ec_state->spectral_coeff));
430   memset(pstr_ec_state->q_spec_coeff, 0, sizeof(pstr_ec_state->q_spec_coeff));
431 
432   pstr_ec_state->prev_frame_ok[0] = 1;
433   pstr_ec_state->prev_frame_ok[1] = 1;
434   pstr_ec_state->fade_idx = 0;
435 }
436 
ixheaacd_aac_apply_ec(ia_ec_state_str * pstr_ec_state,ia_aac_dec_channel_info_struct * pstr_aac_dec_channel_info,const ia_usac_samp_rate_info * pstr_samp_rate_info,const WORD32 num_samples,ia_ics_info_struct * pstr_ics_info,const WORD32 frame_status)437 VOID ixheaacd_aac_apply_ec(ia_ec_state_str *pstr_ec_state,
438                            ia_aac_dec_channel_info_struct *pstr_aac_dec_channel_info,
439                            const ia_usac_samp_rate_info *pstr_samp_rate_info,
440                            const WORD32 num_samples, ia_ics_info_struct *pstr_ics_info,
441                            const WORD32 frame_status) {
442   if (pstr_ec_state->win_shape == CONCEAL_NOT_DEFINED) {
443     pstr_ec_state->win_shape = (UWORD8)pstr_ics_info->window_shape;
444   }
445 
446   if (frame_status && pstr_ec_state->prev_frame_ok[1]) {
447     ixheaacd_aac_ec_store(pstr_ec_state, pstr_aac_dec_channel_info, pstr_ics_info);
448   }
449 
450   ixheaacd_aac_ec_state(pstr_ec_state, frame_status);
451 
452   ixheaacd_aac_ec_interpolate_frame(pstr_ec_state, pstr_aac_dec_channel_info, pstr_samp_rate_info,
453                                     num_samples, frame_status, pstr_ics_info);
454 
455   pstr_ec_state->prev_frame_ok[0] = pstr_ec_state->prev_frame_ok[1];
456   pstr_ec_state->prev_frame_ok[1] = frame_status;
457 }
458