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