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
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "ixheaacd_type_def.h"
26 #include "ixheaacd_constants.h"
27 #include "ixheaacd_basic_ops32.h"
28 #include "ixheaacd_basic_ops16.h"
29 #include "ixheaacd_basic_ops40.h"
30
31 #include "ixheaacd_defines.h"
32 #include "ixheaacd_aac_rom.h"
33 #include "ixheaacd_audioobjtypes.h"
34
35 #include "ixheaacd_bitbuffer.h"
36 #include "ixheaacd_pulsedata.h"
37 #include "ixheaacd_pns.h"
38 #include "ixheaacd_lt_predict.h"
39 #include "ixheaacd_channelinfo.h"
40 #include "ixheaacd_cnst.h"
41 #include "ixheaacd_tns.h"
42 #include "ixheaacd_aac_imdct.h"
43
44 static const WORD32 ixheaacd_codebook_Q30[8] = {
45 612922971, 747985734, 872956397, 978505219,
46 1057528322, 1146642451, 1282693056, 1470524861};
47
48 #define SHIFT_VAL 8
49 #define SHIFT_VAL1 (15 - SHIFT_VAL)
50
ixheaacd_lt_prediction(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,ltp_info * ltp,WORD32 * spec,ia_aac_dec_tables_struct * aac_tables_ptr,UWORD16 win_shape_prev,UWORD32 sr_index,UWORD32 object_type,UWORD32 frame_len,WORD32 * in_data,WORD32 * out_data)51 VOID ixheaacd_lt_prediction(
52 ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, ltp_info *ltp,
53 WORD32 *spec, ia_aac_dec_tables_struct *aac_tables_ptr,
54 UWORD16 win_shape_prev, UWORD32 sr_index, UWORD32 object_type,
55 UWORD32 frame_len, WORD32 *in_data, WORD32 *out_data) {
56 ia_ics_info_struct *ptr_ics_info = &ptr_aac_dec_channel_info->str_ics_info;
57 WORD16 *lt_pred_stat = ptr_aac_dec_channel_info->ltp_buf;
58 UWORD16 win_shape = ptr_aac_dec_channel_info->str_ics_info.window_shape;
59 WORD16 sfb;
60 WORD16 bin, i, num_samples;
61 const WORD8 *swb_offset = aac_tables_ptr->scale_factor_bands_long[sr_index];
62 WORD32 *ptr_spec = &spec[0];
63 WORD32 *ptr_x_est = &out_data[0];
64
65 if (512 == ptr_ics_info->frame_length) {
66 swb_offset = aac_tables_ptr->scale_fac_bands_512[sr_index];
67 } else if (480 == ptr_ics_info->frame_length) {
68 swb_offset = aac_tables_ptr->scale_fac_bands_480[sr_index];
69 }
70
71 if (ptr_ics_info->window_sequence != EIGHT_SHORT_SEQUENCE) {
72 if (ltp->data_present) {
73 num_samples = frame_len << 1;
74
75 for (i = 0; i < num_samples; i++) {
76 in_data[i] =
77 ixheaacd_shr32(ixheaacd_mult32x16in32_shl_sat(
78 ixheaacd_codebook_Q30[ltp->coef],
79 lt_pred_stat[num_samples + i - ltp->lag]),
80 SHIFT_VAL);
81 }
82
83 ixheaacd_filter_bank_ltp(aac_tables_ptr, ptr_ics_info->window_sequence,
84 win_shape, win_shape_prev, in_data, out_data,
85 object_type, frame_len);
86
87 if (ptr_aac_dec_channel_info->str_tns_info.tns_data_present == 1)
88 ixheaacd_aac_tns_process(ptr_aac_dec_channel_info, 1, aac_tables_ptr,
89 object_type, 0, out_data);
90
91 for (sfb = 0; sfb < ltp->last_band; sfb++) {
92 WORD8 sfb_width = swb_offset[sfb];
93 if (ltp->long_used[sfb]) {
94 for (bin = sfb_width - 1; bin >= 0; bin--) {
95 WORD32 temp = *ptr_spec;
96 temp = ixheaacd_add32_sat(temp,
97 ixheaacd_shr32(*ptr_x_est++, SHIFT_VAL1));
98 *ptr_spec++ = temp;
99 }
100 } else {
101 ptr_spec += sfb_width;
102 ptr_x_est += sfb_width;
103 }
104 }
105 }
106 }
107 }
108
ixheaacd_filter_bank_ltp(ia_aac_dec_tables_struct * aac_tables_ptr,WORD16 window_sequence,WORD16 window_shape,WORD16 window_shape_prev,WORD32 * in_data,WORD32 * out_mdct,UWORD32 object_type,UWORD32 frame_len)109 VOID ixheaacd_filter_bank_ltp(ia_aac_dec_tables_struct *aac_tables_ptr,
110 WORD16 window_sequence, WORD16 window_shape,
111 WORD16 window_shape_prev, WORD32 *in_data,
112 WORD32 *out_mdct, UWORD32 object_type,
113 UWORD32 frame_len) {
114 WORD32 i;
115
116 const WORD16 *window_long = NULL;
117 const WORD16 *window_long_prev = NULL;
118 const WORD16 *window_short = NULL;
119 const WORD16 *window_short_prev = NULL;
120
121 UWORD16 nlong = frame_len;
122 UWORD16 nlong2 = frame_len << 1;
123 UWORD16 nshort = frame_len / 8;
124 UWORD16 nflat_ls = (nlong - nshort) / 2;
125 WORD32 imdct_scale = 0;
126 WORD32 expo = 0;
127
128 if (object_type == AOT_ER_AAC_LD) {
129 if (!window_shape) {
130 if (512 == frame_len) {
131 window_long =
132 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->window_sine_512;
133 } else {
134 window_long =
135 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->window_sine_480;
136 }
137 } else {
138 if (512 == frame_len) {
139 window_long =
140 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->low_overlap_win;
141 } else {
142 window_long =
143 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->low_overlap_win_480;
144 }
145 }
146
147 if (!window_shape_prev) {
148 if (512 == frame_len) {
149 window_long_prev =
150 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->window_sine_512;
151 } else {
152 window_long_prev =
153 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->window_sine_480;
154 }
155 } else {
156 if (512 == frame_len) {
157 window_long_prev =
158 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->low_overlap_win;
159 } else {
160 window_long_prev =
161 (WORD16 *)aac_tables_ptr->pstr_imdct_tables->low_overlap_win_480;
162 }
163 }
164
165 if (!window_shape)
166 window_short = aac_tables_ptr->pstr_imdct_tables->only_short_window_sine;
167 else
168 window_short = aac_tables_ptr->pstr_imdct_tables->only_short_window_kbd;
169 if (!window_shape_prev)
170 window_short_prev =
171 aac_tables_ptr->pstr_imdct_tables->only_short_window_sine;
172 else
173 window_short_prev =
174 aac_tables_ptr->pstr_imdct_tables->only_short_window_kbd;
175
176 } else {
177 if (!window_shape)
178 window_long = aac_tables_ptr->pstr_imdct_tables->only_long_window_sine;
179 else
180 window_long = aac_tables_ptr->pstr_imdct_tables->only_long_window_kbd;
181 if (!window_shape_prev)
182 window_long_prev =
183 aac_tables_ptr->pstr_imdct_tables->only_long_window_sine;
184 else
185 window_long_prev =
186 aac_tables_ptr->pstr_imdct_tables->only_long_window_kbd;
187
188 if (!window_shape)
189 window_short = aac_tables_ptr->pstr_imdct_tables->only_short_window_sine;
190 else
191 window_short = aac_tables_ptr->pstr_imdct_tables->only_short_window_kbd;
192 if (!window_shape_prev)
193 window_short_prev =
194 aac_tables_ptr->pstr_imdct_tables->only_short_window_sine;
195 else
196 window_short_prev =
197 aac_tables_ptr->pstr_imdct_tables->only_short_window_kbd;
198 }
199
200 switch (window_sequence) {
201 case ONLY_LONG_SEQUENCE:
202
203 if ((512 != nlong) && (480 != nlong)) {
204 for (i = 0; i<nlong>> 1; i++) {
205 in_data[i] =
206 ixheaacd_mult32x16in32_shl(in_data[i], window_long_prev[2 * i]);
207
208 in_data[i + nlong] = ixheaacd_mult32x16in32_shl(
209 in_data[i + nlong], window_long[2 * i + 1]);
210 }
211 for (i = 0; i<nlong>> 1; i++) {
212 in_data[i + (nlong >> 1)] = ixheaacd_mult32x16in32_shl(
213 in_data[i + (nlong >> 1)], window_long_prev[nlong - 1 - 2 * i]);
214
215 in_data[i + nlong + (nlong >> 1)] =
216 ixheaacd_mult32x16in32_shl(in_data[i + nlong + (nlong >> 1)],
217 window_long[nlong - 1 - 2 * i - 1]);
218 }
219
220 } else {
221 WORD32 *win1, *win2, *win3;
222 WORD32 *ptr_in1, *ptr_in2;
223 win1 = (WORD32 *)window_long_prev;
224 win2 = (WORD32 *)window_long;
225 ptr_in1 = &in_data[0];
226 ptr_in2 = &in_data[nlong];
227 win3 = win2 + nlong - 1;
228
229 for (i = nlong - 1; i >= 0; i--) {
230 WORD32 temp1 = ixheaacd_mult32_shl(*ptr_in1, *win1++);
231 WORD32 temp2 = ixheaacd_mult32_shl(*ptr_in2, win2[i]);
232
233 *ptr_in1++ = temp1;
234 *ptr_in2++ = temp2;
235 }
236 }
237
238 for (i = 0; i < nlong / 2; i++) {
239 out_mdct[nlong / 2 + i] =
240 ixheaacd_sub32(in_data[i], in_data[nlong - 1 - i]);
241 out_mdct[i] = (-ixheaacd_add32(in_data[nlong + i + nlong / 2],
242 in_data[nlong2 - nlong / 2 - 1 - i]));
243 }
244
245 if (512 == nlong || (480 == nlong)) {
246 if (512 == nlong)
247 ixheaacd_inverse_transform_512(
248 out_mdct, in_data, &imdct_scale,
249 aac_tables_ptr->pstr_imdct_tables->cosine_array_1024,
250 aac_tables_ptr->pstr_imdct_tables, object_type);
251
252 else
253 ixheaacd_mdct_480_ld(out_mdct, in_data, &imdct_scale, 1,
254 aac_tables_ptr->pstr_imdct_tables, object_type);
255
256 imdct_scale += 1;
257
258 if (imdct_scale > 0) {
259 WORD32 *ptr_out_mdct = &out_mdct[0];
260
261 for (i = nlong - 1; i >= 0; i -= 4) {
262 *ptr_out_mdct = ixheaacd_shl32(*ptr_out_mdct, imdct_scale);
263 ptr_out_mdct++;
264 *ptr_out_mdct = ixheaacd_shl32(*ptr_out_mdct, imdct_scale);
265 ptr_out_mdct++;
266 *ptr_out_mdct = ixheaacd_shl32(*ptr_out_mdct, imdct_scale);
267 ptr_out_mdct++;
268 *ptr_out_mdct = ixheaacd_shl32(*ptr_out_mdct, imdct_scale);
269 ptr_out_mdct++;
270 }
271 } else if (imdct_scale < 0) {
272 WORD32 *ptr_out_mdct = &out_mdct[0];
273 imdct_scale = -imdct_scale;
274 for (i = nlong - 1; i >= 0; i -= 4) {
275 *ptr_out_mdct = ixheaacd_shr32(*ptr_out_mdct, imdct_scale);
276 ptr_out_mdct++;
277 *ptr_out_mdct = ixheaacd_shr32(*ptr_out_mdct, imdct_scale);
278 ptr_out_mdct++;
279 *ptr_out_mdct = ixheaacd_shr32(*ptr_out_mdct, imdct_scale);
280 ptr_out_mdct++;
281 *ptr_out_mdct = ixheaacd_shr32(*ptr_out_mdct, imdct_scale);
282 ptr_out_mdct++;
283 }
284 }
285 }
286
287 else if (1024 == nlong) {
288 expo = ixheaacd_calc_max_spectral_line_dec(out_mdct, 1024) - 1;
289
290 expo = 8 - expo;
291
292 imdct_scale = ixheaacd_inverse_transform(
293 out_mdct, in_data, aac_tables_ptr->pstr_imdct_tables, expo, 1024);
294
295 ixheaacd_post_twiddle_dec(in_data, out_mdct,
296 aac_tables_ptr->pstr_imdct_tables, 1024);
297
298 imdct_scale += 1;
299
300 for (i = 0; i < nlong; i++) {
301 out_mdct[i] = ixheaacd_shl32_dir(in_data[i], imdct_scale);
302 }
303 }
304
305 break;
306
307 case LONG_START_SEQUENCE:
308
309 for (i = 0; i<nlong>> 1; i++)
310 in_data[i] =
311 ixheaacd_mult32x16in32_shl(in_data[i], window_long_prev[2 * i]);
312
313 for (i = 0; i<nlong>> 1; i++)
314 in_data[i + (nlong >> 1)] = ixheaacd_mult32x16in32_shl(
315 in_data[i + (nlong >> 1)], window_long_prev[nlong - 1 - 2 * i - 1]);
316
317 for (i = 0; i<nshort>> 1; i++)
318 in_data[i + nlong + nflat_ls + (nshort >> 1)] =
319 ixheaacd_mult32x16in32_shl(
320 in_data[i + nlong + nflat_ls + (nshort >> 1)],
321 window_short[nshort - 1 - 2 * i - 1]);
322
323 for (i = 0; i < nflat_ls; i++) in_data[i + nlong + nflat_ls + nshort] = 0;
324
325 for (i = 0; i < nlong / 2; i++) {
326 out_mdct[nlong / 2 + i] =
327 ixheaacd_sub32(in_data[i], in_data[nlong - 1 - i]);
328 out_mdct[nlong / 2 - 1 - i] =
329 -ixheaacd_add32(in_data[nlong + i], in_data[nlong2 - 1 - i]);
330 }
331
332 {
333 expo = ixheaacd_calc_max_spectral_line_dec(out_mdct, 1024) - 1;
334
335 expo = 8 - expo;
336 imdct_scale = ixheaacd_inverse_transform(
337 out_mdct, in_data, aac_tables_ptr->pstr_imdct_tables, expo, 1024);
338
339 ixheaacd_post_twiddle_dec(in_data, out_mdct,
340 aac_tables_ptr->pstr_imdct_tables, 1024);
341 }
342
343 imdct_scale += 1;
344
345 for (i = 0; i < nlong; i++) {
346 out_mdct[i] = ixheaacd_shl32_dir(in_data[i], imdct_scale);
347 }
348 break;
349
350 case LONG_STOP_SEQUENCE:
351 for (i = 0; i < nflat_ls; i++) in_data[i] = 0;
352
353 for (i = 0; i<nshort>> 1; i++)
354 in_data[i + nflat_ls] = ixheaacd_mult32x16in32_shl(
355 in_data[i + nflat_ls], window_short_prev[2 * i]);
356
357 for (i = 0; i<nshort>> 1; i++)
358 in_data[i + nflat_ls + (nshort >> 1)] =
359 ixheaacd_mult32x16in32_shl(in_data[i + nflat_ls + (nshort >> 1)],
360 window_short_prev[127 - 2 * i]);
361
362 for (i = 0; i<nlong>> 1; i++)
363 in_data[i + nlong] = ixheaacd_mult32x16in32_shl(in_data[i + nlong],
364 window_long[2 * i + 1]);
365
366 for (i = 0; i<nlong>> 1; i++)
367 in_data[i + nlong + (nlong >> 1)] =
368 ixheaacd_mult32x16in32_shl(in_data[i + nlong + (nlong >> 1)],
369 window_long[nlong - 1 - 2 * i - 1]);
370
371 for (i = 0; i < nlong / 2; i++) {
372 out_mdct[nlong / 2 + i] =
373 ixheaacd_sub32(in_data[i], in_data[nlong - 1 - i]);
374 out_mdct[nlong / 2 - 1 - i] =
375 -ixheaacd_add32(in_data[nlong + i], in_data[nlong2 - 1 - i]);
376 }
377
378 {
379 expo = ixheaacd_calc_max_spectral_line_dec(out_mdct, 1024) - 1;
380
381 expo = 8 - expo;
382 imdct_scale = ixheaacd_inverse_transform(
383 out_mdct, in_data, aac_tables_ptr->pstr_imdct_tables, expo, 1024);
384
385 ixheaacd_post_twiddle_dec(in_data, out_mdct,
386 aac_tables_ptr->pstr_imdct_tables, 1024);
387 }
388
389 imdct_scale += 1;
390
391 for (i = 0; i < nlong; i++) {
392 out_mdct[i] = ixheaacd_shl32_dir(in_data[i], imdct_scale);
393 }
394
395 break;
396 }
397 }
398
ixheaacd_lt_update_state(WORD16 * lt_pred_stat,WORD16 * time,WORD32 * overlap,WORD32 frame_len,WORD32 object_type,WORD32 stride,WORD16 window_sequence,WORD16 * p_window_next)399 VOID ixheaacd_lt_update_state(WORD16 *lt_pred_stat, WORD16 *time,
400 WORD32 *overlap, WORD32 frame_len,
401 WORD32 object_type, WORD32 stride,
402 WORD16 window_sequence, WORD16 *p_window_next) {
403 WORD32 i;
404 if (object_type == AOT_ER_AAC_LD) {
405 WORD16 *ptr_ltp_state0 = <_pred_stat[0];
406 WORD16 *ptr_ltp_state_fl = <_pred_stat[frame_len + 0];
407 WORD16 *ptr_ltp_state_2fl = <_pred_stat[(frame_len * 2) + 0];
408 WORD16 *ptr_time_in = &time[0 * stride];
409
410 for (i = 0; i < frame_len; i++) {
411 *ptr_ltp_state0++ = *ptr_ltp_state_fl;
412 *ptr_ltp_state_fl++ = *ptr_ltp_state_2fl;
413 *ptr_ltp_state_2fl++ = *ptr_time_in;
414 ptr_time_in += stride;
415 }
416
417 } else {
418 WORD16 *ptr_ltp_state0 = <_pred_stat[0];
419 WORD16 *ptr_ltp_state_fl = <_pred_stat[frame_len + 0];
420 WORD16 *ptr_time_in = &time[0 * stride];
421
422 for (i = 0; i < frame_len; i++) {
423 *ptr_ltp_state0++ = *ptr_ltp_state_fl;
424 *ptr_ltp_state_fl++ = *ptr_time_in;
425 ptr_time_in += stride;
426 }
427 }
428
429 if ((window_sequence == ONLY_LONG_SEQUENCE) ||
430 (window_sequence == LONG_STOP_SEQUENCE)) {
431 if (512 == frame_len) {
432 WORD32 *window = (WORD32 *)p_window_next;
433
434 for (i = 0; i < 256; i++) {
435 lt_pred_stat[(frame_len * 3) + i] =
436 ixheaacd_round16(ixheaacd_mult16x16in32_shl(
437 (WORD16)ixheaacd_shl16(
438 (WORD16)-ixheaacd_sat16(overlap[255 - i]), 1),
439 (WORD16)ixheaacd_shr32(window[511 - i], 15)));
440
441 lt_pred_stat[(frame_len * 3) + 256 + i] =
442 ixheaacd_round16(ixheaacd_mult16x16in32_shl(
443 (WORD16)ixheaacd_shl16((WORD16)-ixheaacd_sat16(overlap[i]), 1),
444 (WORD16)ixheaacd_shr32(window[255 - i], 15)));
445 }
446 } else if (480 == frame_len) {
447 WORD32 *window = (WORD32 *)p_window_next;
448
449 for (i = 0; i < 240; i++) {
450 lt_pred_stat[(frame_len * 3) + i] =
451 ixheaacd_round16(ixheaacd_mult16x16in32_shl(
452 (WORD16)ixheaacd_shl16(
453 (WORD16)-ixheaacd_sat16(overlap[239 - i]), 1),
454 (WORD16)ixheaacd_shr32(window[479 - i], 15)));
455
456 lt_pred_stat[(frame_len * 3) + 240 + i] =
457 ixheaacd_round16(ixheaacd_mult16x16in32_shl(
458 (WORD16)ixheaacd_shl16((WORD16)-ixheaacd_sat16(overlap[i]), 1),
459 (WORD16)ixheaacd_shr32(window[239 - i], 15)));
460 }
461 } else {
462 for (i = 0; i < 512; i++) {
463 lt_pred_stat[(frame_len * 2) + i] = ixheaacd_round16(
464 ixheaacd_shl32_sat(ixheaacd_mult16x16in32_shl(
465 (WORD16)-ixheaacd_sat16(overlap[511 - i]),
466 p_window_next[2 * i + 1]),
467 1));
468
469 lt_pred_stat[(frame_len * 2) + 512 + i] =
470 ixheaacd_round16(ixheaacd_shl32_sat(
471 ixheaacd_mult16x16in32_shl((WORD16)-ixheaacd_sat16(overlap[i]),
472 p_window_next[1023 - 2 * i - 1]),
473 1));
474 }
475 }
476
477 } else if (window_sequence == LONG_START_SEQUENCE) {
478 for (i = 0; i < 448; i++) {
479 lt_pred_stat[(frame_len * 2) + i] =
480 ixheaacd_shl16((WORD16)-ixheaacd_sat16(overlap[511 - i]), 1);
481 }
482 for (i = 0; i < 64; i++) {
483 lt_pred_stat[(frame_len * 2) + 448 + i] =
484 ixheaacd_round16(ixheaacd_shl32_sat(
485 ixheaacd_mult16x16in32_shl(
486 (WORD16)-ixheaacd_sat16(overlap[511 - 448 - i]),
487 p_window_next[2 * i + 1]),
488 1));
489 }
490 for (i = 0; i < 64; i++) {
491 lt_pred_stat[(frame_len * 2) + 512 + i] =
492 ixheaacd_round16(ixheaacd_shl32_sat(
493 ixheaacd_mult16x16in32_shl((WORD16)-ixheaacd_sat16(overlap[i]),
494 p_window_next[127 - 2 * i - 1]),
495 1));
496 }
497 for (i = 576; i < 1024; i++) {
498 lt_pred_stat[(frame_len * 2) + i] = 0;
499 }
500 } else {
501 for (i = 0; i < 448; i++) {
502 lt_pred_stat[(frame_len * 2) + i] =
503 ixheaacd_shl16(ixheaacd_sat16(overlap[i]), 1);
504 }
505 for (i = 0; i < 64; i++) {
506 lt_pred_stat[(frame_len * 2) + 448 + i] = ixheaacd_round16(
507 ixheaacd_shl32_sat(ixheaacd_mult16x16in32_shl(
508 (WORD16)-ixheaacd_sat16(overlap[511 - i]),
509 p_window_next[2 * i + 1]),
510 1));
511 }
512 for (i = 0; i < 64; i++) {
513 lt_pred_stat[(frame_len * 2) + 512 + i] = ixheaacd_round16(
514 ixheaacd_shl32_sat(ixheaacd_mult16x16in32_shl(
515 (WORD16)-ixheaacd_sat16(overlap[448 + i]),
516 p_window_next[127 - 2 * i - 1]),
517 1));
518 }
519 for (i = 576; i < 1024; i++) {
520 lt_pred_stat[(frame_len * 2) + i] = 0;
521 }
522 }
523 }
524