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 <string.h>
21 #include "ixheaacd_sbr_common.h"
22 #include <ixheaacd_type_def.h>
23 
24 #include "ixheaacd_constants.h"
25 #include <ixheaacd_basic_ops32.h>
26 #include <ixheaacd_basic_ops16.h>
27 #include <ixheaacd_basic_ops40.h>
28 #include "ixheaacd_basic_ops.h"
29 
30 #include <ixheaacd_basic_op.h>
31 #include "ixheaacd_intrinsics.h"
32 #include "ixheaacd_bitbuffer.h"
33 #include "ixheaacd_sbrdecsettings.h"
34 #include "ixheaacd_sbr_scale.h"
35 #include "ixheaacd_lpp_tran.h"
36 #include "ixheaacd_env_extr_part.h"
37 #include <ixheaacd_sbr_rom.h>
38 #include "ixheaacd_hybrid.h"
39 #include "ixheaacd_ps_dec.h"
40 
41 #include "ixheaacd_env_extr.h"
42 #include "ixheaacd_common_rom.h"
43 #include "ixheaacd_env_dec.h"
44 #include "ixheaacd_sbr_const.h"
45 
46 #include "ixheaacd_basic_funcs.h"
47 
48 #include "math.h"
49 
50 #define add16_m(a, b) ((a) + (b))
51 #define sub16_m(a, b) ((a) - (b))
52 
53 #define mult16x16_16(a, b) ixheaacd_mult16((a), (b))
54 
ixheaacd_dequant_esbr_env_data(FLOAT32 * ptr_env_sf,WORD32 num_env_sf,WORD32 num_noise_fac,WORD32 amp_res,FLOAT32 * ptr_noise_floor)55 static VOID ixheaacd_dequant_esbr_env_data(FLOAT32 *ptr_env_sf,
56                                            WORD32 num_env_sf,
57                                            WORD32 num_noise_fac, WORD32 amp_res,
58                                            FLOAT32 *ptr_noise_floor) {
59   WORD32 i;
60   FLOAT32 array[2] = {0.5f, 1.0f};
61   FLOAT32 a_flt = array[amp_res];
62 
63   for (i = 0; i < num_env_sf; i++) {
64     ptr_env_sf[i] = (FLOAT32)(pow(2, ptr_env_sf[i] * a_flt) * 64);
65   }
66 
67   for (i = 0; i < num_noise_fac; i++) {
68     FLOAT32 temp = ptr_noise_floor[i];
69 
70     temp = NOISE_FLOOR_OFFSET - temp;
71     temp = (FLOAT32)pow(2.0f, temp);
72 
73     ptr_noise_floor[i] = temp;
74   }
75 }
76 
ixheaacd_dequant_pvc_env_data(WORD32 num_noise_fac,FLOAT32 * ptr_noise_floor)77 static VOID ixheaacd_dequant_pvc_env_data(WORD32 num_noise_fac,
78                                           FLOAT32 *ptr_noise_floor) {
79   WORD32 i;
80 
81   for (i = 0; i < num_noise_fac; i++) {
82     FLOAT32 temp = ptr_noise_floor[i];
83 
84     temp = NOISE_FLOOR_OFFSET - temp;
85     temp = (FLOAT32)pow(2.0f, temp);
86 
87     ptr_noise_floor[i] = temp;
88   }
89 }
90 
ixheaacd_map_res_energy(WORD16 curr_val,WORD16 * prev_data,WORD32 ixheaacd_drc_offset,WORD32 index,WORD32 res)91 VOID ixheaacd_map_res_energy(WORD16 curr_val, WORD16 *prev_data,
92                              WORD32 ixheaacd_drc_offset, WORD32 index,
93                              WORD32 res) {
94   if (res == LOW) {
95     if (ixheaacd_drc_offset >= 0) {
96       if (index < ixheaacd_drc_offset) {
97         prev_data[index] = curr_val;
98       } else {
99         WORD32 index_2;
100         index_2 = ((index + index) - ixheaacd_drc_offset);
101         prev_data[index_2] = curr_val;
102         prev_data[index_2 + 1] = curr_val;
103       }
104     } else {
105       ixheaacd_drc_offset = -(ixheaacd_drc_offset);
106 
107       if (index < ixheaacd_drc_offset) {
108         WORD32 index_3;
109         index_3 = ((index + index) + index);
110         prev_data[index_3] = curr_val;
111         prev_data[index_3 + 1] = curr_val;
112         prev_data[index_3 + 2] = curr_val;
113       } else {
114         WORD32 index_2;
115         index_2 = ((index + index) + ixheaacd_drc_offset);
116         prev_data[index_2] = curr_val;
117         prev_data[index_2 + 1] = curr_val;
118       }
119     }
120   } else {
121     prev_data[index] = curr_val;
122   }
123 }
124 
ixheaacd_process_del_cod_env_data(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data,ia_sbr_prev_frame_data_struct * ptr_prev_data)125 VOID ixheaacd_process_del_cod_env_data(
126     ia_sbr_header_data_struct *ptr_header_data,
127     ia_sbr_frame_info_data_struct *ptr_sbr_data,
128     ia_sbr_prev_frame_data_struct *ptr_prev_data) {
129   WORD32 i, dtdf_dir, num_sf_bands, band, freq_res;
130   WORD16 temp_val;
131   WORD16 *ptr_prev_env_sf = ptr_prev_data->sfb_nrg_prev;
132   WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
133 
134   FLOAT32 *ptr_env_sf_float = ptr_sbr_data->flt_env_sf_arr;
135 
136   WORD32 ixheaacd_drc_offset;
137   band = 0;
138 
139   ixheaacd_drc_offset =
140       ((ptr_header_data->pstr_freq_band_data->num_sf_bands[LOW] << 1) -
141        ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH]);
142 
143   for (i = 0; i < ptr_sbr_data->str_frame_info_details.num_env; i++) {
144     dtdf_dir = ptr_sbr_data->del_cod_dir_arr[i];
145     freq_res = ptr_sbr_data->str_frame_info_details.freq_res[i];
146 
147     num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands[freq_res];
148 
149     if (dtdf_dir == DTDF_DIR_FREQ) {
150       ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf, ixheaacd_drc_offset,
151                               0, freq_res);
152       ptr_env_sf++;
153 
154       ptr_env_sf_float++;
155 
156       for (band = 1; band < num_sf_bands; band++) {
157         *ptr_env_sf = *ptr_env_sf + *(ptr_env_sf - 1);
158         ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf,
159                                 ixheaacd_drc_offset, band, freq_res);
160 
161         *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
162         ptr_env_sf_float++;
163 
164         ptr_env_sf++;
165       }
166 
167     } else {
168       if (freq_res == LOW) {
169         if (ixheaacd_drc_offset < 0) {
170           WORD32 tar, index_3;
171           ixheaacd_drc_offset = -ixheaacd_drc_offset;
172           tar = ixheaacd_min32(ixheaacd_drc_offset, band);
173 
174           for (band = 0; band < tar; band++) {
175             index_3 = ((band + band) + band);
176             temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
177 
178             ptr_prev_env_sf[index_3] = temp_val;
179             ptr_prev_env_sf[index_3 + 1] = temp_val;
180             ptr_prev_env_sf[index_3 + 2] = temp_val;
181             *ptr_env_sf++ = temp_val;
182 
183             *ptr_env_sf_float = (FLOAT32)temp_val;
184             ptr_env_sf_float++;
185           }
186 
187           for (; band < num_sf_bands; band++) {
188             index_3 = (band << 1) + ixheaacd_drc_offset;
189             temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
190             ptr_prev_env_sf[index_3] = temp_val;
191             ptr_prev_env_sf[index_3 + 1] = temp_val;
192             *ptr_env_sf++ = temp_val;
193             *ptr_env_sf_float = (FLOAT32)temp_val;
194             ptr_env_sf_float++;
195           }
196         } else {
197           WORD32 tar, index_2;
198           WORD16 *ptr2 = ptr_prev_env_sf;
199           tar = ixheaacd_min32(ixheaacd_drc_offset, band);
200           for (band = 0; band < tar; band++) {
201             *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
202             *ptr2 = *ptr_env_sf;
203 
204             *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
205             ptr_env_sf_float++;
206 
207             ptr2++;
208             ptr_env_sf++;
209           }
210 
211           for (; band < num_sf_bands; band++) {
212             index_2 = (band < ixheaacd_drc_offset)
213                           ? band
214                           : ((band << 1) - ixheaacd_drc_offset);
215             temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_2]);
216             ptr_prev_env_sf[index_2] = temp_val;
217             ptr_prev_env_sf[index_2 + 1] = temp_val;
218             *ptr_env_sf++ = temp_val;
219 
220             *ptr_env_sf_float = (FLOAT32)temp_val;
221             ptr_env_sf_float++;
222           }
223         }
224 
225       } else {
226         WORD16 *ptr2 = ptr_prev_env_sf;
227         for (band = num_sf_bands - 1; band >= 0; band--) {
228           *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
229           *ptr2 = *ptr_env_sf;
230           *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
231           ptr_env_sf_float++;
232           ptr2++;
233           ptr_env_sf++;
234         }
235         band = num_sf_bands;
236       }
237     }
238   }
239 }
240 
241 static PLATFORM_INLINE VOID
ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data,ia_sbr_prev_frame_data_struct * ptr_prev_data,ixheaacd_misc_tables * pstr_common_tables)242 ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
243                                  ia_sbr_frame_info_data_struct *ptr_sbr_data,
244                                  ia_sbr_prev_frame_data_struct *ptr_prev_data,
245                                  ixheaacd_misc_tables *pstr_common_tables) {
246   WORD32 i, num_env_sf;
247   ia_frame_info_struct *p_frame_info = &ptr_sbr_data->str_frame_info_details;
248   WORD16 *num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands;
249   WORD32 start_pos_est;
250   WORD32 ref_len, new_len, shift;
251   WORD16 delta_exp;
252 
253   start_pos_est =
254       (ptr_prev_data->end_position - ptr_header_data->num_time_slots);
255 
256   ref_len = (p_frame_info->border_vec[1] - p_frame_info->border_vec[0]);
257 
258   new_len = (p_frame_info->border_vec[1] - start_pos_est);
259 
260   if (new_len <= 0) {
261     new_len = ref_len;
262     start_pos_est = p_frame_info->border_vec[0];
263   }
264 
265   delta_exp = pstr_common_tables->log_dual_is_table[ref_len];
266   delta_exp -= pstr_common_tables->log_dual_is_table[new_len];
267 
268   shift = (SHORT_BITS - ENV_EXP_FRACT - 3 - ptr_sbr_data->amp_res);
269   delta_exp = ixheaacd_shr16(delta_exp, (WORD16)shift);
270   p_frame_info->border_vec[0] = start_pos_est;
271   p_frame_info->noise_border_vec[0] = start_pos_est;
272 
273   if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
274     num_env_sf =
275         ((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]);
276 
277     for (i = 0; i < num_env_sf; i++) {
278       ptr_sbr_data->int_env_sf_arr[i] =
279           add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp);
280     }
281   }
282 }
283 
ixheaacd_check_env_data(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data,ia_sbr_prev_frame_data_struct * ptr_prev_data)284 WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data,
285                                ia_sbr_frame_info_data_struct *ptr_sbr_data,
286                                ia_sbr_prev_frame_data_struct *ptr_prev_data) {
287   WORD16 *ptr_evn_sf = ptr_sbr_data->int_env_sf_arr;
288   WORD16 *ptr_prev_evn_sf = ptr_prev_data->sfb_nrg_prev;
289   WORD32 i;
290   FLAG error_code = 0;
291   WORD16 sbr_max_env_sf;
292   WORD32 amp_res = ptr_sbr_data->amp_res;
293 
294   sbr_max_env_sf = (SBR_ENV_SF_MAX_VAL_1_5 >> amp_res);
295 
296   for (i = 0; i < ptr_sbr_data->num_env_sfac; i++) {
297     if (ptr_evn_sf[i] > sbr_max_env_sf) {
298       error_code = 1;
299     }
300     if (ptr_evn_sf[i] < 0) {
301       ptr_evn_sf[i] = 0;
302     }
303   }
304 
305   for (i = 0; i < ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
306        i++) {
307     if (ptr_prev_evn_sf[i] < 0) {
308       ptr_prev_evn_sf[i] = 0;
309     } else {
310       if (ptr_prev_evn_sf[i] > sbr_max_env_sf)
311         ptr_prev_evn_sf[i] = sbr_max_env_sf;
312     }
313   }
314   return (WORD16)(error_code);
315 }
316 
ixheaacd_dequant_env_data(ia_sbr_frame_info_data_struct * ptr_sbr_data,WORD32 amp_res)317 VOID ixheaacd_dequant_env_data(ia_sbr_frame_info_data_struct *ptr_sbr_data,
318                                WORD32 amp_res) {
319   WORD32 i;
320   WORD32 num_env_sf = ptr_sbr_data->num_env_sfac;
321   WORD32 mantissa;
322   WORD32 amp_res_1;
323   WORD32 exponent;
324   WORD32 exp_add = (7 + NRG_EXP_OFFSET);
325   WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
326   WORD32 mant_arr[2] = {0x4000, 0x5a80};
327 
328   amp_res_1 = (1 - amp_res);
329 
330   for (i = num_env_sf - 1; i >= 0; i--) {
331     exponent = *ptr_env_sf;
332     mantissa = mant_arr[(exponent & amp_res_1)];
333     exponent = (exponent >> amp_res_1);
334     exponent = (exponent + exp_add);
335     *ptr_env_sf++ = (WORD16)(mantissa | (exponent & MASK_FOR_EXP));
336   }
337 }
338 
339 static PLATFORM_INLINE VOID
ixheaacd_limit_noise_floor_fac(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data)340 ixheaacd_limit_noise_floor_fac(ia_sbr_header_data_struct *ptr_header_data,
341                                ia_sbr_frame_info_data_struct *ptr_sbr_data) {
342   WORD32 i, tot_nf_bands;
343   WORD32 value;
344   WORD32 num_nf_bands;
345   WORD16 *ptr_noise_floor;
346 
347   num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
348 
349   tot_nf_bands =
350       ptr_sbr_data->str_frame_info_details.num_noise_env * num_nf_bands;
351 
352   ptr_noise_floor = ptr_sbr_data->int_noise_floor;
353 
354   for (i = tot_nf_bands - 1; i >= 0; i--) {
355     value = *ptr_noise_floor;
356     if (value > MAX_NOISE_FLOOR_FAC_VAL) {
357       *ptr_noise_floor = MAX_NOISE_FLOOR_FAC_VAL;
358     } else {
359       if (value < MIN_NOISE_FLOOR_FAC_VAL) {
360         *ptr_noise_floor = MIN_NOISE_FLOOR_FAC_VAL;
361       }
362     }
363     ptr_noise_floor++;
364   }
365 }
366 
ixheaacd_add_arr(WORD16 * ptr1,WORD16 * ptr2,WORD32 num)367 VOID ixheaacd_add_arr(WORD16 *ptr1, WORD16 *ptr2, WORD32 num) {
368   WORD32 i;
369   for (i = num - 1; i >= 0; i--) {
370     *ptr2 = (*ptr2 + *ptr1);
371     ptr2++;
372     ptr1++;
373   }
374 }
375 
ixheaacd_calc_noise_floor(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data,ia_sbr_prev_frame_data_struct * ptr_prev_data)376 VOID ixheaacd_calc_noise_floor(ia_sbr_header_data_struct *ptr_header_data,
377                                ia_sbr_frame_info_data_struct *ptr_sbr_data,
378                                ia_sbr_prev_frame_data_struct *ptr_prev_data) {
379   WORD32 i;
380   WORD32 num_nf_bands;
381   WORD32 num_noise_env;
382   WORD32 ixheaacd_drc_offset;
383   WORD16 *ptr_noise_floor = ptr_sbr_data->int_noise_floor;
384 
385   WORD16 *ptr_prev_noise_floor = ptr_prev_data->prev_noise_level;
386   WORD16 *ptr1, *ptr2;
387   WORD32 num;
388   FLOAT32 *ptr_noise_floor_float = ptr_sbr_data->flt_noise_floor;
389 
390   num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
391   num_noise_env = ptr_sbr_data->str_frame_info_details.num_noise_env;
392 
393   if (ptr_sbr_data->del_cod_dir_noise_arr[0] == DTDF_DIR_FREQ) {
394     ptr1 = ptr_noise_floor++;
395     ptr2 = ptr_noise_floor;
396     num = num_nf_bands - 1;
397   } else {
398     ptr1 = ptr_prev_noise_floor;
399     ptr2 = ptr_sbr_data->int_noise_floor;
400     num = num_nf_bands;
401   }
402 
403   ixheaacd_add_arr(ptr1, ptr2, num);
404 
405   if (num_noise_env > 1) {
406     if (ptr_sbr_data->del_cod_dir_noise_arr[1] == DTDF_DIR_FREQ) {
407       ptr1 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
408       ptr2 = &ptr_sbr_data->int_noise_floor[(num_nf_bands + 1)];
409 
410       num = num_nf_bands - 1;
411     } else {
412       ptr1 = &ptr_sbr_data->int_noise_floor[0];
413       ptr2 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
414 
415       num = num_nf_bands;
416     }
417     ixheaacd_add_arr(ptr1, ptr2, num);
418   }
419 
420   ixheaacd_limit_noise_floor_fac(ptr_header_data, ptr_sbr_data);
421 
422   ixheaacd_drc_offset = num_nf_bands * (num_noise_env - 1);
423   ptr1 = &ptr_sbr_data->int_noise_floor[ixheaacd_drc_offset];
424   ptr2 = ptr_prev_noise_floor;
425 
426   memcpy(ptr2, ptr1, sizeof(WORD16) * (num_nf_bands));
427 
428   if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
429     WORD32 noise_floor_exp, tot_nf_bands;
430 
431     tot_nf_bands = (num_nf_bands * num_noise_env);
432     ptr_noise_floor = &ptr_sbr_data->int_noise_floor[0];
433 
434     for (i = 0; i < tot_nf_bands; i++) {
435       noise_floor_exp =
436           (NOISE_FLOOR_OFFSET_INT + 1 + NOISE_EXP_OFFSET - *ptr_noise_floor);
437 
438       *ptr_noise_floor_float++ = *ptr_noise_floor;
439       *ptr_noise_floor++ = (WORD16)(0x4000 + (noise_floor_exp & MASK_FOR_EXP));
440     }
441   }
442 }
443 
ixheaacd_dec_sbrdata_for_pvc(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data,ia_sbr_prev_frame_data_struct * ptr_prev_data)444 VOID ixheaacd_dec_sbrdata_for_pvc(
445     ia_sbr_header_data_struct *ptr_header_data,
446     ia_sbr_frame_info_data_struct *ptr_sbr_data,
447     ia_sbr_prev_frame_data_struct *ptr_prev_data) {
448   ixheaacd_calc_noise_floor(ptr_header_data, ptr_sbr_data, ptr_prev_data);
449 
450   if (!ptr_sbr_data->coupling_mode) {
451     ptr_sbr_data->num_noise_sfac =
452         ptr_header_data->pstr_freq_band_data->num_nf_bands *
453         ptr_sbr_data->str_frame_info_details.num_noise_env;
454     ixheaacd_dequant_pvc_env_data(ptr_sbr_data->num_noise_sfac,
455                                   ptr_sbr_data->flt_noise_floor);
456   }
457 }
458 
ixheaacd_sbr_env_dequant_coup_fix(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_data_left,ia_sbr_frame_info_data_struct * ptr_data_right,ixheaacd_misc_tables * pstr_common_tables)459 VOID ixheaacd_sbr_env_dequant_coup_fix(
460     ia_sbr_header_data_struct *ptr_header_data,
461     ia_sbr_frame_info_data_struct *ptr_data_left,
462     ia_sbr_frame_info_data_struct *ptr_data_right,
463     ixheaacd_misc_tables *pstr_common_tables) {
464   WORD32 i;
465   WORD32 num_env_sf = ptr_data_left->num_env_sfac;
466   WORD16 temp_left_mant, temp_right_mant, temp_right_plus1_mant, new_left_mant,
467       new_right_mant;
468   WORD16 temp_left_exp, temp_right_exp, temp_rightplus1_exp, new_left_exp,
469       new_right_exp;
470   WORD32 i_end;
471   WORD16 *r_data = ptr_data_right->int_env_sf_arr;
472   WORD16 *l_data = ptr_data_left->int_env_sf_arr;
473 
474   for (i = 0; i < num_env_sf; i++) {
475     temp_right_mant = (WORD16)(*r_data & MASK_M);
476     temp_right_exp = (WORD16)(*r_data & MASK_FOR_EXP);
477 
478     temp_right_exp = sub16_m(temp_right_exp, add16_m(18, NRG_EXP_OFFSET));
479     temp_left_mant = (WORD16)(*l_data & MASK_M);
480     temp_left_exp = (WORD16)(*l_data & MASK_FOR_EXP);
481 
482     temp_left_exp = sub16_m(temp_left_exp, NRG_EXP_OFFSET);
483 
484     ixheaacd_fix_mant_exp_add(temp_right_mant, temp_right_exp, 0x4000, 1,
485                               &temp_right_plus1_mant, &temp_rightplus1_exp);
486 
487     new_right_exp = ixheaacd_fix_mant_div(temp_left_mant, temp_right_plus1_mant,
488                                           &new_right_mant, pstr_common_tables);
489 
490     new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;
491 
492     new_left_mant = ixheaacd_mult16_shl(temp_right_mant, new_right_mant);
493 
494     new_left_exp = add16_m(temp_right_exp, new_right_exp);
495 
496     *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
497                          ((new_right_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
498     *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
499                          ((new_left_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
500   }
501 
502   i_end = ptr_header_data->pstr_freq_band_data->num_nf_bands *
503           ptr_data_left->str_frame_info_details.num_noise_env;
504   r_data = ptr_data_right->int_noise_floor;
505   l_data = ptr_data_left->int_noise_floor;
506 
507   for (i = i_end - 1; i >= 0; i--) {
508     temp_left_exp =
509         sub16_m((WORD16)(*l_data & (WORD16)MASK_FOR_EXP), NOISE_EXP_OFFSET);
510     temp_right_exp = sub16_m(*r_data, 12);
511 
512     ixheaacd_fix_mant_exp_add(0x4000, ixheaacd_add16(1, temp_right_exp), 0x4000,
513                               1, &temp_right_plus1_mant, &temp_rightplus1_exp);
514 
515     new_right_exp = ixheaacd_fix_mant_div(0x4000, temp_right_plus1_mant,
516                                           &new_right_mant, pstr_common_tables);
517 
518     new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;
519 
520     new_left_mant = new_right_mant;
521     new_left_exp = add16_m(new_right_exp, temp_right_exp);
522     *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
523                          ((new_right_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
524     *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
525                          ((new_left_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
526   }
527 }
528 
ixheaacd_sbr_env_dequant_coup(ia_sbr_frame_info_data_struct * ptr_data_ch_0,ia_sbr_frame_info_data_struct * ptr_data_ch_1)529 VOID ixheaacd_sbr_env_dequant_coup(
530     ia_sbr_frame_info_data_struct *ptr_data_ch_0,
531     ia_sbr_frame_info_data_struct *ptr_data_ch_1) {
532   FLOAT32 *ptr_env_sf_left = ptr_data_ch_0->flt_env_sf_arr;
533   FLOAT32 *ptr_env_sf_right = ptr_data_ch_1->flt_env_sf_arr;
534   FLOAT32 *ptr_noise_floor_left = ptr_data_ch_0->flt_noise_floor;
535   FLOAT32 *ptr_noise_floor_right = ptr_data_ch_1->flt_noise_floor;
536   WORD32 num_env_sf = ptr_data_ch_0->num_env_sfac;
537   WORD32 num_noise_fac = ptr_data_ch_0->num_noise_sfac;
538   WORD32 amp_res = ptr_data_ch_0->amp_res;
539 
540   WORD32 i;
541   FLOAT32 temp_l, temp_r;
542   FLOAT32 pan_offset[2] = {24.0f, 12.0f};
543   FLOAT32 a_arr[2] = {0.5f, 1.0f};
544 
545   FLOAT32 a = a_arr[amp_res];
546 
547   for (i = 0; i < num_env_sf; i++) {
548     temp_l = ptr_env_sf_left[i];
549     temp_r = ptr_env_sf_right[i];
550 
551     ptr_env_sf_left[i] =
552         (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
553                         (1 + pow(2, (pan_offset[amp_res] - temp_r) * a))));
554     ptr_env_sf_right[i] =
555         (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
556                         (1 + pow(2, (temp_r - pan_offset[amp_res]) * a))));
557   }
558 
559   for (i = 0; i < num_noise_fac; i++) {
560     temp_l = ptr_noise_floor_left[i];
561     temp_r = ptr_noise_floor_right[i];
562 
563     ptr_noise_floor_left[i] =
564         (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
565                   (1 + pow(2, pan_offset[1] - temp_r)));
566     ptr_noise_floor_right[i] =
567         (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
568                   (1 + pow(2, temp_r - pan_offset[1])));
569   }
570 }
ixheaacd_dec_sbrdata(ia_sbr_header_data_struct * ptr_header_data_ch_0,ia_sbr_header_data_struct * ptr_header_data_ch_1,ia_sbr_frame_info_data_struct * ptr_sbr_data_ch_0,ia_sbr_prev_frame_data_struct * ptr_prev_data_ch_0,ia_sbr_frame_info_data_struct * ptr_sbr_data_ch_1,ia_sbr_prev_frame_data_struct * ptr_prev_data_ch_1,ixheaacd_misc_tables * ptr_common_tables)571 VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
572                           ia_sbr_header_data_struct *ptr_header_data_ch_1,
573                           ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
574                           ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
575                           ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
576                           ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
577                           ixheaacd_misc_tables *ptr_common_tables) {
578   FLAG error_code;
579   WORD32 usac_flag = ptr_header_data_ch_0->usac_flag;
580 
581   ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
582                         ptr_prev_data_ch_0, ptr_prev_data_ch_1,
583                         ptr_common_tables);
584 
585   ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
586                             ptr_prev_data_ch_0);
587 
588   if (!ptr_sbr_data_ch_0->coupling_mode && usac_flag) {
589     ptr_sbr_data_ch_0->num_noise_sfac =
590         ptr_header_data_ch_0->pstr_freq_band_data->num_nf_bands *
591         ptr_sbr_data_ch_0->str_frame_info_details.num_noise_env;
592 
593     ixheaacd_dequant_esbr_env_data(
594         ptr_sbr_data_ch_0->flt_env_sf_arr, ptr_sbr_data_ch_0->num_env_sfac,
595         ptr_sbr_data_ch_0->num_noise_sfac, ptr_sbr_data_ch_0->amp_res,
596         ptr_sbr_data_ch_0->flt_noise_floor);
597   }
598 
599   if (ptr_sbr_data_ch_1 != NULL) {
600     error_code = ptr_header_data_ch_0->err_flag;
601     ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
602                           ptr_prev_data_ch_1, ptr_prev_data_ch_0,
603                           ptr_common_tables);
604 
605     ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
606                               ptr_prev_data_ch_1);
607 
608     if (!ptr_sbr_data_ch_1->coupling_mode && usac_flag) {
609       ptr_sbr_data_ch_1->num_noise_sfac =
610           ptr_header_data_ch_1->pstr_freq_band_data->num_nf_bands *
611           ptr_sbr_data_ch_1->str_frame_info_details.num_noise_env;
612 
613       ixheaacd_dequant_esbr_env_data(
614           ptr_sbr_data_ch_1->flt_env_sf_arr, ptr_sbr_data_ch_1->num_env_sfac,
615           ptr_sbr_data_ch_1->num_noise_sfac, ptr_sbr_data_ch_1->amp_res,
616           ptr_sbr_data_ch_1->flt_noise_floor);
617     }
618 
619     if (!usac_flag) {
620       if (!error_code && ptr_header_data_ch_0->err_flag) {
621         ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
622                               ptr_prev_data_ch_0, ptr_prev_data_ch_1,
623                               ptr_common_tables);
624       }
625     }
626 
627     if (ptr_sbr_data_ch_0->coupling_mode) {
628       ixheaacd_sbr_env_dequant_coup_fix(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
629                                         ptr_sbr_data_ch_1, ptr_common_tables);
630 
631       ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1);
632     }
633   }
634 }
ixheaacd_dec_envelope(ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_sbr_data,ia_sbr_prev_frame_data_struct * ptr_prev_data_ch_0,ia_sbr_prev_frame_data_struct * ptr_prev_data_ch_1,ixheaacd_misc_tables * pstr_common_tables)635 VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
636                            ia_sbr_frame_info_data_struct *ptr_sbr_data,
637                            ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
638                            ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
639                            ixheaacd_misc_tables *pstr_common_tables) {
640   FLAG error_code;
641   WORD16 env_sf_local_arr[MAX_FREQ_COEFFS];
642   WORD32 usac_flag = ptr_header_data->usac_flag;
643   WORD32 temp_1 =
644       ptr_prev_data_ch_0->end_position - ptr_header_data->num_time_slots;
645   temp_1 = ptr_sbr_data->str_frame_info_details.border_vec[0] - temp_1;
646 
647   if ((!ptr_header_data->err_flag_prev) && (!ptr_header_data->err_flag) &&
648       (temp_1 != 0)) {
649     if (ptr_sbr_data->del_cod_dir_arr[0] == DTDF_DIR_TIME) {
650       ptr_header_data->err_flag = 1;
651     } else {
652       ptr_header_data->err_flag_prev = 1;
653     }
654   }
655 
656   if (ptr_header_data->err_flag && !usac_flag) {
657     ixheaacd_lean_sbrconcealment(ptr_header_data, ptr_sbr_data,
658                                  ptr_prev_data_ch_0);
659 
660     ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
661                                       ptr_prev_data_ch_0);
662   } else {
663     WORD32 num = ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
664     if (ptr_header_data->err_flag_prev && !usac_flag) {
665       WORD16 *ptr1, *ptr2;
666       WORD32 i;
667       ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
668                                        ptr_prev_data_ch_0, pstr_common_tables);
669 
670       if (ptr_sbr_data->coupling_mode !=
671           (WORD16)ptr_prev_data_ch_0->coupling_mode) {
672         if (ptr_prev_data_ch_0->coupling_mode == COUPLING_BAL) {
673           memcpy(ptr_prev_data_ch_0->sfb_nrg_prev,
674                  ptr_prev_data_ch_1->sfb_nrg_prev, sizeof(WORD16) * num);
675         } else {
676           if (ptr_sbr_data->coupling_mode == COUPLING_LEVEL) {
677             ptr1 = ptr_prev_data_ch_0->sfb_nrg_prev;
678             ptr2 = ptr_prev_data_ch_1->sfb_nrg_prev;
679 
680             for (i = 0; i < num; i++) {
681               *ptr1 = (add16_m(*ptr1, *ptr2) >> 1);
682               ptr2++;
683               ptr1++;
684             }
685           } else {
686             if (ptr_sbr_data->coupling_mode == COUPLING_BAL) {
687               memset(ptr_prev_data_ch_0->sfb_nrg_prev, SBR_ENERGY_PAN_OFFSET,
688                      sizeof(WORD16) * num);
689             }
690           }
691         }
692       }
693     }
694 
695     memcpy(env_sf_local_arr, ptr_prev_data_ch_0->sfb_nrg_prev,
696            sizeof(WORD16) * MAX_FREQ_COEFFS);
697 
698     ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
699                                       ptr_prev_data_ch_0);
700 
701     if (!usac_flag) {
702       error_code = ixheaacd_check_env_data(ptr_header_data, ptr_sbr_data,
703                                            ptr_prev_data_ch_0);
704 
705       if (error_code) {
706         ptr_header_data->err_flag = 1;
707 
708         memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr,
709                sizeof(WORD16) * MAX_FREQ_COEFFS);
710 
711         ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0,
712                               ptr_prev_data_ch_1, pstr_common_tables);
713         return;
714       }
715     }
716   }
717   if (!usac_flag)
718     ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);
719 }
720 
ixheaacd_adj_timeslot(WORD32 * ptr_buf_real,WORD32 * ptr_buf_imag,WORD16 * ptr_filt_buf,WORD16 * ptr_filt_buf_noise,WORD16 * ptr_gain_buf,WORD16 * ptr_noise_floor,WORD16 * ptr_sine_lvl_buf,WORD16 noise_floor_exp,WORD16 * ptr_harm_index,WORD16 sub_band_start,WORD16 num_sub_bands,WORD16 scale_change,WORD16 smooth_ratio,FLAG num_noise_flg,WORD16 * ptr_phase_index,ia_sbr_tables_struct * ptr_sbr_tables)721 VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag,
722                            WORD16 *ptr_filt_buf, WORD16 *ptr_filt_buf_noise,
723                            WORD16 *ptr_gain_buf, WORD16 *ptr_noise_floor,
724                            WORD16 *ptr_sine_lvl_buf, WORD16 noise_floor_exp,
725                            WORD16 *ptr_harm_index, WORD16 sub_band_start,
726                            WORD16 num_sub_bands, WORD16 scale_change,
727                            WORD16 smooth_ratio, FLAG num_noise_flg,
728                            WORD16 *ptr_phase_index,
729                            ia_sbr_tables_struct *ptr_sbr_tables) {
730   WORD16 k;
731   WORD16 *ptr_smoothed_gain, *ptr_smoothed_noise;
732   WORD16 direct_ratio;
733   WORD32 index = *ptr_phase_index;
734   WORD32 harm_idx = *ptr_harm_index;
735   WORD32 freq_inv_flag;
736   const WORD32 *ptr_rand_ph_buf;
737   WORD32 factor = 0;
738 
739   direct_ratio = ixheaacd_sub16_sat(0x7fff, smooth_ratio);
740   freq_inv_flag = (sub_band_start & 1);
741 
742   scale_change = scale_change - 1;
743 
744   ptr_rand_ph_buf = &ptr_sbr_tables->sbr_rand_ph[index];
745   *ptr_phase_index =
746       (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));
747 
748   if (smooth_ratio) {
749     WORD16 *ptr_filt_buf_local = &ptr_filt_buf[0];
750     WORD16 *ptr_gain_buf_local = &ptr_gain_buf[0];
751     WORD16 *ptr_filt_noise_local = &ptr_filt_buf_noise[0];
752     WORD16 *ptr_noise_floor_local = &ptr_noise_floor[0];
753 
754     WORD16 tmp, tmp1;
755 
756     for (k = 0; k < num_sub_bands; k++) {
757       tmp = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_buf_local),
758                     mult16x16_16(direct_ratio, *ptr_gain_buf_local++));
759 
760       ptr_gain_buf_local++;
761 
762       tmp1 = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_noise_local),
763                      mult16x16_16(direct_ratio, *ptr_noise_floor_local++));
764 
765       ptr_noise_floor_local++;
766 
767       *ptr_filt_buf_local++ = tmp << 1;
768       ptr_filt_buf_local++;
769       *ptr_filt_noise_local++ = tmp1 << 1;
770     }
771     ptr_smoothed_gain = ptr_filt_buf;
772     ptr_smoothed_noise = ptr_filt_buf_noise;
773     factor = 1;
774   } else {
775     ptr_smoothed_gain = ptr_gain_buf;
776     ptr_smoothed_noise = ptr_noise_floor;
777     factor = 2;
778   }
779 
780   switch (harm_idx) {
781     case 0:
782     case 2:
783       ixheaacd_harm_idx_zerotwo(num_noise_flg, num_sub_bands, ptr_buf_real,
784                                 ptr_buf_imag, ptr_smoothed_gain,
785                                 ptr_smoothed_noise, factor, ptr_gain_buf,
786                                 scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf,
787                                 noise_floor_exp, harm_idx);
788       break;
789     case 1:
790     case 3:
791       ixheaacd_harm_idx_onethree(
792           num_noise_flg, num_sub_bands, ptr_buf_real, ptr_buf_imag,
793           ptr_smoothed_gain, ptr_smoothed_noise, factor, ptr_gain_buf,
794           scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf, noise_floor_exp,
795           freq_inv_flag, harm_idx);
796       break;
797   }
798   *ptr_harm_index = (WORD16)((harm_idx + 1) & 3);
799 }
800