Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /*!
     85   \file
     86   \brief  frequency scale
     87 */
     88 
     89 #include "sbrenc_freq_sca.h"
     90 #include "sbr_misc.h"
     91 
     92 #include "genericStds.h"
     93 
     94 /*  StartFreq */
     95 static INT getStartFreq(INT fs, const INT start_freq);
     96 
     97 /* StopFreq */
     98 static INT getStopFreq(INT fs, const INT stop_freq, const INT noChannels);
     99 
    100 static INT  numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor);
    101 static void CalcBands(INT * diff, INT start , INT stop , INT num_bands);
    102 static INT  modifyBands(INT max_band, INT * diff, INT length);
    103 static void cumSum(INT start_value, INT* diff, INT length, UCHAR  *start_adress);
    104 
    105 
    106 
    107 /*******************************************************************************
    108  Functionname:  FDKsbrEnc_getSbrStartFreqRAW
    109  *******************************************************************************
    110  Description:
    111 
    112  Arguments:
    113 
    114  Return:
    115  *******************************************************************************/
    116 
    117 INT
    118 FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs)
    119 {
    120   INT result;
    121 
    122   if ( startFreq < 0 || startFreq > 15) {
    123     return -1;
    124   }
    125   /* Update startFreq struct */
    126   result = getStartFreq(fs, startFreq);
    127 
    128   result = (result*fs/QMFbands+1)>>1;
    129 
    130   return (result);
    131 
    132 } /* End FDKsbrEnc_getSbrStartFreqRAW */
    133 
    134 
    135 /*******************************************************************************
    136  Functionname:  getSbrStopFreq
    137  *******************************************************************************
    138  Description:
    139 
    140  Arguments:
    141 
    142  Return:
    143  *******************************************************************************/
    144 INT FDKsbrEnc_getSbrStopFreqRAW  (INT stopFreq, INT QMFbands, INT fs)
    145 {
    146   INT result;
    147 
    148   if ( stopFreq < 0 || stopFreq > 13)
    149     return -1;
    150 
    151 
    152   /* Uppdate stopFreq struct */
    153   result = getStopFreq( fs, stopFreq, QMFbands);
    154   result =   (result*fs/QMFbands+1)>>1;
    155 
    156   return (result);
    157 } /* End getSbrStopFreq */
    158 
    159 
    160 /*******************************************************************************
    161  Functionname:  getStartFreq
    162  *******************************************************************************
    163  Description:
    164 
    165  Arguments:
    166 
    167  Return:
    168  *******************************************************************************/
    169 static INT
    170 getStartFreq(INT fs, const INT start_freq)
    171 {
    172   INT k0_min;
    173 
    174   switch(fs){
    175   case 16000: k0_min = 24;
    176     break;
    177   case 22050: k0_min = 17;
    178     break;
    179   case 24000: k0_min = 16;
    180     break;
    181   case 32000: k0_min = 16;
    182     break;
    183   case 44100: k0_min = 12;
    184     break;
    185   case 48000: k0_min = 11;
    186     break;
    187   case 64000: k0_min = 10;
    188     break;
    189   case 88200: k0_min = 7;
    190     break;
    191   case 96000: k0_min = 7;
    192     break;
    193   default:
    194     k0_min=11; /* illegal fs */
    195   }
    196 
    197 
    198   switch (fs) {
    199 
    200   case 16000:
    201     {
    202       INT v_offset[]= {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
    203       return (k0_min + v_offset[start_freq]);
    204     }
    205   case 22050:
    206     {
    207       INT v_offset[]= {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13};
    208       return (k0_min + v_offset[start_freq]);
    209     }
    210   case 24000:
    211     {
    212       INT v_offset[]= {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
    213       return (k0_min + v_offset[start_freq]);
    214     }
    215   case 32000:
    216     {
    217       INT v_offset[]= {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
    218       return (k0_min + v_offset[start_freq]);
    219     }
    220   case 44100:
    221   case 48000:
    222   case 64000:
    223     {
    224       INT v_offset[]= {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20};
    225       return (k0_min + v_offset[start_freq]);
    226     }
    227   case 88200:
    228   case 96000:
    229     {
    230       INT v_offset[]= {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24};
    231       return (k0_min + v_offset[start_freq]);
    232     }
    233   default:
    234     {
    235       INT v_offset[]= {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33};
    236       return (k0_min + v_offset[start_freq]);
    237     }
    238   }
    239 } /* End getStartFreq */
    240 
    241 
    242 /*******************************************************************************
    243  Functionname:  getStopFreq
    244  *******************************************************************************
    245  Description:
    246 
    247  Arguments:
    248 
    249  Return:
    250  *******************************************************************************/
    251  static INT
    252 getStopFreq(INT fs, const INT stop_freq, const INT noChannels)
    253 {
    254   INT result,i;
    255   INT k1_min;
    256   INT v_dstop[13];
    257 
    258 
    259   INT *v_stop_freq = NULL;
    260   INT v_stop_freq_16[14] = {48,49,50,51,52,54,55,56,57,59,60,61,63,64};
    261   INT v_stop_freq_22[14] = {35,37,38,40,42,44,46,48,51,53,56,58,61,64};
    262   INT v_stop_freq_24[14] = {32,34,36,38,40,42,44,46,49,52,55,58,61,64};
    263   INT v_stop_freq_32[14] = {32,34,36,38,40,42,44,46,49,52,55,58,61,64};
    264   INT v_stop_freq_44[14] = {23,25,27,29,32,34,37,40,43,47,51,55,59,64};
    265   INT v_stop_freq_48[14] = {21,23,25,27,30,32,35,38,42,45,49,54,59,64};
    266   INT v_stop_freq_64[14] = {20,22,24,26,29,31,34,37,41,45,49,54,59,64};
    267   INT v_stop_freq_88[14] = {15,17,19,21,23,26,29,33,37,41,46,51,57,64};
    268   INT v_stop_freq_96[14] = {13,15,17,19,21,24,27,31,35,39,44,50,57,64};
    269 
    270   switch(fs){
    271   case 16000: k1_min = 48;
    272               v_stop_freq =v_stop_freq_16;
    273     break;
    274   case 22050: k1_min = 35;
    275               v_stop_freq =v_stop_freq_22;
    276     break;
    277   case 24000: k1_min = 32;
    278               v_stop_freq =v_stop_freq_24;
    279     break;
    280   case 32000: k1_min = 32;
    281               v_stop_freq =v_stop_freq_32;
    282     break;
    283   case 44100: k1_min = 23;
    284               v_stop_freq =v_stop_freq_44;
    285     break;
    286   case 48000: k1_min = 21;
    287               v_stop_freq =v_stop_freq_48;
    288     break;
    289   case 64000: k1_min = 20;
    290               v_stop_freq =v_stop_freq_64;
    291     break;
    292   case 88200: k1_min = 15;
    293               v_stop_freq =v_stop_freq_88;
    294     break;
    295   case 96000: k1_min = 13;
    296               v_stop_freq =v_stop_freq_96;
    297     break;
    298   default:
    299     k1_min = 21; /* illegal fs  */
    300   }
    301 
    302 
    303   /* Ensure increasing bandwidth */
    304   for(i = 0; i <= 12; i++) {
    305     v_dstop[i] = v_stop_freq[i+1] - v_stop_freq[i];
    306   }
    307 
    308   FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */
    309 
    310   result = k1_min;
    311   for(i = 0; i < stop_freq; i++) {
    312     result = result + v_dstop[i];
    313   }
    314 
    315   return(result);
    316 
    317 }/* End getStopFreq */
    318 
    319 
    320 /*******************************************************************************
    321  Functionname:  FDKsbrEnc_FindStartAndStopBand
    322  *******************************************************************************
    323  Description:
    324 
    325  Arguments:
    326 
    327  Return:
    328  *******************************************************************************/
    329 INT
    330 FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq,
    331                      const INT noChannels,
    332                      const INT startFreq,
    333                      const INT stopFreq,
    334                      const SR_MODE sampleRateMode,
    335                      INT *k0,
    336                      INT *k2)
    337 {
    338 
    339   /* Update startFreq struct */
    340   *k0 = getStartFreq(samplingFreq, startFreq);
    341 
    342   /* Test if start freq is outside corecoder range */
    343   if( ( sampleRateMode == 1 ) &&
    344       ( samplingFreq*noChannels  <
    345         2**k0 * samplingFreq) ) {
    346     return (1); /* raise the cross-over frequency and/or lower the number
    347                    of target bands per octave (or lower the sampling frequency) */
    348   }
    349 
    350   /*Update stopFreq struct */
    351   if ( stopFreq < 14 ) {
    352     *k2 = getStopFreq(samplingFreq, stopFreq, noChannels);
    353   } else if( stopFreq == 14 ) {
    354     *k2 = 2 * *k0;
    355   } else {
    356     *k2 = 3 * *k0;
    357   }
    358 
    359   /* limit to Nyqvist */
    360   if (*k2 > noChannels) {
    361     *k2 = noChannels;
    362   }
    363 
    364 
    365 
    366   /* Test for invalid  k0 k2 combinations */
    367   if ( (samplingFreq == 44100) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) )
    368     return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs=44.1kHz */
    369 
    370   if ( (samplingFreq >= 48000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) )
    371     return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs>=48kHz */
    372 
    373   if ((*k2 - *k0) > MAX_FREQ_COEFFS)
    374     return (1);/*Number of bands exceeds valid range of MAX_FREQ_COEFFS */
    375 
    376   if ((*k2 - *k0) < 0)
    377     return (1);/* Number of bands is negative */
    378 
    379 
    380   return(0);
    381 }
    382 
    383 /*******************************************************************************
    384  Functionname:  FDKsbrEnc_UpdateFreqScale
    385  *******************************************************************************
    386  Description:
    387 
    388  Arguments:
    389 
    390  Return:
    391  *******************************************************************************/
    392 INT
    393 FDKsbrEnc_UpdateFreqScale(UCHAR  *v_k_master, INT *h_num_bands,
    394                 const INT k0, const INT k2,
    395                 const INT freqScale,
    396                 const INT alterScale)
    397 
    398 {
    399 
    400   INT     b_p_o = 0;        /* bands_per_octave */
    401   FIXP_DBL   warp = FL2FXCONST_DBL(0.0f);
    402   INT     dk = 0;
    403 
    404   /* Internal variables */
    405   INT     k1 = 0, i;
    406   INT     num_bands0;
    407   INT     num_bands1;
    408   INT     diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
    409   INT     *diff0 = diff_tot;
    410   INT     *diff1 = diff_tot+MAX_OCTAVE;
    411   INT     k2_achived;
    412   INT     k2_diff;
    413   INT     incr = 0;
    414 
    415   /* Init */
    416   if (freqScale==1)  b_p_o = 12;
    417   if (freqScale==2)  b_p_o = 10;
    418   if (freqScale==3)  b_p_o = 8;
    419 
    420 
    421   if(freqScale > 0) /*Bark*/
    422     {
    423       if(alterScale==0)
    424         warp = FL2FXCONST_DBL(0.5f);        /* 1.0/(1.0*2.0) */
    425       else
    426         warp = FL2FXCONST_DBL(1.0f/2.6f);   /* 1.0/(1.3*2.0); */
    427 
    428 
    429       if(4*k2 >= 9*k0)  /*two or more regions*/
    430         {
    431           k1=2*k0;
    432 
    433           num_bands0=numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
    434           num_bands1=numberOfBands(b_p_o, k1, k2, warp);
    435 
    436           CalcBands(diff0, k0, k1, num_bands0);/*CalcBands1 => diff0 */
    437           FDKsbrEnc_Shellsort_int( diff0, num_bands0);/*SortBands sort diff0 */
    438 
    439           if (diff0[0] == 0) /* too wide FB bands for target tuning */
    440           {
    441             return (1);/* raise the cross-over frequency and/or lower the number
    442                           of target bands per octave (or lower the sampling frequency */
    443           }
    444 
    445           cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */
    446 
    447           CalcBands(diff1, k1, k2, num_bands1);     /* CalcBands2 => diff1 */
    448           FDKsbrEnc_Shellsort_int( diff1, num_bands1);            /* SortBands sort diff1 */
    449           if(diff0[num_bands0-1] > diff1[0])        /* max(1) > min(2) */
    450             {
    451               if(modifyBands(diff0[num_bands0-1],diff1, num_bands1))
    452                 return(1);
    453             }
    454 
    455           /* Add 2'nd region */
    456           cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
    457           *h_num_bands=num_bands0+num_bands1;     /* Output nr of bands */
    458 
    459         }
    460       else /* one region */
    461         {
    462           k1=k2;
    463 
    464           num_bands0=numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
    465           CalcBands(diff0, k0, k1, num_bands0);/* CalcBands1 => diff0 */
    466           FDKsbrEnc_Shellsort_int( diff0, num_bands0);       /* SortBands sort diff0 */
    467 
    468           if (diff0[0] == 0) /* too wide FB bands for target tuning */
    469           {
    470             return (1); /* raise the cross-over frequency and/or lower the number
    471                            of target bands per octave (or lower the sampling frequency */
    472           }
    473 
    474           cumSum(k0, diff0, num_bands0, v_k_master);/* cumsum */
    475           *h_num_bands=num_bands0;        /* Output nr of bands */
    476 
    477         }
    478     }
    479   else /* Linear mode */
    480     {
    481       if (alterScale==0) {
    482         dk = 1;
    483         num_bands0 = 2 * ((k2 - k0)/2);         /* FLOOR to get to few number of bands*/
    484       } else {
    485         dk = 2;
    486         num_bands0 = 2 * (((k2 - k0)/dk +1)/2); /* ROUND to get closest fit */
    487       }
    488 
    489       k2_achived = k0 + num_bands0*dk;
    490       k2_diff = k2 - k2_achived;
    491 
    492       for(i=0;i<num_bands0;i++)
    493         diff_tot[i] = dk;
    494 
    495       /* If linear scale wasn't achived */
    496       /* and we got wide SBR are */
    497       if (k2_diff < 0) {
    498           incr = 1;
    499           i = 0;
    500       }
    501 
    502       /* If linear scale wasn't achived */
    503       /* and we got small SBR are */
    504       if (k2_diff > 0) {
    505           incr = -1;
    506           i = num_bands0-1;
    507       }
    508 
    509       /* Adjust diff vector to get sepc. SBR range */
    510       while (k2_diff != 0) {
    511         diff_tot[i] = diff_tot[i] - incr;
    512         i = i + incr;
    513         k2_diff = k2_diff + incr;
    514       }
    515 
    516       cumSum(k0, diff_tot, num_bands0, v_k_master);/* cumsum */
    517       *h_num_bands=num_bands0;        /* Output nr of bands */
    518 
    519     }
    520 
    521   if (*h_num_bands < 1)
    522     return(1); /*To small sbr area */
    523 
    524   return (0);
    525 }/* End FDKsbrEnc_UpdateFreqScale */
    526 
    527 static INT
    528 numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor)
    529 {
    530   INT result=0;
    531   /* result = 2* (INT) ( (double)b_p_o * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) * (double)FX_DBL2FL(warp_factor) + 0.5); */
    532   result = ( ( b_p_o * fMult( (CalcLdInt(stop) - CalcLdInt(start)),  warp_factor) + (FL2FX_DBL(0.5f)>>LD_DATA_SHIFT)
    533                ) >> ((DFRACT_BITS-1)-LD_DATA_SHIFT) ) << 1; /* do not optimize anymore (rounding!!) */
    534 
    535   return(result);
    536 }
    537 
    538 
    539 static void
    540 CalcBands(INT * diff, INT start , INT stop , INT num_bands)
    541 {
    542     INT i, qb, qe, qtmp;
    543     INT previous;
    544     INT current;
    545     FIXP_DBL base, exp, tmp;
    546 
    547     previous=start;
    548     for(i=1; i<= num_bands; i++)
    549     {
    550         base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb);
    551         exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe);
    552         tmp = fPow(base, qb, exp, qe, &qtmp);
    553         tmp = fMult(tmp, (FIXP_DBL)(start<<24));
    554         current   = (INT)scaleValue(tmp, qtmp-23);
    555         current   = (current+1) >> 1; /* rounding*/
    556         diff[i-1] = current-previous;
    557         previous  = current;
    558     }
    559 
    560 }/* End CalcBands */
    561 
    562 
    563 static void
    564 cumSum(INT start_value, INT* diff, INT length,  UCHAR *start_adress)
    565 {
    566   INT i;
    567   start_adress[0]=start_value;
    568   for(i=1;i<=length;i++)
    569     start_adress[i]=start_adress[i-1]+diff[i-1];
    570 } /* End cumSum */
    571 
    572 
    573 static INT
    574 modifyBands(INT max_band_previous, INT * diff, INT length)
    575 {
    576   INT change=max_band_previous-diff[0];
    577 
    578   /* Limit the change so that the last band cannot get narrower than the first one */
    579   if ( change > (diff[length-1] - diff[0]) / 2 )
    580     change = (diff[length-1] - diff[0]) / 2;
    581 
    582   diff[0] += change;
    583   diff[length-1] -= change;
    584   FDKsbrEnc_Shellsort_int(diff, length);
    585 
    586   return(0);
    587 }/* End modifyBands */
    588 
    589 
    590 /*******************************************************************************
    591  Functionname:  FDKsbrEnc_UpdateHiRes
    592  *******************************************************************************
    593  Description:
    594 
    595  Arguments:
    596 
    597  Return:
    598  *******************************************************************************/
    599 INT
    600 FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires,UCHAR * v_k_master,
    601             INT num_master , INT *xover_band, SR_MODE drOrSr,
    602             INT noQMFChannels)
    603 {
    604   INT i;
    605   INT divider;
    606   INT max1,max2;
    607 
    608   /* Check if we use a Dual rate => diver=2 else 1 */
    609   divider = (drOrSr == DUAL_RATE) ? 2 : 1;
    610 
    611   if( (v_k_master[*xover_band] > (noQMFChannels/divider) ) ||
    612       ( *xover_band > num_master ) )  {
    613       /* xover_band error, too big for this startFreq. Will be clipped */
    614 
    615     /* Calculate maximum value for xover_band */
    616     max1=0;
    617     max2=num_master;
    618     while( (v_k_master[max1+1] < (noQMFChannels/divider)) &&
    619            ( (max1+1) < max2) )
    620       {
    621         max1++;
    622       }
    623 
    624     *xover_band=max1;
    625   }
    626 
    627   *num_hires = num_master - *xover_band;
    628   for(i = *xover_band; i <= num_master; i++)
    629     {
    630       h_hires[i - *xover_band] = v_k_master[i];
    631     }
    632 
    633   return (0);
    634 }/* End FDKsbrEnc_UpdateHiRes */
    635 
    636 
    637 /*******************************************************************************
    638  Functionname:  FDKsbrEnc_UpdateLoRes
    639  *******************************************************************************
    640  Description:
    641 
    642  Arguments:
    643 
    644  Return:
    645  *******************************************************************************/
    646 void
    647 FDKsbrEnc_UpdateLoRes(UCHAR * h_lores, INT *num_lores, UCHAR * h_hires, INT num_hires)
    648 {
    649   INT i;
    650 
    651   if(num_hires%2 == 0) /* if even number of hires bands */
    652     {
    653       *num_lores=num_hires/2;
    654       /* Use every second lores=hires[0,2,4...] */
    655       for(i=0;i<=*num_lores;i++)
    656         h_lores[i]=h_hires[i*2];
    657 
    658     }
    659   else            /* odd number of hires which means xover is odd */
    660     {
    661       *num_lores=(num_hires+1)/2;
    662 
    663       /* Use lores=hires[0,1,3,5 ...] */
    664       h_lores[0]=h_hires[0];
    665       for(i=1;i<=*num_lores;i++)
    666         {
    667           h_lores[i]=h_hires[i*2-1];
    668         }
    669     }
    670 
    671 }/* End FDKsbrEnc_UpdateLoRes */
    672