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