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 <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "ixheaacd_sbr_common.h"
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaac_basic_ops32.h"
27 #include "ixheaac_basic_ops16.h"
28 #include "ixheaac_basic_ops40.h"
29 #include "ixheaac_basic_ops.h"
30
31 #include "ixheaacd_bitbuffer.h"
32
33 #include "ixheaacd_error_codes.h"
34 #include "ixheaacd_defines.h"
35 #include "ixheaacd_aac_rom.h"
36 #include "ixheaacd_common_rom.h"
37 #include "ixheaacd_basic_funcs.h"
38 #include "ixheaacd_aac_imdct.h"
39 #include "ixheaac_basic_op.h"
40 #include "ixheaacd_intrinsics.h"
41
42 #include "ixheaacd_pulsedata.h"
43
44 #include "ixheaacd_pns.h"
45 #include "ixheaacd_drc_data_struct.h"
46
47 #include "ixheaacd_lt_predict.h"
48 #include "ixheaacd_cnst.h"
49 #include "ixheaacd_ec_defines.h"
50 #include "ixheaacd_ec_struct_def.h"
51 #include "ixheaacd_channelinfo.h"
52 #include "ixheaacd_drc_dec.h"
53 #include "ixheaacd_sbrdecoder.h"
54 #include "ixheaacd_block.h"
55
56 #include "ixheaacd_channel.h"
57
58 #include "ixheaacd_audioobjtypes.h"
59 #include "ixheaacd_latmdemux.h"
60 #include "ixheaacd_aacdec.h"
61 #include "ixheaacd_tns.h"
62 #include "ixheaacd_function_selector.h"
63
ixheaacd_is_correlation(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,WORD16 pns_band)64 static PLATFORM_INLINE WORD16 ixheaacd_is_correlation(
65 ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, WORD16 pns_band) {
66 ia_pns_correlation_info_struct *ptr_corr_info =
67 ptr_aac_dec_channel_info->pstr_pns_corr_info;
68
69 return ((ptr_corr_info->correlated[(pns_band >> PNS_BAND_FLAGS_SHIFT)] >>
70 (pns_band & PNS_BAND_FLAGS_MASK)) &
71 1);
72 }
73
ixheaacd_gen_rand_vec(WORD32 scale,WORD shift,WORD32 * ptr_spec_coef,WORD32 sfb_width,WORD32 * seed)74 VOID ixheaacd_gen_rand_vec(WORD32 scale, WORD shift, WORD32 *ptr_spec_coef,
75 WORD32 sfb_width, WORD32 *seed) {
76 WORD nrg_scale;
77 WORD32 nrg = 0;
78 WORD32 *spec = ptr_spec_coef;
79 WORD32 sfb;
80
81 for (sfb = 0; sfb <= sfb_width; sfb++) {
82 *seed = (WORD32)(((WORD64)1664525 * (WORD64)(*seed)) + (WORD64)1013904223);
83
84 *spec = (*seed >> 3);
85
86 nrg = ixheaac_add32_sat(nrg, ixheaac_mult32_shl_sat(*spec, *spec));
87
88 spec++;
89 }
90
91 nrg_scale = ixheaac_norm32(nrg);
92
93 if (nrg_scale > 0) {
94 nrg_scale &= ~1;
95 nrg = ixheaac_shl32_sat(nrg, nrg_scale);
96 shift = shift - (nrg_scale >> 1);
97 }
98
99 nrg = ixheaacd_sqrt(nrg);
100 scale = ixheaac_div32_pos_normb(scale, nrg);
101
102 spec = ptr_spec_coef;
103
104 if (shift < -31) {
105 shift = -31;
106 }
107 for (sfb = 0; sfb <= sfb_width; sfb++) {
108 *spec = ixheaac_shr32_dir_sat_limit(ixheaac_mult32_shl_sat(*spec, scale),
109 shift);
110 spec++;
111 }
112 }
113
ixheaacd_pns_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info[CHANNELS],WORD32 channel,ia_aac_dec_tables_struct * ptr_aac_tables)114 VOID ixheaacd_pns_process(ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[CHANNELS],
115 WORD32 channel, ia_aac_dec_tables_struct *ptr_aac_tables) {
116 ia_pns_info_struct *ptr_pns_info =
117 &ptr_aac_dec_channel_info[channel]->str_pns_info;
118 ia_ics_info_struct *ptr_ics_info =
119 &ptr_aac_dec_channel_info[channel]->str_ics_info;
120 WORD16 maximum_bins_short = ptr_ics_info->frame_length >> 3;
121 WORD32 *ptr_scale_mant_tab =
122 ptr_aac_tables->pstr_block_tables->scale_mant_tab;
123
124 if (ptr_pns_info->pns_active) {
125 const WORD16 *swb_offset =
126 ptr_aac_tables->str_aac_sfb_info[ptr_ics_info->window_sequence]
127 .sfb_index;
128
129 WORD num_win_group, grp_len, sfb;
130 WORD32 *spec = &ptr_aac_dec_channel_info[channel]->ptr_spec_coeff[0];
131
132 for (num_win_group = 0; num_win_group < ptr_ics_info->num_window_groups;
133 num_win_group++) {
134 grp_len = ptr_ics_info->window_group_length[num_win_group];
135
136 for (grp_len = 0;
137 grp_len < ptr_ics_info->window_group_length[num_win_group];
138 grp_len++) {
139 for (sfb = 0; sfb < ptr_ics_info->max_sfb; sfb++) {
140 WORD16 pns_band = ((num_win_group << 4) + sfb);
141
142 if (ptr_aac_dec_channel_info[channel]
143 ->str_pns_info.pns_used[pns_band]) {
144 WORD32 scale_mant;
145 WORD32 scale_exp;
146 WORD32 sfb_width = swb_offset[sfb + 1] - swb_offset[sfb] - 1;
147 WORD32 *ptr_spec = &spec[swb_offset[sfb]];
148
149 scale_mant = ptr_scale_mant_tab[ptr_aac_dec_channel_info[channel]
150 ->ptr_scale_factor[pns_band] &
151 PNS_SCALE_MANT_TAB_MASK];
152 scale_exp = add_d(sub_d(31, (ptr_aac_dec_channel_info[channel]
153 ->ptr_scale_factor[pns_band] >>
154 PNS_SCALEFACTOR_SCALING)),
155 PNS_SCALE_MANT_TAB_SCALING);
156
157 if (ixheaacd_is_correlation(ptr_aac_dec_channel_info[LEFT],
158 pns_band)) {
159 if (channel == 0) {
160 ptr_aac_dec_channel_info[LEFT]
161 ->pstr_pns_corr_info->random_vector[pns_band] =
162 ptr_aac_dec_channel_info[LEFT]
163 ->pstr_pns_rand_vec_data->current_seed;
164
165 ixheaacd_gen_rand_vec(
166 scale_mant, scale_exp, ptr_spec, sfb_width,
167 &(ptr_aac_dec_channel_info[LEFT]
168 ->pstr_pns_rand_vec_data->current_seed));
169 }
170
171 else {
172 ixheaacd_gen_rand_vec(
173 scale_mant, scale_exp, ptr_spec, sfb_width,
174 &(ptr_aac_dec_channel_info[LEFT]
175 ->pstr_pns_corr_info->random_vector[pns_band]));
176 }
177
178 }
179
180 else {
181 ixheaacd_gen_rand_vec(
182 scale_mant, scale_exp, ptr_spec, sfb_width,
183 &(ptr_aac_dec_channel_info[LEFT]
184 ->pstr_pns_rand_vec_data->current_seed));
185 }
186 }
187 }
188
189 if (maximum_bins_short == 120)
190 spec += maximum_bins_short;
191 else
192 spec += 128;
193 }
194 }
195 }
196
197 if (channel == 0) {
198 ptr_aac_dec_channel_info[0]->pstr_pns_rand_vec_data->pns_frame_number++;
199 }
200 }
201
ixheaacd_tns_decode_coef(const ia_filter_info_struct * filter,WORD16 * parcor_coef,ia_aac_dec_tables_struct * ptr_aac_tables)202 VOID ixheaacd_tns_decode_coef(const ia_filter_info_struct *filter,
203 WORD16 *parcor_coef,
204 ia_aac_dec_tables_struct *ptr_aac_tables) {
205 WORD order, resolution;
206 WORD16 *ptr_par_coef = parcor_coef;
207 WORD16 *tns_coeff_ptr;
208 WORD8 ixheaacd_drc_offset = 4;
209 WORD8 *ptr_coef = (WORD8 *)filter->coef;
210
211 resolution = filter->resolution;
212 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3_16;
213
214 if (resolution) {
215 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4_16;
216 ixheaacd_drc_offset = ixheaacd_drc_offset << 1;
217 }
218
219 for (order = 0; order < filter->order; order++) {
220 WORD8 temp = *ptr_coef++;
221 *ptr_par_coef++ = tns_coeff_ptr[temp + ixheaacd_drc_offset];
222 }
223 }
224
ixheaacd_tns_decode_coef_ld(const ia_filter_info_struct * filter,WORD32 * parcor_coef,ia_aac_dec_tables_struct * ptr_aac_tables)225 VOID ixheaacd_tns_decode_coef_ld(const ia_filter_info_struct *filter,
226 WORD32 *parcor_coef,
227 ia_aac_dec_tables_struct *ptr_aac_tables) {
228 WORD order, resolution;
229 WORD32 *ptr_par_coef = parcor_coef;
230 WORD32 *tns_coeff_ptr;
231 WORD8 offset = 4;
232 WORD8 *ptr_coef = (WORD8 *)filter->coef;
233
234 resolution = filter->resolution;
235 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3;
236
237 if (resolution) {
238 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4;
239 offset = offset << 1;
240 }
241
242 for (order = 0; order < filter->order; order++) {
243 WORD8 temp = *ptr_coef++;
244 *ptr_par_coef++ = tns_coeff_ptr[temp + offset];
245 }
246 }
247
ixheaacd_aac_tns_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,WORD32 num_ch,ia_aac_dec_tables_struct * ptr_aac_tables,WORD32 object_type,WORD32 ar_flag,WORD32 * predicted_spectrum)248 VOID ixheaacd_aac_tns_process(
249 ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, WORD32 num_ch,
250 ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type,
251 WORD32 ar_flag, WORD32 *predicted_spectrum) {
252 WORD i;
253 WORD16 scale_lpc;
254
255 ia_tns_info_aac_struct *ptr_tns_info =
256 &ptr_aac_dec_channel_info->str_tns_info;
257 WORD32 *spec = ptr_aac_dec_channel_info->ptr_spec_coeff;
258 WORD32 *scratch_buf = ptr_aac_dec_channel_info->scratch_buf_ptr;
259
260 WORD win, filt, start, stop, size, scale_spec;
261 ia_ics_info_struct *ptr_ics_info = &ptr_aac_dec_channel_info->str_ics_info;
262 WORD num_window, tns_max_bands, win_seq;
263 WORD16 maximum_bins_short = ptr_ics_info->frame_length >> 3;
264 WORD position;
265
266 WORD32 parcor_coef[MAX_ORDER + 1];
267 WORD16 parcor_coef_16[MAX_ORDER + 1];
268
269 WORD32 lpc_coef[MAX_ORDER + 1];
270 WORD16 lpc_coef_16[MAX_ORDER + 1];
271
272 const WORD16 *ptr_sfb_table;
273
274 WORD16 max_bin_long = ptr_ics_info->frame_length;
275
276 win_seq = ptr_ics_info->window_sequence == 0
277 ? 0
278 : (ptr_ics_info->window_sequence % 2 == 0);
279
280 if (ar_flag)
281 spec = ptr_aac_dec_channel_info->ptr_spec_coeff;
282 else {
283 spec = predicted_spectrum;
284 }
285
286 if (object_type == AOT_ER_AAC_ELD || object_type == AOT_ER_AAC_LD ||
287 object_type == AOT_AAC_LTP) {
288 if (512 == ptr_ics_info->frame_length) {
289 tns_max_bands =
290 ptr_aac_tables->pstr_block_tables
291 ->tns_max_bands_tbl_ld[ptr_ics_info->sampling_rate_index];
292 win_seq = 1;
293 num_window = win_seq;
294 } else if (480 == ptr_ics_info->frame_length) {
295 tns_max_bands =
296 ptr_aac_tables->pstr_block_tables
297 ->tns_max_bands_tbl_480[ptr_ics_info->sampling_rate_index];
298 win_seq = 1;
299 num_window = win_seq;
300 } else {
301 tns_max_bands =
302 ptr_aac_tables->pstr_block_tables
303 ->tns_max_bands_tbl[ptr_ics_info->sampling_rate_index][win_seq];
304
305 num_window = win_seq ? 8 : 1;
306 }
307 } else {
308 tns_max_bands =
309 ptr_aac_tables->pstr_block_tables
310 ->tns_max_bands_tbl[ptr_ics_info->sampling_rate_index][win_seq];
311
312 num_window = win_seq ? 8 : 1;
313 }
314
315 ptr_sfb_table =
316 ptr_aac_tables->str_aac_sfb_info[ptr_ics_info->window_sequence].sfb_index;
317
318 for (win = 0; win < num_window; win++) {
319 WORD n_filt = ptr_tns_info->n_filt[win];
320
321 for (filt = 0; filt < n_filt; filt++) {
322 ia_filter_info_struct *filter = &ptr_tns_info->str_filter[win][filt];
323
324 if (filter->order <= 0) {
325 continue;
326 }
327
328 if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
329 (num_ch > 2)) {
330 ixheaacd_tns_decode_coefficients(filter, parcor_coef, ptr_aac_tables);
331
332 } else {
333 ixheaacd_tns_decode_coef(filter, parcor_coef_16, ptr_aac_tables);
334 }
335
336 start = ixheaac_min32(ixheaac_min32(filter->start_band, tns_max_bands),
337 ptr_ics_info->max_sfb);
338
339 start = ptr_sfb_table[start];
340
341 stop = ixheaac_min32(ixheaac_min32(filter->stop_band, tns_max_bands),
342 ptr_ics_info->max_sfb);
343
344 stop = ptr_sfb_table[stop];
345
346 size = (stop - start);
347
348 if (size <= 0) {
349 continue;
350 }
351 if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
352 (num_ch > 2)) {
353 ixheaacd_tns_parcor_to_lpc(parcor_coef, lpc_coef, &scale_lpc,
354 filter->order);
355
356 } else {
357 (*ixheaacd_tns_parcor_lpc_convert)(parcor_coef_16, lpc_coef_16,
358 &scale_lpc, filter->order);
359 }
360
361 {
362 WORD32 *ptr_tmp;
363
364 if (maximum_bins_short == 120)
365 ptr_tmp = spec + (win * maximum_bins_short) + start;
366 else
367 ptr_tmp = spec + (win << 7) + start;
368
369 scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_tmp, size);
370 }
371
372 if (filter->direction == -1) {
373 position = stop - 1;
374
375 if (maximum_bins_short == 120) {
376 if (((win * maximum_bins_short) + position) < filter->order) continue;
377 } else {
378 if (((win << 7) + position) < filter->order) continue;
379 }
380
381 } else {
382 position = start;
383 if (maximum_bins_short == 120) {
384 if ((((win * maximum_bins_short) + position) + filter->order) > max_bin_long)
385 continue;
386 } else {
387 if ((((win << 7) + position) + filter->order) > MAX_BINS_LONG) continue;
388 }
389 }
390
391 if ((num_ch <= 2) &&
392 ((object_type != AOT_ER_AAC_LD) && (object_type != AOT_AAC_LTP)))
393 scale_spec = ((scale_spec - 4) - scale_lpc);
394 else {
395 if (scale_spec > 17)
396 scale_spec = ((scale_spec - 6) - scale_lpc);
397 else if (scale_spec > 11)
398 scale_spec = ((scale_spec - 5) - scale_lpc);
399 else
400 scale_spec = ((scale_spec - 4) - scale_lpc);
401 }
402
403 if (scale_spec > 0) {
404 scale_spec = ixheaac_min32(scale_spec, 31);
405
406 if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
407 (num_ch > 2)) {
408 if (ar_flag)
409 {
410 if (maximum_bins_short == 120) {
411 (*ixheaacd_tns_ar_filter_fixed)(&spec[(win * maximum_bins_short) + position],
412 size, filter->direction,
413 (WORD32 *)lpc_coef, filter->order,
414 (WORD32)scale_lpc, scale_spec);
415 } else {
416 (*ixheaacd_tns_ar_filter_fixed)(&spec[(win << 7) + position], size,
417 filter->direction,
418 (WORD32 *)lpc_coef, filter->order,
419 (WORD32)scale_lpc, scale_spec);
420 }
421 } else {
422 if (maximum_bins_short == 120) {
423 ixheaacd_tns_ma_filter_fixed_ld(&spec[(win * maximum_bins_short) + position],
424 size, filter->direction, lpc_coef,
425 filter->order, scale_lpc);
426 } else {
427 ixheaacd_tns_ma_filter_fixed_ld(&spec[(win << 7) + position], size,
428 filter->direction, lpc_coef,
429 filter->order, scale_lpc);
430 }
431 }
432 } else {
433 if (object_type == AOT_ER_AAC_ELD) scale_spec = scale_spec - 1;
434 if (maximum_bins_short == 120) {
435 (*ixheaacd_tns_ar_filter)(&spec[(win * maximum_bins_short) + position], size,
436 filter->direction, lpc_coef_16,
437 filter->order, (WORD32)scale_lpc,
438 scale_spec, scratch_buf);
439 } else {
440 (*ixheaacd_tns_ar_filter)(&spec[(win << 7) + position], size,
441 filter->direction, lpc_coef_16,
442 filter->order, (WORD32)scale_lpc,
443 scale_spec, scratch_buf);
444 }
445 }
446 }
447
448 else {
449 WORD32 *ptr_tmp;
450
451 if (maximum_bins_short == 120)
452 ptr_tmp = spec + (win * maximum_bins_short) + start;
453 else
454 ptr_tmp = spec + (win >> 7) + start;
455
456 scale_spec = -scale_spec;
457 scale_spec = ixheaac_min32(scale_spec, 31);
458
459 for (i = size; i != 0; i--) {
460 *ptr_tmp = (*ptr_tmp >> scale_spec);
461 ptr_tmp++;
462 }
463
464 if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
465 num_ch > 2) {
466 if (ar_flag) {
467 if (maximum_bins_short == 120) {
468 (*ixheaacd_tns_ar_filter_fixed)(
469 &spec[(win * maximum_bins_short) + position], size, filter->direction,
470 (WORD32 *)lpc_coef, filter->order, scale_lpc, 0);
471 } else {
472 (*ixheaacd_tns_ar_filter_fixed)(
473 &spec[(win << 7) + position], size, filter->direction,
474 (WORD32 *)lpc_coef, filter->order, scale_lpc, 0);
475 }
476 } else {
477 if (maximum_bins_short == 120) {
478 ixheaacd_tns_ma_filter_fixed_ld(&spec[(win * maximum_bins_short) + position],
479 size, filter->direction, lpc_coef,
480 filter->order, scale_lpc);
481 } else {
482 ixheaacd_tns_ma_filter_fixed_ld(&spec[(win << 7) + position], size,
483 filter->direction, lpc_coef,
484 filter->order, scale_lpc);
485 }
486 }
487 } else {
488 if (object_type == AOT_ER_AAC_ELD) {
489 scale_lpc = scale_lpc - 1;
490 }
491
492 if (maximum_bins_short == 120) {
493 (*ixheaacd_tns_ar_filter)(&spec[(win * maximum_bins_short) + position], size,
494 filter->direction, lpc_coef_16,
495 filter->order, scale_lpc, 0, scratch_buf);
496 } else {
497 (*ixheaacd_tns_ar_filter)(&spec[(win << 7) + position], size,
498 filter->direction, lpc_coef_16,
499 filter->order, scale_lpc, 0, scratch_buf);
500 }
501 }
502
503 if (maximum_bins_short == 120)
504 ptr_tmp = spec + (win * maximum_bins_short) + start;
505 else
506 ptr_tmp = spec + (win << 7) + start;
507
508 for (i = size; i != 0; i--) {
509 *ptr_tmp = (*ptr_tmp << scale_spec);
510 ptr_tmp++;
511 }
512 }
513 }
514 }
515 }