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