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 <math.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include "ixheaacd_sbr_common.h" 25 #include <ixheaacd_type_def.h> 26 27 #include "ixheaacd_constants.h" 28 #include <ixheaacd_basic_ops32.h> 29 #include <ixheaacd_basic_ops16.h> 30 #include <ixheaacd_basic_ops40.h> 31 #include "ixheaacd_basic_ops.h" 32 33 #include <ixheaacd_basic_op.h> 34 #include "ixheaacd_intrinsics.h" 35 #include "ixheaacd_common_rom.h" 36 #include "ixheaacd_basic_funcs.h" 37 #include "ixheaacd_bitbuffer.h" 38 #include "ixheaacd_sbrdecsettings.h" 39 #include "ixheaacd_sbr_scale.h" 40 #include "ixheaacd_lpp_tran.h" 41 #include "ixheaacd_env_extr_part.h" 42 #include <ixheaacd_sbr_rom.h> 43 #include "ixheaacd_hybrid.h" 44 #include "ixheaacd_ps_dec.h" 45 #include "ixheaacd_env_extr.h" 46 47 #include "ixheaacd_sbr_const.h" 48 #include "ixheaacd_env_extr.h" 49 #include "ixheaacd_freq_sca.h" 50 #include "ixheaacd_intrinsics.h" 51 52 WORD32 ixheaacd_samp_rate_table[12] = {92017, 75132, 55426, 46009, 53 37566, 27713, 23004, 18783, 54 13856, 11502, 9391, 16428320}; 55 56 WORD32 ixheaacd_v_offset_40[16] = {3 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 57 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 58 2 + 1, 2 + 1, 1 + 1, 0}; 59 60 static WORD32 ixheaacd_int_div(WORD32 num, WORD32 den) { 61 if (den != 0) { 62 WORD32 result = 0; 63 WORD32 temp = 0; 64 while (den <= num) { 65 temp = 0; 66 while (num >= (den << (temp + 1))) { 67 temp++; 68 } 69 result = result + (1 << temp); 70 num = num - (den * (1 << temp)); 71 } 72 return result; 73 } else { 74 return 0; 75 } 76 } 77 78 VOID ixheaacd_aac_shellsort(WORD16 *in, WORD32 n) { 79 WORD32 i, j; 80 WORD32 inc; 81 WORD32 v, w; 82 83 inc = 1; 84 85 do { 86 inc = (((inc << 1) + inc) + 1); 87 } while (inc <= n); 88 89 do { 90 inc = (ixheaacd_int_div(inc, 3)); 91 for (i = inc; i < n; i++) { 92 v = in[i]; 93 j = i; 94 95 while ((w = in[(j - inc)]) > v) { 96 in[j] = w; 97 j = (j - inc); 98 99 if (j < inc) break; 100 } 101 in[j] = v; 102 } 103 104 } while (inc > 1); 105 } 106 107 WORD32 108 ixheaacd_calc_start_band(WORD32 fs, const WORD32 start_freq, 109 FLOAT32 upsamp_fac) { 110 WORD32 k0_min; 111 WORD32 fs_mapped = 0; 112 113 if (upsamp_fac == 4) { 114 fs = fs / 2; 115 } 116 117 if (fs >= 0 && fs < 18783) { 118 fs_mapped = 16000; 119 } else if (fs >= 18783 && fs < 23004) { 120 fs_mapped = 22050; 121 } else if (fs >= 23004 && fs < 27713) { 122 fs_mapped = 24000; 123 } else if (fs >= 27713 && fs < 35777) { 124 fs_mapped = 32000; 125 } else if (fs >= 35777 && fs < 42000) { 126 fs_mapped = 40000; 127 } else if (fs >= 42000 && fs < 46009) { 128 fs_mapped = 44100; 129 } else if (fs >= 46009 && fs < 55426) { 130 fs_mapped = 48000; 131 } else if (fs >= 55426 && fs < 75132) { 132 fs_mapped = 64000; 133 } else if (fs >= 75132 && fs < 92017) { 134 fs_mapped = 88200; 135 } else if (fs >= 92017) { 136 fs_mapped = 96000; 137 } else { 138 return -1; 139 } 140 141 if (upsamp_fac == 4) { 142 if (fs_mapped < 32000) { 143 k0_min = (WORD32)(((FLOAT32)(3000 * 2 * 32) / fs_mapped) + 0.5); 144 } else { 145 if (fs_mapped < 64000) { 146 k0_min = (WORD32)(((FLOAT32)(4000 * 2 * 32) / fs_mapped) + 0.5); 147 } else { 148 k0_min = (WORD32)(((FLOAT32)(5000 * 2 * 32) / fs_mapped) + 0.5); 149 } 150 } 151 } else { 152 if (fs_mapped < 32000) { 153 k0_min = (WORD32)(((FLOAT32)(3000 * 2 * 64) / fs_mapped) + 0.5); 154 } else { 155 if (fs_mapped < 64000) { 156 k0_min = (WORD32)(((FLOAT32)(4000 * 2 * 64) / fs_mapped) + 0.5); 157 } else { 158 k0_min = (WORD32)(((FLOAT32)(5000 * 2 * 64) / fs_mapped) + 0.5); 159 } 160 } 161 } 162 163 switch (fs_mapped) { 164 case 16000: { 165 WORD32 v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, 166 0, 1, 2, 3, 4, 5, 6, 7}; 167 return (k0_min + v_offset[start_freq]); 168 } break; 169 case 22050: { 170 WORD32 v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, 171 3, 4, 5, 6, 7, 9, 11, 13}; 172 return (k0_min + v_offset[start_freq]); 173 } break; 174 case 24000: { 175 WORD32 v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, 176 4, 5, 6, 7, 9, 11, 13, 16}; 177 return (k0_min + v_offset[start_freq]); 178 } break; 179 case 32000: { 180 WORD32 v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, 181 4, 5, 6, 7, 9, 11, 13, 16}; 182 return (k0_min + v_offset[start_freq]); 183 } break; 184 case 40000: { 185 WORD32 v_offset[] = {-1, 0, 1, 2, 3, 4, 5, 6, 186 7, 8, 9, 11, 13, 15, 17, 19}; 187 return (k0_min + v_offset[start_freq]); 188 } break; 189 case 44100: 190 case 48000: 191 case 64000: { 192 WORD32 v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, 193 5, 6, 7, 9, 11, 13, 16, 20}; 194 return (k0_min + v_offset[start_freq]); 195 } break; 196 case 88200: 197 case 96000: { 198 WORD32 v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, 199 6, 7, 9, 11, 13, 16, 20, 24}; 200 return (k0_min + v_offset[start_freq]); 201 } break; 202 203 default: { 204 WORD32 v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, 205 9, 11, 13, 16, 20, 24, 28, 33}; 206 return (k0_min + v_offset[start_freq]); 207 } 208 } 209 } 210 211 WORD32 212 ixheaacd_calc_stop_band(WORD32 fs, const WORD32 stop_freq, FLOAT32 upsamp_fac) { 213 WORD32 result, i; 214 WORD16 arr_stop_freq[14]; 215 WORD32 k1_min; 216 WORD16 arr_diff_stop_freq[13]; 217 218 if (upsamp_fac == 4) { 219 fs = fs / 2; 220 if (fs < 32000) { 221 k1_min = (WORD32)(((FLOAT32)(6000 * 2 * 32) / fs) + 0.5); 222 } else { 223 if (fs < 64000) { 224 k1_min = (WORD32)(((FLOAT32)(8000 * 2 * 32) / fs) + 0.5); 225 } else { 226 k1_min = (WORD32)(((FLOAT32)(10000 * 2 * 32) / fs) + 0.5); 227 } 228 } 229 } else { 230 if (fs < 32000) { 231 k1_min = (WORD32)(((FLOAT32)(6000 * 2 * 64) / fs) + 0.5); 232 } else { 233 if (fs < 64000) { 234 k1_min = (WORD32)(((FLOAT32)(8000 * 2 * 64) / fs) + 0.5); 235 } else { 236 k1_min = (WORD32)(((FLOAT32)(10000 * 2 * 64) / fs) + 0.5); 237 } 238 } 239 } 240 241 /*Calculate stop frequency vector*/ 242 for (i = 0; i <= 13; i++) { 243 arr_stop_freq[i] = (WORD32)(k1_min * pow(64.0 / k1_min, i / 13.0) + 0.5); 244 } 245 246 /*Ensure increasing bandwidth */ 247 for (i = 0; i <= 12; i++) { 248 arr_diff_stop_freq[i] = arr_stop_freq[i + 1] - arr_stop_freq[i]; 249 } 250 251 ixheaacd_aac_shellsort(&arr_diff_stop_freq[0], 252 13); /*Sort bandwidth changes */ 253 254 result = k1_min; 255 for (i = 0; i < stop_freq; i++) { 256 result = result + arr_diff_stop_freq[i]; 257 } 258 259 return (result); 260 } 261 void ixheaacd_calc_k0_k2_bands(const WORD32 samp_freq, const WORD32 start_freq, 262 const WORD32 stop_freq, FLOAT32 upsamp_fac, 263 WORD16 *ptr_k0, WORD16 *ptr_k2) { 264 /* Update start_freq struct */ 265 *ptr_k0 = ixheaacd_calc_start_band(samp_freq, start_freq, upsamp_fac); 266 267 /*Update stop_freq struct */ 268 if (stop_freq < 14) { 269 *ptr_k2 = ixheaacd_calc_stop_band(samp_freq, stop_freq, upsamp_fac); 270 } else if (stop_freq == 14) { 271 *ptr_k2 = 2 * (*ptr_k0); 272 } else { 273 *ptr_k2 = 3 * (*ptr_k0); 274 } 275 276 /* limit to Nyqvist */ 277 if (*ptr_k2 > 64) { 278 *ptr_k2 = 64; 279 } 280 } 281 282 WORD16 ixheaacd_calc_master_frq_bnd_tbl( 283 ia_freq_band_data_struct *pstr_freq_band_data, 284 ia_sbr_header_data_struct *ptr_header_data, 285 ixheaacd_misc_tables *pstr_common_tables) { 286 WORD32 k; 287 WORD32 fs = ptr_header_data->out_sampling_freq; 288 WORD16 bands; 289 WORD16 k0 = 0, k2 = 0, k1; 290 WORD32 k2_achived; 291 WORD32 k2_diff; 292 WORD32 incr; 293 WORD32 dk; 294 WORD16 vec_dk[MAX_OCTAVE + MAX_SECOND_REGION]; 295 WORD16 *vec_dk0 = &vec_dk[0]; 296 WORD16 *vec_dk1 = &vec_dk[MAX_OCTAVE]; 297 WORD16 upsamp_fac = ptr_header_data->upsamp_fac; 298 WORD16 *f_master_tbl = pstr_freq_band_data->f_master_tbl; 299 WORD16 num_mf_bands; 300 301 k1 = 0; 302 incr = 0; 303 dk = 0; 304 305 ixheaacd_calc_k0_k2_bands(fs, ptr_header_data->start_freq, 306 ptr_header_data->stop_freq, upsamp_fac, &k0, &k2); 307 308 if (k2 > NO_SYNTHESIS_CHANNELS) { 309 k2 = NO_SYNTHESIS_CHANNELS; 310 } 311 if (upsamp_fac == 4) { 312 if ((sub_d(k2, k0) > MAX_FREQ_COEFFS) || (k2 <= k0)) { 313 return -1; 314 } 315 if ((2 * fs == 44100) && (sub_d(k2, k0) > MAX_FREQ_COEFFS)) { 316 return -1; 317 } 318 if ((2 * fs >= 48000) && (sub_d(k2, k0) > MAX_FREQ_COEFFS)) { 319 return -1; 320 } 321 } else { 322 if ((sub_d(k2, k0) > MAX_FREQ_COEFFS_SBR) || (k2 <= k0)) { 323 return -1; 324 } 325 if ((fs == 44100) && (sub_d(k2, k0) > MAX_FREQ_COEFFS_FS44100)) { 326 return -1; 327 } 328 if ((fs >= 48000) && (sub_d(k2, k0) > MAX_FREQ_COEFFS_FS48000)) { 329 return -1; 330 } 331 } 332 333 if (ptr_header_data->freq_scale == 0) { 334 WORD16 num_bands; 335 if (ptr_header_data->alter_scale == 0) { 336 dk = 1; 337 num_bands = (WORD16)(k2 - k0); 338 num_bands = num_bands - (num_bands & 0x1); 339 } else { 340 dk = 2; 341 num_bands = (WORD16)((k2 - k0) + 2) >> 2; 342 num_bands = num_bands << 1; 343 } 344 if (num_bands < 1) { 345 return -1; 346 } 347 k2_achived = k0 + (num_bands << (dk - 1)); 348 349 k2_diff = k2 - k2_achived; 350 351 for (k = 0; k < num_bands; k++) { 352 vec_dk[k] = dk; 353 } 354 355 if (k2_diff < 0) { 356 incr = 1; 357 k = 0; 358 } 359 if (k2_diff > 0) { 360 incr = -1; 361 k = sub_d(num_bands, 1); 362 } 363 while (k2_diff != 0) { 364 vec_dk[k] = vec_dk[k] - incr; 365 k = (WORD16)(k + incr); 366 k2_diff = k2_diff + incr; 367 } 368 f_master_tbl[0] = k0; 369 for (k = 1; k <= num_bands; k++) 370 f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk[k - 1]; 371 num_mf_bands = num_bands; 372 } else { 373 WORD32 num_bands0; 374 WORD32 num_bands1; 375 376 switch (ptr_header_data->freq_scale) { 377 case 1: 378 bands = 12; 379 break; 380 case 2: 381 bands = 10; 382 break; 383 case 3: 384 bands = 8; 385 break; 386 default: 387 bands = 8; 388 }; 389 390 if ((upsamp_fac == 4) && (k0 < bands)) { 391 bands = ((WORD32)(k0 - (k0 & 1))); 392 } 393 394 if ((WORD32)(10000 * k2) > (WORD32)(22449 * k0)) { 395 k1 = k0 << 1; 396 397 num_bands0 = bands; 398 399 num_bands1 = pstr_common_tables->log_dual_is_table[k2] - 400 pstr_common_tables->log_dual_is_table[k1]; 401 num_bands1 = bands * num_bands1; 402 403 if (ptr_header_data->alter_scale) { 404 num_bands1 = num_bands1 * (0x6276); 405 num_bands1 = num_bands1 >> 15; 406 } 407 num_bands1 = num_bands1 + 0x1000; 408 409 num_bands1 = num_bands1 >> 13; 410 num_bands1 = num_bands1 << 1; 411 412 if (num_bands0 < 1) { 413 return -1; 414 } 415 416 if (num_bands1 < 1) { 417 return -1; 418 } 419 420 ixheaacd_calc_bands(vec_dk0, k0, k1, (WORD16)num_bands0); 421 422 ixheaacd_aac_shellsort(vec_dk0, num_bands0); 423 424 if (vec_dk0[0] == 0) { 425 return -1; 426 } 427 428 f_master_tbl[0] = k0; 429 430 for (k = 1; k <= num_bands0; k++) 431 f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk0[k - 1]; 432 433 ixheaacd_calc_bands(vec_dk1, k1, k2, (WORD16)num_bands1); 434 ixheaacd_aac_shellsort(vec_dk1, num_bands1); 435 436 if (vec_dk1[0] < vec_dk0[num_bands0 - 1]) { 437 WORD16 change = vec_dk0[num_bands0 - 1] - vec_dk1[0]; 438 WORD16 temp = vec_dk1[num_bands1 - 1] - vec_dk1[0]; 439 temp = temp >> 1; 440 if (change > temp) { 441 change = temp; 442 } 443 vec_dk1[0] = vec_dk1[0] + change; 444 vec_dk1[num_bands1 - 1] = vec_dk1[num_bands1 - 1] - change; 445 ixheaacd_aac_shellsort(vec_dk1, num_bands1); 446 } 447 448 f_master_tbl[num_bands0] = k1; 449 for (k = 1; k <= num_bands1; k++) 450 f_master_tbl[num_bands0 + k] = 451 f_master_tbl[num_bands0 + k - 1] + vec_dk1[k - 1]; 452 num_mf_bands = add_d(num_bands0, num_bands1); 453 454 } else { 455 k1 = k2; 456 457 num_bands0 = pstr_common_tables->log_dual_is_table[k1] - 458 pstr_common_tables->log_dual_is_table[k0]; 459 460 num_bands0 = bands * num_bands0; 461 462 num_bands0 = num_bands0 + 0x1000; 463 464 num_bands0 = num_bands0 >> 13; 465 num_bands0 = num_bands0 << 1; 466 467 if (num_bands0 < 1) { 468 return -1; 469 } 470 ixheaacd_calc_bands(vec_dk0, k0, k1, (WORD16)num_bands0); 471 ixheaacd_aac_shellsort(vec_dk0, num_bands0); 472 473 if (vec_dk0[0] == 0) { 474 return -1; 475 } 476 477 f_master_tbl[0] = k0; 478 for (k = 1; k <= num_bands0; k++) 479 f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk0[k - 1]; 480 481 num_mf_bands = num_bands0; 482 } 483 } 484 if (num_mf_bands < 1) { 485 return -1; 486 } 487 pstr_freq_band_data->num_mf_bands = num_mf_bands; 488 return 0; 489 } 490 491 static WORD16 ixheaacd_calc_freq_ratio(WORD16 k_start, WORD16 k_stop, 492 WORD16 num_bands) { 493 WORD32 bandfactor; 494 WORD32 step; 495 WORD32 direction; 496 WORD32 start; 497 WORD32 stop; 498 WORD32 temp; 499 WORD32 j, i; 500 501 bandfactor = 0x3f000000L; 502 step = 0x20000000L; 503 direction = 1; 504 start = ixheaacd_shl32(ixheaacd_deposit16l_in32(k_start), INT_BITS - 8); 505 stop = ixheaacd_shl32(ixheaacd_deposit16l_in32(k_stop), INT_BITS - 8); 506 507 i = 0; 508 509 do { 510 i = i + 1; 511 temp = stop; 512 513 for (j = 0; j < num_bands; j++) 514 temp = ixheaacd_mult16x16in32_shl(ixheaacd_extract16h(temp), 515 ixheaacd_extract16h(bandfactor)); 516 517 if (temp < start) { 518 if (direction == 0) step = ixheaacd_shr32(step, 1); 519 direction = 1; 520 bandfactor = ixheaacd_add32_sat(bandfactor, step); 521 522 } else { 523 if (direction == 1) step = ixheaacd_shr32(step, 1); 524 direction = 0; 525 bandfactor = ixheaacd_sub32_sat(bandfactor, step); 526 } 527 528 if (i > 100) { 529 step = 0; 530 } 531 } while (step > 0); 532 533 return ixheaacd_extract16h(bandfactor); 534 } 535 536 VOID ixheaacd_calc_bands(WORD16 *diff, WORD16 start, WORD16 stop, 537 WORD16 num_bands) { 538 WORD32 i; 539 WORD32 previous; 540 WORD32 current; 541 WORD32 temp, exact; 542 WORD16 bandfactor = ixheaacd_calc_freq_ratio(start, stop, num_bands); 543 544 previous = stop; 545 exact = ixheaacd_shl32_sat(ixheaacd_deposit16l_in32(stop), INT_BITS - 8); 546 547 for (i = num_bands - 1; i >= 0; i--) { 548 exact = ixheaacd_mult16x16in32(ixheaacd_extract16h(exact), bandfactor); 549 550 temp = ixheaacd_add32_sat(exact, 0x00400000); 551 exact = exact << 1; 552 553 current = ixheaacd_extract16l(ixheaacd_shr32(temp, (INT_BITS - 9))); 554 555 diff[i] = sub_d(previous, current); 556 previous = current; 557 } 558 } 559 560 static VOID ixheaacd_derive_hi_lo_freq_bnd_tbls( 561 ia_freq_band_data_struct *pstr_freq_band_data, 562 ia_sbr_header_data_struct *ptr_header_data) { 563 WORD16 k; 564 WORD16 xover_band = ptr_header_data->xover_band; 565 WORD16 *f_master_tbl = pstr_freq_band_data->f_master_tbl + xover_band; 566 WORD16 *f_low_tbl = pstr_freq_band_data->freq_band_table[LOW]; 567 WORD16 *f_high_tbl = pstr_freq_band_data->freq_band_table[HIGH]; 568 WORD16 num_mf_bands = pstr_freq_band_data->num_mf_bands; 569 WORD16 num_lf_bands, num_hf_bands; 570 num_hf_bands = num_mf_bands - xover_band; 571 k = 0; 572 *f_low_tbl = *f_high_tbl = *f_master_tbl; 573 f_low_tbl++; 574 f_high_tbl++; 575 f_master_tbl++; 576 k++; 577 if ((num_hf_bands & 1)) { 578 *f_low_tbl = *f_high_tbl = *f_master_tbl; 579 f_high_tbl++; 580 f_master_tbl++; 581 f_low_tbl++; 582 k++; 583 } 584 for (; k <= num_hf_bands; k++) { 585 *f_high_tbl = *f_master_tbl; 586 f_high_tbl++; 587 f_master_tbl++; 588 k++; 589 590 *f_low_tbl = *f_high_tbl = *f_master_tbl; 591 f_high_tbl++; 592 f_master_tbl++; 593 f_low_tbl++; 594 } 595 num_lf_bands = ((num_hf_bands + 1) >> 1); 596 597 pstr_freq_band_data->num_sf_bands[LOW] = num_lf_bands; 598 pstr_freq_band_data->num_sf_bands[HIGH] = num_hf_bands; 599 } 600 601 WORD32 ixheaacd_derive_noise_freq_bnd_tbl( 602 ia_sbr_header_data_struct *ptr_header_data, 603 ixheaacd_misc_tables *pstr_common_tables, 604 ia_freq_band_data_struct *pstr_freq_band_data) { 605 WORD16 k2, kx; 606 WORD32 temp; 607 WORD32 num_lf_bands = pstr_freq_band_data->num_sf_bands[LOW]; 608 WORD32 num_hf_bands = pstr_freq_band_data->num_sf_bands[HIGH]; 609 k2 = pstr_freq_band_data->freq_band_table[HIGH][num_hf_bands]; 610 kx = pstr_freq_band_data->freq_band_table[HIGH][0]; 611 612 if (ptr_header_data->noise_bands == 0) { 613 pstr_freq_band_data->num_nf_bands = 1; 614 } else { 615 temp = pstr_common_tables->log_dual_is_table[k2] - 616 pstr_common_tables->log_dual_is_table[kx]; 617 temp = temp * ptr_header_data->noise_bands; 618 temp = temp + 0x800; 619 temp = temp >> 12; 620 if (temp == 0) { 621 temp = 1; 622 } 623 pstr_freq_band_data->num_nf_bands = temp; 624 } 625 pstr_freq_band_data->num_if_bands = pstr_freq_band_data->num_nf_bands; 626 627 if (pstr_freq_band_data->num_nf_bands > MAX_NOISE_COEFFS) { 628 return -1; 629 } 630 { 631 WORD16 i_k, k; 632 WORD16 num, den; 633 WORD16 *f_noise_tbl = pstr_freq_band_data->freq_band_tbl_noise; 634 WORD16 *f_low_tbl = pstr_freq_band_data->freq_band_table[LOW]; 635 WORD32 num_nf_bands = pstr_freq_band_data->num_nf_bands; 636 637 num = num_lf_bands; 638 den = num_nf_bands; 639 640 k = 0; 641 *f_noise_tbl = f_low_tbl[0]; 642 f_noise_tbl++; 643 k++; 644 i_k = 0; 645 646 for (; k <= num_nf_bands; k++) { 647 i_k = i_k + (WORD16)ixheaacd_int_div(num, den); 648 *f_noise_tbl = f_low_tbl[i_k]; 649 num = num_lf_bands - i_k; 650 den = den - 1; 651 f_noise_tbl++; 652 } 653 } 654 return 0; 655 } 656 657 WORD32 ixheaacd_calc_frq_bnd_tbls(ia_sbr_header_data_struct *ptr_header_data, 658 ixheaacd_misc_tables *pstr_common_tables) { 659 WORD32 err; 660 WORD16 num_lf_bands, num_hf_bands, lsb, usb; 661 ia_freq_band_data_struct *pstr_freq_band_data = 662 ptr_header_data->pstr_freq_band_data; 663 664 err = ixheaacd_calc_master_frq_bnd_tbl(pstr_freq_band_data, ptr_header_data, 665 pstr_common_tables); 666 667 if (err || 668 (ptr_header_data->xover_band > pstr_freq_band_data->num_mf_bands)) { 669 return -1; 670 } 671 672 ixheaacd_derive_hi_lo_freq_bnd_tbls(pstr_freq_band_data, ptr_header_data); 673 674 num_lf_bands = pstr_freq_band_data->num_sf_bands[LOW]; 675 num_hf_bands = pstr_freq_band_data->num_sf_bands[HIGH]; 676 677 if ((num_lf_bands <= 0) || 678 (num_lf_bands > ixheaacd_shr16(MAX_FREQ_COEFFS, 1))) { 679 return -1; 680 } 681 682 lsb = pstr_freq_band_data->freq_band_table[LOW][0]; 683 usb = pstr_freq_band_data->freq_band_table[LOW][num_lf_bands]; 684 685 pstr_freq_band_data->sub_band_start = lsb; 686 687 ptr_header_data->status = 1; 688 689 if ((lsb > NO_ANALYSIS_CHANNELS) || (lsb >= usb)) { 690 return -1; 691 } 692 693 if (ixheaacd_derive_noise_freq_bnd_tbl(ptr_header_data, pstr_common_tables, 694 pstr_freq_band_data)) { 695 return -1; 696 } 697 698 pstr_freq_band_data->sub_band_start = lsb; 699 pstr_freq_band_data->sub_band_end = usb; 700 701 return 0; 702 } 703