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 IA_ERRORCODE 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   IA_ERRORCODE err_code = IA_NO_ERROR;
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     if ((start_pos >= MAX_ENV_COLS) || (end_pos > MAX_ENV_COLS))
813       return IA_FATAL_ERROR;
814     freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
815 
816     if (noise_floor_idx >= MAX_NOISE_ENVELOPES) return IA_FATAL_ERROR;
817 
818     if (ptr_border_vec[i] ==
819         ptr_frame_data->str_frame_info_details
820             .noise_border_vec[noise_floor_idx + 1]) {
821       ptr_noise_floor += num_nf_bands;
822       noise_floor_idx++;
823     }
824 
825     if ((i == ptr_frame_data->str_frame_info_details.transient_env) ||
826         (i == ptr_sbr_calc_env->tansient_env_prev)) {
827       noise_absc_flag = 1;
828       smooth_length = 0;
829     } else {
830       noise_absc_flag = 0;
831       smooth_length = ((1 - ptr_header_data->smoothing_mode) << 2);
832     }
833 
834     input_e = 15 - ptr_sbr_scale_fac->hb_scale;
835 
836     if (ptr_header_data->interpol_freq) {
837       (*ixheaacd_enery_calc_per_subband)(
838           start_pos, end_pos, ptr_frame_data->max_qmf_subband_aac, sub_band_end,
839           input_e, nrg_est, low_pow_flag, ptr_sbr_tables, ptr_qmf_matrix);
840     } else {
841       ixheaacd_enery_calc_persfb(
842           anal_buf_real_mant, anal_buf_imag_mant, num_sf_bands[freq_res],
843           pstr_freq_band_data->freq_band_table[freq_res], start_pos, end_pos,
844           ptr_frame_data->max_qmf_subband_aac, input_e, nrg_est, low_pow_flag,
845           ptr_sbr_tables);
846     }
847 
848     ixheaacd_calc_subband_gains(
849         pstr_freq_band_data, ptr_frame_data, freq_res, ptr_noise_floor,
850         num_sf_bands[freq_res], m, i, sine_mapped_matrix, alias_red_buf,
851         ptr_enrg_orig, nrg_sine, nrg_est, nrg_gain, noise_level_mant,
852         noise_absc_flag, pstr_common_tables);
853 
854     m += num_sf_bands[freq_res];
855 
856     ptr_sbr_lim_gain =
857         &ptr_sbr_tables->env_calc_tables_ptr
858              ->sbr_lim_gains_m[2 * ptr_header_data->limiter_gains];
859     ixheaacd_noiselimiting(pstr_freq_band_data, skip_bands, ptr_enrg_orig,
860                            nrg_est, nrg_gain, noise_level_mant, nrg_sine,
861                            ptr_sbr_lim_gain, noise_absc_flag,
862                            pstr_common_tables);
863 
864     if (low_pow_flag) {
865       ixheaacd_alias_reduction(deg_patched + sub_band_start, nrg_gain, nrg_est,
866                                alias_red_buf, num_sub_bands,
867                                pstr_common_tables);
868     }
869 
870     if ((start_pos < MAX_COLS)) {
871       noise_e = adj_e;
872     } else {
873       noise_e = final_e;
874     }
875 
876     bands = num_sub_bands - skip_bands;
877 
878     if (low_pow_flag) {
879       (*ixheaacd_conv_ergtoamplitudelp)(
880           bands, noise_e, nrg_sine, nrg_gain, noise_level_mant,
881           (WORD16 *)pstr_common_tables->sqrt_table);
882     } else
883 
884     {
885       (*ixheaacd_conv_ergtoamplitude)(bands, noise_e, nrg_sine, nrg_gain,
886                                       noise_level_mant,
887                                       (WORD16 *)pstr_common_tables->sqrt_table);
888     }
889 
890     lb_scale = ixheaacd_sub16(15, ptr_sbr_scale_fac->lb_scale);
891 
892     ixheaacd_adapt_noise_gain_calc(
893         ptr_sbr_calc_env, noise_e, num_sub_bands, skip_bands, nrg_gain,
894         noise_level_mant, nrg_sine, start_pos, end_pos, input_e, adj_e, final_e,
895         ptr_frame_data->max_qmf_subband_aac, lb_scale, noise_absc_flag,
896         smooth_length, anal_buf_real_mant, anal_buf_imag_mant, low_pow_flag,
897         ptr_sbr_tables);
898   }
899 
900   first_start = ptr_border_vec[0] * SBR_TIME_STEP;
901   {
902     WORD32 ov_reserve, reserve;
903 
904     ov_reserve = reserve = 0;
905 
906     if (audio_object_type != AOT_ER_AAC_ELD) {
907       if (ptr_header_data->channel_mode == PS_STEREO) {
908         ov_reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
909             anal_buf_real_mant, anal_buf_imag_mant,
910             ptr_frame_data->max_qmf_subband_aac, sub_band_end, 0, first_start,
911             low_pow_flag);
912 
913         reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
914             anal_buf_real_mant, anal_buf_imag_mant,
915             ptr_frame_data->max_qmf_subband_aac, sub_band_end, first_start,
916             MAX_COLS, low_pow_flag);
917       }
918     }
919 
920     output_e = 0;
921 
922     ov_adj_e = 15 - ptr_sbr_scale_fac->ov_hb_scale;
923 
924     if (((ov_adj_e - ov_reserve) > (adj_e - reserve)))
925       output_e = (ov_adj_e - ov_reserve);
926     else
927       output_e = (adj_e - reserve);
928 
929     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
930                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
931                              0, first_start, (ov_adj_e - output_e),
932                              low_pow_flag);
933 
934     num_cols = (ptr_header_data->num_time_slots * ptr_header_data->time_step);
935 
936     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
937                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
938                              first_start, num_cols, (adj_e - output_e),
939                              low_pow_flag);
940   }
941 
942   ptr_sbr_scale_fac->hb_scale = (WORD16)(15 - output_e);
943 
944   ptr_sbr_scale_fac->ov_hb_scale = (WORD16)(15 - final_e);
945 
946   if (ptr_frame_data->str_frame_info_details.transient_env == num_env) {
947     ptr_sbr_calc_env->tansient_env_prev = 0;
948   } else {
949     ptr_sbr_calc_env->tansient_env_prev = -1;
950   }
951   return err_code;
952 }
953 
ixheaacd_equalize_filt_buff_exp(WORD16 * ptr_filt_buf,WORD16 * nrg_gain,WORD32 subbands)954 VOID ixheaacd_equalize_filt_buff_exp(WORD16 *ptr_filt_buf, WORD16 *nrg_gain,
955                                      WORD32 subbands) {
956   WORD32 band;
957   WORD32 diff;
958   WORD32 gain_m, gain_e;
959   WORD32 filt_buf_mant, filt_buf_exp;
960 
961   for (band = subbands - 1; band >= 0; band--) {
962     filt_buf_exp = *(ptr_filt_buf + 1);
963     gain_e = *(nrg_gain + 1);
964     filt_buf_mant = *ptr_filt_buf;
965     gain_m = *nrg_gain;
966     diff = (gain_e - filt_buf_exp);
967 
968     if (diff >= 0) {
969       *(ptr_filt_buf + 1) = (WORD16)(gain_e);
970 
971       *ptr_filt_buf = (WORD16)(*ptr_filt_buf >> diff);
972     } else {
973       WORD32 reserve;
974       reserve = (ixheaacd_norm32(filt_buf_mant) - 16);
975 
976       if ((diff + reserve) >= 0) {
977         *ptr_filt_buf = (WORD16)(filt_buf_mant << -diff);
978         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp + diff);
979       } else {
980         WORD32 shift;
981 
982         *ptr_filt_buf = (WORD16)(filt_buf_mant << reserve);
983 
984         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp - reserve);
985 
986         shift = -(reserve + diff);
987 
988         *nrg_gain = (WORD16)(gain_m >> shift);
989         *(nrg_gain + 1) = (WORD16)(*(nrg_gain + 1) + shift);
990       }
991     }
992     nrg_gain += 2;
993     ptr_filt_buf += 2;
994   }
995 }
996 
ixheaacd_filt_buf_update(WORD16 * ptr_filt_buf,WORD16 * ptr_filt_buf_noise,WORD16 * nrg_gain,WORD16 * noise_level_mant,WORD32 num_sub_bands)997 static PLATFORM_INLINE VOID ixheaacd_filt_buf_update(WORD16 *ptr_filt_buf,
998                                                      WORD16 *ptr_filt_buf_noise,
999                                                      WORD16 *nrg_gain,
1000                                                      WORD16 *noise_level_mant,
1001                                                      WORD32 num_sub_bands) {
1002   WORD32 k;
1003   WORD32 temp1, temp2;
1004 
1005   for (k = num_sub_bands - 1; k >= 0; k--) {
1006     temp1 = *nrg_gain;
1007     nrg_gain += 2;
1008     temp2 = *noise_level_mant;
1009     noise_level_mant += 2;
1010 
1011     *ptr_filt_buf = temp1;
1012     ptr_filt_buf += 2;
1013     *ptr_filt_buf_noise++ = temp2;
1014   }
1015 }
1016 
ixheaacd_noise_level_rescaling(WORD16 * noise_level_mant,WORD32 diff,WORD32 num_sub_bands,WORD32 ixheaacd_drc_offset)1017 VOID ixheaacd_noise_level_rescaling(WORD16 *noise_level_mant, WORD32 diff,
1018                                     WORD32 num_sub_bands,
1019                                     WORD32 ixheaacd_drc_offset) {
1020   WORD32 k;
1021 
1022   if (diff > 0) {
1023     for (k = num_sub_bands - 1; k >= 0; k--) {
1024       *noise_level_mant = *noise_level_mant >> diff;
1025       noise_level_mant += ixheaacd_drc_offset;
1026     }
1027   } else if (diff < 0) {
1028     diff = -diff;
1029     for (k = num_sub_bands - 1; k >= 0; k--) {
1030       *noise_level_mant = *noise_level_mant << diff;
1031       noise_level_mant += ixheaacd_drc_offset;
1032     }
1033   }
1034 }
1035 
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)1036 VOID ixheaacd_adjust_scale_dec(WORD32 **re, WORD32 **im, WORD32 sub_band_start,
1037                                WORD32 sub_band_end, WORD32 start_pos,
1038                                WORD32 next_pos, WORD32 shift,
1039                                FLAG low_pow_flag) {
1040   WORD32 k, l;
1041 
1042   if (shift != 0) {
1043     WORD32 num_sub_bands = (sub_band_end - sub_band_start);
1044 
1045     shift = ixheaacd_min32(shift, 31);
1046     shift = ixheaacd_max32(shift, -31);
1047 
1048     if (low_pow_flag) {
1049       if (shift > 0) {
1050         for (l = start_pos; l < next_pos; l++) {
1051           WORD32 *ptr = re[l] + sub_band_start;
1052           for (k = num_sub_bands - 1; k >= 0; k--) {
1053             *ptr = (*ptr << shift);
1054             ptr++;
1055           }
1056         }
1057       } else {
1058         shift = -shift;
1059         for (l = start_pos; l < next_pos; l++) {
1060           WORD32 *ptr = re[l] + sub_band_start;
1061           for (k = num_sub_bands - 1; k >= 0; k--) {
1062             *ptr = (*ptr >> shift);
1063             ptr++;
1064           }
1065         }
1066       }
1067     } else {
1068       if (shift > 0) {
1069         for (l = start_pos; l < next_pos; l++) {
1070           WORD32 *ptr = re[l] + sub_band_start;
1071           WORD32 *pti = im[l] + sub_band_start;
1072           for (k = num_sub_bands; k > 0; k--) {
1073             *ptr = (*ptr << shift);
1074             *pti = (*pti << shift);
1075             pti++;
1076             ptr++;
1077           }
1078         }
1079       } else {
1080         shift = -shift;
1081         for (l = start_pos; l < next_pos; l++) {
1082           WORD32 *ptr = re[l] + sub_band_start;
1083           WORD32 *pti = im[l] + sub_band_start;
1084           for (k = num_sub_bands; k > 0; k--) {
1085             *ptr = (*ptr >> shift);
1086             *pti = (*pti >> shift);
1087             ptr++;
1088             pti++;
1089           }
1090         }
1091       }
1092     }
1093   }
1094 }
1095 
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)1096 WORD16 ixheaacd_expsubbandsamples_dec(WORD32 **re, WORD32 **im,
1097                                       WORD32 sub_band_start,
1098                                       WORD32 sub_band_end, WORD32 start_pos,
1099                                       WORD32 next_pos, FLAG low_pow_flag) {
1100   WORD32 l, k;
1101   WORD16 max_shift;
1102 
1103   WORD32 value;
1104   WORD32 max_abs;
1105   WORD32 num_sub_bands;
1106 
1107   WORD32 *ptr_real;
1108   WORD32 *ptr_imag;
1109 
1110   max_abs = 1;
1111   num_sub_bands = (sub_band_end - sub_band_start);
1112 
1113   if (low_pow_flag) {
1114     for (l = start_pos; l < next_pos; l++) {
1115       WORD32 temp_real;
1116       ptr_real = re[l] + sub_band_start;
1117       temp_real = *ptr_real++;
1118       for (k = num_sub_bands; k > 0; k--) {
1119         value = ixheaacd_abs32_nrm(temp_real);
1120         max_abs |= value;
1121         temp_real = *ptr_real++;
1122       }
1123     }
1124     max_shift = ixheaacd_pnorm32(max_abs);
1125   } else {
1126     for (l = start_pos; l < next_pos; l++) {
1127       ptr_real = re[l] + sub_band_start;
1128       ptr_imag = im[l] + sub_band_start;
1129 
1130       for (k = num_sub_bands; k > 0; k--) {
1131         WORD32 temp_real = *ptr_real++;
1132         WORD32 tempIm = *ptr_imag++;
1133 
1134         temp_real = ixheaacd_abs32_nrm(temp_real);
1135         max_abs |= temp_real;
1136         tempIm = ixheaacd_abs32_nrm(tempIm);
1137         max_abs |= tempIm;
1138       }
1139     }
1140     max_shift = ixheaacd_pnorm32(max_abs);
1141   }
1142 
1143   return max_shift;
1144 }
1145 
1146 #define SHIFT_BEFORE_SQUARE 4
1147 
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)1148 VOID ixheaacd_enery_calc_per_subband_dec(WORD32 start_pos, WORD32 next_pos,
1149                                          WORD32 sub_band_start,
1150                                          WORD32 sub_band_end, WORD32 frame_exp,
1151                                          WORD16 *nrg_est, FLAG low_pow_flag,
1152                                          ia_sbr_tables_struct *ptr_sbr_tables,
1153                                          WORD32 *ptr_qmf_matrix) {
1154   WORD16 temp;
1155   WORD16 inv_width;
1156   WORD16 sum_m;
1157   WORD32 accu;
1158   WORD32 k, l;
1159   WORD32 pre_shift_val;
1160   WORD32 shift;
1161   WORD32 *p_real;
1162   WORD32 max_shift_gap = SHIFT_BEFORE_SQUARE;
1163   WORD32 extra_shift = 0;
1164   WORD32 num_cols = next_pos - start_pos;
1165 
1166   if (low_pow_flag) {
1167     max_shift_gap -= 1;
1168     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 6);
1169     extra_shift++;
1170   } else {
1171     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 7);
1172     num_cols = num_cols << 1;
1173   }
1174   inv_width = ptr_sbr_tables->env_calc_tables_ptr
1175                   ->sbr_inv_int_table[(next_pos - start_pos)];
1176   frame_exp = (frame_exp << 1);
1177 
1178   {
1179     WORD32 *ptr;
1180     for (k = sub_band_start; k < sub_band_end; k++) {
1181       WORD32 max_val = 1;
1182 
1183       ptr = p_real;
1184 
1185       for (l = num_cols; l != 0; l -= 2) {
1186         WORD32 value = ixheaacd_abs32_nrm(*ptr);
1187         ptr += 64;
1188         max_val = ixheaacd_max32(value, max_val);
1189         value = ixheaacd_abs32_nrm(*ptr);
1190         ptr += 64;
1191         max_val = ixheaacd_max32(value, max_val);
1192       }
1193       pre_shift_val = (ixheaacd_pnorm32(max_val) - max_shift_gap);
1194 
1195       accu = 0L;
1196       shift = 16 - pre_shift_val;
1197       ptr = p_real;
1198 
1199       if (shift > 0)
1200         for (l = num_cols; l != 0; l -= 2) {
1201           temp = (WORD16)((*(ptr) >> shift));
1202           ptr += 64;
1203           accu += (temp * temp);
1204           temp = (WORD16)((*(ptr) >> shift));
1205           ptr += 64;
1206           accu += (temp * temp);
1207         }
1208       else
1209         for (l = num_cols; l != 0; l -= 2) {
1210           temp = (WORD16)((*(ptr) << (-shift)));
1211           ptr += 64;
1212           accu += (temp * temp);
1213           temp = (WORD16)((*(ptr) << (-shift)));
1214           ptr += 64;
1215           accu += (temp * temp);
1216         }
1217 
1218       if (accu != 0L) {
1219         shift = -(ixheaacd_pnorm32(accu));
1220         sum_m = (WORD16)(ixheaacd_shr32_dir_sat_limit(accu, (16 + shift)));
1221         *nrg_est++ = ixheaacd_mult16_shl_sat(sum_m, inv_width);
1222         shift = (shift - (pre_shift_val << 1));
1223         shift += extra_shift;
1224         *nrg_est++ = (WORD16)(frame_exp + shift + 1);
1225       } else {
1226         *nrg_est++ = 0;
1227         *nrg_est++ = 0;
1228       }
1229 
1230       p_real++;
1231     }
1232   }
1233 }
1234 
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)1235 VOID ixheaacd_enery_calc_persfb(WORD32 **anal_buf_real, WORD32 **anal_buf_imag,
1236                                 WORD32 num_sf_bands, WORD16 *freq_band_table,
1237                                 WORD32 start_pos, WORD32 next_pos,
1238                                 WORD32 max_qmf_subband_aac, WORD32 frame_exp,
1239                                 WORD16 *nrg_est, FLAG low_pow_flag,
1240                                 ia_sbr_tables_struct *ptr_sbr_tables) {
1241   WORD16 inv_width;
1242   WORD32 pre_shift_val;
1243   WORD32 shift;
1244   WORD32 sum_e;
1245   WORD16 sum_m;
1246 
1247   WORD32 j, k, l;
1248   WORD32 li, ui;
1249   WORD32 accu_line;
1250   WORD32 accumulate;
1251   WORD32 extra_shift = 10;
1252 
1253   inv_width = ptr_sbr_tables->env_calc_tables_ptr
1254                   ->sbr_inv_int_table[(next_pos - start_pos)];
1255 
1256   frame_exp = (frame_exp << 1);
1257 
1258   if (low_pow_flag) extra_shift++;
1259 
1260   for (j = 0; j < num_sf_bands; j++) {
1261     li = freq_band_table[j];
1262 
1263     if ((li >= max_qmf_subband_aac)) {
1264       ui = freq_band_table[j + 1];
1265 
1266       pre_shift_val = (*ixheaacd_ixheaacd_expsubbandsamples)(
1267           anal_buf_real, anal_buf_imag, li, ui, start_pos, next_pos,
1268           low_pow_flag);
1269 
1270       pre_shift_val = (pre_shift_val - SHIFT_BEFORE_SQUARE);
1271 
1272       accumulate = 0;
1273 
1274       for (k = li; k < ui; k++) {
1275         WORD32 pre_shift1 = (16 - pre_shift_val);
1276         accu_line = 0L;
1277         pre_shift1 = min(pre_shift1, 31);
1278         {
1279           WORD32 *ptr = &anal_buf_real[start_pos][k];
1280           WORD32 inc = !low_pow_flag;
1281           for (l = (next_pos - start_pos) << inc; l != 0; l--) {
1282             WORD16 temp;
1283             temp = ixheaacd_extract16l(ixheaacd_shr32_dir(*ptr, pre_shift1));
1284             ptr += 64;
1285             accu_line = ixheaacd_mac16x16in32_sat(accu_line, temp, temp);
1286           }
1287         }
1288         accumulate =
1289             ixheaacd_add32_sat(accumulate, ixheaacd_shr32(accu_line, 9));
1290       }
1291 
1292       shift = ixheaacd_pnorm32(accumulate);
1293 
1294       sum_m = ixheaacd_extract16l(
1295           ixheaacd_shr32_dir_sat_limit(accumulate, (16 - shift)));
1296 
1297       if (sum_m == 0) {
1298         sum_e = 0;
1299       } else {
1300         sum_m = ixheaacd_mult16_shl_sat(sum_m, inv_width);
1301 
1302         sum_m = ixheaacd_mult16_shl_sat(
1303             sum_m,
1304             ptr_sbr_tables->env_calc_tables_ptr->sbr_inv_int_table[ui - li]);
1305 
1306         sum_e = ((frame_exp + extra_shift) - shift);
1307 
1308         sum_e = (sum_e - (pre_shift_val << 1));
1309       }
1310 
1311       for (k = li; k < ui; k++) {
1312         *nrg_est++ = sum_m;
1313         *nrg_est++ = (WORD16)sum_e;
1314       }
1315     }
1316   }
1317 }
1318 
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)1319 VOID ixheaacd_subbandgain_calc(WORD16 e_orig_mant_matrix, WORD16 tmp_noise_mant,
1320                                WORD16 nrg_est_mant, WORD16 nrg_est_exp,
1321                                WORD16 tmp_noise_exp, WORD16 nrg_ref_exp,
1322                                FLAG sine_present_flag, FLAG sine_mapped_matrix,
1323                                FLAG noise_absc_flag, WORD16 *ptr_nrg_gain_mant,
1324                                WORD16 *ptr_noise_floor_mant,
1325                                WORD16 *ptr_nrg_sine_m,
1326                                ixheaacd_misc_tables *pstr_common_tables) {
1327   WORD16 var1_mant;
1328   WORD16 var1_exp;
1329   WORD16 var2_mant;
1330   WORD16 var2_exp;
1331   WORD16 var3_mant;
1332   WORD16 var3_exp;
1333   WORD32 temp;
1334 
1335   if (nrg_est_mant == 0) {
1336     nrg_est_mant = 0x4000;
1337     nrg_est_exp = 1;
1338   }
1339 
1340   var1_mant = ixheaacd_mult16_shl_sat(e_orig_mant_matrix, tmp_noise_mant);
1341   var1_exp = (nrg_ref_exp + tmp_noise_exp);
1342 
1343   {
1344     WORD32 accu, exp_diff;
1345 
1346     exp_diff = tmp_noise_exp - 1;
1347 
1348     if (exp_diff >= 0) {
1349       accu = tmp_noise_mant + ixheaacd_shr32(0x4000, exp_diff);
1350       var2_exp = tmp_noise_exp;
1351     } else {
1352       exp_diff = -exp_diff;
1353       accu = ixheaacd_shr32((WORD32)tmp_noise_mant, exp_diff) + 0x4000;
1354       var2_exp = 1;
1355     }
1356     if (ixheaacd_abs32(accu) >= 0x8000) {
1357       accu = accu >> 1;
1358       var2_exp++;
1359     }
1360     var2_mant = (WORD16)(accu);
1361   }
1362 
1363   temp = ixheaacd_fix_mant_div(var1_mant, var2_mant, ptr_noise_floor_mant,
1364                                pstr_common_tables);
1365   *(ptr_noise_floor_mant + 1) = temp + (var1_exp - var2_exp) + 1;
1366 
1367   if (sine_present_flag || !noise_absc_flag) {
1368     var3_mant = ixheaacd_mult16_shl_sat(var2_mant, nrg_est_mant);
1369     var3_exp = (var2_exp + nrg_est_exp);
1370   } else {
1371     var3_mant = nrg_est_mant;
1372     var3_exp = nrg_est_exp;
1373   }
1374 
1375   if (sine_present_flag == 0) {
1376     var1_mant = e_orig_mant_matrix;
1377     var1_exp = nrg_ref_exp;
1378   }
1379 
1380   temp = ixheaacd_fix_mant_div(var1_mant, var3_mant, ptr_nrg_gain_mant,
1381                                pstr_common_tables);
1382   *(ptr_nrg_gain_mant + 1) = temp + (var1_exp - var3_exp) + 1;
1383 
1384   if (sine_present_flag && sine_mapped_matrix) {
1385     temp = ixheaacd_fix_mant_div(e_orig_mant_matrix, var2_mant, ptr_nrg_sine_m,
1386                                  pstr_common_tables);
1387     *(ptr_nrg_sine_m + 1) = temp + (nrg_ref_exp - var2_exp) + 1;
1388   }
1389 }
1390 
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)1391 VOID ixheaacd_avggain_calc(WORD16 *ptr_enrg_orig, WORD16 *nrg_est,
1392                            WORD32 sub_band_start, WORD32 sub_band_end,
1393                            WORD16 *ptr_enrg_orig_mant, WORD16 *ptr_sum_ref_exp,
1394                            WORD16 *ptr_avg_gain_mant, WORD16 *ptr_avg_gain_exp,
1395                            ixheaacd_misc_tables *pstr_common_tables,
1396                            WORD32 flag) {
1397   WORD16 sum_orig_mant;
1398   WORD16 sum_orig_exp;
1399   WORD16 sum_est_mant;
1400   WORD16 sum_est_exp;
1401 
1402   WORD32 accu_sum_orig_mant;
1403   WORD32 accu_sum_orig_exp;
1404   WORD32 accu_sum_est_mant;
1405   WORD32 accu_sum_est_exp;
1406 
1407   WORD32 k, temp;
1408   WORD16 *ptr_enrg_orig_buf;
1409   WORD16 *ptr_enrg_est_buf;
1410 
1411   {
1412     accu_sum_orig_mant = 0;
1413     accu_sum_orig_exp = 0;
1414 
1415     accu_sum_est_mant = 0;
1416     accu_sum_est_exp = 0;
1417   }
1418 
1419   ptr_enrg_orig_buf = &ptr_enrg_orig[sub_band_start << 1];
1420   ptr_enrg_est_buf = &nrg_est[sub_band_start << 1];
1421 
1422   for (k = sub_band_end - sub_band_start; k != 0; k--) {
1423     WORD16 tmp_mant, tmp_e;
1424     WORD16 tmp2_m, tmp2_e;
1425 
1426     tmp_mant = *ptr_enrg_orig_buf++;
1427     tmp_e = *ptr_enrg_orig_buf++;
1428     tmp2_m = *ptr_enrg_est_buf++;
1429     tmp2_e = *ptr_enrg_est_buf++;
1430     {
1431       WORD32 exp_diff;
1432       exp_diff = tmp_e - accu_sum_orig_exp;
1433       if (exp_diff >= 0) {
1434         accu_sum_orig_mant =
1435             tmp_mant + ixheaacd_shr32(accu_sum_orig_mant, exp_diff);
1436         accu_sum_orig_exp = tmp_e;
1437       } else {
1438         exp_diff = -exp_diff;
1439         accu_sum_orig_mant =
1440             ixheaacd_shr32(tmp_mant, exp_diff) + accu_sum_orig_mant;
1441       }
1442     }
1443     if (flag) {
1444       tmp_mant = (tmp_mant * tmp2_m) >> 16;
1445       tmp_e = (tmp_e + tmp2_e + 1);
1446 
1447     } else {
1448       tmp_mant = tmp2_m;
1449       tmp_e = tmp2_e;
1450     }
1451 
1452     {
1453       WORD32 exp_diff;
1454       exp_diff = tmp_e - accu_sum_est_exp;
1455       if (exp_diff >= 0) {
1456         accu_sum_est_mant =
1457             tmp_mant + ixheaacd_shr32(accu_sum_est_mant, exp_diff);
1458         accu_sum_est_exp = tmp_e;
1459       } else {
1460         exp_diff = -exp_diff;
1461         accu_sum_est_mant =
1462             ixheaacd_shr32(tmp_mant, exp_diff) + accu_sum_est_mant;
1463       }
1464     }
1465   }
1466   {
1467     WORD32 norm_val;
1468     norm_val = 16 - ixheaacd_pnorm32(accu_sum_orig_mant);
1469     if (norm_val > 0) {
1470       accu_sum_orig_mant >>= norm_val;
1471       accu_sum_orig_exp += norm_val;
1472     }
1473     norm_val = 16 - ixheaacd_pnorm32(accu_sum_est_mant);
1474     if (norm_val > 0) {
1475       accu_sum_est_mant >>= norm_val;
1476       accu_sum_est_exp += norm_val;
1477     }
1478   }
1479 
1480   if (!flag) {
1481     sum_orig_mant = (WORD16)accu_sum_orig_mant;
1482     sum_orig_exp = (WORD16)accu_sum_orig_exp;
1483     sum_est_mant = (WORD16)accu_sum_est_mant;
1484     sum_est_exp = (WORD16)accu_sum_est_exp;
1485   } else {
1486     sum_est_mant = (WORD16)accu_sum_orig_mant;
1487     sum_est_exp = (WORD16)accu_sum_orig_exp;
1488     sum_orig_mant = (WORD16)accu_sum_est_mant;
1489     sum_orig_exp = (WORD16)accu_sum_est_exp;
1490   }
1491 
1492   {
1493     temp = ixheaacd_fix_mant_div(sum_orig_mant, sum_est_mant, ptr_avg_gain_mant,
1494                                  pstr_common_tables);
1495     *ptr_avg_gain_exp = temp + (sum_orig_exp - sum_est_exp) + 1;
1496     *ptr_enrg_orig_mant = sum_orig_mant;
1497     *ptr_sum_ref_exp = sum_orig_exp;
1498   }
1499 }
1500 
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)1501 VOID ixheaacd_harm_idx_zerotwolp_dec(WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf,
1502                                      WORD32 scale_change,
1503                                      WORD16 *ptr_sine_level_buf,
1504                                      const WORD32 *ptr_rand_ph,
1505                                      WORD16 *noise_level_mant,
1506                                      WORD32 num_sub_bands, FLAG noise_absc_flag,
1507                                      WORD32 harm_index) {
1508   WORD32 shift, k;
1509   WORD32 signal_real;
1510   WORD32 sine_level;
1511 
1512   scale_change = scale_change - 1;
1513   if (!noise_absc_flag) {
1514     for (k = 0; k < num_sub_bands; k++) {
1515       signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1516       shift = (*ptr_gain_buf++ - scale_change);
1517 
1518       if (shift > 0)
1519         signal_real = (signal_real << shift);
1520       else
1521         signal_real = (signal_real >> -(shift));
1522 
1523       sine_level = (ptr_sine_level_buf[2 * k] << 16);
1524 
1525       if (sine_level == 0) {
1526         *ptr_real_buf++ = ixheaacd_mac16x16in32_shl_sat(
1527             signal_real, ixheaacd_extract16h(ptr_rand_ph[k]),
1528             noise_level_mant[2 * k]);
1529       } else if (harm_index == 0)
1530         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, sine_level);
1531       else
1532         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, sine_level);
1533     }
1534   } else {
1535     for (k = 0; k < num_sub_bands; k++) {
1536       signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1537       shift = (*ptr_gain_buf++ - scale_change);
1538 
1539       if (shift > 0)
1540         signal_real = (signal_real << shift);
1541       else
1542         signal_real = (signal_real >> -(shift));
1543 
1544       sine_level = (ptr_sine_level_buf[2 * k] << 16);
1545 
1546       if (harm_index == 0)
1547         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, sine_level);
1548       else
1549         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, sine_level);
1550     }
1551   }
1552 }
1553 
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)1554 VOID ixheaacd_harm_idx_onethreelp(
1555     WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf, WORD32 scale_change,
1556     WORD16 *ptr_sine_level_buf, const WORD32 *ptr_rand_ph,
1557     WORD16 *noise_level_mant, WORD32 num_sub_bands, FLAG noise_absc_flag,
1558     WORD32 freq_inv_flag, WORD32 noise_e, WORD32 sub_band_start) {
1559   WORD32 shift, k = 0;
1560   WORD32 signal_real, temp_mult, temp_mult2;
1561   WORD16 sine_level, sine_level_prev, sine_level_next;
1562   WORD32 tone_count = 0;
1563   WORD16 tmp;
1564 
1565   scale_change = scale_change - 1;
1566 
1567   signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1568   shift = (*ptr_gain_buf++ - scale_change);
1569 
1570   if (shift > 0)
1571     signal_real = (signal_real << shift);
1572   else
1573     signal_real = (signal_real >> -(shift));
1574 
1575   sine_level = ((ptr_sine_level_buf[2 * 0]));
1576 
1577   if (num_sub_bands > 1) {
1578     sine_level_next = ((ptr_sine_level_buf[2 * 1]));
1579   } else {
1580     sine_level_next = 0;
1581   }
1582 
1583   if (ptr_sine_level_buf[2 * 0] != 0) {
1584     tone_count++;
1585   } else {
1586     if (!noise_absc_flag) {
1587       signal_real = ixheaacd_mac16x16in32_shl_sat(
1588           signal_real, ixheaacd_extract16h(ptr_rand_ph[k]), *noise_level_mant);
1589     }
1590   }
1591 
1592   noise_level_mant += 2;
1593   temp_mult2 = ixheaacd_mult32x16in32(FACTOR, sine_level_next);
1594   temp_mult = ixheaacd_mult32x16in32(FACTOR, sine_level);
1595   tmp = noise_e;
1596 
1597   if (tmp > 0) {
1598     temp_mult = ixheaacd_shl32(temp_mult, tmp);
1599   } else {
1600     temp_mult = ixheaacd_shr32(temp_mult, -tmp);
1601   }
1602 
1603   if (freq_inv_flag < 0) {
1604     *(ptr_real_buf - 1) = ixheaacd_add32_sat(*(ptr_real_buf - 1), temp_mult);
1605     signal_real = ixheaacd_sub32_sat(signal_real, temp_mult2);
1606   } else {
1607     *(ptr_real_buf - 1) = ixheaacd_sub32_sat(*(ptr_real_buf - 1), temp_mult);
1608     signal_real = ixheaacd_add32_sat(signal_real, temp_mult2);
1609   }
1610   *ptr_real_buf++ = signal_real;
1611 
1612   num_sub_bands = num_sub_bands - 1;
1613   for (k = 1; k < num_sub_bands; k++) {
1614     WORD16 gain_m = *ptr_gain_buf++;
1615     WORD16 gain_e = *ptr_gain_buf++;
1616     WORD32 q_real = *ptr_real_buf;
1617 
1618     signal_real = ixheaacd_mult32x16in32(q_real, gain_m);
1619 
1620     if ((shift = (gain_e - scale_change)) >= 0)
1621       signal_real = (signal_real << shift);
1622     else
1623       signal_real = (signal_real >> -(shift));
1624 
1625     sine_level_prev = sine_level;
1626     sine_level = sine_level_next;
1627     if (sine_level != 0) {
1628       tone_count++;
1629     }
1630     sine_level_next = (ptr_sine_level_buf[2 * (k + 1)]);
1631 
1632     if ((!noise_absc_flag) && (sine_level == 0)) {
1633       signal_real = ixheaacd_mac16x16in32_shl_sat(
1634           signal_real, ixheaacd_extract16h(ptr_rand_ph[k]), *noise_level_mant);
1635     }
1636     noise_level_mant += 2;
1637 
1638     if (tone_count <= 16) {
1639       WORD32 temp_mult;
1640       WORD32 add_sine = ixheaacd_mult32x16in32(
1641           FACTOR, ixheaacd_sub16(sine_level_prev, sine_level_next));
1642       temp_mult = add_sine * freq_inv_flag;
1643       signal_real = ixheaacd_add32_sat(signal_real, temp_mult);
1644     }
1645     *ptr_real_buf++ = signal_real;
1646     freq_inv_flag = -(freq_inv_flag);
1647   }
1648 
1649   freq_inv_flag = (freq_inv_flag + 1) >> 1;
1650 
1651   if (num_sub_bands > 0) {
1652     WORD32 temp_mult_sine;
1653     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
1654     shift = (*ptr_gain_buf - scale_change);
1655 
1656     if (shift > 0)
1657       signal_real = (signal_real << shift);
1658     else
1659       signal_real = (signal_real >> -(shift));
1660 
1661     temp_mult_sine = ixheaacd_mult32x16in32(FACTOR, sine_level);
1662     sine_level = sine_level_next;
1663 
1664     if (sine_level != 0) {
1665       tone_count++;
1666     } else {
1667       if (!noise_absc_flag) {
1668         signal_real = ixheaacd_mac16x16in32_shl_sat(
1669             signal_real, ixheaacd_extract16h(ptr_rand_ph[k]),
1670             *noise_level_mant);
1671       }
1672     }
1673 
1674     if (tone_count <= 16) {
1675       temp_mult2 = ixheaacd_mult32x16in32(FACTOR, sine_level);
1676 
1677       if (freq_inv_flag) {
1678         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, temp_mult_sine);
1679 
1680         if ((k + sub_band_start) < 62) {
1681           *ptr_real_buf = ixheaacd_sub32_sat(*ptr_real_buf, temp_mult2);
1682         }
1683       } else {
1684         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, temp_mult_sine);
1685 
1686         if ((k + sub_band_start) < 62) {
1687           *ptr_real_buf = ixheaacd_add32_sat(*ptr_real_buf, temp_mult2);
1688         }
1689       }
1690     } else {
1691       *ptr_real_buf = signal_real;
1692     }
1693   }
1694 }
1695 
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)1696 VOID ixheaacd_harm_idx_zerotwo(FLAG noise_absc_flag, WORD16 num_sub_bands,
1697                                WORD32 *ptr_real_buf, WORD32 *ptr_imag,
1698                                WORD16 *smoothed_gain, WORD16 *smoothed_noise,
1699                                WORD32 factor, WORD16 *ptr_gain_buf,
1700                                WORD16 scale_change, const WORD32 *ptr_rand_ph,
1701                                WORD16 *ptr_sine_level_buf, WORD16 noise_e,
1702                                WORD32 harm_index) {
1703   WORD32 k;
1704   WORD32 signal_real, sig_imag;
1705   WORD32 shift;
1706   WORD32 sine_level;
1707   ptr_gain_buf++;
1708 
1709   for (k = 0; k < num_sub_bands; k++) {
1710     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
1711     sig_imag = ixheaacd_mult32x16in32(*ptr_imag, smoothed_gain[0]);
1712 
1713     shift = ixheaacd_sub16(*ptr_gain_buf, scale_change);
1714     ptr_gain_buf += 2;
1715 
1716     if (shift > 0) {
1717       signal_real = ixheaacd_shl32(signal_real, shift);
1718       sig_imag = ixheaacd_shl32(sig_imag, shift);
1719     } else {
1720       shift = -shift;
1721       signal_real = ixheaacd_shr32(signal_real, shift);
1722       sig_imag = ixheaacd_shr32(sig_imag, shift);
1723     }
1724 
1725     ptr_rand_ph++;
1726 
1727     if (*ptr_sine_level_buf != 0) {
1728       WORD32 tmp = ixheaacd_sub16(ptr_sine_level_buf[1], noise_e);
1729 
1730       if (tmp > 0)
1731         sine_level = ixheaacd_shl32(ptr_sine_level_buf[0], tmp);
1732       else
1733         sine_level = ixheaacd_shr32(ptr_sine_level_buf[0], tmp);
1734 
1735       if (harm_index == 0)
1736         *ptr_real_buf = ixheaacd_add32_sat(signal_real, sine_level);
1737       else
1738         *ptr_real_buf = ixheaacd_sub32_sat(signal_real, sine_level);
1739 
1740       *ptr_imag = sig_imag;
1741     } else {
1742       if (!noise_absc_flag) {
1743         WORD32 random = *ptr_rand_ph;
1744         WORD16 noise = smoothed_noise[0];
1745 
1746         *ptr_real_buf = ixheaacd_mac16x16in32_shl_sat(
1747             signal_real, ixheaacd_extract16h(random), noise);
1748         *ptr_imag = ixheaacd_mac16x16in32_shl_sat(
1749             sig_imag, ixheaacd_extract16l(random), noise);
1750       } else {
1751         *ptr_real_buf = signal_real;
1752         *ptr_imag = sig_imag;
1753       }
1754     }
1755 
1756     smoothed_noise += factor;
1757     smoothed_gain += 2;
1758     ptr_sine_level_buf += 2;
1759     ptr_real_buf++;
1760     ptr_imag++;
1761   }
1762 }
1763 
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)1764 VOID ixheaacd_harm_idx_onethree(FLAG noise_absc_flag, WORD16 num_sub_bands,
1765                                 WORD32 *ptr_real_buf, WORD32 *ptr_imag,
1766                                 WORD16 *smoothed_gain, WORD16 *smoothed_noise,
1767                                 WORD32 factor, WORD16 *ptr_gain_buf,
1768                                 WORD16 scale_change, const WORD32 *ptr_rand_ph,
1769                                 WORD16 *ptr_sine_level_buf, WORD16 noise_e,
1770                                 WORD32 freq_inv_flag, WORD32 harm_index) {
1771   WORD32 k;
1772   WORD32 signal_real, sig_imag;
1773   WORD32 shift;
1774   WORD32 sine_level;
1775 
1776   ptr_gain_buf++;
1777 
1778   if (harm_index == 1) freq_inv_flag = !freq_inv_flag;
1779 
1780   for (k = 0; k < num_sub_bands; k++) {
1781     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
1782     sig_imag = ixheaacd_mult32x16in32(*ptr_imag, smoothed_gain[0]);
1783 
1784     shift = ixheaacd_sub16(*ptr_gain_buf, scale_change);
1785     ptr_gain_buf += 2;
1786 
1787     if (shift > 0) {
1788       signal_real = ixheaacd_shl32(signal_real, shift);
1789       sig_imag = ixheaacd_shl32(sig_imag, shift);
1790     } else {
1791       shift = -shift;
1792       signal_real = ixheaacd_shr32(signal_real, shift);
1793       sig_imag = ixheaacd_shr32(sig_imag, shift);
1794     }
1795 
1796     ptr_rand_ph++;
1797 
1798     if (*ptr_sine_level_buf != 0) {
1799       WORD32 tmp = ixheaacd_sub16(ptr_sine_level_buf[1], noise_e);
1800 
1801       if (tmp > 0)
1802         sine_level = ixheaacd_shl32(ptr_sine_level_buf[0], tmp);
1803       else
1804         sine_level = ixheaacd_shr32(ptr_sine_level_buf[0], -tmp);
1805 
1806       *ptr_real_buf = signal_real;
1807 
1808       if (freq_inv_flag) {
1809         *ptr_imag = ixheaacd_add32_sat(sig_imag, sine_level);
1810       } else {
1811         *ptr_imag = ixheaacd_sub32_sat(sig_imag, sine_level);
1812       }
1813 
1814     } else {
1815       if (!noise_absc_flag) {
1816         WORD32 random = *ptr_rand_ph;
1817         WORD16 noise = smoothed_noise[0];
1818 
1819         *ptr_real_buf = ixheaacd_mac16x16in32_shl_sat(
1820             signal_real, ixheaacd_extract16h(random), noise);
1821         *ptr_imag = ixheaacd_mac16x16in32_shl_sat(
1822             sig_imag, ixheaacd_extract16l(random), noise);
1823       } else {
1824         *ptr_real_buf = signal_real;
1825         *ptr_imag = sig_imag;
1826       }
1827     }
1828 
1829     freq_inv_flag = (!freq_inv_flag);
1830     smoothed_gain += 2;
1831     smoothed_noise += factor;
1832     ptr_sine_level_buf += 2;
1833     ptr_real_buf++;
1834     ptr_imag++;
1835   }
1836 }