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 22 #include "ixheaacd_sbr_common.h" 23 #include <ixheaacd_type_def.h> 24 25 #include "ixheaacd_constants.h" 26 #include "ixheaacd_basic_ops32.h" 27 #include "ixheaacd_basic_ops16.h" 28 #include "ixheaacd_basic_ops40.h" 29 #include "ixheaacd_basic_ops.h" 30 31 #include "ixheaacd_intrinsics.h" 32 #include "ixheaacd_common_rom.h" 33 #include "ixheaacd_bitbuffer.h" 34 #include "ixheaacd_sbrdecsettings.h" 35 #include "ixheaacd_sbr_scale.h" 36 #include "ixheaacd_lpp_tran.h" 37 #include "ixheaacd_env_extr_part.h" 38 #include "ixheaacd_sbr_rom.h" 39 #include "ixheaacd_hybrid.h" 40 #include "ixheaacd_ps_dec.h" 41 #include "ixheaacd_env_extr.h" 42 #include "ixheaacd_qmf_dec.h" 43 44 #include <ixheaacd_basic_op.h> 45 #include "ixheaacd_env_calc.h" 46 47 #include "ixheaacd_interface.h" 48 49 #include "ixheaacd_function_selector.h" 50 #include "ixheaacd_audioobjtypes.h" 51 52 #define DCT3_LEN (32) 53 #define DCT2_LEN (64) 54 55 #define LP_SHIFT_VAL 7 56 #define HQ_SHIFT_64 4 57 #define RADIXSHIFT 1 58 #define ROUNDING_SPECTRA 1 59 #define HQ_SHIFT_VAL 4 60 61 static PLATFORM_INLINE WORD32 ixheaacd_mult32x32in32_shift25(WORD32 a, 62 WORD32 b) { 63 WORD32 result; 64 WORD64 temp_result; 65 66 temp_result = (WORD64)a * (WORD64)b; 67 68 result = (WORD32)(temp_result >> 25); 69 70 return (result); 71 } 72 73 VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd) { 74 WORD32 n; 75 WORD32 *out_rev = out_fwd + DCT2_LEN - 1; 76 77 for (n = 0; n < DCT2_LEN / 2; n++) { 78 *out_fwd = *inp; 79 inp++; 80 *out_rev = *inp; 81 out_fwd++; 82 83 out_rev--; 84 inp++; 85 } 86 87 return; 88 } 89 90 static PLATFORM_INLINE VOID ixheaacd_pretwdct2_32(WORD32 *inp, WORD32 *out_fwd, 91 int dct2_len) { 92 WORD32 n; 93 94 WORD32 *out_rev = out_fwd + dct2_len - 1; 95 for (n = dct2_len / 2 - 1; n >= 0; n--) { 96 *out_fwd = *inp; 97 inp++; 98 *out_rev = *inp; 99 out_fwd++; 100 101 out_rev--; 102 inp++; 103 } 104 105 return; 106 } 107 108 VOID ixheaacd_fftposttw(WORD32 *out, 109 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 110 int k; 111 WORD32 *p_out_fwd, *ptr_out_rev; 112 const WORD16 *twidle_fwd, *twidle_rev; 113 WORD32 in1, in2, val1, val2; 114 115 twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 1; 116 twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 15; 117 118 p_out_fwd = out; 119 ptr_out_rev = out + DCT2_LEN - 1; 120 121 in1 = ((*p_out_fwd++) << 1); 122 val1 = ((*p_out_fwd--) << 1); 123 124 *p_out_fwd++ = in1; 125 *p_out_fwd++ = val1; 126 127 for (k = 1; k <= DCT2_LEN / 4; k++) { 128 WORD32 temp[4]; 129 WORD16 twid_re, twid_im; 130 131 temp[0] = *p_out_fwd++; 132 temp[1] = *p_out_fwd--; 133 temp[3] = *ptr_out_rev--; 134 temp[2] = *ptr_out_rev++; 135 136 in2 = temp[3] - temp[1]; 137 in1 = temp[3] + temp[1]; 138 139 temp[1] = temp[0] - temp[2]; 140 temp[3] = temp[0] + temp[2]; 141 142 twid_re = *twidle_fwd++; 143 twid_im = *twidle_rev--; 144 val1 = ixheaacd_mult32x16in32(in1, twid_re) - 145 ixheaacd_mult32x16in32(temp[1], twid_im); 146 val2 = ixheaacd_mult32x16in32(temp[1], twid_re) + 147 ixheaacd_mult32x16in32(in1, twid_im); 148 val1 = val1 << 1; 149 val2 = val2 << 1; 150 151 *p_out_fwd++ = temp[3] + val1; 152 *p_out_fwd++ = in2 + val2; 153 154 *ptr_out_rev-- = -in2 + val2; 155 *ptr_out_rev-- = temp[3] - val1; 156 } 157 158 return; 159 } 160 161 VOID ixheaacd_posttwdct2(WORD32 *inp, WORD16 *out_fwd, 162 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 163 WORD32 k; 164 WORD32 inp_re, inp_im, out_re, out_im, last_val, out_re1; 165 WORD16 *out_fwd2, *out_rev2, *out_rev; 166 WORD16 twid_re, twid_im; 167 const WORD16 *twidle_fwd; 168 WORD16 re1, im1, im2; 169 170 out_rev = out_fwd + DCT2_LEN - 1; 171 out_rev2 = out_fwd - 1; 172 out_fwd2 = out_fwd + 65; 173 out_re = *inp++; 174 out_im = *inp++; 175 out_re1 = (out_re + out_im) >> 1; 176 re1 = ixheaacd_round16(ixheaacd_shl32(out_re1, (5 - 1))); 177 178 *out_fwd++ = re1; 179 180 last_val = (out_re - out_im); 181 182 twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 2; 183 for (k = DCT2_LEN / 2 - 2; k >= 0; k--) { 184 inp_re = *inp++; 185 inp_im = *inp++; 186 187 twid_re = *twidle_fwd++; 188 twid_im = *twidle_fwd++; 189 out_re = ixheaacd_sub32(ixheaacd_mult32x16in32(inp_re, twid_re), 190 ixheaacd_mult32x16in32(inp_im, twid_im)); 191 out_im = ixheaacd_add32(ixheaacd_mult32x16in32(inp_im, twid_re), 192 ixheaacd_mult32x16in32(inp_re, twid_im)); 193 re1 = ixheaacd_round16(ixheaacd_shl32(out_re, (5 - 1))); 194 im1 = ixheaacd_round16(ixheaacd_shl32(out_im, (5 - 1))); 195 im2 = ixheaacd_negate16(im1); 196 197 *out_fwd++ = re1; 198 *out_rev2-- = re1; 199 *out_rev-- = im1; 200 *out_fwd2++ = im2; 201 } 202 twid_re = *twidle_fwd++; 203 204 out_re = ixheaacd_mult32x16in32(last_val, twid_re); 205 re1 = ixheaacd_round16(ixheaacd_shl32(out_re, (5 - 1))); 206 207 *out_fwd++ = re1; 208 *out_rev2-- = re1; 209 210 return; 211 } 212 213 static PLATFORM_INLINE VOID ixheaacd_fftposttw_32( 214 WORD32 *out, int dct2_len, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 215 int k; 216 WORD32 *ptr_out_fwd, *ptr_out_rev; 217 const WORD16 *twidle_fwd, *twidle_rev; 218 WORD32 in1, in2, val1, val2; 219 220 twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 2; 221 twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 14; 222 223 ptr_out_fwd = out; 224 ptr_out_rev = out + dct2_len - 1; 225 226 in1 = ((*ptr_out_fwd++) << 1); 227 val1 = ((*ptr_out_fwd--) << 1); 228 229 *ptr_out_fwd++ = in1; 230 *ptr_out_fwd++ = val1; 231 232 for (k = dct2_len / 4 - 1; k >= 0; k--) { 233 WORD32 temp0, temp1, temp2, temp3; 234 WORD16 twid_re, twid_im; 235 236 temp0 = *ptr_out_fwd++; 237 temp1 = *ptr_out_fwd--; 238 temp3 = *ptr_out_rev--; 239 temp2 = *ptr_out_rev++; 240 241 in1 = temp1 + temp3; 242 in2 = -temp1 + temp3; 243 244 temp1 = temp0 - temp2; 245 temp3 = temp0 + temp2; 246 247 twid_re = *twidle_fwd; 248 twidle_fwd += 2; 249 250 twid_im = *twidle_rev; 251 twidle_rev -= 2; 252 253 val1 = ixheaacd_mult32x16in32(in1, twid_re) - 254 ixheaacd_mult32x16in32(temp1, twid_im); 255 val2 = ixheaacd_mult32x16in32(temp1, twid_re) + 256 ixheaacd_mult32x16in32(in1, twid_im); 257 258 val1 = val1 << 1; 259 val2 = val2 << 1; 260 261 *ptr_out_fwd++ = temp3 + val1; 262 *ptr_out_fwd++ = in2 + val2; 263 264 *ptr_out_rev-- = -in2 + val2; 265 *ptr_out_rev-- = temp3 - val1; 266 } 267 268 return; 269 } 270 271 static PLATFORM_INLINE VOID 272 ixheaacd_posttwdct2_32(WORD32 *inp, WORD16 *out_fwd, 273 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 274 int k; 275 WORD32 inp_re, out_re, out_im, last_val, out_re1; 276 WORD16 *out_rev, *out_rev2, *out_fwd2; 277 WORD16 twid_re, twid_im; 278 const WORD16 *twidle_fwd; 279 WORD16 re1, im1, im2; 280 WORD32 rounding_fac = 0x8000; 281 282 out_rev = out_fwd + 32 - 1; 283 out_rev2 = out_fwd - 1; 284 out_fwd2 = out_fwd + 32 + 1; 285 out_fwd[32] = 0; 286 287 out_re = *inp++; 288 out_im = *inp++; 289 290 out_re1 = (out_re + out_im) >> 1; 291 re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re1, (5 - 1))); 292 *out_fwd++ = re1; 293 last_val = (out_re - out_im); 294 295 twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 4; 296 for (k = 14; k >= 0; k--) { 297 WORD32 temp1, temp2; 298 inp_re = *inp++; 299 twid_re = *twidle_fwd++; 300 twid_im = *twidle_fwd; 301 twidle_fwd += 3; 302 303 temp1 = ixheaacd_mult32x16in32(inp_re, twid_re); 304 temp2 = ixheaacd_mult32x16in32(inp_re, twid_im); 305 306 inp_re = *inp++; 307 308 out_re = ixheaacd_sub32(temp1, ixheaacd_mult32x16in32(inp_re, twid_im)); 309 out_im = ixheaacd_add32(ixheaacd_mult32x16in32(inp_re, twid_re), temp2); 310 311 out_re = ixheaacd_add32_sat(out_re, out_re); 312 out_im = ixheaacd_add32_sat(out_im, out_im); 313 out_re = ixheaacd_add32_sat(out_re, out_re); 314 out_im = ixheaacd_add32_sat(out_im, out_im); 315 out_re = ixheaacd_add32_sat(out_re, out_re); 316 out_im = ixheaacd_add32_sat(out_im, out_im); 317 out_re = ixheaacd_add32_sat(out_re, out_re); 318 out_im = ixheaacd_add32_sat(out_im, out_im); 319 out_re = ixheaacd_add32_sat(out_re, rounding_fac); 320 out_im = ixheaacd_add32_sat(out_im, rounding_fac); 321 re1 = (out_re >> 16); 322 im1 = (out_im >> 16); 323 im2 = ixheaacd_negate16(im1); 324 325 *out_fwd++ = re1; 326 *out_rev2-- = re1; 327 *out_rev-- = im1; 328 *out_fwd2++ = im2; 329 } 330 twid_re = *twidle_fwd++; 331 332 out_re = ixheaacd_mult32x16in32(last_val, twid_re); 333 re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re, (5 - 1))); 334 *out_fwd++ = re1; 335 *out_rev2-- = re1; 336 337 return; 338 } 339 340 VOID ixheaacd_dct2_32(WORD32 *inp, WORD32 *out, 341 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, 342 WORD16 *filter_states) { 343 WORD32 *output; 344 345 output = out + 16; 346 filter_states = filter_states + 16; 347 ixheaacd_pretwdct2_32(inp, output, 32); 348 349 ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_16, output, 1, 4); 350 ixheaacd_postradixcompute4(inp, output, qmf_dec_tables_ptr->dig_rev_table4_16, 351 16); 352 ixheaacd_fftposttw_32(inp, 32, qmf_dec_tables_ptr); 353 354 ixheaacd_posttwdct2_32(inp, filter_states, qmf_dec_tables_ptr); 355 356 return; 357 } 358 359 VOID ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 *inp1, WORD16 *inp2, 360 WORD16 *p_qmf1, WORD16 *p_qmf2, 361 WORD32 *p_out) { 362 WORD32 n; 363 364 for (n = 0; n < 32; n += 2) { 365 WORD32 accu; 366 accu = ixheaacd_mult16x16in32(inp1[n + 0], p_qmf1[(n + 0)]); 367 accu = ixheaacd_add32( 368 accu, ixheaacd_mult16x16in32(inp1[n + 64], p_qmf1[(n + 64)])); 369 accu = ixheaacd_add32( 370 accu, ixheaacd_mult16x16in32(inp1[n + 128], p_qmf1[(n + 128)])); 371 accu = ixheaacd_add32( 372 accu, ixheaacd_mult16x16in32(inp1[n + 192], p_qmf1[(n + 192)])); 373 accu = ixheaacd_add32( 374 accu, ixheaacd_mult16x16in32(inp1[n + 256], p_qmf1[(n + 256)])); 375 p_out[n] = accu; 376 377 accu = ixheaacd_mult16x16in32(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]); 378 accu = ixheaacd_add32_sat( 379 accu, ixheaacd_mult16x16in32(inp1[n + 1 + 64], p_qmf1[(n + 1 + 64)])); 380 accu = ixheaacd_add32_sat( 381 accu, ixheaacd_mult16x16in32(inp1[n + 1 + 128], p_qmf1[(n + 1 + 128)])); 382 accu = ixheaacd_add32_sat( 383 accu, ixheaacd_mult16x16in32(inp1[n + 1 + 192], p_qmf1[(n + 1 + 192)])); 384 accu = ixheaacd_add32_sat( 385 accu, ixheaacd_mult16x16in32(inp1[n + 1 + 256], p_qmf1[(n + 1 + 256)])); 386 p_out[n + 1] = accu; 387 388 accu = ixheaacd_mult16x16in32(inp2[n + 0], p_qmf2[(n + 0)]); 389 accu = ixheaacd_add32( 390 accu, ixheaacd_mult16x16in32(inp2[n + 64], p_qmf2[(n + 64)])); 391 accu = ixheaacd_add32( 392 accu, ixheaacd_mult16x16in32(inp2[n + 128], p_qmf2[(n + 128)])); 393 accu = ixheaacd_add32( 394 accu, ixheaacd_mult16x16in32(inp2[n + 192], p_qmf2[(n + 192)])); 395 accu = ixheaacd_add32( 396 accu, ixheaacd_mult16x16in32(inp2[n + 256], p_qmf2[(n + 256)])); 397 p_out[n + 32] = accu; 398 399 accu = ixheaacd_mult16x16in32(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]); 400 accu = ixheaacd_add32_sat( 401 accu, ixheaacd_mult16x16in32(inp2[n + 1 + 64], p_qmf2[(n + 1 + 64)])); 402 accu = ixheaacd_add32_sat( 403 accu, ixheaacd_mult16x16in32(inp2[n + 1 + 128], p_qmf2[(n + 1 + 128)])); 404 accu = ixheaacd_add32_sat( 405 accu, ixheaacd_mult16x16in32(inp2[n + 1 + 192], p_qmf2[(n + 1 + 192)])); 406 accu = ixheaacd_add32_sat( 407 accu, ixheaacd_mult16x16in32(inp2[n + 1 + 256], p_qmf2[(n + 1 + 256)])); 408 p_out[n + 1 + 32] = accu; 409 } 410 } 411 412 VOID ixheaacd_esbr_qmfanal32_winadd(WORD32 *inp1, WORD32 *inp2, WORD32 *p_qmf1, 413 WORD32 *p_qmf2, WORD32 *p_out, 414 WORD32 num_band_anal_qmf) { 415 WORD32 n; 416 WORD64 accu; 417 418 if (num_band_anal_qmf == 32) { 419 for (n = 0; n < num_band_anal_qmf; n += 2) { 420 accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[2 * (n + 0)]); 421 accu = ixheaacd_add64( 422 accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf], 423 p_qmf1[2 * (n + 2 * num_band_anal_qmf)])); 424 accu = ixheaacd_add64( 425 accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf], 426 p_qmf1[2 * (n + 4 * num_band_anal_qmf)])); 427 accu = ixheaacd_add64( 428 accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf], 429 p_qmf1[2 * (n + 6 * num_band_anal_qmf)])); 430 accu = ixheaacd_add64( 431 accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf], 432 p_qmf1[2 * (n + 8 * num_band_anal_qmf)])); 433 p_out[n] = (WORD32)(accu >> 31); 434 435 accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[2 * (n + 1 + 0)]); 436 accu = ixheaacd_add64( 437 accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf], 438 p_qmf1[2 * (n + 1 + 2 * num_band_anal_qmf)])); 439 accu = ixheaacd_add64( 440 accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf], 441 p_qmf1[2 * (n + 1 + 4 * num_band_anal_qmf)])); 442 accu = ixheaacd_add64( 443 accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf], 444 p_qmf1[2 * (n + 1 + 6 * num_band_anal_qmf)])); 445 accu = ixheaacd_add64( 446 accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf], 447 p_qmf1[2 * (n + 1 + 8 * num_band_anal_qmf)])); 448 p_out[n + 1] = (WORD32)(accu >> 31); 449 450 accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[2 * (n + 0)]); 451 accu = ixheaacd_add64( 452 accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf], 453 p_qmf2[2 * (n + 2 * num_band_anal_qmf)])); 454 accu = ixheaacd_add64( 455 accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf], 456 p_qmf2[2 * (n + 4 * num_band_anal_qmf)])); 457 accu = ixheaacd_add64( 458 accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf], 459 p_qmf2[2 * (n + 6 * num_band_anal_qmf)])); 460 accu = ixheaacd_add64( 461 accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf], 462 p_qmf2[2 * (n + 8 * num_band_anal_qmf)])); 463 p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31); 464 465 accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[2 * (n + 1 + 0)]); 466 accu = ixheaacd_add64( 467 accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf], 468 p_qmf2[2 * (n + 1 + 2 * num_band_anal_qmf)])); 469 accu = ixheaacd_add64( 470 accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf], 471 p_qmf2[2 * (n + 1 + 4 * num_band_anal_qmf)])); 472 accu = ixheaacd_add64( 473 accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf], 474 p_qmf2[2 * (n + 1 + 6 * num_band_anal_qmf)])); 475 accu = ixheaacd_add64( 476 accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf], 477 p_qmf2[2 * (n + 1 + 8 * num_band_anal_qmf)])); 478 p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31); 479 } 480 } else if (num_band_anal_qmf == 24) { 481 for (n = 0; n < num_band_anal_qmf; n += 2) { 482 accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[(n + 0)]); 483 accu = ixheaacd_add64( 484 accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf], 485 p_qmf1[(n + 2 * num_band_anal_qmf)])); 486 accu = ixheaacd_add64( 487 accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf], 488 p_qmf1[(n + 4 * num_band_anal_qmf)])); 489 accu = ixheaacd_add64( 490 accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf], 491 p_qmf1[(n + 6 * num_band_anal_qmf)])); 492 accu = ixheaacd_add64( 493 accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf], 494 p_qmf1[(n + 8 * num_band_anal_qmf)])); 495 p_out[n] = (WORD32)(accu >> 31); 496 497 accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]); 498 accu = ixheaacd_add64( 499 accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf], 500 p_qmf1[(n + 1 + 2 * num_band_anal_qmf)])); 501 accu = ixheaacd_add64( 502 accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf], 503 p_qmf1[(n + 1 + 4 * num_band_anal_qmf)])); 504 accu = ixheaacd_add64( 505 accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf], 506 p_qmf1[(n + 1 + 6 * num_band_anal_qmf)])); 507 accu = ixheaacd_add64( 508 accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf], 509 p_qmf1[(n + 1 + 8 * num_band_anal_qmf)])); 510 p_out[n + 1] = (WORD32)(accu >> 31); 511 512 accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[(n + 0)]); 513 accu = ixheaacd_add64( 514 accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf], 515 p_qmf2[(n + 2 * num_band_anal_qmf)])); 516 accu = ixheaacd_add64( 517 accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf], 518 p_qmf2[(n + 4 * num_band_anal_qmf)])); 519 accu = ixheaacd_add64( 520 accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf], 521 p_qmf2[(n + 6 * num_band_anal_qmf)])); 522 accu = ixheaacd_add64( 523 accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf], 524 p_qmf2[(n + 8 * num_band_anal_qmf)])); 525 p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31); 526 527 accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]); 528 accu = ixheaacd_add64( 529 accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf], 530 p_qmf2[(n + 1 + 2 * num_band_anal_qmf)])); 531 accu = ixheaacd_add64( 532 accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf], 533 p_qmf2[(n + 1 + 4 * num_band_anal_qmf)])); 534 accu = ixheaacd_add64( 535 accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf], 536 p_qmf2[(n + 1 + 6 * num_band_anal_qmf)])); 537 accu = ixheaacd_add64( 538 accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf], 539 p_qmf2[(n + 1 + 8 * num_band_anal_qmf)])); 540 p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31); 541 } 542 543 } else { 544 for (n = 0; n < num_band_anal_qmf; n += 2) { 545 accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[4 * (n + 0)]); 546 accu = ixheaacd_add64( 547 accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf], 548 p_qmf1[4 * (n + 2 * num_band_anal_qmf)])); 549 accu = ixheaacd_add64( 550 accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf], 551 p_qmf1[4 * (n + 4 * num_band_anal_qmf)])); 552 accu = ixheaacd_add64( 553 accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf], 554 p_qmf1[4 * (n + 6 * num_band_anal_qmf)])); 555 accu = ixheaacd_add64( 556 accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf], 557 p_qmf1[4 * (n + 8 * num_band_anal_qmf)])); 558 p_out[n] = (WORD32)(accu >> 31); 559 560 accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[4 * (n + 1 + 0)]); 561 accu = ixheaacd_add64( 562 accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf], 563 p_qmf1[4 * (n + 1 + 2 * num_band_anal_qmf)])); 564 accu = ixheaacd_add64( 565 accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf], 566 p_qmf1[4 * (n + 1 + 4 * num_band_anal_qmf)])); 567 accu = ixheaacd_add64( 568 accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf], 569 p_qmf1[4 * (n + 1 + 6 * num_band_anal_qmf)])); 570 accu = ixheaacd_add64( 571 accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf], 572 p_qmf1[4 * (n + 1 + 8 * num_band_anal_qmf)])); 573 p_out[n + 1] = (WORD32)(accu >> 31); 574 575 accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[4 * (n + 0)]); 576 accu = ixheaacd_add64( 577 accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf], 578 p_qmf2[4 * (n + 2 * num_band_anal_qmf)])); 579 accu = ixheaacd_add64( 580 accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf], 581 p_qmf2[4 * (n + 4 * num_band_anal_qmf)])); 582 accu = ixheaacd_add64( 583 accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf], 584 p_qmf2[4 * (n + 6 * num_band_anal_qmf)])); 585 accu = ixheaacd_add64( 586 accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf], 587 p_qmf2[4 * (n + 8 * num_band_anal_qmf)])); 588 p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31); 589 590 accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[4 * (n + 1 + 0)]); 591 accu = ixheaacd_add64( 592 accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf], 593 p_qmf2[4 * (n + 1 + 2 * num_band_anal_qmf)])); 594 accu = ixheaacd_add64( 595 accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf], 596 p_qmf2[4 * (n + 1 + 4 * num_band_anal_qmf)])); 597 accu = ixheaacd_add64( 598 accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf], 599 p_qmf2[4 * (n + 1 + 6 * num_band_anal_qmf)])); 600 accu = ixheaacd_add64( 601 accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf], 602 p_qmf2[4 * (n + 1 + 8 * num_band_anal_qmf)])); 603 p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31); 604 } 605 } 606 } 607 608 VOID ixheaacd_esbr_inv_modulation( 609 WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, 610 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 611 ixheaacd_esbr_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->esbr_w_32, 612 qmf_dec_tables_ptr->dig_rev_table2_32); 613 } 614 615 VOID ixheaacd_sbr_qmfsyn32_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1, 616 WORD16 *sample_buffer, FLAG shift, 617 WORD32 ch_fac) { 618 WORD32 k; 619 WORD32 rounding_fac = 0x8000; 620 rounding_fac = rounding_fac >> shift; 621 622 for (k = 0; k < 32; k++) { 623 WORD32 syn_out = rounding_fac; 624 625 syn_out = ixheaacd_add32( 626 syn_out, ixheaacd_mult16x16in32(tmp1[0 + k], inp1[2 * (k + 0)])); 627 syn_out = ixheaacd_add32( 628 syn_out, ixheaacd_mult16x16in32(tmp1[128 + k], inp1[2 * (k + 64)])); 629 syn_out = ixheaacd_add32( 630 syn_out, ixheaacd_mult16x16in32(tmp1[256 + k], inp1[2 * (k + 128)])); 631 syn_out = ixheaacd_add32( 632 syn_out, ixheaacd_mult16x16in32(tmp1[384 + k], inp1[2 * (k + 192)])); 633 syn_out = ixheaacd_add32( 634 syn_out, ixheaacd_mult16x16in32(tmp1[512 + k], inp1[2 * (k + 256)])); 635 636 syn_out = ixheaacd_add32( 637 syn_out, ixheaacd_mult16x16in32(tmp2[64 + k], inp1[2 * (k + 32)])); 638 syn_out = ixheaacd_add32( 639 syn_out, ixheaacd_mult16x16in32(tmp2[192 + k], inp1[2 * (k + 96)])); 640 syn_out = ixheaacd_add32( 641 syn_out, ixheaacd_mult16x16in32(tmp2[320 + k], inp1[2 * (k + 160)])); 642 syn_out = ixheaacd_add32( 643 syn_out, ixheaacd_mult16x16in32(tmp2[448 + k], inp1[2 * (k + 224)])); 644 syn_out = ixheaacd_add32( 645 syn_out, ixheaacd_mult16x16in32(tmp2[576 + k], inp1[2 * (k + 288)])); 646 syn_out = ixheaacd_add32_sat(syn_out, syn_out); 647 if (shift == 2) { 648 syn_out = ixheaacd_add32_sat(syn_out, syn_out); 649 } 650 sample_buffer[ch_fac * k] = (syn_out >> 16); 651 } 652 } 653 654 void ixheaacd_sbr_pre_twiddle(WORD32 *p_xre, WORD32 *p_xim, 655 WORD16 *p_twiddles) { 656 int k; 657 658 for (k = 62; k >= 0; k--) { 659 WORD32 x_re = *p_xre; 660 WORD32 x_im = *p_xim; 661 662 WORD16 ixheaacd_cosine = *p_twiddles++; 663 WORD16 ixheaacd_sine = *p_twiddles++; 664 665 WORD32 re, im; 666 667 re = ixheaacd_mac32x16in32_shl( 668 ixheaacd_mult32x16in32_shl(x_re, ixheaacd_cosine), x_im, ixheaacd_sine); 669 im = ixheaacd_sub32(ixheaacd_mult32x16in32_shl(x_im, ixheaacd_cosine), 670 ixheaacd_mult32x16in32_shl(x_re, ixheaacd_sine)); 671 672 *p_xre++ = re; 673 *p_xim++ = im; 674 } 675 } 676 677 VOID ixheaacd_cplx_synt_qmffilt( 678 WORD32 **qmf_real, WORD32 **qmf_imag, WORD32 split, 679 ia_sbr_scale_fact_struct *sbr_scale_factor, WORD16 *time_out, 680 ia_sbr_qmf_filter_bank_struct *qmf_bank, ia_ps_dec_struct *ptr_ps_dec, 681 FLAG active, FLAG low_pow_flag, ia_sbr_tables_struct *sbr_tables_ptr, 682 ixheaacd_misc_tables *pstr_common_tables, WORD32 ch_fac, FLAG drc_on, 683 WORD32 drc_sbr_factors[][64], WORD32 audio_object_type) { 684 WORD32 i; 685 686 WORD32 code_scale_factor; 687 WORD32 scale_factor; 688 WORD32 out_scale_factor; 689 WORD32 low_band_scale_factor; 690 WORD32 high_band_scale_factor; 691 WORD16 *filter_states = qmf_bank->filter_states; 692 WORD32 **ptr_qmf_imag_temp; 693 WORD32 qmf_real2[2 * NO_SYNTHESIS_CHANNELS]; 694 695 WORD32 no_synthesis_channels = qmf_bank->no_channels; 696 WORD32 p1; 697 698 WORD16 *fp1; 699 WORD16 *fp2; 700 701 WORD32 sixty4 = NO_SYNTHESIS_CHANNELS; 702 WORD32 thirty2 = qmf_bank->no_channels; 703 704 WORD16 *filter_coeff; 705 WORD32 num_time_slots = qmf_bank->num_time_slots; 706 WORD32 ixheaacd_drc_offset; 707 WORD32 ov_lb_scale = sbr_scale_factor->ov_lb_scale; 708 WORD32 lb_scale = sbr_scale_factor->lb_scale; 709 WORD32 st_syn_scale = sbr_scale_factor->st_syn_scale; 710 WORD32 ov_lb_shift, lb_shift, hb_shift; 711 712 WORD32 *qmf_real_tmp = qmf_real2; 713 WORD32 *qmf_imag_tmp = &qmf_real2[NO_SYNTHESIS_CHANNELS]; 714 WORD32 env = 0; 715 716 WORD32 common_shift; 717 718 if (no_synthesis_channels == 32) { 719 qmf_bank->cos_twiddle = 720 (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32; 721 qmf_bank->alt_sin_twiddle = 722 (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32; 723 qmf_bank->t_cos = 724 (WORD16 *) 725 sbr_tables_ptr->qmf_dec_tables_ptr->sbr_cos_sin_twiddle_ds_l32; 726 } else { 727 qmf_bank->cos_twiddle = 728 (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l64; 729 qmf_bank->alt_sin_twiddle = 730 (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l64; 731 } 732 if (audio_object_type != AOT_ER_AAC_ELD && 733 audio_object_type != AOT_ER_AAC_LD) { 734 qmf_bank->filter_pos_syn += 735 (sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c - qmf_bank->p_filter); 736 qmf_bank->p_filter = sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c; 737 } else { 738 qmf_bank->filter_pos_syn += 739 (sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c_eld - qmf_bank->p_filter); 740 qmf_bank->p_filter = sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c_eld; 741 } 742 743 fp1 = &filter_states[0]; 744 fp2 = fp1 + no_synthesis_channels; 745 746 if (audio_object_type == AOT_ER_AAC_ELD || 747 audio_object_type == AOT_ER_AAC_LD) { 748 fp1 = qmf_bank->fp1_syn; 749 fp2 = qmf_bank->fp2_syn; 750 sixty4 = qmf_bank->sixty4; 751 } 752 753 filter_coeff = qmf_bank->filter_pos_syn; 754 755 if (active) { 756 code_scale_factor = scale_factor = sbr_scale_factor->ps_scale; 757 } else { 758 code_scale_factor = ixheaacd_min32(lb_scale, ov_lb_scale); 759 scale_factor = sbr_scale_factor->hb_scale; 760 } 761 762 low_band_scale_factor = (st_syn_scale - code_scale_factor); 763 high_band_scale_factor = (st_syn_scale - scale_factor); 764 765 p1 = 0; 766 767 if (low_pow_flag) 768 769 { 770 ov_lb_shift = (st_syn_scale - ov_lb_scale) - 4; 771 lb_shift = (st_syn_scale - lb_scale) - 4; 772 hb_shift = high_band_scale_factor - 4; 773 out_scale_factor = -((sbr_scale_factor->st_syn_scale - 1)); 774 ptr_qmf_imag_temp = 0; 775 776 } 777 778 else { 779 out_scale_factor = -((sbr_scale_factor->st_syn_scale - 3)); 780 if (active) { 781 ov_lb_shift = (sbr_scale_factor->ps_scale - ov_lb_scale); 782 lb_shift = (sbr_scale_factor->ps_scale - lb_scale); 783 hb_shift = (sbr_scale_factor->ps_scale - sbr_scale_factor->hb_scale); 784 common_shift = low_band_scale_factor - 8; 785 786 } else { 787 if (audio_object_type != AOT_ER_AAC_ELD && 788 audio_object_type != AOT_ER_AAC_LD) { 789 ov_lb_shift = (st_syn_scale - ov_lb_scale) - 8; 790 lb_shift = (st_syn_scale - lb_scale) - 8; 791 hb_shift = high_band_scale_factor - 8; 792 } else { 793 ov_lb_shift = (st_syn_scale - ov_lb_scale) - 7; 794 lb_shift = (st_syn_scale - lb_scale) - 7; 795 hb_shift = high_band_scale_factor - 7; 796 } 797 common_shift = 0; 798 } 799 ptr_qmf_imag_temp = qmf_imag; 800 } 801 802 { 803 if (ov_lb_shift == lb_shift) { 804 (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 0, 805 num_time_slots, ov_lb_shift, low_pow_flag); 806 807 } else { 808 (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 0, 809 split, ov_lb_shift, low_pow_flag); 810 811 (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 812 split, num_time_slots, lb_shift, low_pow_flag); 813 } 814 815 (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, qmf_bank->lsb, 816 qmf_bank->usb, 0, num_time_slots, hb_shift, 817 low_pow_flag); 818 } 819 820 ixheaacd_drc_offset = qmf_bank->ixheaacd_drc_offset; 821 822 if (1 == drc_on) { 823 for (i = 0; i < num_time_slots; i++) { 824 WORD32 loop_val; 825 for (loop_val = 0; loop_val < 64; loop_val++) { 826 qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25( 827 qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]); 828 } 829 } 830 } 831 832 if (low_pow_flag) 833 834 { 835 WORD16 *fptemp; 836 837 VOID(*sbr_qmf_syn_winadd) 838 (WORD16 *, WORD16 *, WORD16 *, WORD16 *, FLAG, WORD32); 839 ia_qmf_dec_tables_struct *qmf_tab_ptr = sbr_tables_ptr->qmf_dec_tables_ptr; 840 841 if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED) 842 sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn32_winadd; 843 else 844 sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn64_winadd; 845 846 for (i = 0; i < num_time_slots; i++) { 847 ixheaacd_inv_modulation_lp(qmf_real[i], 848 &filter_states[ixheaacd_drc_offset], qmf_bank, 849 qmf_tab_ptr); 850 851 sbr_qmf_syn_winadd(fp1, fp2, filter_coeff, &time_out[ch_fac * p1], 2, 852 ch_fac); 853 854 ixheaacd_drc_offset -= no_synthesis_channels << 1; 855 856 if (ixheaacd_drc_offset < 0) 857 ixheaacd_drc_offset += ((no_synthesis_channels << 1) * 10); 858 859 fptemp = fp1; 860 fp1 = fp2; 861 fp2 = fptemp; 862 863 filter_coeff += 64; 864 865 if (filter_coeff == qmf_bank->p_filter + 640) 866 filter_coeff = (WORD16 *)qmf_bank->p_filter; 867 868 p1 += no_synthesis_channels; 869 } 870 871 } else { 872 for (i = 0; i < num_time_slots; i++) { 873 WORD32 *t_qmf_imag; 874 t_qmf_imag = qmf_imag[i]; 875 876 if (active) { 877 if (i == ptr_ps_dec->border_position[env]) { 878 ixheaacd_init_rot_env(ptr_ps_dec, (WORD16)env, qmf_bank->usb, 879 sbr_tables_ptr, pstr_common_tables->trig_data); 880 env++; 881 } 882 883 ixheaacd_apply_ps(ptr_ps_dec, &qmf_real[i], &qmf_imag[i], qmf_real_tmp, 884 qmf_imag_tmp, sbr_scale_factor, (WORD16)i, 885 sbr_tables_ptr); 886 } 887 if (1 == drc_on) { 888 WORD32 loop_val; 889 for (loop_val = 0; loop_val < 64; loop_val++) { 890 qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25( 891 qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]); 892 } 893 } 894 895 if (active) { 896 if (common_shift) 897 ixheaacd_shiftrountine(qmf_real[i], t_qmf_imag, no_synthesis_channels, 898 common_shift); 899 } 900 901 if (audio_object_type == AOT_ER_AAC_ELD || 902 audio_object_type == AOT_ER_AAC_LD) 903 ixheaacd_sbr_pre_twiddle( 904 qmf_real[i], t_qmf_imag, 905 sbr_tables_ptr->qmf_dec_tables_ptr->ixheaacd_sbr_synth_cos_sin_l32); 906 907 ixheaacd_inv_emodulation(qmf_real[i], qmf_bank, 908 sbr_tables_ptr->qmf_dec_tables_ptr); 909 910 { 911 WORD32 temp_out_scale_fac = out_scale_factor + 1; 912 if (audio_object_type == AOT_ER_AAC_LD || 913 audio_object_type == AOT_ER_AAC_ELD) { 914 temp_out_scale_fac = temp_out_scale_fac - 1; 915 916 ixheaacd_shiftrountine_with_rnd_eld( 917 qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset], 918 no_synthesis_channels, temp_out_scale_fac); 919 920 } 921 922 else { 923 ixheaacd_shiftrountine_with_rnd( 924 qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset], 925 no_synthesis_channels, temp_out_scale_fac); 926 } 927 } 928 929 if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED) { 930 WORD32 temp = 1; 931 if (audio_object_type == AOT_ER_AAC_LD || 932 audio_object_type == AOT_ER_AAC_ELD) { 933 temp = 2; 934 } 935 ixheaacd_sbr_qmfsyn32_winadd(fp1, fp2, filter_coeff, 936 &time_out[ch_fac * p1], temp, ch_fac); 937 938 fp1 += thirty2; 939 fp2 -= thirty2; 940 thirty2 = -thirty2; 941 942 ixheaacd_drc_offset -= 64; 943 944 if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 640; 945 946 } else { 947 WORD32 temp = 1; 948 if (audio_object_type == AOT_ER_AAC_LD || 949 audio_object_type == AOT_ER_AAC_ELD) { 950 temp = 2; 951 } 952 ixheaacd_sbr_qmfsyn64_winadd(fp1, fp2, filter_coeff, 953 &time_out[ch_fac * p1], temp, ch_fac); 954 955 fp1 += sixty4; 956 fp2 -= sixty4; 957 sixty4 = -sixty4; 958 ixheaacd_drc_offset -= 128; 959 960 if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 1280; 961 } 962 963 filter_coeff += 64; 964 965 if (filter_coeff == qmf_bank->p_filter + 640) 966 filter_coeff = (WORD16 *)qmf_bank->p_filter; 967 968 p1 += no_synthesis_channels; 969 970 if (active) 971 memcpy(qmf_real[i], qmf_real_tmp, 972 2 * no_synthesis_channels * sizeof(WORD32)); 973 } 974 } 975 976 if (audio_object_type == AOT_ER_AAC_LD || 977 audio_object_type == AOT_ER_AAC_ELD) { 978 qmf_bank->fp1_syn = fp1; 979 qmf_bank->fp2_syn = fp2; 980 qmf_bank->sixty4 = sixty4; 981 } 982 983 qmf_bank->filter_pos_syn = filter_coeff; 984 qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset; 985 } 986