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 - 2013 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   \author Tobias Chalupka
     88 */
     89 
     90 #include "sbrenc_freq_sca.h"
     91 #include "sbr_misc.h"
     92 
     93 #include "genericStds.h"
     94 
     95 /*  StartFreq */
     96 static INT getStartFreq(INT fsCore, const INT start_freq);
     97 
     98 /* StopFreq */
     99 static INT getStopFreq(INT fsCore, const INT stop_freq);
    100 
    101 static INT  numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor);
    102 static void CalcBands(INT * diff, INT start , INT stop , INT num_bands);
    103 static INT  modifyBands(INT max_band, INT * diff, INT length);
    104 static void cumSum(INT start_value, INT* diff, INT length, UCHAR  *start_adress);
    105 
    106 
    107 
    108 /*******************************************************************************
    109  Functionname:  FDKsbrEnc_getSbrStartFreqRAW
    110  *******************************************************************************
    111  Description:
    112 
    113  Arguments:
    114 
    115  Return:
    116  *******************************************************************************/
    117 
    118 INT
    119 FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT fsCore)
    120 {
    121   INT result;
    122 
    123   if ( startFreq < 0 || startFreq > 15) {
    124     return -1;
    125   }
    126   /* Update startFreq struct */
    127   result = getStartFreq(fsCore, startFreq);
    128 
    129   result = (result*(fsCore>>5)+1)>>1; /* (result*fsSBR/QMFbands+1)>>1; */
    130 
    131   return (result);
    132 
    133 } /* End FDKsbrEnc_getSbrStartFreqRAW */
    134 
    135 
    136 /*******************************************************************************
    137  Functionname:  getSbrStopFreq
    138  *******************************************************************************
    139  Description:
    140 
    141  Arguments:
    142 
    143  Return:
    144  *******************************************************************************/
    145 INT FDKsbrEnc_getSbrStopFreqRAW  (INT stopFreq, INT fsCore)
    146 {
    147   INT result;
    148 
    149   if ( stopFreq < 0 || stopFreq > 13)
    150     return -1;
    151 
    152   /* Uppdate stopFreq struct */
    153   result = getStopFreq(fsCore, stopFreq);
    154   result = (result*(fsCore>>5)+1)>>1; /* (result*fsSBR/QMFbands+1)>>1; */
    155 
    156   return (result);
    157 } /* End getSbrStopFreq */
    158 
    159 
    160 /*******************************************************************************
    161  Functionname:  getStartFreq
    162  *******************************************************************************
    163  Description:
    164 
    165  Arguments:  fsCore - core sampling rate
    166 
    167 
    168  Return:
    169  *******************************************************************************/
    170 static INT
    171 getStartFreq(INT fsCore, const INT start_freq)
    172 {
    173   INT k0_min;
    174 
    175   switch(fsCore){
    176   case  8000: k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
    177     break;
    178   case 11025: k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
    179     break;
    180   case 12000: k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
    181     break;
    182   case 16000: k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
    183     break;
    184   case 22050: k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
    185     break;
    186   case 24000: k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
    187     break;
    188   case 32000: k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
    189     break;
    190   case 44100: k0_min = 7;  /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
    191     break;
    192   case 48000: k0_min = 7;  /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
    193     break;
    194   case 96000: k0_min = 3;  /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
    195     break;
    196   default:
    197     k0_min=11; /* illegal fs */
    198   }
    199 
    200 
    201   switch (fsCore) {
    202 
    203   case  8000:
    204     {
    205       INT v_offset[]= {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
    206       return (k0_min + v_offset[start_freq]);
    207     }
    208   case 11025:
    209     {
    210       INT v_offset[]= {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13};
    211       return (k0_min + v_offset[start_freq]);
    212     }
    213   case 12000:
    214     {
    215       INT v_offset[]= {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
    216       return (k0_min + v_offset[start_freq]);
    217     }
    218   case 16000:
    219     {
    220       INT v_offset[]= {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
    221       return (k0_min + v_offset[start_freq]);
    222     }
    223   case 22050:
    224   case 24000:
    225   case 32000:
    226     {
    227       INT v_offset[]= {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20};
    228       return (k0_min + v_offset[start_freq]);
    229     }
    230   case 44100:
    231   case 48000:
    232   case 96000:
    233     {
    234       INT v_offset[]= {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24};
    235       return (k0_min + v_offset[start_freq]);
    236     }
    237   default:
    238     {
    239       INT v_offset[]= {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33};
    240       return (k0_min + v_offset[start_freq]);
    241     }
    242   }
    243 } /* End getStartFreq */
    244 
    245 
    246 /*******************************************************************************
    247  Functionname:  getStopFreq
    248  *******************************************************************************
    249  Description:
    250 
    251  Arguments:
    252 
    253  Return:
    254  *******************************************************************************/
    255  static INT
    256 getStopFreq(INT fsCore, const INT stop_freq)
    257 {
    258   INT result,i;
    259   INT k1_min;
    260   INT v_dstop[13];
    261 
    262   INT *v_stop_freq = NULL;
    263   INT v_stop_freq_16[14] = {48,49,50,51,52,54,55,56,57,59,60,61,63,64};
    264   INT v_stop_freq_22[14] = {35,37,38,40,42,44,46,48,51,53,56,58,61,64};
    265   INT v_stop_freq_24[14] = {32,34,36,38,40,42,44,46,49,52,55,58,61,64};
    266   INT v_stop_freq_32[14] = {32,34,36,38,40,42,44,46,49,52,55,58,61,64};
    267   INT v_stop_freq_44[14] = {23,25,27,29,32,34,37,40,43,47,51,55,59,64};
    268   INT v_stop_freq_48[14] = {21,23,25,27,30,32,35,38,42,45,49,54,59,64};
    269   INT v_stop_freq_64[14] = {20,22,24,26,29,31,34,37,41,45,49,54,59,64};
    270   INT v_stop_freq_88[14] = {15,17,19,21,23,26,29,33,37,41,46,51,57,64};
    271   INT v_stop_freq_96[14] = {13,15,17,19,21,24,27,31,35,39,44,50,57,64};
    272   INT v_stop_freq_192[14] = {7, 8,10,12,14,16,19,23,27,32,38,46,54,64};
    273 
    274   switch(fsCore){
    275   case  8000: k1_min = 48;
    276               v_stop_freq =v_stop_freq_16;
    277     break;
    278   case 11025: k1_min = 35;
    279               v_stop_freq =v_stop_freq_22;
    280     break;
    281   case 12000: k1_min = 32;
    282               v_stop_freq =v_stop_freq_24;
    283     break;
    284   case 16000: k1_min = 32;
    285               v_stop_freq =v_stop_freq_32;
    286     break;
    287   case 22050: k1_min = 23;
    288               v_stop_freq =v_stop_freq_44;
    289     break;
    290   case 24000: k1_min = 21;
    291               v_stop_freq =v_stop_freq_48;
    292     break;
    293   case 32000: k1_min = 20;
    294               v_stop_freq =v_stop_freq_64;
    295     break;
    296   case 44100: k1_min = 15;
    297               v_stop_freq =v_stop_freq_88;
    298     break;
    299   case 48000: k1_min = 13;
    300               v_stop_freq =v_stop_freq_96;
    301     break;
    302   case 96000: k1_min =  7;
    303               v_stop_freq =v_stop_freq_192;
    304     break;
    305   default:
    306     k1_min = 21; /* illegal fs  */
    307   }
    308 
    309   /* if no valid core samplingrate is used this loop produces
    310      a segfault, because v_stop_freq is not initialized */
    311   /* Ensure increasing bandwidth */
    312   for(i = 0; i <= 12; i++) {
    313     v_dstop[i] = v_stop_freq[i+1] - v_stop_freq[i];
    314   }
    315 
    316   FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */
    317 
    318   result = k1_min;
    319   for(i = 0; i < stop_freq; i++) {
    320     result = result + v_dstop[i];
    321   }
    322 
    323   return(result);
    324 
    325 }/* End getStopFreq */
    326 
    327 
    328 /*******************************************************************************
    329  Functionname:  FDKsbrEnc_FindStartAndStopBand
    330  *******************************************************************************
    331  Description:
    332 
    333  Arguments:     srSbr            SBR sampling freqency
    334                 srCore           AAC core sampling freqency
    335                 noChannels       Number of QMF channels
    336                 startFreq        SBR start frequency in QMF bands
    337                 stopFreq         SBR start frequency in QMF bands
    338 
    339                *k0               Output parameter
    340                *k2               Output parameter
    341 
    342  Return:       Error code (0 is OK)
    343  *******************************************************************************/
    344 INT
    345 FDKsbrEnc_FindStartAndStopBand(
    346         const INT srSbr,
    347         const INT srCore,
    348         const INT noChannels,
    349         const INT startFreq,
    350         const INT stopFreq,
    351         INT *k0,
    352         INT *k2
    353         )
    354 {
    355 
    356   /* Update startFreq struct */
    357   *k0 = getStartFreq(srCore, startFreq);
    358 
    359   /* Test if start freq is outside corecoder range */
    360   if( srSbr*noChannels < *k0 * srCore ) {
    361     return (1); /* raise the cross-over frequency and/or lower the number
    362                    of target bands per octave (or lower the sampling frequency) */
    363   }
    364 
    365   /*Update stopFreq struct */
    366   if ( stopFreq < 14 ) {
    367     *k2 = getStopFreq(srCore, stopFreq);
    368   } else if( stopFreq == 14 ) {
    369     *k2 = 2 * *k0;
    370   } else {
    371     *k2 = 3 * *k0;
    372   }
    373 
    374   /* limit to Nyqvist */
    375   if (*k2 > noChannels) {
    376     *k2 = noChannels;
    377   }
    378 
    379 
    380 
    381   /* Test for invalid  k0 k2 combinations */
    382   if ( (srCore == 22050) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) )
    383     return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs=44.1kHz */
    384 
    385   if ( (srCore >= 24000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) )
    386     return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs>=48kHz */
    387 
    388   if ((*k2 - *k0) > MAX_FREQ_COEFFS)
    389     return (1);/*Number of bands exceeds valid range of MAX_FREQ_COEFFS */
    390 
    391   if ((*k2 - *k0) < 0)
    392     return (1);/* Number of bands is negative */
    393 
    394 
    395   return(0);
    396 }
    397 
    398 /*******************************************************************************
    399  Functionname:  FDKsbrEnc_UpdateFreqScale
    400  *******************************************************************************
    401  Description:
    402 
    403  Arguments:
    404 
    405  Return:
    406  *******************************************************************************/
    407 INT
    408 FDKsbrEnc_UpdateFreqScale(
    409         UCHAR     *v_k_master,
    410         INT       *h_num_bands,
    411         const INT  k0,
    412         const INT  k2,
    413         const INT  freqScale,
    414         const INT  alterScale
    415         )
    416 
    417 {
    418 
    419   INT     b_p_o = 0;        /* bands_per_octave */
    420   FIXP_DBL warp = FL2FXCONST_DBL(0.0f);
    421   INT     dk = 0;
    422 
    423   /* Internal variables */
    424   INT     k1 = 0, i;
    425   INT     num_bands0;
    426   INT     num_bands1;
    427   INT     diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
    428   INT     *diff0 = diff_tot;
    429   INT     *diff1 = diff_tot+MAX_OCTAVE;
    430   INT     k2_achived;
    431   INT     k2_diff;
    432   INT     incr = 0;
    433 
    434   /* Init */
    435   if (freqScale==1)  b_p_o = 12;
    436   if (freqScale==2)  b_p_o = 10;
    437   if (freqScale==3)  b_p_o = 8;
    438 
    439 
    440   if(freqScale > 0) /*Bark*/
    441     {
    442       if(alterScale==0)
    443         warp = FL2FXCONST_DBL(0.5f);        /* 1.0/(1.0*2.0) */
    444       else
    445         warp = FL2FXCONST_DBL(1.0f/2.6f);   /* 1.0/(1.3*2.0); */
    446 
    447 
    448       if(4*k2 >= 9*k0)  /*two or more regions (how many times the basis band is copied)*/
    449         {
    450           k1=2*k0;
    451 
    452           num_bands0=numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
    453           num_bands1=numberOfBands(b_p_o, k1, k2, warp);
    454 
    455           CalcBands(diff0, k0, k1, num_bands0);/*CalcBands1 => diff0 */
    456           FDKsbrEnc_Shellsort_int( diff0, num_bands0);/*SortBands sort diff0 */
    457 
    458           if (diff0[0] == 0) /* too wide FB bands for target tuning */
    459           {
    460             return (1);/* raise the cross-over frequency and/or lower the number
    461                           of target bands per octave (or lower the sampling frequency */
    462           }
    463 
    464           cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */
    465 
    466           CalcBands(diff1, k1, k2, num_bands1);     /* CalcBands2 => diff1 */
    467           FDKsbrEnc_Shellsort_int( diff1, num_bands1);            /* SortBands sort diff1 */
    468           if(diff0[num_bands0-1] > diff1[0])        /* max(1) > min(2) */
    469             {
    470               if(modifyBands(diff0[num_bands0-1],diff1, num_bands1))
    471                 return(1);
    472             }
    473 
    474           /* Add 2'nd region */
    475           cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
    476           *h_num_bands=num_bands0+num_bands1;     /* Output nr of bands */
    477 
    478         }
    479       else /* one region */
    480         {
    481           k1=k2;
    482 
    483           num_bands0=numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
    484           CalcBands(diff0, k0, k1, num_bands0);/* CalcBands1 => diff0 */
    485           FDKsbrEnc_Shellsort_int( diff0, num_bands0);       /* SortBands sort diff0 */
    486 
    487           if (diff0[0] == 0) /* too wide FB bands for target tuning */
    488           {
    489             return (1); /* raise the cross-over frequency and/or lower the number
    490                            of target bands per octave (or lower the sampling frequency */
    491           }
    492 
    493           cumSum(k0, diff0, num_bands0, v_k_master);/* cumsum */
    494           *h_num_bands=num_bands0;        /* Output nr of bands */
    495 
    496         }
    497     }
    498   else /* Linear mode */
    499     {
    500       if (alterScale==0) {
    501         dk = 1;
    502         num_bands0 = 2 * ((k2 - k0)/2);         /* FLOOR to get to few number of bands*/
    503       } else {
    504         dk = 2;
    505         num_bands0 = 2 * (((k2 - k0)/dk +1)/2); /* ROUND to get closest fit */
    506       }
    507 
    508       k2_achived = k0 + num_bands0*dk;
    509       k2_diff = k2 - k2_achived;
    510 
    511       for(i=0;i<num_bands0;i++)
    512         diff_tot[i] = dk;
    513 
    514       /* If linear scale wasn't achived */
    515       /* and we got wide SBR are */
    516       if (k2_diff < 0) {
    517           incr = 1;
    518           i = 0;
    519       }
    520 
    521       /* If linear scale wasn't achived */
    522       /* and we got small SBR are */
    523       if (k2_diff > 0) {
    524           incr = -1;
    525           i = num_bands0-1;
    526       }
    527 
    528       /* Adjust diff vector to get sepc. SBR range */
    529       while (k2_diff != 0) {
    530         diff_tot[i] = diff_tot[i] - incr;
    531         i = i + incr;
    532         k2_diff = k2_diff + incr;
    533       }
    534 
    535       cumSum(k0, diff_tot, num_bands0, v_k_master);/* cumsum */
    536       *h_num_bands=num_bands0;        /* Output nr of bands */
    537 
    538     }
    539 
    540   if (*h_num_bands < 1)
    541     return(1); /*To small sbr area */
    542 
    543   return (0);
    544 }/* End FDKsbrEnc_UpdateFreqScale */
    545 
    546 static INT
    547 numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor)
    548 {
    549   INT result=0;
    550   /* result = 2* (INT) ( (double)b_p_o * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) * (double)FX_DBL2FL(warp_factor) + 0.5); */
    551   result = ( ( b_p_o * fMult( (CalcLdInt(stop) - CalcLdInt(start)),  warp_factor) + (FL2FX_DBL(0.5f)>>LD_DATA_SHIFT)
    552                ) >> ((DFRACT_BITS-1)-LD_DATA_SHIFT) ) << 1; /* do not optimize anymore (rounding!!) */
    553 
    554   return(result);
    555 }
    556 
    557 
    558 static void
    559 CalcBands(INT * diff, INT start , INT stop , INT num_bands)
    560 {
    561     INT i, qb, qe, qtmp;
    562     INT previous;
    563     INT current;
    564     FIXP_DBL base, exp, tmp;
    565 
    566     previous=start;
    567     for(i=1; i<= num_bands; i++)
    568     {
    569         base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb);
    570         exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe);
    571         tmp = fPow(base, qb, exp, qe, &qtmp);
    572         tmp = fMult(tmp, (FIXP_DBL)(start<<24));
    573         current   = (INT)scaleValue(tmp, qtmp-23);
    574         current   = (current+1) >> 1; /* rounding*/
    575         diff[i-1] = current-previous;
    576         previous  = current;
    577     }
    578 
    579 }/* End CalcBands */
    580 
    581 
    582 static void
    583 cumSum(INT start_value, INT* diff, INT length,  UCHAR *start_adress)
    584 {
    585   INT i;
    586   start_adress[0]=start_value;
    587   for(i=1;i<=length;i++)
    588     start_adress[i]=start_adress[i-1]+diff[i-1];
    589 } /* End cumSum */
    590 
    591 
    592 static INT
    593 modifyBands(INT max_band_previous, INT * diff, INT length)
    594 {
    595   INT change=max_band_previous-diff[0];
    596 
    597   /* Limit the change so that the last band cannot get narrower than the first one */
    598   if ( change > (diff[length-1] - diff[0]) / 2 )
    599     change = (diff[length-1] - diff[0]) / 2;
    600 
    601   diff[0] += change;
    602   diff[length-1] -= change;
    603   FDKsbrEnc_Shellsort_int(diff, length);
    604 
    605   return(0);
    606 }/* End modifyBands */
    607 
    608 
    609 /*******************************************************************************
    610  Functionname:  FDKsbrEnc_UpdateHiRes
    611  *******************************************************************************
    612  Description:
    613 
    614 
    615  Arguments:
    616 
    617  Return:
    618  *******************************************************************************/
    619 INT
    620 FDKsbrEnc_UpdateHiRes(
    621         UCHAR   *h_hires,
    622         INT     *num_hires,
    623         UCHAR   *v_k_master,
    624         INT      num_master,
    625         INT     *xover_band
    626         )
    627 {
    628   INT i;
    629   INT max1,max2;
    630 
    631   if( (v_k_master[*xover_band] > 32 ) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */
    632       ( *xover_band > num_master ) )  {
    633       /* xover_band error, too big for this startFreq. Will be clipped */
    634 
    635     /* Calculate maximum value for xover_band */
    636     max1=0;
    637     max2=num_master;
    638     while( (v_k_master[max1+1] < 32 ) && /* noQMFChannels(dualRate)/divider */
    639            ( (max1+1) < max2) )
    640       {
    641         max1++;
    642       }
    643 
    644     *xover_band=max1;
    645   }
    646 
    647   *num_hires = num_master - *xover_band;
    648   for(i = *xover_band; i <= num_master; i++)
    649     {
    650       h_hires[i - *xover_band] = v_k_master[i];
    651     }
    652 
    653   return (0);
    654 }/* End FDKsbrEnc_UpdateHiRes */
    655 
    656 
    657 /*******************************************************************************
    658  Functionname:  FDKsbrEnc_UpdateLoRes
    659  *******************************************************************************
    660  Description:
    661 
    662  Arguments:
    663 
    664  Return:
    665  *******************************************************************************/
    666 void
    667 FDKsbrEnc_UpdateLoRes(UCHAR * h_lores, INT *num_lores, UCHAR * h_hires, INT num_hires)
    668 {
    669   INT i;
    670 
    671   if(num_hires%2 == 0) /* if even number of hires bands */
    672     {
    673       *num_lores=num_hires/2;
    674       /* Use every second lores=hires[0,2,4...] */
    675       for(i=0;i<=*num_lores;i++)
    676         h_lores[i]=h_hires[i*2];
    677 
    678     }
    679   else            /* odd number of hires which means xover is odd */
    680     {
    681       *num_lores=(num_hires+1)/2;
    682 
    683       /* Use lores=hires[0,1,3,5 ...] */
    684       h_lores[0]=h_hires[0];
    685       for(i=1;i<=*num_lores;i++)
    686         {
    687           h_lores[i]=h_hires[i*2-1];
    688         }
    689     }
    690 
    691 }/* End FDKsbrEnc_UpdateLoRes */
    692