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 }