Home | History | Annotate | Download | only in decoder
      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