• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ixheaacd_sbr_common.h"
21 #include "ixheaacd_type_def.h"
22 
23 #include "ixheaacd_constants.h"
24 #include "ixheaacd_basic_ops32.h"
25 #include "ixheaacd_basic_ops16.h"
26 #include "ixheaacd_basic_ops40.h"
27 #include "ixheaacd_basic_ops.h"
28 
29 #include "ixheaacd_intrinsics.h"
30 #include "ixheaacd_bitbuffer.h"
31 #include "ixheaacd_sbrdecsettings.h"
32 #include "ixheaacd_defines.h"
33 
34 #include "ixheaacd_pns.h"
35 
36 #include "ixheaacd_aac_rom.h"
37 #include "ixheaacd_pulsedata.h"
38 #include "ixheaacd_drc_data_struct.h"
39 
40 #include "ixheaacd_lt_predict.h"
41 
42 #include "ixheaacd_cnst.h"
43 #include "ixheaacd_ec_defines.h"
44 #include "ixheaacd_ec_struct_def.h"
45 #include "ixheaacd_channelinfo.h"
46 #include "ixheaacd_drc_dec.h"
47 
48 #include "ixheaacd_sbrdecoder.h"
49 #include "ixheaacd_sbr_scale.h"
50 #include "ixheaacd_lpp_tran.h"
51 
52 #include "ixheaacd_env_extr_part.h"
53 #include "ixheaacd_sbr_rom.h"
54 #include "ixheaacd_hybrid.h"
55 #include "ixheaacd_ps_dec.h"
56 #include "ixheaacd_env_extr.h"
57 
58 #include "ixheaacd_sbr_const.h"
59 #include "ixheaacd_common_rom.h"
60 #include "ixheaacd_freq_sca.h"
61 
62 #include "ixheaacd_basic_funcs.h"
63 #include "ixheaacd_env_extr.h"
64 
65 #include "ixheaacd_env_calc.h"
66 #include "ixheaacd_basic_op.h"
67 
68 #include "ixheaacd_qmf_dec.h"
69 
70 #include "ixheaacd_pvc_dec.h"
71 #include "ixheaacd_sbr_dec.h"
72 #include "ixheaacd_function_selector.h"
73 
74 #include "ixheaacd_audioobjtypes.h"
75 
76 #define FACTOR 0x010b0000 * 2
77 
ixheaacd_alias_reduction(WORD16 * deg_patched,WORD16 * nrg_gain,WORD16 * nrg_est,WORD8 * alias_red_buf,WORD32 num_sub_bands,ixheaacd_misc_tables * pstr_common_tables)78 static VOID ixheaacd_alias_reduction(WORD16 *deg_patched, WORD16 *nrg_gain,
79                                      WORD16 *nrg_est, WORD8 *alias_red_buf,
80                                      WORD32 num_sub_bands,
81                                      ixheaacd_misc_tables *pstr_common_tables) {
82   WORD32 group, grouping, i, num_groups, k;
83   WORD16 f_group_vec[MAX_FREQ_COEFFS], *ptr_f_group_vec;
84 
85   grouping = 0;
86   i = 0;
87 
88   for (k = 0; k < num_sub_bands - 1; k++) {
89     if ((deg_patched[k + 1] != 0) && alias_red_buf[k]) {
90       if (grouping == 0) {
91         f_group_vec[i] = k;
92         grouping = 1;
93         i++;
94       } else {
95         if ((f_group_vec[i - 1] + 3) == k) {
96           f_group_vec[i] = (k + 1);
97           grouping = 0;
98           i++;
99         }
100       }
101     } else {
102       if (grouping) {
103         grouping = 0;
104         f_group_vec[i] = k;
105 
106         if (alias_red_buf[k]) f_group_vec[i] = k + 1;
107 
108         i++;
109       }
110     }
111   }
112 
113   if (grouping) {
114     f_group_vec[i] = num_sub_bands;
115     i++;
116   }
117   num_groups = (i >> 1);
118 
119   ptr_f_group_vec = f_group_vec;
120 
121   for (group = num_groups; group != 0; group--) {
122     WORD16 nrg_amp_mant;
123     WORD16 nrg_amp_exp;
124     WORD16 nrgMod_m;
125     WORD16 nrgMod_e;
126     WORD16 grp_gain_mant;
127     WORD16 grp_gain_exp;
128     WORD16 compensation_m;
129     WORD16 compensation_e;
130     WORD32 nrg_mod_mant;
131     WORD32 nrg_mod_exp;
132 
133     WORD32 start_grp = *ptr_f_group_vec++;
134     WORD32 stop_grp = *ptr_f_group_vec++;
135 
136     ixheaacd_avggain_calc(nrg_est, nrg_gain, start_grp, stop_grp, &nrg_amp_mant,
137                           &nrg_amp_exp, &grp_gain_mant, &grp_gain_exp,
138                           pstr_common_tables, 1);
139 
140     nrg_mod_mant = 0;
141     nrg_mod_exp = 0;
142     {
143       WORD16 *ptr_nrg_gain_mant = &nrg_gain[2 * start_grp];
144 
145       for (k = start_grp; k < stop_grp; k++) {
146         WORD32 tmp_mant, tmp_gain_mant, gain_m;
147         WORD32 tmp_e, tmp_gain_exp;
148         WORD16 one_minus_alpha, alpha = deg_patched[k];
149 
150         if (k < (num_sub_bands - 1)) {
151           alpha = ixheaacd_max16(deg_patched[k + 1], alpha);
152         }
153         gain_m = (alpha * grp_gain_mant);
154         one_minus_alpha = 0x7fff - alpha;
155 
156         tmp_gain_mant = *ptr_nrg_gain_mant;
157         tmp_gain_exp = *(ptr_nrg_gain_mant + 1);
158 
159         {
160           WORD32 exp_diff;
161 
162           tmp_gain_mant = (one_minus_alpha * tmp_gain_mant) >> 15;
163 
164           exp_diff = (grp_gain_exp - tmp_gain_exp);
165 
166           if (exp_diff >= 0) {
167             tmp_gain_exp = grp_gain_exp;
168             tmp_gain_mant = ixheaacd_shr32(tmp_gain_mant, exp_diff);
169 
170             tmp_gain_mant = (gain_m >> 15) + tmp_gain_mant;
171 
172           } else {
173             tmp_gain_mant =
174                 (ixheaacd_shr32(gain_m, (15 - exp_diff))) + tmp_gain_mant;
175           }
176         }
177         *ptr_nrg_gain_mant++ = tmp_gain_mant;
178         *ptr_nrg_gain_mant++ = tmp_gain_exp;
179 
180         tmp_mant = (tmp_gain_mant * (nrg_est[2 * k])) >> 16;
181         tmp_e = (tmp_gain_exp + (nrg_est[2 * k + 1]) + 1);
182 
183         {
184           WORD32 exp_diff;
185           exp_diff = tmp_e - nrg_mod_exp;
186           if (exp_diff >= 0) {
187             nrg_mod_mant = tmp_mant + (ixheaacd_shr32(nrg_mod_mant, exp_diff));
188             nrg_mod_exp = tmp_e;
189           } else {
190             exp_diff = -exp_diff;
191             nrg_mod_mant = (ixheaacd_shr32(tmp_mant, exp_diff)) + nrg_mod_mant;
192           }
193         }
194       }
195     }
196 
197     {
198       WORD32 norm_val;
199       norm_val = 16 - ixheaacd_pnorm32(nrg_mod_mant);
200       if (norm_val > 0) {
201         nrg_mod_mant >>= norm_val;
202         nrg_mod_exp += norm_val;
203       }
204     }
205 
206     nrgMod_m = (WORD16)nrg_mod_mant;
207     nrgMod_e = (WORD16)nrg_mod_exp;
208 
209     compensation_e = ixheaacd_fix_mant_div(nrg_amp_mant, nrgMod_m,
210                                            &compensation_m, pstr_common_tables);
211     compensation_e += nrg_amp_exp - nrgMod_e + 1 + 1;
212 
213     {
214       WORD16 *ptr_nrg_gain_mant = &nrg_gain[2 * start_grp];
215 
216       for (k = stop_grp - start_grp; k != 0; k--) {
217         WORD16 temp1, temp2;
218         temp1 = *ptr_nrg_gain_mant;
219         temp2 = *(ptr_nrg_gain_mant + 1);
220         temp1 = (temp1 * compensation_m) >> 16;
221         temp2 = (temp2 + compensation_e);
222         *ptr_nrg_gain_mant++ = temp1;
223         *ptr_nrg_gain_mant++ = temp2;
224       }
225     }
226   }
227 }
228 
ixheaacd_noiselimiting(ia_freq_band_data_struct * pstr_freq_band_data,WORD32 skip_bands,WORD16 * ptr_enrg_orig,WORD16 * nrg_est,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD16 * nrg_sine,WORD16 * ptr_limit_gain_table,FLAG noise_absc_flag,ixheaacd_misc_tables * pstr_common_tables)229 VOID ixheaacd_noiselimiting(ia_freq_band_data_struct *pstr_freq_band_data,
230                             WORD32 skip_bands, WORD16 *ptr_enrg_orig,
231                             WORD16 *nrg_est, WORD16 *nrg_gain,
232                             WORD16 *noise_level_mant, WORD16 *nrg_sine,
233                             WORD16 *ptr_limit_gain_table, FLAG noise_absc_flag,
234                             ixheaacd_misc_tables *pstr_common_tables) {
235   WORD32 c, k;
236   WORD32 temp_val;
237   WORD16 limit_gain_mant = *ptr_limit_gain_table++;
238   WORD16 limit_gain_exp = *ptr_limit_gain_table;
239   for (c = 0; c < pstr_freq_band_data->num_lf_bands; c++) {
240     WORD16 max_gain_mant;
241     WORD16 sum_orig_mant, sum_orig_exp;
242     WORD16 max_gain_exp;
243     WORD32 max_temp;
244     WORD32 start_band = 0;
245     WORD32 stop_band = 0;
246 
247     if ((pstr_freq_band_data->freq_band_tbl_lim[c] > skip_bands)) {
248       start_band = (pstr_freq_band_data->freq_band_tbl_lim[c] - skip_bands);
249     }
250 
251     if ((pstr_freq_band_data->freq_band_tbl_lim[c + 1] > skip_bands)) {
252       stop_band = (pstr_freq_band_data->freq_band_tbl_lim[c + 1] - skip_bands);
253     }
254 
255     if ((start_band < stop_band)) {
256       ixheaacd_avggain_calc(ptr_enrg_orig, nrg_est, start_band, stop_band,
257                             &sum_orig_mant, &sum_orig_exp, &max_gain_mant,
258                             &max_gain_exp, pstr_common_tables, 0);
259 
260       max_temp = ixheaacd_mult16x16in32_shl(max_gain_mant, limit_gain_mant);
261       max_gain_exp = (max_gain_exp + limit_gain_exp);
262 
263       temp_val = ixheaacd_norm32(max_temp);
264 
265       max_gain_exp = (WORD16)(max_gain_exp - temp_val);
266       max_gain_mant = (WORD16)((max_temp << temp_val) >> 16);
267 
268       if ((max_gain_exp >= MAX_GAIN_EXP)) {
269         max_gain_mant = 0x3000;
270         max_gain_exp = MAX_GAIN_EXP;
271       }
272 
273       {
274         WORD16 *ptr_nrg_gain = &nrg_gain[2 * start_band];
275         WORD16 *p_noise_level = &noise_level_mant[2 * start_band];
276 
277         for (k = stop_band - start_band; k != 0; k--) {
278           WORD16 noise_amp_mant;
279           WORD16 noise_amp_exp;
280 
281           WORD16 t_gain_mant = *(ptr_nrg_gain);
282           WORD16 t_gain_exp = *(ptr_nrg_gain + 1);
283 
284           if (((t_gain_exp > max_gain_exp)) ||
285               ((t_gain_exp == max_gain_exp) && (t_gain_mant > max_gain_mant))) {
286             noise_amp_exp =
287                 ixheaacd_fix_mant_div(max_gain_mant, t_gain_mant,
288                                       &noise_amp_mant, pstr_common_tables);
289             noise_amp_exp += (max_gain_exp - t_gain_exp) + 1;
290 
291             *p_noise_level = ixheaacd_extract16h(ixheaacd_shl32_dir_sat_limit(
292                 ixheaacd_mult16x16in32_shl(*p_noise_level, noise_amp_mant),
293                 noise_amp_exp));
294 
295             *ptr_nrg_gain = max_gain_mant;
296             *(ptr_nrg_gain + 1) = max_gain_exp;
297           }
298           ptr_nrg_gain += 2;
299           p_noise_level += 2;
300         }
301       }
302 
303       {
304         WORD16 boost_gain_mant;
305         WORD16 boost_gain_exp;
306         WORD16 accu_m;
307         WORD16 accu_e;
308         WORD32 accu_m_t;
309         WORD32 accu_e_t;
310         WORD16 *ptr_nrg_gain = &nrg_gain[2 * start_band];
311         WORD16 *ptr_enrg_est_buf = &nrg_est[2 * start_band];
312         WORD16 *p_noise_level = &noise_level_mant[2 * start_band];
313         WORD16 *p_nrg_sine = &nrg_sine[2 * start_band];
314 
315         accu_m_t = 0;
316         accu_e_t = 0;
317 
318         for (k = stop_band - start_band; k != 0; k--) {
319           WORD32 tmp_mant, tmp_e;
320 
321           tmp_mant = *ptr_nrg_gain++;
322           tmp_e = *ptr_nrg_gain++;
323           tmp_mant = (tmp_mant * (*ptr_enrg_est_buf++));
324           tmp_e = (tmp_e + (*ptr_enrg_est_buf++));
325           tmp_mant = tmp_mant >> 15;
326           {
327             WORD32 exp_diff;
328             exp_diff = tmp_e - accu_e_t;
329             if (exp_diff >= 0) {
330               accu_m_t = tmp_mant + ixheaacd_shr32(accu_m_t, exp_diff);
331               accu_e_t = tmp_e;
332             } else {
333               exp_diff = -exp_diff;
334               accu_m_t = ixheaacd_shr32(tmp_mant, exp_diff) + accu_m_t;
335             }
336           }
337 
338           if (p_nrg_sine[0] != 0) {
339             WORD32 exp_diff = p_nrg_sine[1] - accu_e_t;
340             if (exp_diff >= 0) {
341               accu_m_t = p_nrg_sine[0] + ixheaacd_shr32(accu_m_t, exp_diff);
342               accu_e_t = p_nrg_sine[1];
343             } else {
344               exp_diff = -exp_diff;
345               accu_m_t = accu_m_t + ixheaacd_shr32(p_nrg_sine[0], exp_diff);
346             }
347 
348           } else {
349             if (noise_absc_flag == 0) {
350               WORD32 exp_diff = p_noise_level[1] - accu_e_t;
351               if (exp_diff >= 0) {
352                 accu_m_t =
353                     p_noise_level[0] + ixheaacd_shr32(accu_m_t, exp_diff);
354                 accu_e_t = p_noise_level[1];
355               } else {
356                 exp_diff = -exp_diff;
357                 accu_m_t =
358                     accu_m_t + ixheaacd_shr32(p_noise_level[0], exp_diff);
359               }
360             }
361           }
362           p_noise_level += 2;
363           p_nrg_sine += 2;
364         }
365 
366         {
367           WORD32 norm_val;
368           norm_val = 16 - ixheaacd_norm32(accu_m_t);
369           if (norm_val > 0) {
370             accu_m_t >>= norm_val;
371             accu_e_t += norm_val;
372           }
373         }
374 
375         accu_m = (WORD16)accu_m_t;
376         accu_e = (WORD16)accu_e_t;
377 
378         boost_gain_exp = ixheaacd_fix_mant_div(
379             sum_orig_mant, accu_m, &boost_gain_mant, pstr_common_tables);
380 
381         boost_gain_exp += (sum_orig_exp - accu_e) + 1;
382 
383         if ((boost_gain_exp > 2) ||
384             ((boost_gain_exp == 2) && (boost_gain_mant > 0x5061))) {
385           boost_gain_mant = 0x5061;
386           boost_gain_exp = 2;
387         }
388 
389         ptr_nrg_gain = &nrg_gain[2 * start_band];
390         p_noise_level = &noise_level_mant[2 * start_band];
391         p_nrg_sine = &nrg_sine[2 * start_band];
392 
393         for (k = stop_band - start_band; k != 0; k--) {
394           WORD16 temp1, temp2, temp3;
395 
396           temp1 = *ptr_nrg_gain;
397           temp2 = *p_nrg_sine;
398           temp3 = *p_noise_level;
399 
400           temp1 = ixheaacd_mult16_shl(temp1, boost_gain_mant);
401           temp2 = ixheaacd_mult16_shl(temp2, boost_gain_mant);
402           temp3 = ixheaacd_mult16_shl(temp3, boost_gain_mant);
403           *ptr_nrg_gain++ = temp1;
404           *p_nrg_sine++ = temp2;
405           *p_noise_level++ = temp3;
406 
407           temp1 = *ptr_nrg_gain;
408           temp2 = *p_nrg_sine;
409           temp3 = *p_noise_level;
410 
411           temp1 = (temp1 + boost_gain_exp);
412           temp2 = (temp2 + boost_gain_exp);
413           temp3 = (temp3 + boost_gain_exp);
414           *ptr_nrg_gain++ = (temp1);
415           *p_nrg_sine++ = (temp2);
416           *p_noise_level++ = (temp3);
417         }
418       }
419     }
420   }
421 }
422 
ixheaacd_conv_ergtoamplitudelp_dec(WORD32 bands,WORD16 noise_e,WORD16 * nrg_sine,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD16 * sqrt_table)423 VOID ixheaacd_conv_ergtoamplitudelp_dec(WORD32 bands, WORD16 noise_e,
424                                         WORD16 *nrg_sine, WORD16 *nrg_gain,
425                                         WORD16 *noise_level_mant,
426                                         WORD16 *sqrt_table) {
427   WORD32 k;
428   for (k = 0; k < bands; k++) {
429     WORD32 shift;
430     ixheaacd_fix_mant_exp_sqrt(&nrg_sine[2 * k], sqrt_table);
431     ixheaacd_fix_mant_exp_sqrt(&nrg_gain[2 * k], sqrt_table);
432     ixheaacd_fix_mant_exp_sqrt(&noise_level_mant[2 * k], sqrt_table);
433 
434     shift = (noise_e - noise_level_mant[2 * k + 1]);
435 
436     shift = (shift - 4);
437     if (shift > 0)
438       noise_level_mant[2 * k] = (noise_level_mant[2 * k] >> shift);
439     else
440       noise_level_mant[2 * k] = (noise_level_mant[2 * k] << -shift);
441 
442     shift = (nrg_sine[2 * k + 1] - noise_e);
443     if (shift > 0)
444       nrg_sine[2 * k] = ixheaacd_shl16_sat(nrg_sine[2 * k], (WORD16)shift);
445     else
446       nrg_sine[2 * k] = ixheaacd_shr16(nrg_sine[2 * k], (WORD16)-shift);
447   }
448 }
449 
ixheaacd_conv_ergtoamplitude_dec(WORD32 bands,WORD16 noise_e,WORD16 * nrg_sine,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD16 * sqrt_table)450 VOID ixheaacd_conv_ergtoamplitude_dec(WORD32 bands, WORD16 noise_e,
451                                       WORD16 *nrg_sine, WORD16 *nrg_gain,
452                                       WORD16 *noise_level_mant,
453                                       WORD16 *sqrt_table) {
454   WORD32 k;
455   for (k = 0; k < bands; k++) {
456     WORD32 shift;
457 
458     ixheaacd_fix_mant_exp_sqrt(&nrg_sine[2 * k], sqrt_table);
459     ixheaacd_fix_mant_exp_sqrt(&nrg_gain[2 * k], sqrt_table);
460     ixheaacd_fix_mant_exp_sqrt(&noise_level_mant[2 * k], sqrt_table);
461 
462     shift = (noise_e - noise_level_mant[2 * k + 1]);
463 
464     shift = (shift - 4);
465     if (shift > 0)
466       noise_level_mant[2 * k] = (noise_level_mant[2 * k] >> shift);
467     else
468       noise_level_mant[2 * k] = (noise_level_mant[2 * k] << -shift);
469   }
470 }
471 
ixheaacd_adapt_noise_gain_calc(ia_sbr_calc_env_struct * ptr_sbr_calc_env,WORD32 noise_e,WORD32 num_sub_bands,WORD32 skip_bands,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD16 * nrg_sine,WORD32 start_pos,WORD32 end_pos,WORD32 input_e,WORD32 adj_e,WORD32 final_e,WORD32 sub_band_start,WORD32 lb_scale,FLAG noise_absc_flag,WORD32 smooth_length,WORD32 ** anal_buf_real_mant,WORD32 ** anal_buf_imag_mant,WORD32 low_pow_flag,ia_sbr_tables_struct * ptr_sbr_tables,WORD16 max_cols)472 static PLATFORM_INLINE VOID ixheaacd_adapt_noise_gain_calc(
473     ia_sbr_calc_env_struct *ptr_sbr_calc_env, WORD32 noise_e,
474     WORD32 num_sub_bands, WORD32 skip_bands, WORD16 *nrg_gain,
475     WORD16 *noise_level_mant, WORD16 *nrg_sine, WORD32 start_pos,
476     WORD32 end_pos, WORD32 input_e, WORD32 adj_e, WORD32 final_e,
477     WORD32 sub_band_start, WORD32 lb_scale, FLAG noise_absc_flag,
478     WORD32 smooth_length, WORD32 **anal_buf_real_mant,
479     WORD32 **anal_buf_imag_mant, WORD32 low_pow_flag,
480     ia_sbr_tables_struct *ptr_sbr_tables, WORD16 max_cols) {
481   WORD32 l, k;
482   WORD32 scale_change;
483   WORD32 bands = num_sub_bands - skip_bands;
484   WORD16 *ptr_filt_buf;
485   WORD16 *ptr_filt_buf_noise;
486   WORD16 *ptr_gain = &nrg_gain[0];
487 
488   if (ptr_sbr_calc_env->start_up) {
489     WORD16 *ptr_noise = noise_level_mant;
490     ptr_sbr_calc_env->start_up = 0;
491 
492     ptr_sbr_calc_env->filt_buf_noise_e = noise_e;
493     ptr_filt_buf = &ptr_sbr_calc_env->filt_buf_me[skip_bands * 2];
494     ptr_filt_buf_noise = &ptr_sbr_calc_env->filt_buf_noise_m[skip_bands];
495 
496     for (k = bands; k != 0; k--) {
497       WORD16 temp1 = *ptr_gain++;
498       WORD16 temp2 = *ptr_gain++;
499       WORD16 temp3 = *ptr_noise;
500       ptr_noise += 2;
501 
502       *ptr_filt_buf++ = temp1;
503       *ptr_filt_buf++ = temp2;
504       *ptr_filt_buf_noise++ = temp3;
505     }
506   } else {
507     ixheaacd_equalize_filt_buff_exp(
508         &ptr_sbr_calc_env->filt_buf_me[2 * skip_bands], nrg_gain, bands);
509   }
510 
511   for (l = start_pos; l < end_pos; l++) {
512 
513     if (max_cols != 30) {
514       if ((l < MAX_COLS)) {
515         scale_change = (adj_e - input_e);
516       } else {
517         scale_change = (final_e - input_e);
518 
519         if (((l == MAX_COLS)) && ((start_pos < MAX_COLS))) {
520           WORD32 diff = final_e - noise_e;
521           noise_e = final_e;
522           ixheaacd_noise_level_rescaling(noise_level_mant, diff, bands, 2);
523         }
524       }
525     } else {
526       if ((l < max_cols)) {
527         scale_change = (adj_e - input_e);
528       } else {
529         scale_change = (final_e - input_e);
530 
531         if (((l == max_cols)) && ((start_pos < max_cols))) {
532           WORD32 diff = final_e - noise_e;
533           noise_e = final_e;
534           ixheaacd_noise_level_rescaling(noise_level_mant, diff, bands, 2);
535         }
536       }
537     }
538 
539     ixheaacd_noise_level_rescaling(ptr_sbr_calc_env->filt_buf_noise_m,
540                                    ptr_sbr_calc_env->filt_buf_noise_e - noise_e,
541                                    num_sub_bands, 1);
542 
543     ptr_sbr_calc_env->filt_buf_noise_e = noise_e;
544 
545     {
546       WORD32 *anal_buf_real_m_l;
547       anal_buf_real_m_l = anal_buf_real_mant[l];
548 
549       if (low_pow_flag) {
550         WORD32 index = ptr_sbr_calc_env->ph_index;
551         WORD32 harm_index = ptr_sbr_calc_env->harm_index;
552         WORD32 freq_inv_flag = (sub_band_start & 1);
553         WORD32 *ptr_real_buf = &anal_buf_real_m_l[sub_band_start];
554 
555         const WORD32 *ptr_rand_ph = &ptr_sbr_tables->sbr_rand_ph[index + 1];
556 
557         ptr_sbr_calc_env->ph_index =
558             (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));
559         ptr_sbr_calc_env->harm_index = (WORD16)(((harm_index + 1)) & 3);
560 
561         if (!(harm_index & 0x1)) {
562           (*ixheaacd_harm_idx_zerotwolp)(
563               ptr_real_buf, nrg_gain, scale_change, nrg_sine, ptr_rand_ph,
564               noise_level_mant, num_sub_bands, noise_absc_flag, harm_index);
565         } else {
566           WORD32 noise = (noise_e - 16) - lb_scale;
567 
568           freq_inv_flag = (!freq_inv_flag);
569           freq_inv_flag = (freq_inv_flag << 1) - 1;
570 
571           if (harm_index == 3) freq_inv_flag = -freq_inv_flag;
572 
573           ixheaacd_harm_idx_onethreelp(ptr_real_buf, nrg_gain, scale_change,
574                                        nrg_sine, ptr_rand_ph, noise_level_mant,
575                                        num_sub_bands, noise_absc_flag,
576                                        freq_inv_flag, noise, sub_band_start);
577         }
578 
579       } else {
580         WORD16 smooth_ratio;
581         WORD32 *anal_buf_imag_m_l;
582         anal_buf_imag_m_l = anal_buf_imag_mant[l];
583 
584         if (((l - start_pos) < smooth_length)) {
585           smooth_ratio = ptr_sbr_tables->env_calc_tables_ptr
586                              ->sbr_smooth_filter[(l - start_pos)];
587         } else {
588           smooth_ratio = 0;
589         }
590 
591         ixheaacd_adj_timeslot(
592             &anal_buf_real_m_l[sub_band_start],
593             &anal_buf_imag_m_l[sub_band_start],
594             &ptr_sbr_calc_env->filt_buf_me[2 * skip_bands],
595             &ptr_sbr_calc_env->filt_buf_noise_m[skip_bands], nrg_gain,
596             noise_level_mant, nrg_sine, (WORD16)(noise_e - 16),
597             &ptr_sbr_calc_env->harm_index, (WORD16)sub_band_start,
598             (WORD16)(bands), (WORD16)scale_change, smooth_ratio,
599             noise_absc_flag, &ptr_sbr_calc_env->ph_index, ptr_sbr_tables);
600       }
601     }
602   }
603 
604   ixheaacd_filt_buf_update(ptr_sbr_calc_env->filt_buf_me + 2 * skip_bands,
605                            ptr_sbr_calc_env->filt_buf_noise_m + skip_bands,
606                            nrg_gain, noise_level_mant, bands);
607 }
608 
ixheaacd_calc_subband_gains(ia_freq_band_data_struct * pstr_freq_band_data,ia_sbr_frame_info_data_struct * ptr_frame_data,WORD32 freq_res,WORD16 * ptr_noise_floor,WORD32 num_sf_bands,WORD32 mvalue,WORD32 env,WORD8 * sine_mapped_matrix,WORD8 * alias_red_buf,WORD16 * ptr_enrg_orig,WORD16 * nrg_sine,WORD16 * nrg_est,WORD16 * nrg_gain,WORD16 * noise_level_mant,FLAG noise_absc_flag,ixheaacd_misc_tables * pstr_common_tables)609 VOID ixheaacd_calc_subband_gains(ia_freq_band_data_struct *pstr_freq_band_data,
610                                  ia_sbr_frame_info_data_struct *ptr_frame_data,
611                                  WORD32 freq_res, WORD16 *ptr_noise_floor,
612                                  WORD32 num_sf_bands, WORD32 mvalue, WORD32 env,
613                                  WORD8 *sine_mapped_matrix,
614                                  WORD8 *alias_red_buf, WORD16 *ptr_enrg_orig,
615                                  WORD16 *nrg_sine, WORD16 *nrg_est,
616                                  WORD16 *nrg_gain, WORD16 *noise_level_mant,
617                                  FLAG noise_absc_flag,
618                                  ixheaacd_misc_tables *pstr_common_tables) {
619   WORD16 *ptr_freq_band_tbl = pstr_freq_band_data->freq_band_table[freq_res];
620   WORD32 ui_noise = pstr_freq_band_data->freq_band_tbl_noise[1];
621   WORD32 nb_idx = 0;
622   WORD16 tmp_noise_mant;
623   WORD16 tmp_noise_exp;
624   WORD8 *ptr_sine_mapped = sine_mapped_matrix;
625   WORD32 sub_band_start = pstr_freq_band_data->sub_band_start;
626   WORD32 skip_bands = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
627   WORD8 *ptr_sine_mapped_1 = &sine_mapped_matrix[skip_bands];
628   WORD32 k, c = 0, j;
629 
630   WORD16 *ptr_env_sf_arr = &ptr_frame_data->int_env_sf_arr[mvalue];
631   WORD8 *ptr_alias_red_buf =
632       &alias_red_buf[ptr_freq_band_tbl[0] - sub_band_start];
633 
634   tmp_noise_mant = (WORD16)(ptr_noise_floor[nb_idx] & MASK_M);
635   tmp_noise_exp =
636       (WORD16)(ptr_noise_floor[nb_idx] & MASK_FOR_EXP) - NOISE_EXP_OFFSET;
637 
638   for (j = 0; j < num_sf_bands; j++) {
639     WORD8 sine_present_flag;
640     WORD16 tmp_nrg_ref_exp, tmp_nrg_ref_mant;
641     WORD16 li = *ptr_freq_band_tbl++;
642     WORD16 ui = *ptr_freq_band_tbl;
643     WORD16 env_sf_val = *ptr_env_sf_arr++;
644 
645     tmp_nrg_ref_exp =
646         (WORD16)((env_sf_val & (WORD16)MASK_FOR_EXP) - NRG_EXP_OFFSET);
647     tmp_nrg_ref_mant = (WORD16)(env_sf_val & MASK_M);
648 
649     sine_present_flag = 0;
650     for (k = li; k < ui; k++) {
651       if ((env >= *ptr_sine_mapped++)) sine_present_flag = 1;
652     }
653     for (k = li; k < ui; k++) {
654       *ptr_alias_red_buf++ = !sine_present_flag;
655 
656       if ((k >= ui_noise)) {
657         nb_idx++;
658         ui_noise = pstr_freq_band_data->freq_band_tbl_noise[nb_idx + 1];
659         tmp_noise_mant = (WORD16)(ptr_noise_floor[nb_idx] & MASK_M);
660         tmp_noise_exp =
661             (WORD16)(ptr_noise_floor[nb_idx] & MASK_FOR_EXP) - NOISE_EXP_OFFSET;
662       }
663 
664       if ((k >= ptr_frame_data->max_qmf_subband_aac)) {
665         ptr_enrg_orig[2 * c] = tmp_nrg_ref_mant;
666         ptr_enrg_orig[2 * c + 1] = tmp_nrg_ref_exp;
667         nrg_sine[2 * c] = 0;
668         nrg_sine[2 * c + 1] = 0;
669 
670         ixheaacd_subbandgain_calc(
671             tmp_nrg_ref_mant, tmp_noise_mant, nrg_est[2 * c],
672             nrg_est[2 * c + 1], tmp_noise_exp, tmp_nrg_ref_exp,
673             sine_present_flag,
674             (env >= ptr_sine_mapped_1[c]) ? (FLAG)1 : (FLAG)0, noise_absc_flag,
675             &nrg_gain[2 * c], &noise_level_mant[2 * c], &nrg_sine[2 * c],
676             pstr_common_tables);
677         c++;
678       }
679     }
680   }
681 }
682 
683 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
684 
ixheaacd_calc_sbrenvelope(ia_sbr_scale_fact_struct * ptr_sbr_scale_fac,ia_sbr_calc_env_struct * ptr_sbr_calc_env,ia_sbr_header_data_struct * ptr_header_data,ia_sbr_frame_info_data_struct * ptr_frame_data,ia_sbr_prev_frame_data_struct * ptr_frame_data_prev,WORD32 ** anal_buf_real_mant,WORD32 ** anal_buf_imag_mant,WORD16 * deg_patched,FLAG low_pow_flag,ia_sbr_tables_struct * ptr_sbr_tables,ixheaacd_misc_tables * pstr_common_tables,WORD32 * ptr_qmf_matrix,WORD32 audio_object_type)685 IA_ERRORCODE ixheaacd_calc_sbrenvelope(
686     ia_sbr_scale_fact_struct *ptr_sbr_scale_fac,
687     ia_sbr_calc_env_struct *ptr_sbr_calc_env,
688     ia_sbr_header_data_struct *ptr_header_data,
689     ia_sbr_frame_info_data_struct *ptr_frame_data,
690     ia_sbr_prev_frame_data_struct *ptr_frame_data_prev,
691     WORD32 **anal_buf_real_mant, WORD32 **anal_buf_imag_mant,
692     WORD16 *deg_patched, FLAG low_pow_flag,
693     ia_sbr_tables_struct *ptr_sbr_tables,
694     ixheaacd_misc_tables *pstr_common_tables, WORD32 *ptr_qmf_matrix,
695     WORD32 audio_object_type) {
696   WORD32 i, j, m;
697   WORD32 noise_floor_idx;
698   WORD32 start_pos, end_pos;
699   WORD32 freq_res;
700   WORD32 num_env = ptr_frame_data->str_frame_info_details.num_env;
701   WORD16 *ptr_border_vec = ptr_frame_data->str_frame_info_details.border_vec;
702   IA_ERRORCODE err_code = IA_NO_ERROR;
703   WORD16 *ptr_noise_floor;
704   ia_freq_band_data_struct *pstr_freq_band_data =
705       ptr_header_data->pstr_freq_band_data;
706 
707   FLAG noise_absc_flag;
708   WORD32 smooth_length;
709 
710   const WORD16 *num_sf_bands = pstr_freq_band_data->num_sf_bands;
711   const WORD32 num_nf_bands = pstr_freq_band_data->num_nf_bands;
712 
713   WORD32 sub_band_start = pstr_freq_band_data->sub_band_start;
714   WORD32 sub_band_end = pstr_freq_band_data->sub_band_end;
715 
716   WORD16 num_timeslots = ptr_header_data->num_time_slots;
717   WORD16 max_cols = ptr_header_data->num_time_slots * 2;
718 
719   WORD32 num_sub_bands;
720   WORD32 skip_bands;
721   WORD32 bands;
722 
723   WORD num_cols;
724   WORD32 first_start;
725 
726   WORD16 *ptr_sbr_lim_gain;
727   WORD32 max_sfb_nrg_exp;
728 
729   WORD16 *ptr_enrg_orig;
730 
731   WORD32 input_e;
732   WORD32 ov_adj_e;
733   WORD32 adj_e;
734   WORD32 output_e;
735   WORD32 final_e;
736   WORD16 noise_e;
737   WORD16 lb_scale;
738 
739   WORD16 nrg_est[2 * MAX_FREQ_COEFFS];
740 
741   WORD16 nrg_gain[2 * MAX_FREQ_COEFFS];
742   WORD16 noise_level_mant[2 * MAX_FREQ_COEFFS];
743   WORD16 nrg_sine[2 * MAX_FREQ_COEFFS];
744 
745   WORD8 sine_mapped_matrix[MAX_FREQ_COEFFS];
746   WORD8 alias_red_buf[64];
747 
748   ptr_noise_floor = ptr_frame_data->int_noise_floor;
749 
750   ptr_enrg_orig =
751       (WORD16 *)((WORD8 *)ptr_frame_data +
752                  ALIGN_SIZE64(sizeof(ia_sbr_frame_info_data_struct)));
753 
754   num_env = ptr_frame_data->str_frame_info_details.num_env;
755   ptr_border_vec = ptr_frame_data->str_frame_info_details.border_vec;
756   num_sub_bands = (sub_band_end - sub_band_start);
757   skip_bands = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
758 
759   ixheaacd_map_sineflags(
760       pstr_freq_band_data->freq_band_table[HIGH],
761       pstr_freq_band_data->num_sf_bands[HIGH], ptr_frame_data->add_harmonics,
762       ptr_sbr_calc_env->harm_flags_prev,
763       ptr_frame_data->str_frame_info_details.transient_env, sine_mapped_matrix);
764 
765   adj_e = 0;
766   {
767     WORD16 max_noise;
768     WORD32 first_band;
769 
770     if (ptr_frame_data_prev->max_qmf_subband_aac >
771         ptr_frame_data->max_qmf_subband_aac)
772       first_band = (ptr_frame_data_prev->max_qmf_subband_aac - sub_band_start);
773     else
774       first_band = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
775 
776     max_noise = 0;
777     for (i = first_band; i < num_sub_bands; i++) {
778       if (ptr_sbr_calc_env->filt_buf_noise_m[i] > max_noise) {
779         max_noise = ptr_sbr_calc_env->filt_buf_noise_m[i];
780       }
781     }
782     adj_e = ((ptr_sbr_calc_env->filt_buf_noise_e - ixheaacd_norm32(max_noise)) -
783              16);
784   }
785 
786   final_e = 0;
787   {
788     WORD16 *ptr_env_sf_buf = ptr_frame_data->int_env_sf_arr;
789     for (i = 0; i < num_env; i++) {
790       WORD32 temp_val;
791 
792       max_sfb_nrg_exp = NRG_EXP_OFFSET - SHORT_BITS;
793 
794       freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
795 
796       for (j = 0; j < num_sf_bands[freq_res]; j++) {
797         temp_val = ((*ptr_env_sf_buf++ & MASK_FOR_EXP));
798 
799         if ((temp_val > max_sfb_nrg_exp)) {
800           max_sfb_nrg_exp = temp_val;
801         }
802       }
803 
804       max_sfb_nrg_exp = (max_sfb_nrg_exp - NRG_EXP_OFFSET);
805 
806       temp_val = ((max_sfb_nrg_exp + 13) >> 1);
807 
808       if (num_timeslots != 15) {
809         if ((ptr_border_vec[i] < SBR_TIME_SLOTS)) {
810           if ((temp_val > adj_e)) {
811             adj_e = (WORD16)temp_val;
812           }
813         }
814 
815         if ((ptr_border_vec[i + 1] > SBR_TIME_SLOTS)) {
816           if ((temp_val > final_e)) {
817             final_e = (WORD16)temp_val;
818           }
819         }
820       } else {
821         if ((ptr_border_vec[i] < num_timeslots)) {
822           if ((temp_val > adj_e)) {
823             adj_e = (WORD16)temp_val;
824           }
825         }
826 
827         if ((ptr_border_vec[i + 1] > num_timeslots)) {
828           if ((temp_val > final_e)) {
829             final_e = (WORD16)temp_val;
830           }
831         }
832       }
833     }
834   }
835 
836   m = 0;
837   noise_floor_idx = 0;
838 
839   for (i = 0; i < num_env; i++) {
840     if (audio_object_type == AOT_ER_AAC_ELD ||
841         audio_object_type == AOT_ER_AAC_LD) {
842       start_pos = ptr_border_vec[i];
843       end_pos = ptr_border_vec[i + 1];
844     } else {
845       start_pos = SBR_TIME_STEP * ptr_border_vec[i];
846       end_pos = SBR_TIME_STEP * ptr_border_vec[i + 1];
847     }
848     if ((start_pos >= MAX_ENV_COLS) || (end_pos > MAX_ENV_COLS))
849       return IA_FATAL_ERROR;
850     freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
851 
852     if (noise_floor_idx >= MAX_NOISE_ENVELOPES) return IA_FATAL_ERROR;
853 
854     if (ptr_border_vec[i] ==
855         ptr_frame_data->str_frame_info_details
856             .noise_border_vec[noise_floor_idx + 1]) {
857       ptr_noise_floor += num_nf_bands;
858       noise_floor_idx++;
859     }
860 
861     if ((i == ptr_frame_data->str_frame_info_details.transient_env) ||
862         (i == ptr_sbr_calc_env->tansient_env_prev)) {
863       noise_absc_flag = 1;
864       smooth_length = 0;
865     } else {
866       noise_absc_flag = 0;
867       smooth_length = ((1 - ptr_header_data->smoothing_mode) << 2);
868     }
869 
870     input_e = 15 - ptr_sbr_scale_fac->hb_scale;
871 
872     if (ptr_header_data->interpol_freq) {
873       (*ixheaacd_enery_calc_per_subband)(
874           start_pos, end_pos, ptr_frame_data->max_qmf_subband_aac, sub_band_end,
875           input_e, nrg_est, low_pow_flag, ptr_sbr_tables, ptr_qmf_matrix);
876     } else {
877       ixheaacd_enery_calc_persfb(
878           anal_buf_real_mant, anal_buf_imag_mant, num_sf_bands[freq_res],
879           pstr_freq_band_data->freq_band_table[freq_res], start_pos, end_pos,
880           ptr_frame_data->max_qmf_subband_aac, input_e, nrg_est, low_pow_flag,
881           ptr_sbr_tables);
882     }
883 
884     if (pstr_freq_band_data->freq_band_table[freq_res][0] < pstr_freq_band_data->sub_band_start) {
885       pstr_freq_band_data->sub_band_start = pstr_freq_band_data->freq_band_table[freq_res][0];
886       return IA_FATAL_ERROR;
887     }
888 
889     ixheaacd_calc_subband_gains(
890         pstr_freq_band_data, ptr_frame_data, freq_res, ptr_noise_floor,
891         num_sf_bands[freq_res], m, i, sine_mapped_matrix, alias_red_buf,
892         ptr_enrg_orig, nrg_sine, nrg_est, nrg_gain, noise_level_mant,
893         noise_absc_flag, pstr_common_tables);
894 
895     m += num_sf_bands[freq_res];
896 
897     ptr_sbr_lim_gain =
898         &ptr_sbr_tables->env_calc_tables_ptr
899              ->sbr_lim_gains_m[2 * ptr_header_data->limiter_gains];
900     ixheaacd_noiselimiting(pstr_freq_band_data, skip_bands, ptr_enrg_orig,
901                            nrg_est, nrg_gain, noise_level_mant, nrg_sine,
902                            ptr_sbr_lim_gain, noise_absc_flag,
903                            pstr_common_tables);
904 
905     if (low_pow_flag) {
906       ixheaacd_alias_reduction(deg_patched + sub_band_start, nrg_gain, nrg_est,
907                                alias_red_buf, num_sub_bands,
908                                pstr_common_tables);
909     }
910 
911     if (max_cols != 30) {
912       if ((start_pos < MAX_COLS)) {
913         noise_e = adj_e;
914       } else {
915         noise_e = final_e;
916       }
917     } else {
918       if ((start_pos < max_cols)) {
919         noise_e = adj_e;
920       } else {
921         noise_e = final_e;
922       }
923     }
924 
925     bands = num_sub_bands - skip_bands;
926 
927     if (low_pow_flag) {
928       (*ixheaacd_conv_ergtoamplitudelp)(
929           bands, noise_e, nrg_sine, nrg_gain, noise_level_mant,
930           (WORD16 *)pstr_common_tables->sqrt_table);
931     } else
932 
933     {
934       (*ixheaacd_conv_ergtoamplitude)(bands, noise_e, nrg_sine, nrg_gain,
935                                       noise_level_mant,
936                                       (WORD16 *)pstr_common_tables->sqrt_table);
937     }
938 
939     lb_scale = ixheaacd_sub16(15, ptr_sbr_scale_fac->lb_scale);
940 
941     ixheaacd_adapt_noise_gain_calc(
942         ptr_sbr_calc_env, noise_e, num_sub_bands, skip_bands, nrg_gain,
943         noise_level_mant, nrg_sine, start_pos, end_pos, input_e, adj_e, final_e,
944         ptr_frame_data->max_qmf_subband_aac, lb_scale, noise_absc_flag,
945         smooth_length, anal_buf_real_mant, anal_buf_imag_mant, low_pow_flag,
946         ptr_sbr_tables, max_cols);
947   }
948 
949   first_start = ptr_border_vec[0] * SBR_TIME_STEP;
950   {
951     WORD32 ov_reserve, reserve;
952 
953     ov_reserve = reserve = 0;
954 
955     if (audio_object_type != AOT_ER_AAC_ELD) {
956       if (ptr_header_data->channel_mode == PS_STEREO) {
957         ov_reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
958             anal_buf_real_mant, anal_buf_imag_mant,
959             ptr_frame_data->max_qmf_subband_aac, sub_band_end, 0, first_start,
960             low_pow_flag);
961 
962         if (max_cols != 30) {
963           reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
964             anal_buf_real_mant, anal_buf_imag_mant,
965             ptr_frame_data->max_qmf_subband_aac, sub_band_end, first_start,
966             MAX_COLS, low_pow_flag);
967         } else {
968           reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
969             anal_buf_real_mant, anal_buf_imag_mant,
970             ptr_frame_data->max_qmf_subband_aac, sub_band_end, first_start,
971             max_cols, low_pow_flag);
972         }
973       }
974     }
975 
976     output_e = 0;
977 
978     ov_adj_e = 15 - ptr_sbr_scale_fac->ov_hb_scale;
979 
980     if (((ov_adj_e - ov_reserve) > (adj_e - reserve)))
981       output_e = (ov_adj_e - ov_reserve);
982     else
983       output_e = (adj_e - reserve);
984 
985     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
986                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
987                              0, first_start, (ov_adj_e - output_e),
988                              low_pow_flag);
989 
990     num_cols = (ptr_header_data->num_time_slots * ptr_header_data->time_step);
991 
992     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
993                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
994                              first_start, num_cols, (adj_e - output_e),
995                              low_pow_flag);
996   }
997 
998   ptr_sbr_scale_fac->hb_scale = (WORD16)(15 - output_e);
999 
1000   ptr_sbr_scale_fac->ov_hb_scale = (WORD16)(15 - final_e);
1001 
1002   if (ptr_frame_data->str_frame_info_details.transient_env == num_env) {
1003     ptr_sbr_calc_env->tansient_env_prev = 0;
1004   } else {
1005     ptr_sbr_calc_env->tansient_env_prev = -1;
1006   }
1007   return err_code;
1008 }
1009 
ixheaacd_equalize_filt_buff_exp(WORD16 * ptr_filt_buf,WORD16 * nrg_gain,WORD32 subbands)1010 VOID ixheaacd_equalize_filt_buff_exp(WORD16 *ptr_filt_buf, WORD16 *nrg_gain,
1011                                      WORD32 subbands) {
1012   WORD32 band;
1013   WORD32 diff;
1014   WORD32 gain_m, gain_e;
1015   WORD32 filt_buf_mant, filt_buf_exp;
1016 
1017   for (band = subbands - 1; band >= 0; band--) {
1018     filt_buf_exp = *(ptr_filt_buf + 1);
1019     gain_e = *(nrg_gain + 1);
1020     filt_buf_mant = *ptr_filt_buf;
1021     gain_m = *nrg_gain;
1022     diff = (gain_e - filt_buf_exp);
1023 
1024     if (diff >= 0) {
1025       *(ptr_filt_buf + 1) = (WORD16)(gain_e);
1026 
1027       *ptr_filt_buf = (WORD16)(*ptr_filt_buf >> diff);
1028     } else {
1029       WORD32 reserve;
1030       reserve = (ixheaacd_norm32(filt_buf_mant) - 16);
1031 
1032       if ((diff + reserve) >= 0) {
1033         *ptr_filt_buf = (WORD16)(filt_buf_mant << -diff);
1034         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp + diff);
1035       } else {
1036         WORD32 shift;
1037 
1038         *ptr_filt_buf = (WORD16)(filt_buf_mant << reserve);
1039 
1040         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp - reserve);
1041 
1042         shift = -(reserve + diff);
1043 
1044         *nrg_gain = (WORD16)(gain_m >> shift);
1045         *(nrg_gain + 1) = (WORD16)(*(nrg_gain + 1) + shift);
1046       }
1047     }
1048     nrg_gain += 2;
1049     ptr_filt_buf += 2;
1050   }
1051 }
1052 
ixheaacd_filt_buf_update(WORD16 * ptr_filt_buf,WORD16 * ptr_filt_buf_noise,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD32 num_sub_bands)1053 VOID ixheaacd_filt_buf_update(WORD16 *ptr_filt_buf,
1054                                                      WORD16 *ptr_filt_buf_noise,
1055                                                      WORD16 *nrg_gain,
1056                                                      WORD16 *noise_level_mant,
1057                                                      WORD32 num_sub_bands) {
1058   WORD32 k;
1059   WORD32 temp1, temp2;
1060 
1061   for (k = num_sub_bands - 1; k >= 0; k--) {
1062     temp1 = *nrg_gain;
1063     nrg_gain += 2;
1064     temp2 = *noise_level_mant;
1065     noise_level_mant += 2;
1066 
1067     *ptr_filt_buf = temp1;
1068     ptr_filt_buf += 2;
1069     *ptr_filt_buf_noise++ = temp2;
1070   }
1071 }
1072 
ixheaacd_noise_level_rescaling(WORD16 * noise_level_mant,WORD32 diff,WORD32 num_sub_bands,WORD32 ixheaacd_drc_offset)1073 VOID ixheaacd_noise_level_rescaling(WORD16 *noise_level_mant, WORD32 diff,
1074                                     WORD32 num_sub_bands,
1075                                     WORD32 ixheaacd_drc_offset) {
1076   WORD32 k;
1077 
1078   if (diff > 0) {
1079     for (k = num_sub_bands - 1; k >= 0; k--) {
1080       *noise_level_mant = *noise_level_mant >> diff;
1081       noise_level_mant += ixheaacd_drc_offset;
1082     }
1083   } else if (diff < 0) {
1084     diff = -diff;
1085     for (k = num_sub_bands - 1; k >= 0; k--) {
1086       *noise_level_mant = *noise_level_mant << diff;
1087       noise_level_mant += ixheaacd_drc_offset;
1088     }
1089   }
1090 }
1091 
ixheaacd_adjust_scale_dec(WORD32 ** re,WORD32 ** im,WORD32 sub_band_start,WORD32 sub_band_end,WORD32 start_pos,WORD32 next_pos,WORD32 shift,FLAG low_pow_flag)1092 VOID ixheaacd_adjust_scale_dec(WORD32 **re, WORD32 **im, WORD32 sub_band_start,
1093                                WORD32 sub_band_end, WORD32 start_pos,
1094                                WORD32 next_pos, WORD32 shift,
1095                                FLAG low_pow_flag) {
1096   WORD32 k, l;
1097 
1098   if (shift != 0) {
1099     WORD32 num_sub_bands = (sub_band_end - sub_band_start);
1100 
1101     shift = ixheaacd_min32(shift, 31);
1102     shift = ixheaacd_max32(shift, -31);
1103 
1104     if (low_pow_flag) {
1105       if (shift > 0) {
1106         for (l = start_pos; l < next_pos; l++) {
1107           WORD32 *ptr = re[l] + sub_band_start;
1108           for (k = num_sub_bands - 1; k >= 0; k--) {
1109             *ptr = (*ptr << shift);
1110             ptr++;
1111           }
1112         }
1113       } else {
1114         shift = -shift;
1115         for (l = start_pos; l < next_pos; l++) {
1116           WORD32 *ptr = re[l] + sub_band_start;
1117           for (k = num_sub_bands - 1; k >= 0; k--) {
1118             *ptr = (*ptr >> shift);
1119             ptr++;
1120           }
1121         }
1122       }
1123     } else {
1124       if (shift > 0) {
1125         for (l = start_pos; l < next_pos; l++) {
1126           WORD32 *ptr = re[l] + sub_band_start;
1127           WORD32 *pti = im[l] + sub_band_start;
1128           for (k = num_sub_bands; k > 0; k--) {
1129             *ptr = (*ptr << shift);
1130             *pti = (*pti << shift);
1131             pti++;
1132             ptr++;
1133           }
1134         }
1135       } else {
1136         shift = -shift;
1137         for (l = start_pos; l < next_pos; l++) {
1138           WORD32 *ptr = re[l] + sub_band_start;
1139           WORD32 *pti = im[l] + sub_band_start;
1140           for (k = num_sub_bands; k > 0; k--) {
1141             *ptr = (*ptr >> shift);
1142             *pti = (*pti >> shift);
1143             ptr++;
1144             pti++;
1145           }
1146         }
1147       }
1148     }
1149   }
1150 }
1151 
ixheaacd_expsubbandsamples_dec(WORD32 ** re,WORD32 ** im,WORD32 sub_band_start,WORD32 sub_band_end,WORD32 start_pos,WORD32 next_pos,FLAG low_pow_flag)1152 WORD16 ixheaacd_expsubbandsamples_dec(WORD32 **re, WORD32 **im,
1153                                       WORD32 sub_band_start,
1154                                       WORD32 sub_band_end, WORD32 start_pos,
1155                                       WORD32 next_pos, FLAG low_pow_flag) {
1156   WORD32 l, k;
1157   WORD16 max_shift;
1158 
1159   WORD32 value;
1160   WORD32 max_abs;
1161   WORD32 num_sub_bands;
1162 
1163   WORD32 *ptr_real;
1164   WORD32 *ptr_imag;
1165 
1166   max_abs = 1;
1167   num_sub_bands = (sub_band_end - sub_band_start);
1168 
1169   if (low_pow_flag) {
1170     for (l = start_pos; l < next_pos; l++) {
1171       WORD32 temp_real;
1172       ptr_real = re[l] + sub_band_start;
1173       temp_real = *ptr_real++;
1174       for (k = num_sub_bands; k > 0; k--) {
1175         value = ixheaacd_abs32_nrm(temp_real);
1176         max_abs |= value;
1177         temp_real = *ptr_real++;
1178       }
1179     }
1180     max_shift = ixheaacd_pnorm32(max_abs);
1181   } else {
1182     for (l = start_pos; l < next_pos; l++) {
1183       ptr_real = re[l] + sub_band_start;
1184       ptr_imag = im[l] + sub_band_start;
1185 
1186       for (k = num_sub_bands; k > 0; k--) {
1187         WORD32 temp_real = *ptr_real++;
1188         WORD32 tempIm = *ptr_imag++;
1189 
1190         temp_real = ixheaacd_abs32_nrm(temp_real);
1191         max_abs |= temp_real;
1192         tempIm = ixheaacd_abs32_nrm(tempIm);
1193         max_abs |= tempIm;
1194       }
1195     }
1196     max_shift = ixheaacd_pnorm32(max_abs);
1197   }
1198 
1199   return max_shift;
1200 }
1201 
1202 #define SHIFT_BEFORE_SQUARE 4
1203 
ixheaacd_enery_calc_per_subband_dec(WORD32 start_pos,WORD32 next_pos,WORD32 sub_band_start,WORD32 sub_band_end,WORD32 frame_exp,WORD16 * nrg_est,FLAG low_pow_flag,ia_sbr_tables_struct * ptr_sbr_tables,WORD32 * ptr_qmf_matrix)1204 VOID ixheaacd_enery_calc_per_subband_dec(WORD32 start_pos, WORD32 next_pos,
1205                                          WORD32 sub_band_start,
1206                                          WORD32 sub_band_end, WORD32 frame_exp,
1207                                          WORD16 *nrg_est, FLAG low_pow_flag,
1208                                          ia_sbr_tables_struct *ptr_sbr_tables,
1209                                          WORD32 *ptr_qmf_matrix) {
1210   WORD16 temp;
1211   WORD16 inv_width;
1212   WORD16 sum_m;
1213   WORD32 accu;
1214   WORD32 k, l;
1215   WORD32 pre_shift_val;
1216   WORD32 shift;
1217   WORD32 *p_real;
1218   WORD32 max_shift_gap = SHIFT_BEFORE_SQUARE;
1219   WORD32 extra_shift = 0;
1220   WORD32 num_cols = next_pos - start_pos;
1221 
1222   if (low_pow_flag) {
1223     max_shift_gap -= 1;
1224     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 6);
1225     extra_shift++;
1226   } else {
1227     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 7);
1228     num_cols = num_cols << 1;
1229   }
1230   inv_width = ptr_sbr_tables->env_calc_tables_ptr
1231                   ->sbr_inv_int_table[(next_pos - start_pos)];
1232   frame_exp = (frame_exp << 1);
1233 
1234   {
1235     WORD32 *ptr;
1236     for (k = sub_band_start; k < sub_band_end; k++) {
1237       WORD32 max_val = 1;
1238 
1239       ptr = p_real;
1240 
1241       for (l = num_cols; l != 0; l -= 2) {
1242         WORD32 value = ixheaacd_abs32_nrm(*ptr);
1243         ptr += 64;
1244         max_val = ixheaacd_max32(value, max_val);
1245         value = ixheaacd_abs32_nrm(*ptr);
1246         ptr += 64;
1247         max_val = ixheaacd_max32(value, max_val);
1248       }
1249       pre_shift_val = (ixheaacd_pnorm32(max_val) - max_shift_gap);
1250 
1251       accu = 0L;
1252       shift = 16 - pre_shift_val;
1253       ptr = p_real;
1254 
1255       if (shift > 0)
1256         for (l = num_cols; l != 0; l -= 2) {
1257           temp = (WORD16)((*(ptr) >> shift));
1258           ptr += 64;
1259           accu += (temp * temp);
1260           temp = (WORD16)((*(ptr) >> shift));
1261           ptr += 64;
1262           accu += (temp * temp);
1263         }
1264       else
1265         for (l = num_cols; l != 0; l -= 2) {
1266           temp = (WORD16)((*(ptr) << (-shift)));
1267           ptr += 64;
1268           accu += (temp * temp);
1269           temp = (WORD16)((*(ptr) << (-shift)));
1270           ptr += 64;
1271           accu += (temp * temp);
1272         }
1273 
1274       if (accu != 0L) {
1275         shift = -(ixheaacd_pnorm32(accu));
1276         sum_m = (WORD16)(ixheaacd_shr32_dir_sat_limit(accu, (16 + shift)));
1277         *nrg_est++ = ixheaacd_mult16_shl_sat(sum_m, inv_width);
1278         shift = (shift - (pre_shift_val << 1));
1279         shift += extra_shift;
1280         *nrg_est++ = (WORD16)(frame_exp + shift + 1);
1281       } else {
1282         *nrg_est++ = 0;
1283         *nrg_est++ = 0;
1284       }
1285 
1286       p_real++;
1287     }
1288   }
1289 }
1290 
ixheaacd_enery_calc_persfb(WORD32 ** anal_buf_real,WORD32 ** anal_buf_imag,WORD32 num_sf_bands,WORD16 * freq_band_table,WORD32 start_pos,WORD32 next_pos,WORD32 max_qmf_subband_aac,WORD32 frame_exp,WORD16 * nrg_est,FLAG low_pow_flag,ia_sbr_tables_struct * ptr_sbr_tables)1291 VOID ixheaacd_enery_calc_persfb(WORD32 **anal_buf_real, WORD32 **anal_buf_imag,
1292                                 WORD32 num_sf_bands, WORD16 *freq_band_table,
1293                                 WORD32 start_pos, WORD32 next_pos,
1294                                 WORD32 max_qmf_subband_aac, WORD32 frame_exp,
1295                                 WORD16 *nrg_est, FLAG low_pow_flag,
1296                                 ia_sbr_tables_struct *ptr_sbr_tables) {
1297   WORD16 inv_width;
1298   WORD32 pre_shift_val;
1299   WORD32 shift;
1300   WORD32 sum_e;
1301   WORD16 sum_m;
1302 
1303   WORD32 j, k, l;
1304   WORD32 li, ui;
1305   WORD32 accu_line;
1306   WORD32 accumulate;
1307   WORD32 extra_shift = 10;
1308 
1309   inv_width = ptr_sbr_tables->env_calc_tables_ptr
1310                   ->sbr_inv_int_table[(next_pos - start_pos)];
1311 
1312   frame_exp = (frame_exp << 1);
1313 
1314   if (low_pow_flag) extra_shift++;
1315 
1316   for (j = 0; j < num_sf_bands; j++) {
1317     li = freq_band_table[j];
1318 
1319     if ((li >= max_qmf_subband_aac)) {
1320       ui = freq_band_table[j + 1];
1321 
1322       pre_shift_val = (*ixheaacd_ixheaacd_expsubbandsamples)(
1323           anal_buf_real, anal_buf_imag, li, ui, start_pos, next_pos,
1324           low_pow_flag);
1325 
1326       pre_shift_val = (pre_shift_val - SHIFT_BEFORE_SQUARE);
1327 
1328       accumulate = 0;
1329 
1330       for (k = li; k < ui; k++) {
1331         WORD32 pre_shift1 = (16 - pre_shift_val);
1332         accu_line = 0L;
1333         pre_shift1 = min(pre_shift1, 31);
1334         {
1335           WORD32 *ptr = &anal_buf_real[start_pos][k];
1336           WORD32 inc = !low_pow_flag;
1337           for (l = (next_pos - start_pos) << inc; l != 0; l--) {
1338             WORD16 temp;
1339             temp = ixheaacd_extract16l(ixheaacd_shr32_dir(*ptr, pre_shift1));
1340             ptr += 64;
1341             accu_line = ixheaacd_mac16x16in32_sat(accu_line, temp, temp);
1342           }
1343         }
1344         accumulate =
1345             ixheaacd_add32_sat(accumulate, ixheaacd_shr32(accu_line, 9));
1346       }
1347 
1348       shift = ixheaacd_pnorm32(accumulate);
1349 
1350       sum_m = ixheaacd_extract16l(
1351           ixheaacd_shr32_dir_sat_limit(accumulate, (16 - shift)));
1352 
1353       if (sum_m == 0) {
1354         sum_e = 0;
1355       } else {
1356         sum_m = ixheaacd_mult16_shl_sat(sum_m, inv_width);
1357 
1358         sum_m = ixheaacd_mult16_shl_sat(
1359             sum_m,
1360             ptr_sbr_tables->env_calc_tables_ptr->sbr_inv_int_table[ui - li]);
1361 
1362         sum_e = ((frame_exp + extra_shift) - shift);
1363 
1364         sum_e = (sum_e - (pre_shift_val << 1));
1365       }
1366 
1367       for (k = li; k < ui; k++) {
1368         *nrg_est++ = sum_m;
1369         *nrg_est++ = (WORD16)sum_e;
1370       }
1371     }
1372   }
1373 }
1374 
ixheaacd_subbandgain_calc(WORD16 e_orig_mant_matrix,WORD16 tmp_noise_mant,WORD16 nrg_est_mant,WORD16 nrg_est_exp,WORD16 tmp_noise_exp,WORD16 nrg_ref_exp,FLAG sine_present_flag,FLAG sine_mapped_matrix,FLAG noise_absc_flag,WORD16 * ptr_nrg_gain_mant,WORD16 * ptr_noise_floor_mant,WORD16 * ptr_nrg_sine_m,ixheaacd_misc_tables * pstr_common_tables)1375 VOID ixheaacd_subbandgain_calc(WORD16 e_orig_mant_matrix, WORD16 tmp_noise_mant,
1376                                WORD16 nrg_est_mant, WORD16 nrg_est_exp,
1377                                WORD16 tmp_noise_exp, WORD16 nrg_ref_exp,
1378                                FLAG sine_present_flag, FLAG sine_mapped_matrix,
1379                                FLAG noise_absc_flag, WORD16 *ptr_nrg_gain_mant,
1380                                WORD16 *ptr_noise_floor_mant,
1381                                WORD16 *ptr_nrg_sine_m,
1382                                ixheaacd_misc_tables *pstr_common_tables) {
1383   WORD16 var1_mant;
1384   WORD16 var1_exp;
1385   WORD16 var2_mant;
1386   WORD16 var2_exp;
1387   WORD16 var3_mant;
1388   WORD16 var3_exp;
1389   WORD32 temp;
1390 
1391   if (nrg_est_mant == 0) {
1392     nrg_est_mant = 0x4000;
1393     nrg_est_exp = 1;
1394   }
1395 
1396   var1_mant = ixheaacd_mult16_shl_sat(e_orig_mant_matrix, tmp_noise_mant);
1397   var1_exp = (nrg_ref_exp + tmp_noise_exp);
1398 
1399   {
1400     WORD32 accu, exp_diff;
1401 
1402     exp_diff = tmp_noise_exp - 1;
1403 
1404     if (exp_diff >= 0) {
1405       accu = tmp_noise_mant + ixheaacd_shr32(0x4000, exp_diff);
1406       var2_exp = tmp_noise_exp;
1407     } else {
1408       exp_diff = -exp_diff;
1409       accu = ixheaacd_shr32((WORD32)tmp_noise_mant, exp_diff) + 0x4000;
1410       var2_exp = 1;
1411     }
1412     if (ixheaacd_abs32(accu) >= 0x8000) {
1413       accu = accu >> 1;
1414       var2_exp++;
1415     }
1416     var2_mant = (WORD16)(accu);
1417   }
1418 
1419   temp = ixheaacd_fix_mant_div(var1_mant, var2_mant, ptr_noise_floor_mant,
1420                                pstr_common_tables);
1421   *(ptr_noise_floor_mant + 1) = temp + (var1_exp - var2_exp) + 1;
1422 
1423   if (sine_present_flag || !noise_absc_flag) {
1424     var3_mant = ixheaacd_mult16_shl_sat(var2_mant, nrg_est_mant);
1425     var3_exp = (var2_exp + nrg_est_exp);
1426   } else {
1427     var3_mant = nrg_est_mant;
1428     var3_exp = nrg_est_exp;
1429   }
1430 
1431   if (sine_present_flag == 0) {
1432     var1_mant = e_orig_mant_matrix;
1433     var1_exp = nrg_ref_exp;
1434   }
1435 
1436   temp = ixheaacd_fix_mant_div(var1_mant, var3_mant, ptr_nrg_gain_mant,
1437                                pstr_common_tables);
1438   *(ptr_nrg_gain_mant + 1) = temp + (var1_exp - var3_exp) + 1;
1439 
1440   if (sine_present_flag && sine_mapped_matrix) {
1441     temp = ixheaacd_fix_mant_div(e_orig_mant_matrix, var2_mant, ptr_nrg_sine_m,
1442                                  pstr_common_tables);
1443     *(ptr_nrg_sine_m + 1) = temp + (nrg_ref_exp - var2_exp) + 1;
1444   }
1445 }
1446 
ixheaacd_avggain_calc(WORD16 * ptr_enrg_orig,WORD16 * nrg_est,WORD32 sub_band_start,WORD32 sub_band_end,WORD16 * ptr_enrg_orig_mant,WORD16 * ptr_sum_ref_exp,WORD16 * ptr_avg_gain_mant,WORD16 * ptr_avg_gain_exp,ixheaacd_misc_tables * pstr_common_tables,WORD32 flag)1447 VOID ixheaacd_avggain_calc(WORD16 *ptr_enrg_orig, WORD16 *nrg_est,
1448                            WORD32 sub_band_start, WORD32 sub_band_end,
1449                            WORD16 *ptr_enrg_orig_mant, WORD16 *ptr_sum_ref_exp,
1450                            WORD16 *ptr_avg_gain_mant, WORD16 *ptr_avg_gain_exp,
1451                            ixheaacd_misc_tables *pstr_common_tables,
1452                            WORD32 flag) {
1453   WORD16 sum_orig_mant;
1454   WORD16 sum_orig_exp;
1455   WORD16 sum_est_mant;
1456   WORD16 sum_est_exp;
1457 
1458   WORD32 accu_sum_orig_mant;
1459   WORD32 accu_sum_orig_exp;
1460   WORD32 accu_sum_est_mant;
1461   WORD32 accu_sum_est_exp;
1462 
1463   WORD32 k, temp;
1464   WORD16 *ptr_enrg_orig_buf;
1465   WORD16 *ptr_enrg_est_buf;
1466 
1467   {
1468     accu_sum_orig_mant = 0;
1469     accu_sum_orig_exp = 0;
1470 
1471     accu_sum_est_mant = 0;
1472     accu_sum_est_exp = 0;
1473   }
1474 
1475   ptr_enrg_orig_buf = &ptr_enrg_orig[sub_band_start << 1];
1476   ptr_enrg_est_buf = &nrg_est[sub_band_start << 1];
1477 
1478   for (k = sub_band_end - sub_band_start; k != 0; k--) {
1479     WORD16 tmp_mant, tmp_e;
1480     WORD16 tmp2_m, tmp2_e;
1481 
1482     tmp_mant = *ptr_enrg_orig_buf++;
1483     tmp_e = *ptr_enrg_orig_buf++;
1484     tmp2_m = *ptr_enrg_est_buf++;
1485     tmp2_e = *ptr_enrg_est_buf++;
1486     {
1487       WORD32 exp_diff;
1488       exp_diff = tmp_e - accu_sum_orig_exp;
1489       if (exp_diff >= 0) {
1490         accu_sum_orig_mant =
1491             tmp_mant + ixheaacd_shr32(accu_sum_orig_mant, exp_diff);
1492         accu_sum_orig_exp = tmp_e;
1493       } else {
1494         exp_diff = -exp_diff;
1495         accu_sum_orig_mant =
1496             ixheaacd_shr32(tmp_mant, exp_diff) + accu_sum_orig_mant;
1497       }
1498     }
1499     if (flag) {
1500       tmp_mant = (tmp_mant * tmp2_m) >> 16;
1501       tmp_e = (tmp_e + tmp2_e + 1);
1502 
1503     } else {
1504       tmp_mant = tmp2_m;
1505       tmp_e = tmp2_e;
1506     }
1507 
1508     {
1509       WORD32 exp_diff;
1510       exp_diff = tmp_e - accu_sum_est_exp;
1511       if (exp_diff >= 0) {
1512         accu_sum_est_mant =
1513             tmp_mant + ixheaacd_shr32(accu_sum_est_mant, exp_diff);
1514         accu_sum_est_exp = tmp_e;
1515       } else {
1516         exp_diff = -exp_diff;
1517         accu_sum_est_mant =
1518             ixheaacd_shr32(tmp_mant, exp_diff) + accu_sum_est_mant;
1519       }
1520     }
1521   }
1522   {
1523     WORD32 norm_val;
1524     norm_val = 16 - ixheaacd_pnorm32(accu_sum_orig_mant);
1525     if (norm_val > 0) {
1526       accu_sum_orig_mant >>= norm_val;
1527       accu_sum_orig_exp += norm_val;
1528     }
1529     norm_val = 16 - ixheaacd_pnorm32(accu_sum_est_mant);
1530     if (norm_val > 0) {
1531       accu_sum_est_mant >>= norm_val;
1532       accu_sum_est_exp += norm_val;
1533     }
1534   }
1535 
1536   if (!flag) {
1537     sum_orig_mant = (WORD16)accu_sum_orig_mant;
1538     sum_orig_exp = (WORD16)accu_sum_orig_exp;
1539     sum_est_mant = (WORD16)accu_sum_est_mant;
1540     sum_est_exp = (WORD16)accu_sum_est_exp;
1541   } else {
1542     sum_est_mant = (WORD16)accu_sum_orig_mant;
1543     sum_est_exp = (WORD16)accu_sum_orig_exp;
1544     sum_orig_mant = (WORD16)accu_sum_est_mant;
1545     sum_orig_exp = (WORD16)accu_sum_est_exp;
1546   }
1547 
1548   {
1549     temp = ixheaacd_fix_mant_div(sum_orig_mant, sum_est_mant, ptr_avg_gain_mant,
1550                                  pstr_common_tables);
1551     *ptr_avg_gain_exp = temp + (sum_orig_exp - sum_est_exp) + 1;
1552     *ptr_enrg_orig_mant = sum_orig_mant;
1553     *ptr_sum_ref_exp = sum_orig_exp;
1554   }
1555 }
1556 
ixheaacd_harm_idx_zerotwolp_dec(WORD32 * ptr_real_buf,WORD16 * ptr_gain_buf,WORD32 scale_change,WORD16 * ptr_sine_level_buf,const WORD32 * ptr_rand_ph,WORD16 * noise_level_mant,WORD32 num_sub_bands,FLAG noise_absc_flag,WORD32 harm_index)1557 VOID ixheaacd_harm_idx_zerotwolp_dec(WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf,
1558                                      WORD32 scale_change,
1559                                      WORD16 *ptr_sine_level_buf,
1560                                      const WORD32 *ptr_rand_ph,
1561                                      WORD16 *noise_level_mant,
1562                                      WORD32 num_sub_bands, FLAG noise_absc_flag,
1563                                      WORD32 harm_index) {
1564   WORD32 shift, k;
1565   WORD32 signal_real;
1566   WORD32 sine_level;
1567 
1568   scale_change = scale_change - 1;
1569   if (!noise_absc_flag) {
1570     for (k = 0; k < num_sub_bands; k++) {
1571       signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1572       shift = (*ptr_gain_buf++ - scale_change);
1573 
1574       if (shift > 0)
1575         signal_real = (signal_real << shift);
1576       else
1577         signal_real = (signal_real >> -(shift));
1578 
1579       sine_level = (ptr_sine_level_buf[2 * k] << 16);
1580 
1581       if (sine_level == 0) {
1582         *ptr_real_buf++ = ixheaacd_mac16x16in32_shl_sat(
1583             signal_real, ixheaacd_extract16h(ptr_rand_ph[k]),
1584             noise_level_mant[2 * k]);
1585       } else if (harm_index == 0)
1586         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, sine_level);
1587       else
1588         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, sine_level);
1589     }
1590   } else {
1591     for (k = 0; k < num_sub_bands; k++) {
1592       signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1593       shift = (*ptr_gain_buf++ - scale_change);
1594 
1595       if (shift > 0)
1596         signal_real = (signal_real << shift);
1597       else
1598         signal_real = (signal_real >> -(shift));
1599 
1600       sine_level = (ptr_sine_level_buf[2 * k] << 16);
1601 
1602       if (harm_index == 0)
1603         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, sine_level);
1604       else
1605         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, sine_level);
1606     }
1607   }
1608 }
1609 
ixheaacd_harm_idx_onethreelp(WORD32 * ptr_real_buf,WORD16 * ptr_gain_buf,WORD32 scale_change,WORD16 * ptr_sine_level_buf,const WORD32 * ptr_rand_ph,WORD16 * noise_level_mant,WORD32 num_sub_bands,FLAG noise_absc_flag,WORD32 freq_inv_flag,WORD32 noise_e,WORD32 sub_band_start)1610 VOID ixheaacd_harm_idx_onethreelp(
1611     WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf, WORD32 scale_change,
1612     WORD16 *ptr_sine_level_buf, const WORD32 *ptr_rand_ph,
1613     WORD16 *noise_level_mant, WORD32 num_sub_bands, FLAG noise_absc_flag,
1614     WORD32 freq_inv_flag, WORD32 noise_e, WORD32 sub_band_start) {
1615   WORD32 shift, k = 0;
1616   WORD32 signal_real, temp_mult, temp_mult2;
1617   WORD16 sine_level, sine_level_prev, sine_level_next;
1618   WORD32 tone_count = 0;
1619   WORD16 tmp;
1620 
1621   scale_change = scale_change - 1;
1622 
1623   signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1624   shift = (*ptr_gain_buf++ - scale_change);
1625 
1626   if (shift > 0)
1627     signal_real = (signal_real << shift);
1628   else
1629     signal_real = (signal_real >> -(shift));
1630 
1631   sine_level = ((ptr_sine_level_buf[2 * 0]));
1632 
1633   if (num_sub_bands > 1) {
1634     sine_level_next = ((ptr_sine_level_buf[2 * 1]));
1635   } else {
1636     sine_level_next = 0;
1637   }
1638 
1639   if (ptr_sine_level_buf[2 * 0] != 0) {
1640     tone_count++;
1641   } else {
1642     if (!noise_absc_flag) {
1643       signal_real = ixheaacd_mac16x16in32_shl_sat(
1644           signal_real, ixheaacd_extract16h(ptr_rand_ph[k]), *noise_level_mant);
1645     }
1646   }
1647 
1648   noise_level_mant += 2;
1649   temp_mult2 = ixheaacd_mult32x16in32(FACTOR, sine_level_next);
1650   temp_mult = ixheaacd_mult32x16in32(FACTOR, sine_level);
1651   tmp = noise_e;
1652 
1653   if (tmp > 0) {
1654     temp_mult = ixheaacd_shl32(temp_mult, tmp);
1655   } else {
1656     temp_mult = ixheaacd_shr32(temp_mult, -tmp);
1657   }
1658 
1659   if (freq_inv_flag < 0) {
1660     *(ptr_real_buf - 1) = ixheaacd_add32_sat(*(ptr_real_buf - 1), temp_mult);
1661     signal_real = ixheaacd_sub32_sat(signal_real, temp_mult2);
1662   } else {
1663     *(ptr_real_buf - 1) = ixheaacd_sub32_sat(*(ptr_real_buf - 1), temp_mult);
1664     signal_real = ixheaacd_add32_sat(signal_real, temp_mult2);
1665   }
1666   *ptr_real_buf++ = signal_real;
1667 
1668   num_sub_bands = num_sub_bands - 1;
1669   for (k = 1; k < num_sub_bands; k++) {
1670     WORD16 gain_m = *ptr_gain_buf++;
1671     WORD16 gain_e = *ptr_gain_buf++;
1672     WORD32 q_real = *ptr_real_buf;
1673 
1674     signal_real = ixheaacd_mult32x16in32(q_real, gain_m);
1675 
1676     if ((shift = (gain_e - scale_change)) >= 0)
1677       signal_real = (signal_real << shift);
1678     else
1679       signal_real = (signal_real >> -(shift));
1680 
1681     sine_level_prev = sine_level;
1682     sine_level = sine_level_next;
1683     if (sine_level != 0) {
1684       tone_count++;
1685     }
1686     sine_level_next = (ptr_sine_level_buf[2 * (k + 1)]);
1687 
1688     if ((!noise_absc_flag) && (sine_level == 0)) {
1689       signal_real = ixheaacd_mac16x16in32_shl_sat(
1690           signal_real, ixheaacd_extract16h(ptr_rand_ph[k]), *noise_level_mant);
1691     }
1692     noise_level_mant += 2;
1693 
1694     if (tone_count <= 16) {
1695       WORD32 temp_mult;
1696       WORD32 add_sine = ixheaacd_mult32x16in32(
1697           FACTOR, ixheaacd_sub16(sine_level_prev, sine_level_next));
1698       temp_mult = add_sine * freq_inv_flag;
1699       signal_real = ixheaacd_add32_sat(signal_real, temp_mult);
1700     }
1701     *ptr_real_buf++ = signal_real;
1702     freq_inv_flag = -(freq_inv_flag);
1703   }
1704 
1705   freq_inv_flag = (freq_inv_flag + 1) >> 1;
1706 
1707   if (num_sub_bands > 0) {
1708     WORD32 temp_mult_sine;
1709     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1710     shift = (*ptr_gain_buf - scale_change);
1711 
1712     if (shift > 0)
1713       signal_real = (signal_real << shift);
1714     else
1715       signal_real = (signal_real >> -(shift));
1716 
1717     temp_mult_sine = ixheaacd_mult32x16in32(FACTOR, sine_level);
1718     sine_level = sine_level_next;
1719 
1720     if (sine_level != 0) {
1721       tone_count++;
1722     } else {
1723       if (!noise_absc_flag) {
1724         signal_real = ixheaacd_mac16x16in32_shl_sat(
1725             signal_real, ixheaacd_extract16h(ptr_rand_ph[k]),
1726             *noise_level_mant);
1727       }
1728     }
1729 
1730     if (tone_count <= 16) {
1731       temp_mult2 = ixheaacd_mult32x16in32(FACTOR, sine_level);
1732 
1733       if (freq_inv_flag) {
1734         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, temp_mult_sine);
1735 
1736         if ((k + sub_band_start) < 62) {
1737           *ptr_real_buf = ixheaacd_sub32_sat(*ptr_real_buf, temp_mult2);
1738         }
1739       } else {
1740         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, temp_mult_sine);
1741 
1742         if ((k + sub_band_start) < 62) {
1743           *ptr_real_buf = ixheaacd_add32_sat(*ptr_real_buf, temp_mult2);
1744         }
1745       }
1746     } else {
1747       *ptr_real_buf = signal_real;
1748     }
1749   }
1750 }
1751 
ixheaacd_harm_idx_zerotwo(FLAG noise_absc_flag,WORD16 num_sub_bands,WORD32 * ptr_real_buf,WORD32 * ptr_imag,WORD16 * smoothed_gain,WORD16 * smoothed_noise,WORD32 factor,WORD16 * ptr_gain_buf,WORD16 scale_change,const WORD32 * ptr_rand_ph,WORD16 * ptr_sine_level_buf,WORD16 noise_e,WORD32 harm_index)1752 VOID ixheaacd_harm_idx_zerotwo(FLAG noise_absc_flag, WORD16 num_sub_bands,
1753                                WORD32 *ptr_real_buf, WORD32 *ptr_imag,
1754                                WORD16 *smoothed_gain, WORD16 *smoothed_noise,
1755                                WORD32 factor, WORD16 *ptr_gain_buf,
1756                                WORD16 scale_change, const WORD32 *ptr_rand_ph,
1757                                WORD16 *ptr_sine_level_buf, WORD16 noise_e,
1758                                WORD32 harm_index) {
1759   WORD32 k;
1760   WORD32 signal_real, sig_imag;
1761   WORD32 shift;
1762   WORD32 sine_level;
1763   ptr_gain_buf++;
1764 
1765   for (k = 0; k < num_sub_bands; k++) {
1766     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
1767     sig_imag = ixheaacd_mult32x16in32(*ptr_imag, smoothed_gain[0]);
1768 
1769     shift = ixheaacd_sub16(*ptr_gain_buf, scale_change);
1770     ptr_gain_buf += 2;
1771 
1772     if (shift > 0) {
1773       signal_real = ixheaacd_shl32(signal_real, shift);
1774       sig_imag = ixheaacd_shl32(sig_imag, shift);
1775     } else {
1776       shift = -shift;
1777       signal_real = ixheaacd_shr32(signal_real, shift);
1778       sig_imag = ixheaacd_shr32(sig_imag, shift);
1779     }
1780 
1781     ptr_rand_ph++;
1782 
1783     if (*ptr_sine_level_buf != 0) {
1784       WORD32 tmp = ixheaacd_sub16(ptr_sine_level_buf[1], noise_e);
1785 
1786       if (tmp > 0)
1787         sine_level = ixheaacd_shl32(ptr_sine_level_buf[0], tmp);
1788       else
1789         sine_level = ixheaacd_shr32(ptr_sine_level_buf[0], tmp);
1790 
1791       if (harm_index == 0)
1792         *ptr_real_buf = ixheaacd_add32_sat(signal_real, sine_level);
1793       else
1794         *ptr_real_buf = ixheaacd_sub32_sat(signal_real, sine_level);
1795 
1796       *ptr_imag = sig_imag;
1797     } else {
1798       if (!noise_absc_flag) {
1799         WORD32 random = *ptr_rand_ph;
1800         WORD16 noise = smoothed_noise[0];
1801 
1802         *ptr_real_buf = ixheaacd_mac16x16in32_shl_sat(
1803             signal_real, ixheaacd_extract16h(random), noise);
1804         *ptr_imag = ixheaacd_mac16x16in32_shl_sat(
1805             sig_imag, ixheaacd_extract16l(random), noise);
1806       } else {
1807         *ptr_real_buf = signal_real;
1808         *ptr_imag = sig_imag;
1809       }
1810     }
1811 
1812     smoothed_noise += factor;
1813     smoothed_gain += 2;
1814     ptr_sine_level_buf += 2;
1815     ptr_real_buf++;
1816     ptr_imag++;
1817   }
1818 }
1819 
ixheaacd_harm_idx_onethree(FLAG noise_absc_flag,WORD16 num_sub_bands,WORD32 * ptr_real_buf,WORD32 * ptr_imag,WORD16 * smoothed_gain,WORD16 * smoothed_noise,WORD32 factor,WORD16 * ptr_gain_buf,WORD16 scale_change,const WORD32 * ptr_rand_ph,WORD16 * ptr_sine_level_buf,WORD16 noise_e,WORD32 freq_inv_flag,WORD32 harm_index)1820 VOID ixheaacd_harm_idx_onethree(FLAG noise_absc_flag, WORD16 num_sub_bands,
1821                                 WORD32 *ptr_real_buf, WORD32 *ptr_imag,
1822                                 WORD16 *smoothed_gain, WORD16 *smoothed_noise,
1823                                 WORD32 factor, WORD16 *ptr_gain_buf,
1824                                 WORD16 scale_change, const WORD32 *ptr_rand_ph,
1825                                 WORD16 *ptr_sine_level_buf, WORD16 noise_e,
1826                                 WORD32 freq_inv_flag, WORD32 harm_index) {
1827   WORD32 k;
1828   WORD32 signal_real, sig_imag;
1829   WORD32 shift;
1830   WORD32 sine_level;
1831 
1832   ptr_gain_buf++;
1833 
1834   if (harm_index == 1) freq_inv_flag = !freq_inv_flag;
1835 
1836   for (k = 0; k < num_sub_bands; k++) {
1837     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
1838     sig_imag = ixheaacd_mult32x16in32(*ptr_imag, smoothed_gain[0]);
1839 
1840     shift = ixheaacd_sub16(*ptr_gain_buf, scale_change);
1841     ptr_gain_buf += 2;
1842 
1843     if (shift > 0) {
1844       signal_real = ixheaacd_shl32(signal_real, shift);
1845       sig_imag = ixheaacd_shl32(sig_imag, shift);
1846     } else {
1847       shift = -shift;
1848       signal_real = ixheaacd_shr32(signal_real, shift);
1849       sig_imag = ixheaacd_shr32(sig_imag, shift);
1850     }
1851 
1852     ptr_rand_ph++;
1853 
1854     if (*ptr_sine_level_buf != 0) {
1855       WORD32 tmp = ixheaacd_sub16(ptr_sine_level_buf[1], noise_e);
1856 
1857       if (tmp > 0)
1858         sine_level = ixheaacd_shl32(ptr_sine_level_buf[0], tmp);
1859       else
1860         sine_level = ixheaacd_shr32(ptr_sine_level_buf[0], -tmp);
1861 
1862       *ptr_real_buf = signal_real;
1863 
1864       if (freq_inv_flag) {
1865         *ptr_imag = ixheaacd_add32_sat(sig_imag, sine_level);
1866       } else {
1867         *ptr_imag = ixheaacd_sub32_sat(sig_imag, sine_level);
1868       }
1869 
1870     } else {
1871       if (!noise_absc_flag) {
1872         WORD32 random = *ptr_rand_ph;
1873         WORD16 noise = smoothed_noise[0];
1874 
1875         *ptr_real_buf = ixheaacd_mac16x16in32_shl_sat(
1876             signal_real, ixheaacd_extract16h(random), noise);
1877         *ptr_imag = ixheaacd_mac16x16in32_shl_sat(
1878             sig_imag, ixheaacd_extract16l(random), noise);
1879       } else {
1880         *ptr_real_buf = signal_real;
1881         *ptr_imag = sig_imag;
1882       }
1883     }
1884 
1885     freq_inv_flag = (!freq_inv_flag);
1886     smoothed_gain += 2;
1887     smoothed_noise += factor;
1888     ptr_sine_level_buf += 2;
1889     ptr_real_buf++;
1890     ptr_imag++;
1891   }
1892 }