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 "ixheaacd_sbr_common.h" 22 #include "ixheaacd_type_def.h" 23 24 #include "ixheaacd_constants.h" 25 #include "ixheaacd_basic_ops32.h" 26 #include "ixheaacd_basic_ops16.h" 27 #include "ixheaacd_basic_ops40.h" 28 #include "ixheaacd_basic_ops.h" 29 #include "ixheaacd_bitbuffer.h" 30 31 #include "ixheaacd_basic_op.h" 32 #include "ixheaacd_intrinsics.h" 33 34 #include "ixheaacd_defines.h" 35 36 #include "ixheaacd_aac_rom.h" 37 38 #include "ixheaacd_definitions.h" 39 40 #include "ixheaacd_error_codes.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_channelinfo.h" 49 #include "ixheaacd_cnst.h" 50 #include "ixheaacd_drc_dec.h" 51 52 #include "ixheaacd_sbrdecoder.h" 53 54 #include "ixheaacd_block.h" 55 #include "ixheaacd_channel.h" 56 57 #include "ixheaacd_sbr_payload.h" 58 #include "ixheaacd_common_rom.h" 59 #include "ixheaacd_sbrdecsettings.h" 60 #include "ixheaacd_sbr_scale.h" 61 #include "ixheaacd_env_extr_part.h" 62 #include "ixheaacd_sbr_rom.h" 63 64 #include "ixheaacd_lpp_tran.h" 65 #include "ixheaacd_hybrid.h" 66 #include "ixheaacd_ps_dec.h" 67 68 #include "ixheaacd_env_extr.h" 69 #include "ixheaacd_adts.h" 70 #include "ixheaacd_audioobjtypes.h" 71 #include "ixheaacd_memory_standards.h" 72 73 #include "ixheaacd_latmdemux.h" 74 75 #include "ixheaacd_aacdec.h" 76 #include "ixheaacd_mps_polyphase.h" 77 #include "ixheaacd_config.h" 78 #include "ixheaacd_mps_dec.h" 79 80 #include "ixheaacd_struct_def.h" 81 82 #include "ixheaacd_tns.h" 83 #include "ixheaacd_aac_imdct.h" 84 85 #include "ixheaacd_multichannel.h" 86 #include "ixheaacd_function_selector.h" 87 88 static PLATFORM_INLINE WORD32 ixheaacd_shr32_drc(WORD32 a, WORD32 b) { 89 WORD32 out_val; 90 91 b = ((UWORD32)(b << 24) >> 24); 92 if (b >= 31) { 93 if (a < 0) 94 out_val = -1; 95 else 96 out_val = 0; 97 } else { 98 a = ixheaacd_add32_sat(a, (1 << (b - 1))); 99 out_val = (WORD32)a >> b; 100 } 101 102 return out_val; 103 } 104 105 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_drc(WORD32 a, WORD16 b) { 106 WORD32 result; 107 WORD64 temp_result; 108 109 temp_result = (WORD64)a * (WORD64)b; 110 111 if (temp_result < (WORD64)MIN_32) 112 result = MIN_32; 113 114 else if (temp_result > (WORD64)MAX_32) 115 result = MAX_32; 116 117 else 118 result = (WORD32)(temp_result); 119 120 return (result); 121 } 122 123 VOID ixheaacd_process_win_seq(WORD32 *coef, WORD32 *prev, WORD16 *out, 124 const WORD16 *window_long, 125 const WORD16 *window_short, WORD16 q_shift, 126 WORD16 ch_fac, WORD16 flag) { 127 WORD32 i, accu; 128 WORD32 *coef_1; 129 const WORD16 *temp_win_sh, *temp_win_long; 130 WORD16 *out1, *out2; 131 WORD32 *temp_prev; 132 133 if (flag == 1) { 134 for (i = 0; i < SIZE07; i++) { 135 WORD32 temp1 = ixheaacd_shl32_dir_sat_limit( 136 ixheaacd_mult32x16in32(coef[SIZE08 + i], window_long[2 * i]), 137 (q_shift + 1)); 138 139 accu = ixheaacd_add32_sat(temp1, ((WORD32)prev[i] << 16)); 140 out[ch_fac * i] = ixheaacd_round16(accu << 1); 141 142 accu = ixheaacd_shl32_dir_sat_limit( 143 ixheaacd_mult32x16in32(-(coef[SIZE15 - 1 - i]), 144 window_long[2 * (SIZE07 - i) - 1]), 145 q_shift); 146 out[ch_fac * (i + SIZE09)] = ixheaacd_round16(accu << 2); 147 } 148 149 temp_win_sh = &(window_short[0]); 150 coef_1 = &(coef[SIZE15]); 151 temp_win_long = &(window_long[SIZE14]); 152 temp_prev = &(prev[SIZE08 - 1]); 153 out1 = &(out[ch_fac * (SIZE07)]); 154 out2 = &(out[ch_fac * (SIZE09 - 1)]); 155 156 } else { 157 for (i = 0; i < SIZE07; i++) { 158 accu = ixheaacd_mult32x16in32_drc( 159 prev[SIZE08 - 1 - i], ixheaacd_negate16(window_long[2 * i + 1])); 160 161 out[ch_fac * i] = ixheaacd_round16(accu << 2); 162 163 accu = ixheaacd_sub32_sat( 164 ixheaacd_shl32_dir_sat_limit(-(coef[SIZE15 - 1 - i]), (q_shift - 1)), 165 ixheaacd_mult32x16in32_drc(prev[i + SIZE01], 166 window_long[2 * SIZE07 - 2 - 2 * i])); 167 168 out[ch_fac * (SIZE09 + i)] = ixheaacd_round16(accu << 2); 169 } 170 171 temp_win_sh = &(window_long[SIZE14]); 172 coef_1 = &(coef[SIZE15]); 173 temp_win_long = &(window_short[0]); 174 temp_prev = &(prev[SIZE01 - 1]); 175 out1 = &(out[ch_fac * (SIZE07)]); 176 out2 = &(out[ch_fac * (SIZE09 - 1)]); 177 } 178 179 for (i = SIZE01 - 1; i >= 0; i--) { 180 WORD32 temp_coef = *coef_1++; 181 WORD16 win1 = *temp_win_long++; 182 WORD16 win2 = *temp_win_long++; 183 WORD32 prev1 = *temp_prev--; 184 WORD16 win4 = *temp_win_sh++; 185 WORD16 win3 = *temp_win_sh++; 186 accu = ixheaacd_sub32_sat( 187 ixheaacd_shl32_dir_sat_limit(ixheaacd_mult32x16in32(temp_coef, win1), 188 q_shift), 189 ixheaacd_mult32x16in32_drc(prev1, win3)); 190 *out1 = ixheaacd_round16(accu << 2); 191 out1 += ch_fac; 192 193 accu = ixheaacd_sub32_sat( 194 ixheaacd_shl32_dir_sat_limit( 195 ixheaacd_mult32x16in32(ixheaacd_negate32_sat(temp_coef), win2), 196 q_shift), 197 ixheaacd_mult32x16in32_drc(prev1, win4)); 198 *out2 = ixheaacd_round16(accu << 2); 199 out2 -= ch_fac; 200 } 201 } 202 203 static PLATFORM_INLINE VOID ixheaacd_long_short_win_process( 204 WORD32 *current, WORD32 *prev, WORD16 *out, const WORD16 *short_window, 205 const WORD16 *long_window_prev, WORD16 q_shift, WORD16 ch_fac, 206 WORD32 flag) { 207 WORD i; 208 WORD32 accu; 209 WORD32 *current_tmp1 = &(current[(SIZE03 - 1)]); 210 WORD32 *current_tmp2 = &(current[-SIZE01]); 211 const WORD16 *short_ptr = &(short_window[SIZE02 - 1]); 212 213 for (i = SIZE01 - 1; i >= 0; i--) { 214 WORD32 tmp1_cur = *current_tmp1--; 215 WORD32 tmp2_cur = *current_tmp2++; 216 WORD16 short1 = *short_ptr--; 217 WORD16 short2 = *short_ptr--; 218 accu = ixheaacd_sub32_sat( 219 ixheaacd_shl32_dir_sat_limit((ixheaacd_mult32x16in32(tmp1_cur, short2) - 220 ixheaacd_mult32x16in32(tmp2_cur, short1)), 221 q_shift), 222 ixheaacd_mult32x16in32_drc(prev[i], long_window_prev[0 - 2 - 2 * i])); 223 out[ch_fac * (0 + i)] = ixheaacd_round16(accu << 2); 224 225 if (flag) { 226 accu = ixheaacd_sub32_sat( 227 ixheaacd_shl32_dir_sat_limit( 228 (ixheaacd_mult32x16in32(-(tmp1_cur), short1) - 229 ixheaacd_mult32x16in32(tmp2_cur, short2)), 230 q_shift), 231 ixheaacd_mult32x16in32_drc(prev[SIZE02 - 1 - i], 232 long_window_prev[-2 * SIZE02 + 2 * i])); 233 out[ch_fac * (SIZE02 - 1 - i)] = ixheaacd_round16(accu << 2); 234 } 235 } 236 } 237 238 VOID ixheaacd_long_short_win_seq(WORD32 *current, WORD32 *prev, WORD16 *out, 239 const WORD16 *short_window, 240 const WORD16 *short_window_prev, 241 const WORD16 *long_window_prev, WORD16 q_shift, 242 WORD16 ch_fac) { 243 WORD32 i, flag; 244 WORD32 accu; 245 for (i = 0; i < SIZE07; i++) { 246 accu = ixheaacd_mult32x16in32_drc( 247 prev[SIZE08 - 1 - i], ixheaacd_negate16(long_window_prev[2 * i + 1])); 248 out[ch_fac * i] = ixheaacd_round16(accu << 2); 249 } 250 251 for (i = 0; i < SIZE01; i++) { 252 accu = ixheaacd_sub32_sat( 253 ixheaacd_shl32_dir_sat_limit( 254 ixheaacd_mult32x16in32(current[SIZE01 + i], 255 short_window_prev[2 * i]), 256 q_shift), 257 ixheaacd_mult32x16in32_drc(prev[SIZE01 - 1 - i], 258 long_window_prev[2 * SIZE07 + 1 + 2 * i])); 259 out[ch_fac * (SIZE07 + i)] = ixheaacd_round16(accu << 2); 260 } 261 262 for (i = 0; i < SIZE01; i++) { 263 accu = ixheaacd_sub32_sat( 264 ixheaacd_shl32_dir_sat_limit( 265 ixheaacd_mult32x16in32(-(current[SIZE02 - 1 - i]), 266 short_window_prev[SIZE02 - 2 * i - 1]), 267 q_shift), 268 ixheaacd_mult32x16in32_drc(prev[i], 269 long_window_prev[SIZE16 - 2 - (2 * i)])); 270 out[ch_fac * (SIZE08 + i)] = ixheaacd_round16(accu << 2); 271 } 272 273 flag = 1; 274 for (i = 0; i < 4; i++) { 275 WORD32 inc = i * SIZE02; 276 277 if (i == 3) { 278 flag = 0; 279 } 280 281 ixheaacd_long_short_win_process(¤t[SIZE01 + inc], &prev[SIZE01 + inc], 282 &out[ch_fac * (SIZE09 + inc)], short_window, 283 &long_window_prev[2 * (SIZE07 - inc)], 284 q_shift, ch_fac, flag); 285 } 286 287 for (i = 0; i < SIZE01; i++) { 288 accu = (ixheaacd_mult32x16in32(-(current[SIZE10 - 1 - i]), 289 short_window[SIZE02 - 2 * i - 1]) - 290 ixheaacd_mult32x16in32(current[SIZE06 + i], 291 short_window[SIZE02 - 2 * i - 2])); 292 prev[i] = 293 ixheaacd_round16(ixheaacd_shl32_dir_sat_limit(accu, (q_shift + 1))); 294 } 295 } 296 297 VOID ixheaacd_nolap1_32(WORD32 *coef, 298 299 WORD32 *out, 300 301 WORD16 q_shift, WORD16 ch_fac) { 302 WORD32 i; 303 304 for (i = 0; i < SIZE07; i++) { 305 out[ch_fac * i] = ixheaacd_shr32_drc( 306 ixheaacd_negate32_sat(coef[SIZE07 - 1 - i]), 16 - q_shift); 307 } 308 } 309 310 VOID ixheaacd_neg_shift_spec_dec(WORD32 *coef, WORD16 *out, WORD16 q_shift, 311 WORD16 ch_fac) { 312 WORD32 i; 313 314 for (i = 0; i < SIZE07; i++) { 315 out[ch_fac * i] = ixheaacd_round16(ixheaacd_shl32_dir_sat_limit( 316 ixheaacd_negate32_sat(coef[SIZE07 - 1 - i]), q_shift)); 317 } 318 } 319 320 VOID ixheaacd_spec_to_overlapbuf_dec(WORD32 *ptr_overlap_buf, 321 WORD32 *ptr_spec_coeff, WORD32 q_shift, 322 WORD32 size) { 323 WORD32 i; 324 for (i = 0; i < size; i++) { 325 ptr_overlap_buf[i] = ixheaacd_shr32_drc(ptr_spec_coeff[i], 16 - q_shift); 326 } 327 } 328 329 VOID ixheaacd_overlap_buf_out_dec(WORD16 *out_samples, WORD32 *ptr_overlap_buf, 330 WORD32 size, const WORD16 ch_fac) { 331 WORD32 i; 332 333 for (i = 0; i < size; i++) { 334 out_samples[ch_fac * i] = ixheaacd_shl16_sat((WORD16)ptr_overlap_buf[i], 1); 335 } 336 } 337 338 VOID ixheaacd_overlap_out_copy_dec(WORD16 *out_samples, WORD32 *ptr_overlap_buf, 339 WORD32 *ptr_overlap_buf1, 340 const WORD16 ch_fac) { 341 WORD32 i; 342 343 for (i = 0; i < SIZE01; i++) { 344 out_samples[ch_fac * i] = ixheaacd_shl16_sat((WORD16)ptr_overlap_buf[i], 1); 345 ptr_overlap_buf[i] = ptr_overlap_buf1[i]; 346 } 347 } 348 349 VOID ixheaacd_imdct_process(ia_aac_dec_overlap_info *ptr_aac_dec_overlap_info, 350 WORD32 *ptr_spec_coeff, 351 ia_ics_info_struct *ptr_ics_info, 352 WORD16 out_samples[], const WORD16 ch_fac, 353 WORD32 *scratch, 354 ia_aac_dec_tables_struct *ptr_aac_tables, 355 WORD32 object_type) { 356 WORD32 *ptr_overlap_buf; 357 const WORD16 *ptr_long_window; 358 const WORD16 *ptr_short_window; 359 360 ptr_overlap_buf = ptr_aac_dec_overlap_info->ptr_overlap_buf; 361 ptr_long_window = 362 ptr_aac_dec_overlap_info 363 ->ptr_long_window[(WORD32)ptr_aac_dec_overlap_info->window_shape]; 364 ptr_short_window = 365 ptr_aac_dec_overlap_info 366 ->ptr_short_window[(WORD32)ptr_aac_dec_overlap_info->window_shape]; 367 368 if (ptr_ics_info->window_sequence != EIGHT_SHORT_SEQUENCE) { 369 WORD16 q_shift; 370 WORD32 expo, imdct_scale; 371 372 if ((512 == ptr_ics_info->frame_length) || 373 (480 == ptr_ics_info->frame_length)) { 374 if (512 == ptr_ics_info->frame_length) { 375 WORD32 *ld_cos_sin_ptr = 376 (WORD32 *)ptr_aac_tables->pstr_imdct_tables->cosine_array_1024; 377 378 ixheaacd_inverse_transform_512( 379 ptr_spec_coeff, scratch, &imdct_scale, ld_cos_sin_ptr, 380 ptr_aac_tables->pstr_imdct_tables, object_type); 381 382 } else { 383 ixheaacd_mdct_480_ld(ptr_spec_coeff, scratch, &imdct_scale, 0, 384 ptr_aac_tables->pstr_imdct_tables, object_type); 385 } 386 387 if (object_type == AOT_ER_AAC_ELD) { 388 int i, N = (ptr_ics_info->frame_length << 1); 389 390 for (i = 0; i < N / 2; i++) { 391 ptr_spec_coeff[i] = -ptr_spec_coeff[i + N]; 392 ptr_spec_coeff[i + N + N / 2] = -ptr_spec_coeff[i + N / 2]; 393 } 394 } 395 } else 396 397 { 398 expo = (*ixheaacd_calc_max_spectral_line)(ptr_spec_coeff, 1024) - 1; 399 400 expo = 8 - expo; 401 402 imdct_scale = ixheaacd_inverse_transform( 403 ptr_spec_coeff, scratch, ptr_aac_tables->pstr_imdct_tables, expo, 404 1024); 405 } 406 407 q_shift = (31 + imdct_scale) + (-1 - 16 - 9); 408 409 switch (ptr_ics_info->window_sequence) { 410 case ONLY_LONG_SEQUENCE: 411 412 switch (ptr_aac_dec_overlap_info->window_sequence) { 413 case ONLY_LONG_SEQUENCE: 414 case LONG_STOP_SEQUENCE: 415 416 if (1024 == ptr_ics_info->frame_length) { 417 ia_ics_info_struct *tmp_ptr_ics_info = ptr_ics_info; 418 (*ixheaacd_post_twid_overlap_add)( 419 out_samples, ptr_spec_coeff, 420 ptr_aac_tables->pstr_imdct_tables, 1024, ptr_overlap_buf, 421 q_shift, ptr_long_window, ch_fac); 422 ptr_ics_info = tmp_ptr_ics_info; 423 } 424 if ((512 == ptr_ics_info->frame_length) || 425 (480 == ptr_ics_info->frame_length)) { 426 if (object_type != AOT_ER_AAC_ELD) { 427 if (512 == ptr_ics_info->frame_length) { 428 ixheaacd_lap1_512_480(ptr_spec_coeff, ptr_overlap_buf, 429 out_samples, ptr_long_window, q_shift, 430 SIZE04, ch_fac); 431 ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff, 432 q_shift, SIZE04); 433 } else if (480 == ptr_ics_info->frame_length) { 434 ixheaacd_lap1_512_480(ptr_spec_coeff, ptr_overlap_buf, 435 out_samples, ptr_long_window, q_shift, 436 240, ch_fac); 437 ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff, 438 q_shift, 240); 439 } 440 } else { 441 ixheaacd_eld_dec_windowing( 442 ptr_spec_coeff, ptr_long_window, ptr_ics_info->frame_length, 443 q_shift, ptr_overlap_buf, ch_fac, out_samples); 444 } 445 } 446 break; 447 448 case LONG_START_SEQUENCE: 449 case EIGHT_SHORT_SEQUENCE: 450 if (1024 == ptr_ics_info->frame_length) { 451 (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff, 452 ptr_aac_tables->pstr_imdct_tables, 1024); 453 } 454 455 ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples, 456 ptr_long_window, ptr_short_window, q_shift, 457 ch_fac, 1); 458 459 if (512 == ptr_ics_info->frame_length) { 460 ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff, 461 q_shift, SIZE04); 462 } else if (480 == ptr_ics_info->frame_length) { 463 ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff, 464 q_shift, 240); 465 } else { 466 (*ixheaacd_spec_to_overlapbuf)(ptr_overlap_buf, scratch, q_shift, 467 SIZE08); 468 } 469 break; 470 } 471 472 break; 473 474 case LONG_START_SEQUENCE: 475 if (1024 == ptr_ics_info->frame_length) { 476 (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff, 477 ptr_aac_tables->pstr_imdct_tables, 1024); 478 } 479 switch (ptr_aac_dec_overlap_info->window_sequence) { 480 case ONLY_LONG_SEQUENCE: 481 case LONG_STOP_SEQUENCE: 482 483 (*ixheaacd_over_lap_add1)(scratch, ptr_overlap_buf, out_samples, 484 ptr_long_window, q_shift, SIZE08, ch_fac); 485 486 break; 487 488 case LONG_START_SEQUENCE: 489 case EIGHT_SHORT_SEQUENCE: 490 491 ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples, 492 ptr_long_window, ptr_short_window, q_shift, 493 ch_fac, 1); 494 495 break; 496 } 497 498 ixheaacd_nolap1_32(&scratch[SIZE01], ptr_overlap_buf, q_shift, 1); 499 500 (*ixheaacd_spec_to_overlapbuf)(&ptr_overlap_buf[SIZE07], scratch, 501 q_shift, SIZE01); 502 503 break; 504 505 case LONG_STOP_SEQUENCE: 506 if (1024 == ptr_ics_info->frame_length) { 507 (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff, 508 ptr_aac_tables->pstr_imdct_tables, 1024); 509 } 510 511 switch (ptr_aac_dec_overlap_info->window_sequence) { 512 case EIGHT_SHORT_SEQUENCE: 513 case LONG_START_SEQUENCE: 514 515 (*ixheaacd_overlap_buf_out)(out_samples, ptr_overlap_buf, SIZE07, 516 ch_fac); 517 518 (*ixheaacd_over_lap_add1)( 519 &scratch[SIZE14], &ptr_overlap_buf[SIZE07], 520 &out_samples[ch_fac * (SIZE07)], ptr_short_window, q_shift, 521 SIZE01, ch_fac); 522 523 { 524 WORD16 q_shift1 = q_shift + 1; 525 (*ixheaacd_neg_shift_spec)(&scratch[SIZE08], 526 &out_samples[ch_fac * SIZE09], 527 q_shift1, ch_fac); 528 } 529 530 break; 531 case ONLY_LONG_SEQUENCE: 532 case LONG_STOP_SEQUENCE: 533 534 ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples, 535 ptr_long_window, ptr_short_window, q_shift, 536 ch_fac, 0); 537 break; 538 } 539 540 (*ixheaacd_spec_to_overlapbuf)(ptr_overlap_buf, scratch, q_shift, 541 SIZE08); 542 543 break; 544 } 545 546 } else { 547 WORD16 q_shift, max_scale; 548 WORD32 imdct_scale[8], i; 549 const WORD16 *short_window; 550 551 short_window = ptr_aac_dec_overlap_info 552 ->ptr_short_window[(WORD32)ptr_ics_info->window_shape]; 553 554 { 555 WORD32 expo; 556 557 expo = (*ixheaacd_calc_max_spectral_line)(ptr_spec_coeff, 1024) - 1; 558 559 expo = 5 - expo; 560 561 for (i = 0; i < MAX_WINDOWS; i++) { 562 imdct_scale[i] = ixheaacd_inverse_transform( 563 &ptr_spec_coeff[i * SIZE02], &scratch[i * SIZE02], 564 ptr_aac_tables->pstr_imdct_tables, expo, 128); 565 566 (*ixheaacd_post_twiddle)(&scratch[i * SIZE02], 567 &ptr_spec_coeff[i * SIZE02], 568 ptr_aac_tables->pstr_imdct_tables, 128); 569 } 570 } 571 572 max_scale = 31 + imdct_scale[0]; 573 574 q_shift = max_scale + (-16 - 6 - 1); 575 576 switch (ptr_aac_dec_overlap_info->window_sequence) { 577 WORD32 overlap_buf_loc[SIZE01]; 578 579 case EIGHT_SHORT_SEQUENCE: 580 case LONG_START_SEQUENCE: 581 582 (*ixheaacd_overlap_buf_out)(out_samples, ptr_overlap_buf, SIZE07, 583 ch_fac); 584 585 (*ixheaacd_over_lap_add1)(&scratch[0], &ptr_overlap_buf[SIZE07], 586 &out_samples[ch_fac * SIZE07], 587 ptr_short_window, q_shift, SIZE01, ch_fac); 588 589 for (i = 0; i < 3; i++) { 590 WORD32 inc = (i * SIZE02); 591 (*ixheaacd_spec_to_overlapbuf)(overlap_buf_loc, &scratch[inc], 592 q_shift, SIZE01); 593 594 (*ixheaacd_over_lap_add1)(&scratch[SIZE02 + inc], overlap_buf_loc, 595 &out_samples[ch_fac * (SIZE09 + inc)], 596 short_window, q_shift, SIZE01, ch_fac); 597 } 598 599 (*ixheaacd_over_lap_add2)(&scratch[SIZE08], &scratch[SIZE06], 600 ptr_overlap_buf, short_window, q_shift, 601 SIZE01, 1); 602 603 (*ixheaacd_overlap_out_copy)(&out_samples[ch_fac * SIZE15], 604 ptr_overlap_buf, &ptr_overlap_buf[SIZE01], 605 ch_fac); 606 607 break; 608 609 case ONLY_LONG_SEQUENCE: 610 case LONG_STOP_SEQUENCE: 611 612 ixheaacd_long_short_win_seq(scratch, ptr_overlap_buf, out_samples, 613 short_window, ptr_short_window, 614 ptr_long_window, q_shift, ch_fac); 615 616 break; 617 } 618 619 for (i = 0; i < 3; i++) { 620 WORD32 inc = (i * SIZE02); 621 (*ixheaacd_over_lap_add2)(&scratch[SIZE10 + inc], &scratch[SIZE08 + inc], 622 &ptr_overlap_buf[SIZE01 + inc], short_window, 623 q_shift, SIZE01, 1); 624 } 625 626 (*ixheaacd_spec_to_overlapbuf)(&ptr_overlap_buf[SIZE07], &scratch[SIZE14], 627 q_shift, SIZE01); 628 } 629 630 ptr_aac_dec_overlap_info->window_shape = ptr_ics_info->window_shape; 631 ptr_aac_dec_overlap_info->window_sequence = ptr_ics_info->window_sequence; 632 } 633 void ixheaacd_eld_dec_windowing(WORD32 *ptr_spect_coeff, const WORD16 *p_win, 634 WORD32 framesize, WORD16 q_shift, 635 WORD32 *p_overlap_buffer, const WORD16 stride, 636 WORD16 *out_samples) 637 638 { 639 int i = 0; 640 int loop_size; 641 WORD32 *ptr_z = ptr_spect_coeff; 642 643 WORD32 *ptr_out, *p_out2; 644 WORD32 *p_overlap_buffer32 = (WORD32 *)p_overlap_buffer; 645 WORD32 delay = framesize >> 2; 646 647 ptr_z = ptr_spect_coeff + delay; 648 p_win += delay; 649 ptr_out = p_overlap_buffer32; 650 651 q_shift = q_shift + 2; 652 653 if (q_shift >= 0) { 654 for (i = (delay)-1; i >= 0; i--) { 655 WORD32 win_op; 656 WORD32 win_ovadd_op; 657 WORD16 win_val; 658 659 win_val = *p_win++; 660 661 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 662 663 win_ovadd_op = 664 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 665 666 *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1)); 667 out_samples += stride; 668 669 win_val = *p_win++; 670 671 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 672 673 win_ovadd_op = 674 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 675 676 *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1)); 677 out_samples += stride; 678 win_val = *p_win++; 679 680 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 681 682 win_ovadd_op = 683 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 684 685 *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1)); 686 out_samples += stride; 687 688 win_val = *p_win++; 689 690 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 691 692 win_ovadd_op = 693 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 694 695 *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1)); 696 out_samples += stride; 697 } 698 699 p_out2 = p_overlap_buffer32; 700 loop_size = (((framesize * 3) - framesize) >> 2) - 1; 701 702 for (i = loop_size; i >= 0; i--) { 703 WORD32 win_op; 704 WORD16 win_val; 705 win_val = *p_win++; 706 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 707 *p_out2++ = 708 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 709 710 win_val = *p_win++; 711 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 712 *p_out2++ = 713 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 714 715 win_val = *p_win++; 716 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 717 *p_out2++ = 718 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 719 720 win_val = *p_win++; 721 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 722 *p_out2++ = 723 ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++); 724 } 725 726 loop_size = ((((framesize << 2) - delay) - (framesize * 3)) >> 2) - 1; 727 for (i = loop_size; i >= 0; i--) { 728 WORD32 win_op; 729 WORD16 win_val; 730 731 win_val = *p_win++; 732 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 733 *p_out2++ = ixheaacd_shl32(win_op, q_shift); 734 735 win_val = *p_win++; 736 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 737 *p_out2++ = ixheaacd_shl32(win_op, q_shift); 738 739 win_val = *p_win++; 740 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 741 *p_out2++ = ixheaacd_shl32(win_op, q_shift); 742 743 win_val = *p_win++; 744 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 745 *p_out2++ = ixheaacd_shl32(win_op, q_shift); 746 } 747 } else { 748 q_shift = -q_shift; 749 750 for (i = (delay)-1; i >= 0; i--) { 751 WORD32 win_op; 752 WORD32 win_ovadd_op; 753 WORD16 win_val; 754 755 win_val = *p_win++; 756 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 757 758 win_ovadd_op = 759 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 760 761 *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1)); 762 out_samples += stride; 763 764 win_val = *p_win++; 765 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 766 767 win_ovadd_op = 768 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 769 770 *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1)); 771 out_samples += stride; 772 773 win_val = *p_win++; 774 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 775 776 win_ovadd_op = 777 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 778 779 *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1)); 780 out_samples += stride; 781 782 win_val = *p_win++; 783 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 784 785 win_ovadd_op = 786 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 787 788 *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1)); 789 out_samples += stride; 790 } 791 792 p_out2 = p_overlap_buffer32; 793 loop_size = (((framesize * 3) - framesize) >> 2) - 1; 794 795 for (i = loop_size; i >= 0; i--) { 796 WORD32 win_op; 797 WORD16 win_val; 798 win_val = *p_win++; 799 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 800 *p_out2++ = 801 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 802 803 win_val = *p_win++; 804 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 805 *p_out2++ = 806 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 807 808 win_val = *p_win++; 809 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 810 *p_out2++ = 811 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 812 813 win_val = *p_win++; 814 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 815 *p_out2++ = 816 ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++); 817 } 818 loop_size = ((((framesize << 2) - delay) - (framesize * 3)) >> 2) - 1; 819 for (i = loop_size; i >= 0; i--) { 820 WORD32 win_op; 821 WORD16 win_val; 822 win_val = *p_win++; 823 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 824 *p_out2++ = ixheaacd_shr32(win_op, q_shift); 825 826 win_val = *p_win++; 827 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 828 *p_out2++ = ixheaacd_shr32(win_op, q_shift); 829 830 win_val = *p_win++; 831 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 832 *p_out2++ = ixheaacd_shr32(win_op, q_shift); 833 834 win_val = *p_win++; 835 win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val)); 836 *p_out2++ = ixheaacd_shr32(win_op, q_shift); 837 } 838 } 839 } 840