xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_env_calc.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include "ixheaacd_sbr_common.h"
21 #include "ixheaac_type_def.h"
22 
23 #include "ixheaac_constants.h"
24 #include "ixheaac_basic_ops32.h"
25 #include "ixheaac_basic_ops16.h"
26 #include "ixheaac_basic_ops40.h"
27 #include "ixheaac_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 "ixheaac_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 "ixheaac_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 = ixheaac_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 = ixheaac_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                 (ixheaac_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 + (ixheaac_shr32(nrg_mod_mant, exp_diff));
188             nrg_mod_exp = tmp_e;
189           } else {
190             exp_diff = -exp_diff;
191             nrg_mod_mant = (ixheaac_shr32(tmp_mant, exp_diff)) + nrg_mod_mant;
192           }
193         }
194       }
195     }
196 
197     {
198       WORD32 norm_val;
199       norm_val = 16 - ixheaac_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 = ixheaac_mult16x16in32_shl(max_gain_mant, limit_gain_mant);
261       max_gain_exp = (max_gain_exp + limit_gain_exp);
262 
263       temp_val = ixheaac_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 = ixheaac_extract16h(ixheaac_shl32_dir_sat_limit(
292                 ixheaac_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 + ixheaac_shr32(accu_m_t, exp_diff);
331               accu_e_t = tmp_e;
332             } else {
333               exp_diff = -exp_diff;
334               accu_m_t = ixheaac_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] + ixheaac_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 + ixheaac_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] + ixheaac_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 + ixheaac_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 - ixheaac_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 = ixheaac_mult16_shl(temp1, boost_gain_mant);
401           temp2 = ixheaac_mult16_shl(temp2, boost_gain_mant);
402           temp3 = ixheaac_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] = ixheaac_shl16_sat(nrg_sine[2 * k], (WORD16)shift);
445     else
446       nrg_sine[2 * k] = ixheaac_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       if (shift > 31) {
467         shift = 31;
468       }
469       noise_level_mant[2 * k] = (noise_level_mant[2 * k] >> shift);
470     } else {
471       if (shift < -31) {
472         shift = -31;
473       }
474       noise_level_mant[2 * k] = (noise_level_mant[2 * k] << -shift);
475     }
476   }
477 }
478 
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)479 static PLATFORM_INLINE VOID ixheaacd_adapt_noise_gain_calc(
480     ia_sbr_calc_env_struct *ptr_sbr_calc_env, WORD32 noise_e,
481     WORD32 num_sub_bands, WORD32 skip_bands, WORD16 *nrg_gain,
482     WORD16 *noise_level_mant, WORD16 *nrg_sine, WORD32 start_pos,
483     WORD32 end_pos, WORD32 input_e, WORD32 adj_e, WORD32 final_e,
484     WORD32 sub_band_start, WORD32 lb_scale, FLAG noise_absc_flag,
485     WORD32 smooth_length, WORD32 **anal_buf_real_mant,
486     WORD32 **anal_buf_imag_mant, WORD32 low_pow_flag,
487     ia_sbr_tables_struct *ptr_sbr_tables, WORD16 max_cols) {
488   WORD32 l, k;
489   WORD32 scale_change;
490   WORD32 bands = num_sub_bands - skip_bands;
491   WORD16 *ptr_filt_buf;
492   WORD16 *ptr_filt_buf_noise;
493   WORD16 *ptr_gain = &nrg_gain[0];
494 
495   if (ptr_sbr_calc_env->start_up) {
496     WORD16 *ptr_noise = noise_level_mant;
497     ptr_sbr_calc_env->start_up = 0;
498 
499     ptr_sbr_calc_env->filt_buf_noise_e = noise_e;
500     ptr_filt_buf = &ptr_sbr_calc_env->filt_buf_me[skip_bands * 2];
501     ptr_filt_buf_noise = &ptr_sbr_calc_env->filt_buf_noise_m[skip_bands];
502 
503     for (k = bands; k != 0; k--) {
504       WORD16 temp1 = *ptr_gain++;
505       WORD16 temp2 = *ptr_gain++;
506       WORD16 temp3 = *ptr_noise;
507       ptr_noise += 2;
508 
509       *ptr_filt_buf++ = temp1;
510       *ptr_filt_buf++ = temp2;
511       *ptr_filt_buf_noise++ = temp3;
512     }
513   } else {
514     ixheaacd_equalize_filt_buff_exp(
515         &ptr_sbr_calc_env->filt_buf_me[2 * skip_bands], nrg_gain, bands);
516   }
517 
518   for (l = start_pos; l < end_pos; l++) {
519 
520     if (max_cols != 30) {
521       if ((l < MAX_COLS)) {
522         scale_change = (adj_e - input_e);
523       } else {
524         scale_change = (final_e - input_e);
525 
526         if (((l == MAX_COLS)) && ((start_pos < MAX_COLS))) {
527           WORD32 diff = final_e - noise_e;
528           noise_e = final_e;
529           ixheaacd_noise_level_rescaling(noise_level_mant, diff, bands, 2);
530         }
531       }
532     } else {
533       if ((l < max_cols)) {
534         scale_change = (adj_e - input_e);
535       } else {
536         scale_change = (final_e - input_e);
537 
538         if (((l == max_cols)) && ((start_pos < max_cols))) {
539           WORD32 diff = final_e - noise_e;
540           noise_e = final_e;
541           ixheaacd_noise_level_rescaling(noise_level_mant, diff, bands, 2);
542         }
543       }
544     }
545 
546     ixheaacd_noise_level_rescaling(ptr_sbr_calc_env->filt_buf_noise_m,
547                                    ptr_sbr_calc_env->filt_buf_noise_e - noise_e,
548                                    num_sub_bands, 1);
549 
550     ptr_sbr_calc_env->filt_buf_noise_e = noise_e;
551 
552     {
553       WORD32 *anal_buf_real_m_l;
554       anal_buf_real_m_l = anal_buf_real_mant[l];
555 
556       if (low_pow_flag) {
557         WORD32 index = ptr_sbr_calc_env->ph_index;
558         WORD32 harm_index = ptr_sbr_calc_env->harm_index;
559         WORD32 freq_inv_flag = (sub_band_start & 1);
560         WORD32 *ptr_real_buf = &anal_buf_real_m_l[sub_band_start];
561 
562         const WORD32 *ptr_rand_ph = &ptr_sbr_tables->sbr_rand_ph[index + 1];
563 
564         ptr_sbr_calc_env->ph_index =
565             (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));
566         ptr_sbr_calc_env->harm_index = (WORD16)(((harm_index + 1)) & 3);
567 
568         if (!(harm_index & 0x1)) {
569           (*ixheaacd_harm_idx_zerotwolp)(
570               ptr_real_buf, nrg_gain, scale_change, nrg_sine, ptr_rand_ph,
571               noise_level_mant, num_sub_bands, noise_absc_flag, harm_index);
572         } else {
573           WORD32 noise = (noise_e - 16) - lb_scale;
574 
575           freq_inv_flag = (!freq_inv_flag);
576           freq_inv_flag = (freq_inv_flag << 1) - 1;
577 
578           if (harm_index == 3) freq_inv_flag = -freq_inv_flag;
579 
580           ixheaacd_harm_idx_onethreelp(ptr_real_buf, nrg_gain, scale_change,
581                                        nrg_sine, ptr_rand_ph, noise_level_mant,
582                                        num_sub_bands, noise_absc_flag,
583                                        freq_inv_flag, noise, sub_band_start);
584         }
585 
586       } else {
587         WORD16 smooth_ratio;
588         WORD32 *anal_buf_imag_m_l;
589         anal_buf_imag_m_l = anal_buf_imag_mant[l];
590 
591         if (((l - start_pos) < smooth_length)) {
592           smooth_ratio = ptr_sbr_tables->env_calc_tables_ptr
593                              ->sbr_smooth_filter[(l - start_pos)];
594         } else {
595           smooth_ratio = 0;
596         }
597 
598         ixheaacd_adj_timeslot(
599             &anal_buf_real_m_l[sub_band_start],
600             &anal_buf_imag_m_l[sub_band_start],
601             &ptr_sbr_calc_env->filt_buf_me[2 * skip_bands],
602             &ptr_sbr_calc_env->filt_buf_noise_m[skip_bands], nrg_gain,
603             noise_level_mant, nrg_sine, (WORD16)(noise_e - 16),
604             &ptr_sbr_calc_env->harm_index, (WORD16)sub_band_start,
605             (WORD16)(bands), (WORD16)scale_change, smooth_ratio,
606             noise_absc_flag, &ptr_sbr_calc_env->ph_index, ptr_sbr_tables);
607       }
608     }
609   }
610 
611   ixheaacd_filt_buf_update(ptr_sbr_calc_env->filt_buf_me + 2 * skip_bands,
612                            ptr_sbr_calc_env->filt_buf_noise_m + skip_bands,
613                            nrg_gain, noise_level_mant, bands);
614 }
615 
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)616 VOID ixheaacd_calc_subband_gains(ia_freq_band_data_struct *pstr_freq_band_data,
617                                  ia_sbr_frame_info_data_struct *ptr_frame_data,
618                                  WORD32 freq_res, WORD16 *ptr_noise_floor,
619                                  WORD32 num_sf_bands, WORD32 mvalue, WORD32 env,
620                                  WORD8 *sine_mapped_matrix,
621                                  WORD8 *alias_red_buf, WORD16 *ptr_enrg_orig,
622                                  WORD16 *nrg_sine, WORD16 *nrg_est,
623                                  WORD16 *nrg_gain, WORD16 *noise_level_mant,
624                                  FLAG noise_absc_flag,
625                                  ixheaacd_misc_tables *pstr_common_tables) {
626   WORD16 *ptr_freq_band_tbl = pstr_freq_band_data->freq_band_table[freq_res];
627   WORD32 ui_noise = pstr_freq_band_data->freq_band_tbl_noise[1];
628   WORD32 nb_idx = 0;
629   WORD16 tmp_noise_mant;
630   WORD16 tmp_noise_exp;
631   WORD8 *ptr_sine_mapped = sine_mapped_matrix;
632   WORD32 sub_band_start = pstr_freq_band_data->sub_band_start;
633   WORD32 skip_bands = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
634   WORD8 *ptr_sine_mapped_1 = &sine_mapped_matrix[skip_bands];
635   WORD32 k, c = 0, j;
636 
637   WORD16 *ptr_env_sf_arr = &ptr_frame_data->int_env_sf_arr[mvalue];
638   WORD8 *ptr_alias_red_buf =
639       &alias_red_buf[ptr_freq_band_tbl[0] - sub_band_start];
640 
641   tmp_noise_mant = (WORD16)(ptr_noise_floor[nb_idx] & MASK_M);
642   tmp_noise_exp =
643       (WORD16)(ptr_noise_floor[nb_idx] & MASK_FOR_EXP) - NOISE_EXP_OFFSET;
644 
645   for (j = 0; j < num_sf_bands; j++) {
646     WORD8 sine_present_flag;
647     WORD16 tmp_nrg_ref_exp, tmp_nrg_ref_mant;
648     WORD16 li = *ptr_freq_band_tbl++;
649     WORD16 ui = *ptr_freq_band_tbl;
650     WORD16 env_sf_val = *ptr_env_sf_arr++;
651 
652     tmp_nrg_ref_exp =
653         (WORD16)((env_sf_val & (WORD16)MASK_FOR_EXP) - NRG_EXP_OFFSET);
654     tmp_nrg_ref_mant = (WORD16)(env_sf_val & MASK_M);
655 
656     sine_present_flag = 0;
657     for (k = li; k < ui; k++) {
658       if ((env >= *ptr_sine_mapped++)) sine_present_flag = 1;
659     }
660     for (k = li; k < ui; k++) {
661       *ptr_alias_red_buf++ = !sine_present_flag;
662 
663       if ((k >= ui_noise)) {
664         nb_idx++;
665         ui_noise = pstr_freq_band_data->freq_band_tbl_noise[nb_idx + 1];
666         tmp_noise_mant = (WORD16)(ptr_noise_floor[nb_idx] & MASK_M);
667         tmp_noise_exp =
668             (WORD16)(ptr_noise_floor[nb_idx] & MASK_FOR_EXP) - NOISE_EXP_OFFSET;
669       }
670 
671       if ((k >= ptr_frame_data->max_qmf_subband_aac)) {
672         ptr_enrg_orig[2 * c] = tmp_nrg_ref_mant;
673         ptr_enrg_orig[2 * c + 1] = tmp_nrg_ref_exp;
674         nrg_sine[2 * c] = 0;
675         nrg_sine[2 * c + 1] = 0;
676 
677         ixheaacd_subbandgain_calc(
678             tmp_nrg_ref_mant, tmp_noise_mant, nrg_est[2 * c],
679             nrg_est[2 * c + 1], tmp_noise_exp, tmp_nrg_ref_exp,
680             sine_present_flag,
681             (env >= ptr_sine_mapped_1[c]) ? (FLAG)1 : (FLAG)0, noise_absc_flag,
682             &nrg_gain[2 * c], &noise_level_mant[2 * c], &nrg_sine[2 * c],
683             pstr_common_tables);
684         c++;
685       }
686     }
687   }
688 }
689 
690 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
691 
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)692 IA_ERRORCODE ixheaacd_calc_sbrenvelope(
693     ia_sbr_scale_fact_struct *ptr_sbr_scale_fac,
694     ia_sbr_calc_env_struct *ptr_sbr_calc_env,
695     ia_sbr_header_data_struct *ptr_header_data,
696     ia_sbr_frame_info_data_struct *ptr_frame_data,
697     ia_sbr_prev_frame_data_struct *ptr_frame_data_prev,
698     WORD32 **anal_buf_real_mant, WORD32 **anal_buf_imag_mant,
699     WORD16 *deg_patched, FLAG low_pow_flag,
700     ia_sbr_tables_struct *ptr_sbr_tables,
701     ixheaacd_misc_tables *pstr_common_tables, WORD32 *ptr_qmf_matrix,
702     WORD32 audio_object_type) {
703   WORD32 i, j, m;
704   WORD32 noise_floor_idx;
705   WORD32 start_pos, end_pos;
706   WORD32 freq_res;
707   WORD32 num_env = ptr_frame_data->str_frame_info_details.num_env;
708   WORD16 *ptr_border_vec = ptr_frame_data->str_frame_info_details.border_vec;
709   IA_ERRORCODE err_code = IA_NO_ERROR;
710   WORD16 *ptr_noise_floor;
711   ia_freq_band_data_struct *pstr_freq_band_data =
712       ptr_header_data->pstr_freq_band_data;
713 
714   FLAG noise_absc_flag;
715   WORD32 smooth_length;
716 
717   const WORD16 *num_sf_bands = pstr_freq_band_data->num_sf_bands;
718   const WORD32 num_nf_bands = pstr_freq_band_data->num_nf_bands;
719 
720   WORD32 sub_band_start = pstr_freq_band_data->sub_band_start;
721   WORD32 sub_band_end = pstr_freq_band_data->sub_band_end;
722 
723   WORD16 num_timeslots = ptr_header_data->num_time_slots;
724   WORD16 max_cols = ptr_header_data->num_time_slots * 2;
725 
726   WORD32 num_sub_bands;
727   WORD32 skip_bands;
728   WORD32 bands;
729 
730   WORD num_cols;
731   WORD32 first_start;
732 
733   WORD16 *ptr_sbr_lim_gain;
734   WORD32 max_sfb_nrg_exp;
735 
736   WORD16 *ptr_enrg_orig;
737 
738   WORD32 input_e;
739   WORD32 ov_adj_e;
740   WORD32 adj_e;
741   WORD32 output_e;
742   WORD32 final_e;
743   WORD16 noise_e;
744   WORD16 lb_scale;
745 
746   WORD16 nrg_est[2 * MAX_FREQ_COEFFS];
747 
748   WORD16 nrg_gain[2 * MAX_FREQ_COEFFS];
749   WORD16 noise_level_mant[2 * MAX_FREQ_COEFFS];
750   WORD16 nrg_sine[2 * MAX_FREQ_COEFFS];
751 
752   WORD8 sine_mapped_matrix[MAX_FREQ_COEFFS];
753   WORD8 alias_red_buf[64];
754 
755   ptr_noise_floor = ptr_frame_data->int_noise_floor;
756 
757   ptr_enrg_orig =
758       (WORD16 *)((WORD8 *)ptr_frame_data +
759                  ALIGN_SIZE64(sizeof(ia_sbr_frame_info_data_struct)));
760 
761   num_env = ptr_frame_data->str_frame_info_details.num_env;
762   ptr_border_vec = ptr_frame_data->str_frame_info_details.border_vec;
763   num_sub_bands = (sub_band_end - sub_band_start);
764   skip_bands = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
765 
766   ixheaacd_map_sineflags(
767       pstr_freq_band_data->freq_band_table[HIGH],
768       pstr_freq_band_data->num_sf_bands[HIGH], ptr_frame_data->add_harmonics,
769       ptr_sbr_calc_env->harm_flags_prev,
770       ptr_frame_data->str_frame_info_details.transient_env, sine_mapped_matrix);
771 
772   adj_e = 0;
773   {
774     WORD16 max_noise;
775     WORD32 first_band;
776 
777     if (ptr_frame_data_prev->max_qmf_subband_aac >
778         ptr_frame_data->max_qmf_subband_aac)
779       first_band = (ptr_frame_data_prev->max_qmf_subband_aac - sub_band_start);
780     else
781       first_band = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
782 
783     max_noise = 0;
784     for (i = first_band; i < num_sub_bands; i++) {
785       if (ptr_sbr_calc_env->filt_buf_noise_m[i] > max_noise) {
786         max_noise = ptr_sbr_calc_env->filt_buf_noise_m[i];
787       }
788     }
789     adj_e = ((ptr_sbr_calc_env->filt_buf_noise_e - ixheaac_norm32(max_noise)) -
790              16);
791   }
792 
793   final_e = 0;
794   {
795     WORD16 *ptr_env_sf_buf = ptr_frame_data->int_env_sf_arr;
796     for (i = 0; i < num_env; i++) {
797       WORD32 temp_val;
798 
799       max_sfb_nrg_exp = NRG_EXP_OFFSET - SHORT_BITS;
800 
801       freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
802 
803       for (j = 0; j < num_sf_bands[freq_res]; j++) {
804         temp_val = ((*ptr_env_sf_buf++ & MASK_FOR_EXP));
805 
806         if ((temp_val > max_sfb_nrg_exp)) {
807           max_sfb_nrg_exp = temp_val;
808         }
809       }
810 
811       max_sfb_nrg_exp = (max_sfb_nrg_exp - NRG_EXP_OFFSET);
812 
813       temp_val = ((max_sfb_nrg_exp + 13) >> 1);
814 
815       if (num_timeslots != 15) {
816         if ((ptr_border_vec[i] < SBR_TIME_SLOTS)) {
817           if ((temp_val > adj_e)) {
818             adj_e = (WORD16)temp_val;
819           }
820         }
821 
822         if ((ptr_border_vec[i + 1] > SBR_TIME_SLOTS)) {
823           if ((temp_val > final_e)) {
824             final_e = (WORD16)temp_val;
825           }
826         }
827       } else {
828         if ((ptr_border_vec[i] < num_timeslots)) {
829           if ((temp_val > adj_e)) {
830             adj_e = (WORD16)temp_val;
831           }
832         }
833 
834         if ((ptr_border_vec[i + 1] > num_timeslots)) {
835           if ((temp_val > final_e)) {
836             final_e = (WORD16)temp_val;
837           }
838         }
839       }
840     }
841   }
842 
843   m = 0;
844   noise_floor_idx = 0;
845 
846   for (i = 0; i < num_env; i++) {
847     if (audio_object_type == AOT_ER_AAC_ELD ||
848         audio_object_type == AOT_ER_AAC_LD) {
849       start_pos = ptr_border_vec[i];
850       end_pos = ptr_border_vec[i + 1];
851     } else {
852       start_pos = SBR_TIME_STEP * ptr_border_vec[i];
853       end_pos = SBR_TIME_STEP * ptr_border_vec[i + 1];
854     }
855     if ((start_pos >= MAX_ENV_COLS) || (end_pos > MAX_ENV_COLS))
856       return IA_FATAL_ERROR;
857     freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
858 
859     if (noise_floor_idx >= MAX_NOISE_ENVELOPES) return IA_FATAL_ERROR;
860 
861     if (ptr_border_vec[i] ==
862         ptr_frame_data->str_frame_info_details
863             .noise_border_vec[noise_floor_idx + 1]) {
864       ptr_noise_floor += num_nf_bands;
865       noise_floor_idx++;
866     }
867 
868     if ((i == ptr_frame_data->str_frame_info_details.transient_env) ||
869         (i == ptr_sbr_calc_env->tansient_env_prev)) {
870       noise_absc_flag = 1;
871       smooth_length = 0;
872     } else {
873       noise_absc_flag = 0;
874       smooth_length = ((1 - ptr_header_data->smoothing_mode) << 2);
875     }
876 
877     input_e = 15 - ptr_sbr_scale_fac->hb_scale;
878 
879     if (ptr_header_data->interpol_freq) {
880       (*ixheaacd_enery_calc_per_subband)(
881           start_pos, end_pos, ptr_frame_data->max_qmf_subband_aac, sub_band_end,
882           input_e, nrg_est, low_pow_flag, ptr_sbr_tables, ptr_qmf_matrix);
883     } else {
884       ixheaacd_enery_calc_persfb(
885           anal_buf_real_mant, anal_buf_imag_mant, num_sf_bands[freq_res],
886           pstr_freq_band_data->freq_band_table[freq_res], start_pos, end_pos,
887           ptr_frame_data->max_qmf_subband_aac, input_e, nrg_est, low_pow_flag,
888           ptr_sbr_tables);
889     }
890 
891     if (pstr_freq_band_data->freq_band_table[freq_res][0] < pstr_freq_band_data->sub_band_start) {
892       pstr_freq_band_data->sub_band_start = pstr_freq_band_data->freq_band_table[freq_res][0];
893       return IA_FATAL_ERROR;
894     }
895 
896     ixheaacd_calc_subband_gains(
897         pstr_freq_band_data, ptr_frame_data, freq_res, ptr_noise_floor,
898         num_sf_bands[freq_res], m, i, sine_mapped_matrix, alias_red_buf,
899         ptr_enrg_orig, nrg_sine, nrg_est, nrg_gain, noise_level_mant,
900         noise_absc_flag, pstr_common_tables);
901 
902     m += num_sf_bands[freq_res];
903 
904     ptr_sbr_lim_gain =
905         &ptr_sbr_tables->env_calc_tables_ptr
906              ->sbr_lim_gains_m[2 * ptr_header_data->limiter_gains];
907     ixheaacd_noiselimiting(pstr_freq_band_data, skip_bands, ptr_enrg_orig,
908                            nrg_est, nrg_gain, noise_level_mant, nrg_sine,
909                            ptr_sbr_lim_gain, noise_absc_flag,
910                            pstr_common_tables);
911 
912     if (low_pow_flag) {
913       ixheaacd_alias_reduction(deg_patched + sub_band_start, nrg_gain, nrg_est,
914                                alias_red_buf, num_sub_bands,
915                                pstr_common_tables);
916     }
917 
918     if (max_cols != 30) {
919       if ((start_pos < MAX_COLS)) {
920         noise_e = adj_e;
921       } else {
922         noise_e = final_e;
923       }
924     } else {
925       if ((start_pos < max_cols)) {
926         noise_e = adj_e;
927       } else {
928         noise_e = final_e;
929       }
930     }
931 
932     bands = num_sub_bands - skip_bands;
933 
934     if (low_pow_flag) {
935       (*ixheaacd_conv_ergtoamplitudelp)(
936           bands, noise_e, nrg_sine, nrg_gain, noise_level_mant,
937           (WORD16 *)pstr_common_tables->sqrt_table);
938     } else
939 
940     {
941       (*ixheaacd_conv_ergtoamplitude)(bands, noise_e, nrg_sine, nrg_gain,
942                                       noise_level_mant,
943                                       (WORD16 *)pstr_common_tables->sqrt_table);
944     }
945 
946     lb_scale = ixheaac_sub16(15, ptr_sbr_scale_fac->lb_scale);
947 
948     ixheaacd_adapt_noise_gain_calc(
949         ptr_sbr_calc_env, noise_e, num_sub_bands, skip_bands, nrg_gain,
950         noise_level_mant, nrg_sine, start_pos, end_pos, input_e, adj_e, final_e,
951         ptr_frame_data->max_qmf_subband_aac, lb_scale, noise_absc_flag,
952         smooth_length, anal_buf_real_mant, anal_buf_imag_mant, low_pow_flag,
953         ptr_sbr_tables, max_cols);
954   }
955 
956   first_start = ptr_border_vec[0] * SBR_TIME_STEP;
957   {
958     WORD32 ov_reserve, reserve;
959 
960     ov_reserve = reserve = 0;
961 
962     if (audio_object_type != AOT_ER_AAC_ELD) {
963       if (ptr_header_data->channel_mode == PS_STEREO) {
964         ov_reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
965             anal_buf_real_mant, anal_buf_imag_mant,
966             ptr_frame_data->max_qmf_subband_aac, sub_band_end, 0, first_start,
967             low_pow_flag);
968 
969         if (max_cols != 30) {
970           reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
971             anal_buf_real_mant, anal_buf_imag_mant,
972             ptr_frame_data->max_qmf_subband_aac, sub_band_end, first_start,
973             MAX_COLS, low_pow_flag);
974         } else {
975           reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
976             anal_buf_real_mant, anal_buf_imag_mant,
977             ptr_frame_data->max_qmf_subband_aac, sub_band_end, first_start,
978             max_cols, low_pow_flag);
979         }
980       }
981     }
982 
983     output_e = 0;
984 
985     ov_adj_e = 15 - ptr_sbr_scale_fac->ov_hb_scale;
986 
987     if (((ov_adj_e - ov_reserve) > (adj_e - reserve)))
988       output_e = (ov_adj_e - ov_reserve);
989     else
990       output_e = (adj_e - reserve);
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                              0, first_start, (ov_adj_e - output_e),
995                              low_pow_flag);
996 
997     num_cols = (ptr_header_data->num_time_slots * ptr_header_data->time_step);
998 
999     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
1000                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
1001                              first_start, num_cols, (adj_e - output_e),
1002                              low_pow_flag);
1003   }
1004 
1005   ptr_sbr_scale_fac->hb_scale = (WORD16)(15 - output_e);
1006 
1007   ptr_sbr_scale_fac->ov_hb_scale = (WORD16)(15 - final_e);
1008 
1009   if (ptr_frame_data->str_frame_info_details.transient_env == num_env) {
1010     ptr_sbr_calc_env->tansient_env_prev = 0;
1011   } else {
1012     ptr_sbr_calc_env->tansient_env_prev = -1;
1013   }
1014   return err_code;
1015 }
1016 
ixheaacd_equalize_filt_buff_exp(WORD16 * ptr_filt_buf,WORD16 * nrg_gain,WORD32 subbands)1017 VOID ixheaacd_equalize_filt_buff_exp(WORD16 *ptr_filt_buf, WORD16 *nrg_gain,
1018                                      WORD32 subbands) {
1019   WORD32 band;
1020   WORD32 diff;
1021   WORD32 gain_m, gain_e;
1022   WORD32 filt_buf_mant, filt_buf_exp;
1023 
1024   for (band = subbands - 1; band >= 0; band--) {
1025     filt_buf_exp = *(ptr_filt_buf + 1);
1026     gain_e = *(nrg_gain + 1);
1027     filt_buf_mant = *ptr_filt_buf;
1028     gain_m = *nrg_gain;
1029     diff = (gain_e - filt_buf_exp);
1030 
1031     if (diff >= 0) {
1032       *(ptr_filt_buf + 1) = (WORD16)(gain_e);
1033 
1034       *ptr_filt_buf = (WORD16)(*ptr_filt_buf >> diff);
1035     } else {
1036       WORD32 reserve;
1037       reserve = (ixheaac_norm32(filt_buf_mant) - 16);
1038 
1039       if ((diff + reserve) >= 0) {
1040         *ptr_filt_buf = (WORD16)(filt_buf_mant << -diff);
1041         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp + diff);
1042       } else {
1043         WORD32 shift;
1044 
1045         *ptr_filt_buf = (WORD16)(filt_buf_mant << reserve);
1046 
1047         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp - reserve);
1048 
1049         shift = -(reserve + diff);
1050 
1051         *nrg_gain = (WORD16)(gain_m >> shift);
1052         *(nrg_gain + 1) = (WORD16)(*(nrg_gain + 1) + shift);
1053       }
1054     }
1055     nrg_gain += 2;
1056     ptr_filt_buf += 2;
1057   }
1058 }
1059 
ixheaacd_filt_buf_update(WORD16 * ptr_filt_buf,WORD16 * ptr_filt_buf_noise,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD32 num_sub_bands)1060 VOID ixheaacd_filt_buf_update(WORD16 *ptr_filt_buf,
1061                                                      WORD16 *ptr_filt_buf_noise,
1062                                                      WORD16 *nrg_gain,
1063                                                      WORD16 *noise_level_mant,
1064                                                      WORD32 num_sub_bands) {
1065   WORD32 k;
1066   WORD32 temp1, temp2;
1067 
1068   for (k = num_sub_bands - 1; k >= 0; k--) {
1069     temp1 = *nrg_gain;
1070     nrg_gain += 2;
1071     temp2 = *noise_level_mant;
1072     noise_level_mant += 2;
1073 
1074     *ptr_filt_buf = temp1;
1075     ptr_filt_buf += 2;
1076     *ptr_filt_buf_noise++ = temp2;
1077   }
1078 }
1079 
ixheaacd_noise_level_rescaling(WORD16 * noise_level_mant,WORD32 diff,WORD32 num_sub_bands,WORD32 ixheaacd_drc_offset)1080 VOID ixheaacd_noise_level_rescaling(WORD16 *noise_level_mant, WORD32 diff,
1081                                     WORD32 num_sub_bands,
1082                                     WORD32 ixheaacd_drc_offset) {
1083   WORD32 k;
1084 
1085   if (diff > 0) {
1086     for (k = num_sub_bands - 1; k >= 0; k--) {
1087       *noise_level_mant = *noise_level_mant >> diff;
1088       noise_level_mant += ixheaacd_drc_offset;
1089     }
1090   } else if (diff < 0) {
1091     diff = -diff;
1092     for (k = num_sub_bands - 1; k >= 0; k--) {
1093       *noise_level_mant = *noise_level_mant << diff;
1094       noise_level_mant += ixheaacd_drc_offset;
1095     }
1096   }
1097 }
1098 
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)1099 VOID ixheaacd_adjust_scale_dec(WORD32 **re, WORD32 **im, WORD32 sub_band_start,
1100                                WORD32 sub_band_end, WORD32 start_pos,
1101                                WORD32 next_pos, WORD32 shift,
1102                                FLAG low_pow_flag) {
1103   WORD32 k, l;
1104 
1105   if (shift != 0) {
1106     WORD32 num_sub_bands = (sub_band_end - sub_band_start);
1107 
1108     shift = ixheaac_min32(shift, 31);
1109     shift = ixheaac_max32(shift, -31);
1110 
1111     if (low_pow_flag) {
1112       if (shift > 0) {
1113         for (l = start_pos; l < next_pos; l++) {
1114           WORD32 *ptr = re[l] + sub_band_start;
1115           for (k = num_sub_bands - 1; k >= 0; k--) {
1116             *ptr = (*ptr << shift);
1117             ptr++;
1118           }
1119         }
1120       } else {
1121         shift = -shift;
1122         for (l = start_pos; l < next_pos; l++) {
1123           WORD32 *ptr = re[l] + sub_band_start;
1124           for (k = num_sub_bands - 1; k >= 0; k--) {
1125             *ptr = (*ptr >> shift);
1126             ptr++;
1127           }
1128         }
1129       }
1130     } else {
1131       if (shift > 0) {
1132         for (l = start_pos; l < next_pos; l++) {
1133           WORD32 *ptr = re[l] + sub_band_start;
1134           WORD32 *pti = im[l] + sub_band_start;
1135           for (k = num_sub_bands; k > 0; k--) {
1136             *ptr = (*ptr << shift);
1137             *pti = (*pti << shift);
1138             pti++;
1139             ptr++;
1140           }
1141         }
1142       } else {
1143         shift = -shift;
1144         for (l = start_pos; l < next_pos; l++) {
1145           WORD32 *ptr = re[l] + sub_band_start;
1146           WORD32 *pti = im[l] + sub_band_start;
1147           for (k = num_sub_bands; k > 0; k--) {
1148             *ptr = (*ptr >> shift);
1149             *pti = (*pti >> shift);
1150             ptr++;
1151             pti++;
1152           }
1153         }
1154       }
1155     }
1156   }
1157 }
1158 
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)1159 WORD16 ixheaacd_expsubbandsamples_dec(WORD32 **re, WORD32 **im,
1160                                       WORD32 sub_band_start,
1161                                       WORD32 sub_band_end, WORD32 start_pos,
1162                                       WORD32 next_pos, FLAG low_pow_flag) {
1163   WORD32 l, k;
1164   WORD16 max_shift;
1165 
1166   WORD32 value;
1167   WORD32 max_abs;
1168   WORD32 num_sub_bands;
1169 
1170   WORD32 *ptr_real;
1171   WORD32 *ptr_imag;
1172 
1173   max_abs = 1;
1174   num_sub_bands = (sub_band_end - sub_band_start);
1175 
1176   if (low_pow_flag) {
1177     for (l = start_pos; l < next_pos; l++) {
1178       WORD32 temp_real;
1179       ptr_real = re[l] + sub_band_start;
1180       temp_real = *ptr_real++;
1181       for (k = num_sub_bands; k > 0; k--) {
1182         value = ixheaac_abs32_nrm(temp_real);
1183         max_abs |= value;
1184         temp_real = *ptr_real++;
1185       }
1186     }
1187     max_shift = ixheaac_pnorm32(max_abs);
1188   } else {
1189     for (l = start_pos; l < next_pos; l++) {
1190       ptr_real = re[l] + sub_band_start;
1191       ptr_imag = im[l] + sub_band_start;
1192 
1193       for (k = num_sub_bands; k > 0; k--) {
1194         WORD32 temp_real = *ptr_real++;
1195         WORD32 tempIm = *ptr_imag++;
1196 
1197         temp_real = ixheaac_abs32_nrm(temp_real);
1198         max_abs |= temp_real;
1199         tempIm = ixheaac_abs32_nrm(tempIm);
1200         max_abs |= tempIm;
1201       }
1202     }
1203     max_shift = ixheaac_pnorm32(max_abs);
1204   }
1205 
1206   return max_shift;
1207 }
1208 
1209 #define SHIFT_BEFORE_SQUARE 4
1210 
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)1211 VOID ixheaacd_enery_calc_per_subband_dec(WORD32 start_pos, WORD32 next_pos,
1212                                          WORD32 sub_band_start,
1213                                          WORD32 sub_band_end, WORD32 frame_exp,
1214                                          WORD16 *nrg_est, FLAG low_pow_flag,
1215                                          ia_sbr_tables_struct *ptr_sbr_tables,
1216                                          WORD32 *ptr_qmf_matrix) {
1217   WORD16 temp;
1218   WORD16 inv_width;
1219   WORD16 sum_m;
1220   WORD32 accu;
1221   WORD32 k, l;
1222   WORD32 pre_shift_val;
1223   WORD32 shift;
1224   WORD32 *p_real;
1225   WORD32 max_shift_gap = SHIFT_BEFORE_SQUARE;
1226   WORD32 extra_shift = 0;
1227   WORD32 num_cols = next_pos - start_pos;
1228 
1229   if (low_pow_flag) {
1230     max_shift_gap -= 1;
1231     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 6);
1232     extra_shift++;
1233   } else {
1234     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 7);
1235     num_cols = num_cols << 1;
1236   }
1237   inv_width = ptr_sbr_tables->env_calc_tables_ptr
1238                   ->sbr_inv_int_table[(next_pos - start_pos)];
1239   frame_exp = (frame_exp << 1);
1240 
1241   {
1242     WORD32 *ptr;
1243     for (k = sub_band_start; k < sub_band_end; k++) {
1244       WORD32 max_val = 1;
1245 
1246       ptr = p_real;
1247 
1248       for (l = num_cols; l != 0; l -= 2) {
1249         WORD32 value = ixheaac_abs32_nrm(*ptr);
1250         ptr += 64;
1251         max_val = ixheaac_max32(value, max_val);
1252         value = ixheaac_abs32_nrm(*ptr);
1253         ptr += 64;
1254         max_val = ixheaac_max32(value, max_val);
1255       }
1256       pre_shift_val = (ixheaac_pnorm32(max_val) - max_shift_gap);
1257 
1258       accu = 0L;
1259       shift = 16 - pre_shift_val;
1260       ptr = p_real;
1261 
1262       if (shift > 0)
1263         for (l = num_cols; l != 0; l -= 2) {
1264           temp = (WORD16)((*(ptr) >> shift));
1265           ptr += 64;
1266           accu += (temp * temp);
1267           temp = (WORD16)((*(ptr) >> shift));
1268           ptr += 64;
1269           accu += (temp * temp);
1270         }
1271       else
1272         for (l = num_cols; l != 0; l -= 2) {
1273           temp = (WORD16)((*(ptr) << (-shift)));
1274           ptr += 64;
1275           accu += (temp * temp);
1276           temp = (WORD16)((*(ptr) << (-shift)));
1277           ptr += 64;
1278           accu += (temp * temp);
1279         }
1280 
1281       if (accu != 0L) {
1282         shift = -(ixheaac_pnorm32(accu));
1283         sum_m = (WORD16)(ixheaac_shr32_dir_sat_limit(accu, (16 + shift)));
1284         *nrg_est++ = ixheaac_mult16_shl_sat(sum_m, inv_width);
1285         shift = (shift - (pre_shift_val << 1));
1286         shift += extra_shift;
1287         *nrg_est++ = (WORD16)(frame_exp + shift + 1);
1288       } else {
1289         *nrg_est++ = 0;
1290         *nrg_est++ = 0;
1291       }
1292 
1293       p_real++;
1294     }
1295   }
1296 }
1297 
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)1298 VOID ixheaacd_enery_calc_persfb(WORD32 **anal_buf_real, WORD32 **anal_buf_imag,
1299                                 WORD32 num_sf_bands, WORD16 *freq_band_table,
1300                                 WORD32 start_pos, WORD32 next_pos,
1301                                 WORD32 max_qmf_subband_aac, WORD32 frame_exp,
1302                                 WORD16 *nrg_est, FLAG low_pow_flag,
1303                                 ia_sbr_tables_struct *ptr_sbr_tables) {
1304   WORD16 inv_width;
1305   WORD32 pre_shift_val;
1306   WORD32 shift;
1307   WORD32 sum_e;
1308   WORD16 sum_m;
1309 
1310   WORD32 j, k, l;
1311   WORD32 li, ui;
1312   WORD32 accu_line;
1313   WORD32 accumulate;
1314   WORD32 extra_shift = 10;
1315 
1316   inv_width = ptr_sbr_tables->env_calc_tables_ptr
1317                   ->sbr_inv_int_table[(next_pos - start_pos)];
1318 
1319   frame_exp = (frame_exp << 1);
1320 
1321   if (low_pow_flag) extra_shift++;
1322 
1323   for (j = 0; j < num_sf_bands; j++) {
1324     li = freq_band_table[j];
1325 
1326     if ((li >= max_qmf_subband_aac)) {
1327       ui = freq_band_table[j + 1];
1328 
1329       pre_shift_val = (*ixheaacd_ixheaacd_expsubbandsamples)(
1330           anal_buf_real, anal_buf_imag, li, ui, start_pos, next_pos,
1331           low_pow_flag);
1332 
1333       pre_shift_val = (pre_shift_val - SHIFT_BEFORE_SQUARE);
1334 
1335       accumulate = 0;
1336 
1337       for (k = li; k < ui; k++) {
1338         WORD32 pre_shift1 = (16 - pre_shift_val);
1339         accu_line = 0L;
1340         pre_shift1 = min(pre_shift1, 31);
1341         {
1342           WORD32 *ptr = &anal_buf_real[start_pos][k];
1343           WORD32 inc = !low_pow_flag;
1344           for (l = (next_pos - start_pos) << inc; l != 0; l--) {
1345             WORD16 temp;
1346             temp = ixheaac_extract16l(ixheaac_shr32_dir(*ptr, pre_shift1));
1347             ptr += 64;
1348             accu_line = ixheaac_mac16x16in32_sat(accu_line, temp, temp);
1349           }
1350         }
1351         accumulate =
1352             ixheaac_add32_sat(accumulate, ixheaac_shr32(accu_line, 9));
1353       }
1354 
1355       shift = ixheaac_pnorm32(accumulate);
1356 
1357       sum_m = ixheaac_extract16l(
1358           ixheaac_shr32_dir_sat_limit(accumulate, (16 - shift)));
1359 
1360       if (sum_m == 0) {
1361         sum_e = 0;
1362       } else {
1363         sum_m = ixheaac_mult16_shl_sat(sum_m, inv_width);
1364 
1365         sum_m = ixheaac_mult16_shl_sat(
1366             sum_m,
1367             ptr_sbr_tables->env_calc_tables_ptr->sbr_inv_int_table[ui - li]);
1368 
1369         sum_e = ((frame_exp + extra_shift) - shift);
1370 
1371         sum_e = (sum_e - (pre_shift_val << 1));
1372       }
1373 
1374       for (k = li; k < ui; k++) {
1375         *nrg_est++ = sum_m;
1376         *nrg_est++ = (WORD16)sum_e;
1377       }
1378     }
1379   }
1380 }
1381 
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)1382 VOID ixheaacd_subbandgain_calc(WORD16 e_orig_mant_matrix, WORD16 tmp_noise_mant,
1383                                WORD16 nrg_est_mant, WORD16 nrg_est_exp,
1384                                WORD16 tmp_noise_exp, WORD16 nrg_ref_exp,
1385                                FLAG sine_present_flag, FLAG sine_mapped_matrix,
1386                                FLAG noise_absc_flag, WORD16 *ptr_nrg_gain_mant,
1387                                WORD16 *ptr_noise_floor_mant,
1388                                WORD16 *ptr_nrg_sine_m,
1389                                ixheaacd_misc_tables *pstr_common_tables) {
1390   WORD16 var1_mant;
1391   WORD16 var1_exp;
1392   WORD16 var2_mant;
1393   WORD16 var2_exp;
1394   WORD16 var3_mant;
1395   WORD16 var3_exp;
1396   WORD32 temp;
1397 
1398   if (nrg_est_mant == 0) {
1399     nrg_est_mant = 0x4000;
1400     nrg_est_exp = 1;
1401   }
1402 
1403   var1_mant = ixheaac_mult16_shl_sat(e_orig_mant_matrix, tmp_noise_mant);
1404   var1_exp = (nrg_ref_exp + tmp_noise_exp);
1405 
1406   {
1407     WORD32 accu, exp_diff;
1408 
1409     exp_diff = tmp_noise_exp - 1;
1410 
1411     if (exp_diff >= 0) {
1412       accu = tmp_noise_mant + ixheaac_shr32(0x4000, exp_diff);
1413       var2_exp = tmp_noise_exp;
1414     } else {
1415       exp_diff = -exp_diff;
1416       accu = ixheaac_shr32((WORD32)tmp_noise_mant, exp_diff) + 0x4000;
1417       var2_exp = 1;
1418     }
1419     if (ixheaac_abs32(accu) >= 0x8000) {
1420       accu = accu >> 1;
1421       var2_exp++;
1422     }
1423     var2_mant = (WORD16)(accu);
1424   }
1425 
1426   temp = ixheaacd_fix_mant_div(var1_mant, var2_mant, ptr_noise_floor_mant,
1427                                pstr_common_tables);
1428   *(ptr_noise_floor_mant + 1) = temp + (var1_exp - var2_exp) + 1;
1429 
1430   if (sine_present_flag || !noise_absc_flag) {
1431     var3_mant = ixheaac_mult16_shl_sat(var2_mant, nrg_est_mant);
1432     var3_exp = (var2_exp + nrg_est_exp);
1433   } else {
1434     var3_mant = nrg_est_mant;
1435     var3_exp = nrg_est_exp;
1436   }
1437 
1438   if (sine_present_flag == 0) {
1439     var1_mant = e_orig_mant_matrix;
1440     var1_exp = nrg_ref_exp;
1441   }
1442 
1443   temp = ixheaacd_fix_mant_div(var1_mant, var3_mant, ptr_nrg_gain_mant,
1444                                pstr_common_tables);
1445   *(ptr_nrg_gain_mant + 1) = temp + (var1_exp - var3_exp) + 1;
1446 
1447   if (sine_present_flag && sine_mapped_matrix) {
1448     temp = ixheaacd_fix_mant_div(e_orig_mant_matrix, var2_mant, ptr_nrg_sine_m,
1449                                  pstr_common_tables);
1450     *(ptr_nrg_sine_m + 1) = temp + (nrg_ref_exp - var2_exp) + 1;
1451   }
1452 }
1453 
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)1454 VOID ixheaacd_avggain_calc(WORD16 *ptr_enrg_orig, WORD16 *nrg_est,
1455                            WORD32 sub_band_start, WORD32 sub_band_end,
1456                            WORD16 *ptr_enrg_orig_mant, WORD16 *ptr_sum_ref_exp,
1457                            WORD16 *ptr_avg_gain_mant, WORD16 *ptr_avg_gain_exp,
1458                            ixheaacd_misc_tables *pstr_common_tables,
1459                            WORD32 flag) {
1460   WORD16 sum_orig_mant;
1461   WORD16 sum_orig_exp;
1462   WORD16 sum_est_mant;
1463   WORD16 sum_est_exp;
1464 
1465   WORD32 accu_sum_orig_mant;
1466   WORD32 accu_sum_orig_exp;
1467   WORD32 accu_sum_est_mant;
1468   WORD32 accu_sum_est_exp;
1469 
1470   WORD32 k, temp;
1471   WORD16 *ptr_enrg_orig_buf;
1472   WORD16 *ptr_enrg_est_buf;
1473 
1474   {
1475     accu_sum_orig_mant = 0;
1476     accu_sum_orig_exp = 0;
1477 
1478     accu_sum_est_mant = 0;
1479     accu_sum_est_exp = 0;
1480   }
1481 
1482   ptr_enrg_orig_buf = &ptr_enrg_orig[sub_band_start << 1];
1483   ptr_enrg_est_buf = &nrg_est[sub_band_start << 1];
1484 
1485   for (k = sub_band_end - sub_band_start; k != 0; k--) {
1486     WORD16 tmp_mant, tmp_e;
1487     WORD16 tmp2_m, tmp2_e;
1488 
1489     tmp_mant = *ptr_enrg_orig_buf++;
1490     tmp_e = *ptr_enrg_orig_buf++;
1491     tmp2_m = *ptr_enrg_est_buf++;
1492     tmp2_e = *ptr_enrg_est_buf++;
1493     {
1494       WORD32 exp_diff;
1495       exp_diff = tmp_e - accu_sum_orig_exp;
1496       if (exp_diff >= 0) {
1497         accu_sum_orig_mant =
1498             tmp_mant + ixheaac_shr32(accu_sum_orig_mant, exp_diff);
1499         accu_sum_orig_exp = tmp_e;
1500       } else {
1501         exp_diff = -exp_diff;
1502         accu_sum_orig_mant =
1503             ixheaac_shr32(tmp_mant, exp_diff) + accu_sum_orig_mant;
1504       }
1505     }
1506     if (flag) {
1507       tmp_mant = (tmp_mant * tmp2_m) >> 16;
1508       tmp_e = (tmp_e + tmp2_e + 1);
1509 
1510     } else {
1511       tmp_mant = tmp2_m;
1512       tmp_e = tmp2_e;
1513     }
1514 
1515     {
1516       WORD32 exp_diff;
1517       exp_diff = tmp_e - accu_sum_est_exp;
1518       if (exp_diff >= 0) {
1519         accu_sum_est_mant =
1520             tmp_mant + ixheaac_shr32(accu_sum_est_mant, exp_diff);
1521         accu_sum_est_exp = tmp_e;
1522       } else {
1523         exp_diff = -exp_diff;
1524         accu_sum_est_mant =
1525             ixheaac_shr32(tmp_mant, exp_diff) + accu_sum_est_mant;
1526       }
1527     }
1528   }
1529   {
1530     WORD32 norm_val;
1531     norm_val = 16 - ixheaac_pnorm32(accu_sum_orig_mant);
1532     if (norm_val > 0) {
1533       accu_sum_orig_mant >>= norm_val;
1534       accu_sum_orig_exp += norm_val;
1535     }
1536     norm_val = 16 - ixheaac_pnorm32(accu_sum_est_mant);
1537     if (norm_val > 0) {
1538       accu_sum_est_mant >>= norm_val;
1539       accu_sum_est_exp += norm_val;
1540     }
1541   }
1542 
1543   if (!flag) {
1544     sum_orig_mant = (WORD16)accu_sum_orig_mant;
1545     sum_orig_exp = (WORD16)accu_sum_orig_exp;
1546     sum_est_mant = (WORD16)accu_sum_est_mant;
1547     sum_est_exp = (WORD16)accu_sum_est_exp;
1548   } else {
1549     sum_est_mant = (WORD16)accu_sum_orig_mant;
1550     sum_est_exp = (WORD16)accu_sum_orig_exp;
1551     sum_orig_mant = (WORD16)accu_sum_est_mant;
1552     sum_orig_exp = (WORD16)accu_sum_est_exp;
1553   }
1554 
1555   {
1556     temp = ixheaacd_fix_mant_div(sum_orig_mant, sum_est_mant, ptr_avg_gain_mant,
1557                                  pstr_common_tables);
1558     *ptr_avg_gain_exp = temp + (sum_orig_exp - sum_est_exp) + 1;
1559     *ptr_enrg_orig_mant = sum_orig_mant;
1560     *ptr_sum_ref_exp = sum_orig_exp;
1561   }
1562 }
1563 
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)1564 VOID ixheaacd_harm_idx_zerotwolp_dec(WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf,
1565                                      WORD32 scale_change,
1566                                      WORD16 *ptr_sine_level_buf,
1567                                      const WORD32 *ptr_rand_ph,
1568                                      WORD16 *noise_level_mant,
1569                                      WORD32 num_sub_bands, FLAG noise_absc_flag,
1570                                      WORD32 harm_index) {
1571   WORD32 shift, k;
1572   WORD32 signal_real;
1573   WORD32 sine_level;
1574 
1575   scale_change = scale_change - 1;
1576   if (!noise_absc_flag) {
1577     for (k = 0; k < num_sub_bands; k++) {
1578       signal_real = ixheaac_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1579       shift = (*ptr_gain_buf++ - scale_change);
1580 
1581       if (shift > 0)
1582         signal_real = (signal_real << shift);
1583       else
1584         signal_real = (signal_real >> -(shift));
1585 
1586       sine_level = (ptr_sine_level_buf[2 * k] << 16);
1587 
1588       if (sine_level == 0) {
1589         *ptr_real_buf++ = ixheaac_mac16x16in32_shl_sat(
1590             signal_real, ixheaac_extract16h(ptr_rand_ph[k]),
1591             noise_level_mant[2 * k]);
1592       } else if (harm_index == 0)
1593         *ptr_real_buf++ = ixheaac_add32_sat(signal_real, sine_level);
1594       else
1595         *ptr_real_buf++ = ixheaac_sub32_sat(signal_real, sine_level);
1596     }
1597   } else {
1598     for (k = 0; k < num_sub_bands; k++) {
1599       signal_real = ixheaac_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1600       shift = (*ptr_gain_buf++ - scale_change);
1601 
1602       if (shift > 0)
1603         signal_real = (signal_real << shift);
1604       else
1605         signal_real = (signal_real >> -(shift));
1606 
1607       sine_level = (ptr_sine_level_buf[2 * k] << 16);
1608 
1609       if (harm_index == 0)
1610         *ptr_real_buf++ = ixheaac_add32_sat(signal_real, sine_level);
1611       else
1612         *ptr_real_buf++ = ixheaac_sub32_sat(signal_real, sine_level);
1613     }
1614   }
1615 }
1616 
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)1617 VOID ixheaacd_harm_idx_onethreelp(
1618     WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf, WORD32 scale_change,
1619     WORD16 *ptr_sine_level_buf, const WORD32 *ptr_rand_ph,
1620     WORD16 *noise_level_mant, WORD32 num_sub_bands, FLAG noise_absc_flag,
1621     WORD32 freq_inv_flag, WORD32 noise_e, WORD32 sub_band_start) {
1622   WORD32 shift, k = 0;
1623   WORD32 signal_real, temp_mult, temp_mult2;
1624   WORD16 sine_level, sine_level_prev, sine_level_next;
1625   WORD32 tone_count = 0;
1626   WORD16 tmp;
1627 
1628   scale_change = scale_change - 1;
1629 
1630   signal_real = ixheaac_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1631   shift = (*ptr_gain_buf++ - scale_change);
1632 
1633   if (shift > 0)
1634     signal_real = (signal_real << shift);
1635   else
1636     signal_real = (signal_real >> -(shift));
1637 
1638   sine_level = ((ptr_sine_level_buf[2 * 0]));
1639 
1640   if (num_sub_bands > 1) {
1641     sine_level_next = ((ptr_sine_level_buf[2 * 1]));
1642   } else {
1643     sine_level_next = 0;
1644   }
1645 
1646   if (ptr_sine_level_buf[2 * 0] != 0) {
1647     tone_count++;
1648   } else {
1649     if (!noise_absc_flag) {
1650       signal_real = ixheaac_mac16x16in32_shl_sat(
1651           signal_real, ixheaac_extract16h(ptr_rand_ph[k]), *noise_level_mant);
1652     }
1653   }
1654 
1655   noise_level_mant += 2;
1656   temp_mult2 = ixheaac_mult32x16in32(FACTOR, sine_level_next);
1657   temp_mult = ixheaac_mult32x16in32(FACTOR, sine_level);
1658   tmp = noise_e;
1659 
1660   if (tmp > 0) {
1661     temp_mult = ixheaac_shl32(temp_mult, tmp);
1662   } else {
1663     temp_mult = ixheaac_shr32(temp_mult, -tmp);
1664   }
1665 
1666   if (freq_inv_flag < 0) {
1667     *(ptr_real_buf - 1) = ixheaac_add32_sat(*(ptr_real_buf - 1), temp_mult);
1668     signal_real = ixheaac_sub32_sat(signal_real, temp_mult2);
1669   } else {
1670     *(ptr_real_buf - 1) = ixheaac_sub32_sat(*(ptr_real_buf - 1), temp_mult);
1671     signal_real = ixheaac_add32_sat(signal_real, temp_mult2);
1672   }
1673   *ptr_real_buf++ = signal_real;
1674 
1675   num_sub_bands = num_sub_bands - 1;
1676   for (k = 1; k < num_sub_bands; k++) {
1677     WORD16 gain_m = *ptr_gain_buf++;
1678     WORD16 gain_e = *ptr_gain_buf++;
1679     WORD32 q_real = *ptr_real_buf;
1680 
1681     signal_real = ixheaac_mult32x16in32(q_real, gain_m);
1682 
1683     if ((shift = (gain_e - scale_change)) >= 0)
1684       signal_real = (signal_real << shift);
1685     else
1686       signal_real = (signal_real >> -(shift));
1687 
1688     sine_level_prev = sine_level;
1689     sine_level = sine_level_next;
1690     if (sine_level != 0) {
1691       tone_count++;
1692     }
1693     sine_level_next = (ptr_sine_level_buf[2 * (k + 1)]);
1694 
1695     if ((!noise_absc_flag) && (sine_level == 0)) {
1696       signal_real = ixheaac_mac16x16in32_shl_sat(
1697           signal_real, ixheaac_extract16h(ptr_rand_ph[k]), *noise_level_mant);
1698     }
1699     noise_level_mant += 2;
1700 
1701     if (tone_count <= 16) {
1702       WORD32 temp_mult;
1703       WORD32 add_sine = ixheaac_mult32x16in32(
1704           FACTOR, ixheaac_sub16(sine_level_prev, sine_level_next));
1705       temp_mult = add_sine * freq_inv_flag;
1706       signal_real = ixheaac_add32_sat(signal_real, temp_mult);
1707     }
1708     *ptr_real_buf++ = signal_real;
1709     freq_inv_flag = -(freq_inv_flag);
1710   }
1711 
1712   freq_inv_flag = (freq_inv_flag + 1) >> 1;
1713 
1714   if (num_sub_bands > 0) {
1715     WORD32 temp_mult_sine;
1716     signal_real = ixheaac_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1717     shift = (*ptr_gain_buf - scale_change);
1718 
1719     if (shift > 0)
1720       signal_real = (signal_real << shift);
1721     else
1722       signal_real = (signal_real >> -(shift));
1723 
1724     temp_mult_sine = ixheaac_mult32x16in32(FACTOR, sine_level);
1725     sine_level = sine_level_next;
1726 
1727     if (sine_level != 0) {
1728       tone_count++;
1729     } else {
1730       if (!noise_absc_flag) {
1731         signal_real = ixheaac_mac16x16in32_shl_sat(
1732             signal_real, ixheaac_extract16h(ptr_rand_ph[k]),
1733             *noise_level_mant);
1734       }
1735     }
1736 
1737     if (tone_count <= 16) {
1738       temp_mult2 = ixheaac_mult32x16in32(FACTOR, sine_level);
1739 
1740       if (freq_inv_flag) {
1741         *ptr_real_buf++ = ixheaac_add32_sat(signal_real, temp_mult_sine);
1742 
1743         if ((k + sub_band_start) < 62) {
1744           *ptr_real_buf = ixheaac_sub32_sat(*ptr_real_buf, temp_mult2);
1745         }
1746       } else {
1747         *ptr_real_buf++ = ixheaac_sub32_sat(signal_real, temp_mult_sine);
1748 
1749         if ((k + sub_band_start) < 62) {
1750           *ptr_real_buf = ixheaac_add32_sat(*ptr_real_buf, temp_mult2);
1751         }
1752       }
1753     } else {
1754       *ptr_real_buf = signal_real;
1755     }
1756   }
1757 }
1758 
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)1759 VOID ixheaacd_harm_idx_zerotwo(FLAG noise_absc_flag, WORD16 num_sub_bands,
1760                                WORD32 *ptr_real_buf, WORD32 *ptr_imag,
1761                                WORD16 *smoothed_gain, WORD16 *smoothed_noise,
1762                                WORD32 factor, WORD16 *ptr_gain_buf,
1763                                WORD16 scale_change, const WORD32 *ptr_rand_ph,
1764                                WORD16 *ptr_sine_level_buf, WORD16 noise_e,
1765                                WORD32 harm_index) {
1766   WORD32 k;
1767   WORD32 signal_real, sig_imag;
1768   WORD32 shift;
1769   WORD32 sine_level;
1770   ptr_gain_buf++;
1771 
1772   for (k = 0; k < num_sub_bands; k++) {
1773     signal_real = ixheaac_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
1774     sig_imag = ixheaac_mult32x16in32(*ptr_imag, smoothed_gain[0]);
1775 
1776     shift = ixheaac_sub16(*ptr_gain_buf, scale_change);
1777     ptr_gain_buf += 2;
1778 
1779     if (shift > 0) {
1780       signal_real = ixheaac_shl32(signal_real, shift);
1781       sig_imag = ixheaac_shl32(sig_imag, shift);
1782     } else {
1783       shift = -shift;
1784       signal_real = ixheaac_shr32(signal_real, shift);
1785       sig_imag = ixheaac_shr32(sig_imag, shift);
1786     }
1787 
1788     ptr_rand_ph++;
1789 
1790     if (*ptr_sine_level_buf != 0) {
1791       WORD32 tmp = ixheaac_sub16(ptr_sine_level_buf[1], noise_e);
1792 
1793       if (tmp > 0)
1794         sine_level = ixheaac_shl32(ptr_sine_level_buf[0], tmp);
1795       else
1796         sine_level = ixheaac_shr32(ptr_sine_level_buf[0], tmp);
1797 
1798       if (harm_index == 0)
1799         *ptr_real_buf = ixheaac_add32_sat(signal_real, sine_level);
1800       else
1801         *ptr_real_buf = ixheaac_sub32_sat(signal_real, sine_level);
1802 
1803       *ptr_imag = sig_imag;
1804     } else {
1805       if (!noise_absc_flag) {
1806         WORD32 random = *ptr_rand_ph;
1807         WORD16 noise = smoothed_noise[0];
1808 
1809         *ptr_real_buf = ixheaac_mac16x16in32_shl_sat(
1810             signal_real, ixheaac_extract16h(random), noise);
1811         *ptr_imag = ixheaac_mac16x16in32_shl_sat(
1812             sig_imag, ixheaac_extract16l(random), noise);
1813       } else {
1814         *ptr_real_buf = signal_real;
1815         *ptr_imag = sig_imag;
1816       }
1817     }
1818 
1819     smoothed_noise += factor;
1820     smoothed_gain += 2;
1821     ptr_sine_level_buf += 2;
1822     ptr_real_buf++;
1823     ptr_imag++;
1824   }
1825 }
1826 
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)1827 VOID ixheaacd_harm_idx_onethree(FLAG noise_absc_flag, WORD16 num_sub_bands,
1828                                 WORD32 *ptr_real_buf, WORD32 *ptr_imag,
1829                                 WORD16 *smoothed_gain, WORD16 *smoothed_noise,
1830                                 WORD32 factor, WORD16 *ptr_gain_buf,
1831                                 WORD16 scale_change, const WORD32 *ptr_rand_ph,
1832                                 WORD16 *ptr_sine_level_buf, WORD16 noise_e,
1833                                 WORD32 freq_inv_flag, WORD32 harm_index) {
1834   WORD32 k;
1835   WORD32 signal_real, sig_imag;
1836   WORD32 shift;
1837   WORD32 sine_level;
1838 
1839   ptr_gain_buf++;
1840 
1841   if (harm_index == 1) freq_inv_flag = !freq_inv_flag;
1842 
1843   for (k = 0; k < num_sub_bands; k++) {
1844     signal_real = ixheaac_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
1845     sig_imag = ixheaac_mult32x16in32(*ptr_imag, smoothed_gain[0]);
1846 
1847     shift = ixheaac_sub16(*ptr_gain_buf, scale_change);
1848     ptr_gain_buf += 2;
1849 
1850     if (shift > 0) {
1851       signal_real = ixheaac_shl32(signal_real, shift);
1852       sig_imag = ixheaac_shl32(sig_imag, shift);
1853     } else {
1854       shift = -shift;
1855       signal_real = ixheaac_shr32(signal_real, shift);
1856       sig_imag = ixheaac_shr32(sig_imag, shift);
1857     }
1858 
1859     ptr_rand_ph++;
1860 
1861     if (*ptr_sine_level_buf != 0) {
1862       WORD32 tmp = ixheaac_sub16(ptr_sine_level_buf[1], noise_e);
1863 
1864       if (tmp > 0)
1865         sine_level = ixheaac_shl32(ptr_sine_level_buf[0], tmp);
1866       else
1867         sine_level = ixheaac_shr32(ptr_sine_level_buf[0], -tmp);
1868 
1869       *ptr_real_buf = signal_real;
1870 
1871       if (freq_inv_flag) {
1872         *ptr_imag = ixheaac_add32_sat(sig_imag, sine_level);
1873       } else {
1874         *ptr_imag = ixheaac_sub32_sat(sig_imag, sine_level);
1875       }
1876 
1877     } else {
1878       if (!noise_absc_flag) {
1879         WORD32 random = *ptr_rand_ph;
1880         WORD16 noise = smoothed_noise[0];
1881 
1882         *ptr_real_buf = ixheaac_mac16x16in32_shl_sat(
1883             signal_real, ixheaac_extract16h(random), noise);
1884         *ptr_imag = ixheaac_mac16x16in32_shl_sat(
1885             sig_imag, ixheaac_extract16l(random), noise);
1886       } else {
1887         *ptr_real_buf = signal_real;
1888         *ptr_imag = sig_imag;
1889       }
1890     }
1891 
1892     freq_inv_flag = (!freq_inv_flag);
1893     smoothed_gain += 2;
1894     smoothed_noise += factor;
1895     ptr_sine_level_buf += 2;
1896     ptr_real_buf++;
1897     ptr_imag++;
1898   }
1899 }