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_defines.h" 30 #include "ixheaacd_bitbuffer.h" 31 32 #include "ixheaacd_error_codes.h" 33 #include <ixheaacd_aac_rom.h> 34 #include "ixheaacd_pulsedata.h" 35 36 #include "ixheaacd_pns.h" 37 #include "ixheaacd_drc_data_struct.h" 38 39 #include "ixheaacd_lt_predict.h" 40 41 #include "ixheaacd_channelinfo.h" 42 #include "ixheaacd_drc_dec.h" 43 #include "ixheaacd_sbrdecoder.h" 44 #include "ixheaacd_tns.h" 45 #include "ixheaacd_intrinsics.h" 46 47 #include "ixheaacd_common_rom.h" 48 #include "ixheaacd_block.h" 49 #include "ixheaacd_channel.h" 50 #include "ixheaacd_audioobjtypes.h" 51 #include "ixheaacd_latmdemux.h" 52 53 #include "ixheaacd_aacdec.h" 54 55 static PLATFORM_INLINE WORD32 ixheaacd_mac32_tns(WORD32 a, WORD32 b, WORD32 c) { 56 WORD32 result; 57 WORD64 temp_result; 58 59 temp_result = (WORD64)a * (WORD64)b; 60 result = (WORD32)(temp_result >> 32); 61 result = ixheaacd_add32(c, result); 62 return (result); 63 } 64 65 static PLATFORM_INLINE WORD64 mac32x32in64_dual(WORD32 a, WORD32 b, WORD64 c) { 66 WORD64 result; 67 WORD64 temp_result; 68 69 temp_result = (WORD64)a * (WORD64)b; 70 result = c + (temp_result); 71 return (result); 72 } 73 74 VOID ixheaacd_tns_decode_coefficients( 75 const ia_filter_info_struct *filter, WORD32 *a, 76 ia_aac_dec_tables_struct *ptr_aac_tables) { 77 WORD32 i; 78 WORD32 tmp; 79 WORD32 *aptr = a; 80 WORD32 *tns_coeff_ptr; 81 WORD8 ixheaacd_drc_offset; 82 83 tmp = filter->resolution; 84 if (tmp == 0) { 85 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3; 86 ixheaacd_drc_offset = 4; 87 88 } else { 89 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4; 90 ixheaacd_drc_offset = 8; 91 } 92 93 for (i = 0; i < filter->order; i++) { 94 *aptr++ = tns_coeff_ptr[filter->coef[i] + ixheaacd_drc_offset]; 95 } 96 } 97 98 VOID ixheaacd_tns_parcor_to_lpc(WORD32 *parcor, WORD32 *lpc, WORD16 *scale, 99 WORD32 order) 100 101 { 102 WORD i, j, status; 103 WORD32 z1; 104 WORD32 z[MAX_ORDER + 1]; 105 WORD32 w[MAX_ORDER + 1]; 106 WORD32 accu1, accu2; 107 108 status = 1; 109 *scale = 1; 110 111 while (status) { 112 status = 0; 113 114 for (i = MAX_ORDER; i >= 0; i--) { 115 z[i] = 0; 116 w[i] = 0; 117 } 118 119 accu1 = (0x40000000 >> (*scale - 1)); 120 121 for (i = 0; i <= order; i++) { 122 z1 = accu1; 123 124 for (j = 0; j < order; j++) { 125 w[j] = (accu1); 126 127 accu1 = ixheaacd_add32_sat(accu1, 128 ixheaacd_mult32_shl_sat(parcor[j], (z[j]))); 129 if (ixheaacd_abs32_sat(accu1) == 0x7fffffff) status = 1; 130 } 131 for (j = (order - 1); j >= 0; j--) { 132 accu2 = (z[j]); 133 accu2 = ixheaacd_add32_sat(accu2, 134 ixheaacd_mult32_shl_sat(parcor[j], (w[j]))); 135 z[j + 1] = (accu2); 136 if (ixheaacd_abs32_sat(accu2) == 0x7fffffff) status = 1; 137 } 138 139 z[0] = (z1); 140 lpc[i] = (accu1); 141 accu1 = 0; 142 } 143 144 accu1 = (status - 1); 145 146 if (accu1 == 0) { 147 *scale = *scale + 1; 148 } 149 } 150 } 151 152 VOID ixheaacd_tns_parcor_lpc_convert_dec(WORD16 *parcor, WORD16 *lpc, 153 WORD16 *scale, WORD order) 154 155 { 156 WORD i, j, status; 157 WORD32 accu; 158 WORD16 temp_buf1[MAX_ORDER + 1]; 159 WORD16 temp_buf2[MAX_ORDER + 1]; 160 WORD32 accu1, accu2; 161 162 status = 1; 163 *scale = 0; 164 165 while (status) { 166 status = 0; 167 168 for (i = MAX_ORDER; i >= 0; i--) { 169 temp_buf1[i] = 0; 170 temp_buf2[i] = 0; 171 } 172 173 accu1 = (0x7fffffff >> *scale); 174 175 for (i = 0; i <= order; i++) { 176 accu = accu1; 177 178 for (j = 0; j < order; j++) { 179 temp_buf2[j] = ixheaacd_round16(accu1); 180 accu1 = ixheaacd_mac16x16in32_shl_sat(accu1, parcor[j], temp_buf1[j]); 181 182 if (ixheaacd_abs32_sat(accu1) == 0x7fffffff) { 183 status = 1; 184 } 185 } 186 187 for (j = (order - 1); j >= 0; j--) { 188 accu2 = ixheaacd_deposit16h_in32(temp_buf1[j]); 189 accu2 = ixheaacd_mac16x16in32_shl_sat(accu2, parcor[j], temp_buf2[j]); 190 temp_buf1[j + 1] = ixheaacd_round16(accu2); 191 if (ixheaacd_abs32_sat(accu2) == 0x7fffffff) { 192 status = 1; 193 } 194 } 195 196 temp_buf1[0] = ixheaacd_round16(accu); 197 lpc[i] = ixheaacd_round16(accu1); 198 accu1 = 0; 199 } 200 201 accu1 = (status - 1); 202 203 if (accu1 == 0) { 204 *scale = *scale + 1; 205 } 206 } 207 } 208 209 VOID ixheaacd_tns_ar_filter_fixed_dec(WORD32 *spectrum, WORD32 size, WORD32 inc, 210 WORD32 *lpc, WORD32 order, 211 WORD32 shift_value, WORD scale_spec) 212 213 { 214 WORD32 i, j; 215 WORD32 y, state[MAX_ORDER + 1]; 216 WORD32 acc; 217 218 if ((order & 3) != 0) { 219 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) { 220 lpc[i] = 0; 221 } 222 lpc[i] = 0; 223 order = ((order & 0xfffffffc) + 4); 224 } 225 { 226 WORD32 temp_lo = 0; 227 for (i = 0; i < order; i++) { 228 y = (*spectrum) << scale_spec; 229 acc = 0; 230 231 for (j = i; j > 0; j--) { 232 acc = ixheaacd_mac32_tns(state[j - 1], lpc[j], acc); 233 state[j] = state[j - 1]; 234 } 235 y = ixheaacd_sub32(y, (acc << 1)); 236 state[0] = ixheaacd_shl32(y, shift_value); 237 238 *spectrum = y >> scale_spec; 239 spectrum += inc; 240 } 241 temp_lo = 0; 242 for (i = order; i < size; i++) { 243 y = (*spectrum) << scale_spec; 244 acc = 0; 245 for (j = order; j > 0; j--) { 246 acc = ixheaacd_mac32_tns(state[j - 1], lpc[j], acc); 247 state[j] = state[j - 1]; 248 } 249 y = ixheaacd_sub32(y, (acc << 1)); 250 state[0] = ixheaacd_shl32(y, shift_value); 251 252 *spectrum = y >> scale_spec; 253 spectrum += inc; 254 } 255 } 256 } 257 258 VOID ixheaacd_tns_ar_filter_fixed_non_neon_armv7(WORD32 *spectrum, WORD32 size, 259 WORD32 inc, WORD32 *lpc, 260 WORD32 order, 261 WORD32 shift_value, 262 WORD scale_spec) { 263 WORD32 i, j; 264 WORD32 y, state[MAX_ORDER + 1]; 265 WORD32 acc; 266 267 if ((order & 3) != 0) { 268 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) { 269 lpc[i] = 0; 270 } 271 lpc[i] = 0; 272 order = ((order & 0xfffffffc) + 4); 273 } 274 { 275 WORD32 temp_lo = 0; 276 for (i = 0; i < order; i++) { 277 y = (*spectrum) << scale_spec; 278 acc = 0; 279 280 for (j = i; j > 0; j--) { 281 acc = ixheaacd_mac32_tns(state[j - 1], lpc[j], acc); 282 state[j] = state[j - 1]; 283 } 284 y = ixheaacd_sub32(y, (acc << 1)); 285 state[0] = ixheaacd_shl32(y, shift_value); 286 287 *spectrum = y >> scale_spec; 288 spectrum += inc; 289 } 290 temp_lo = 0; 291 for (i = order; i < size; i++) { 292 WORD64 acc = 0; 293 WORD32 acc1; 294 y = (*spectrum) << scale_spec; 295 for (j = order; j > 0; j--) { 296 acc = mac32x32in64_dual(state[j - 1], lpc[j], acc); 297 state[j] = state[j - 1]; 298 } 299 acc1 = (WORD32)(acc >> 32); 300 301 y = ixheaacd_sub32(y, (acc1 << 1)); 302 state[0] = ixheaacd_shl32(y, shift_value); 303 304 *spectrum = y >> scale_spec; 305 spectrum += inc; 306 } 307 } 308 } 309 310 VOID ixheaacd_tns_ar_filter_fixed_armv8(WORD32 *spectrum, WORD32 size, 311 WORD32 inc, WORD32 *lpc, WORD32 order, 312 WORD32 shift_value, WORD scale_spec) { 313 WORD32 i, j; 314 WORD32 y, state[MAX_ORDER + 1]; 315 WORD32 acc; 316 317 if ((order & 3) != 0) { 318 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) { 319 lpc[i] = 0; 320 } 321 lpc[i] = 0; 322 order = ((order & 0xfffffffc) + 4); 323 } 324 { 325 WORD32 temp_lo = 0; 326 for (i = 0; i < order; i++) { 327 y = (*spectrum) << scale_spec; 328 acc = 0; 329 330 for (j = i; j > 0; j--) { 331 acc = ixheaacd_mac32_tns(state[j - 1], lpc[j], acc); 332 state[j] = state[j - 1]; 333 } 334 y = ixheaacd_sub32(y, (acc << 1)); 335 state[0] = ixheaacd_shl32(y, shift_value); 336 337 *spectrum = y >> scale_spec; 338 spectrum += inc; 339 } 340 temp_lo = 0; 341 for (i = order; i < size; i++) { 342 WORD64 acc = 0; 343 WORD32 acc1; 344 y = (*spectrum) << scale_spec; 345 for (j = order; j > 0; j--) { 346 acc = ixheaacd_mac32x32in64_dual(state[j - 1], lpc[j], acc); 347 state[j] = state[j - 1]; 348 } 349 acc1 = (WORD32)(acc >> 32); 350 351 y = ixheaacd_sub32(y, (acc1 << 1)); 352 state[0] = ixheaacd_shl32(y, shift_value); 353 354 *spectrum = y >> scale_spec; 355 spectrum += inc; 356 } 357 } 358 } 359 360 void ixheaacd_tns_ma_filter_fixed_ld(WORD32 *spectrum, WORD32 size, WORD32 inc, 361 WORD32 *lpc, WORD32 order, 362 WORD16 shift_value) { 363 WORD32 i, j; 364 WORD32 y, state[MAX_ORDER]; 365 366 for (i = 0; i < order; i++) state[i] = 0; 367 368 for (i = 0; i < size; i++) { 369 y = *spectrum; 370 371 for (j = 0; j < order; j++) y += ixheaacd_mult32_shl(state[j], lpc[j + 1]); 372 373 for (j = order - 1; j > 0; j--) state[j] = state[j - 1]; 374 375 state[0] = ixheaacd_shl32_dir_sat(*spectrum, shift_value); 376 *spectrum = y; 377 spectrum += inc; 378 } 379 } 380 381 VOID ixheaacd_tns_ar_filter_dec(WORD32 *spectrum, WORD32 size, WORD32 inc, 382 WORD16 *lpc, WORD32 order, WORD32 shift_value, 383 WORD scale_spec, WORD32 *ptr_filter_state) { 384 WORD32 i, j; 385 WORD32 y; 386 WORD32 acc; 387 388 if ((order & 3) != 0) { 389 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) { 390 lpc[i] = 0; 391 } 392 lpc[i] = 0; 393 order = ((order & 0xfffffffc) + 4); 394 } 395 396 for (i = 0; i < order; i++) { 397 y = (*spectrum) << scale_spec; 398 acc = 0; 399 400 for (j = i; j > 0; j--) { 401 acc = ixheaacd_add32( 402 acc, ixheaacd_mult32x16in32(ptr_filter_state[j - 1], lpc[j])); 403 ptr_filter_state[j] = ptr_filter_state[j - 1]; 404 } 405 406 y = ixheaacd_sub32(y, (acc << 1)); 407 ptr_filter_state[0] = ixheaacd_shl32(y, shift_value); 408 *spectrum = y >> scale_spec; 409 spectrum += inc; 410 } 411 412 for (i = order; i < size; i++) { 413 y = (*spectrum) << scale_spec; 414 acc = 0; 415 for (j = order; j > 0; j--) { 416 acc = ixheaacd_add32( 417 acc, ixheaacd_mult32x16in32(ptr_filter_state[j - 1], lpc[j])); 418 ptr_filter_state[j] = ptr_filter_state[j - 1]; 419 } 420 421 y = ixheaacd_sub32(y, (acc << 1)); 422 ptr_filter_state[0] = ixheaacd_shl32(y, shift_value); 423 *spectrum = y >> scale_spec; 424 spectrum += inc; 425 } 426 } 427 428 WORD32 ixheaacd_calc_max_spectral_line_dec(WORD32 *ptr_tmp, WORD32 size) { 429 WORD32 max_spec_line = 0, i; 430 WORD unroll_cnt, rem; 431 432 unroll_cnt = size >> 3; 433 for (i = unroll_cnt; i--;) { 434 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 435 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 436 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 437 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 438 439 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 440 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 441 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 442 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 443 } 444 445 rem = size - (unroll_cnt << 3); 446 447 if (rem) { 448 for (i = rem; i--;) { 449 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line; 450 } 451 } 452 453 return ixheaacd_norm32(max_spec_line); 454 }