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