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 #include "fram_gen.h"
    104 #include "sbr_misc.h"
    105 
    106 #include "genericStds.h"
    107 
    108 static const SBR_FRAME_INFO frameInfo1_2048 = {1, {0, 16}, {FREQ_RES_HIGH},
    109                                                0, 1,       {0, 16}};
    110 
    111 static const SBR_FRAME_INFO frameInfo2_2048 = {
    112     2, {0, 8, 16}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 8, 16}};
    113 
    114 static const SBR_FRAME_INFO frameInfo4_2048 = {
    115     4,
    116     {0, 4, 8, 12, 16},
    117     {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
    118     0,
    119     2,
    120     {0, 8, 16}};
    121 
    122 static const SBR_FRAME_INFO frameInfo1_2304 = {1, {0, 18}, {FREQ_RES_HIGH},
    123                                                0, 1,       {0, 18}};
    124 
    125 static const SBR_FRAME_INFO frameInfo2_2304 = {
    126     2, {0, 9, 18}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 9, 18}};
    127 
    128 static const SBR_FRAME_INFO frameInfo4_2304 = {
    129     4,
    130     {0, 5, 9, 14, 18},
    131     {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
    132     0,
    133     2,
    134     {0, 9, 18}};
    135 
    136 static const SBR_FRAME_INFO frameInfo1_1920 = {1, {0, 15}, {FREQ_RES_HIGH},
    137                                                0, 1,       {0, 15}};
    138 
    139 static const SBR_FRAME_INFO frameInfo2_1920 = {
    140     2, {0, 8, 15}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 8, 15}};
    141 
    142 static const SBR_FRAME_INFO frameInfo4_1920 = {
    143     4,
    144     {0, 4, 8, 12, 15},
    145     {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
    146     0,
    147     2,
    148     {0, 8, 15}};
    149 
    150 static const SBR_FRAME_INFO frameInfo1_1152 = {1, {0, 9}, {FREQ_RES_HIGH},
    151                                                0, 1,      {0, 9}};
    152 
    153 static const SBR_FRAME_INFO frameInfo2_1152 = {
    154     2, {0, 5, 9}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 5, 9}};
    155 
    156 static const SBR_FRAME_INFO frameInfo4_1152 = {
    157     4,
    158     {0, 2, 5, 7, 9},
    159     {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
    160     0,
    161     2,
    162     {0, 5, 9}};
    163 
    164 /* AACLD frame info */
    165 static const SBR_FRAME_INFO frameInfo1_512LD = {1, {0, 8}, {FREQ_RES_HIGH},
    166                                                 0, 1,      {0, 8}};
    167 
    168 static const SBR_FRAME_INFO frameInfo2_512LD = {
    169     2, {0, 4, 8}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 4, 8}};
    170 
    171 static const SBR_FRAME_INFO frameInfo4_512LD = {
    172     4,
    173     {0, 2, 4, 6, 8},
    174     {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
    175     0,
    176     2,
    177     {0, 4, 8}};
    178 
    179 static int calcFillLengthMax(
    180     int tranPos,        /*!< input : transient position (ref: tran det) */
    181     int numberTimeSlots /*!< input : number of timeslots */
    182 );
    183 
    184 static void fillFrameTran(
    185     const int *v_tuningSegm, /*!< tuning: desired segment lengths */
    186     const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */
    187     int tran,                /*!< input : position of transient */
    188     int *v_bord,             /*!< memNew: borders */
    189     int *length_v_bord,      /*!< memNew: # borders */
    190     int *v_freq,             /*!< memNew: frequency resolutions */
    191     int *length_v_freq,      /*!< memNew: # frequency resolutions */
    192     int *bmin,               /*!< hlpNew: first mandatory border */
    193     int *bmax                /*!< hlpNew: last  mandatory border */
    194 );
    195 
    196 static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq,
    197                          INT *length_v_freq, INT bmin, INT rest);
    198 
    199 static void fillFramePost(INT *parts, INT *d, INT dmax, INT *v_bord,
    200                           INT *length_v_bord, INT *v_freq, INT *length_v_freq,
    201                           INT bmax, INT bufferFrameStart, INT numberTimeSlots,
    202                           INT fmax);
    203 
    204 static void fillFrameInter(INT *nL, const int *v_tuningSegm, INT *v_bord,
    205                            INT *length_v_bord, INT bmin, INT *v_freq,
    206                            INT *length_v_freq, INT *v_bordFollow,
    207                            INT *length_v_bordFollow, INT *v_freqFollow,
    208                            INT *length_v_freqFollow, INT i_fillFollow, INT dmin,
    209                            INT dmax, INT numberTimeSlots);
    210 
    211 static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld,
    212                            INT tranFlag, INT *spreadFlag);
    213 
    214 static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord,
    215                         INT *length_v_bord, INT *v_freq, INT *length_v_freq,
    216                         INT *parts, INT d);
    217 
    218 static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord,
    219                            INT *length_v_bord, INT tran, INT bufferFrameStart,
    220                            INT numberTimeSlots);
    221 
    222 static void keepForFollowUp(INT *v_bordFollow, INT *length_v_bordFollow,
    223                             INT *v_freqFollow, INT *length_v_freqFollow,
    224                             INT *i_tranFollow, INT *i_fillFollow, INT *v_bord,
    225                             INT *length_v_bord, INT *v_freq, INT i_cmon,
    226                             INT i_tran, INT parts, INT numberTimeSlots);
    227 
    228 static void calcCtrlSignal(HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
    229                            INT *v_bord, INT length_v_bord, INT *v_freq,
    230                            INT length_v_freq, INT i_cmon, INT i_tran,
    231                            INT spreadFlag, INT nL);
    232 
    233 static void ctrlSignal2FrameInfo(HANDLE_SBR_GRID hSbrGrid,
    234                                  HANDLE_SBR_FRAME_INFO hFrameInfo,
    235                                  FREQ_RES *freq_res_fixfix);
    236 
    237 /* table for 8 time slot index */
    238 static const int envelopeTable_8[8][5] = {
    239     /* transientIndex  nEnv, tranIdx, shortEnv, border1, border2, ... */
    240     /* borders from left to right side; -1 = not in use */
    241     /*[|T-|------]*/ {2, 0, 0, 1, -1},
    242     /*[|-T-|-----]*/ {2, 0, 0, 2, -1},
    243     /*[--|T-|----]*/ {3, 1, 1, 2, 4},
    244     /*[---|T-|---]*/ {3, 1, 1, 3, 5},
    245     /*[----|T-|--]*/ {3, 1, 1, 4, 6},
    246     /*[-----|T--|]*/ {2, 1, 1, 5, -1},
    247     /*[------|T-|]*/ {2, 1, 1, 6, -1},
    248     /*[-------|T|]*/ {2, 1, 1, 7, -1},
    249 };
    250 
    251 /* table for 16 time slot index */
    252 static const int envelopeTable_16[16][6] = {
    253     /* transientIndex  nEnv, tranIdx, shortEnv, border1, border2, ... */
    254     /* length from left to right side; -1 = not in use */
    255     /*[|T---|------------|]*/ {2, 0, 0, 4, -1, -1},
    256     /*[|-T---|-----------|]*/ {2, 0, 0, 5, -1, -1},
    257     /*[|--|T---|----------]*/ {3, 1, 1, 2, 6, -1},
    258     /*[|---|T---|---------]*/ {3, 1, 1, 3, 7, -1},
    259     /*[|----|T---|--------]*/ {3, 1, 1, 4, 8, -1},
    260     /*[|-----|T---|-------]*/ {3, 1, 1, 5, 9, -1},
    261     /*[|------|T---|------]*/ {3, 1, 1, 6, 10, -1},
    262     /*[|-------|T---|-----]*/ {3, 1, 1, 7, 11, -1},
    263     /*[|--------|T---|----]*/ {3, 1, 1, 8, 12, -1},
    264     /*[|---------|T---|---]*/ {3, 1, 1, 9, 13, -1},
    265     /*[|----------|T---|--]*/ {3, 1, 1, 10, 14, -1},
    266     /*[|-----------|T----|]*/ {2, 1, 1, 11, -1, -1},
    267     /*[|------------|T---|]*/ {2, 1, 1, 12, -1, -1},
    268     /*[|-------------|T--|]*/ {2, 1, 1, 13, -1, -1},
    269     /*[|--------------|T-|]*/ {2, 1, 1, 14, -1, -1},
    270     /*[|---------------|T|]*/ {2, 1, 1, 15, -1, -1},
    271 };
    272 
    273 /* table for 15 time slot index */
    274 static const int envelopeTable_15[15][6] = {
    275     /* transientIndex  nEnv, tranIdx, shortEnv, border1, border2, ... */
    276     /* length from left to right side; -1 = not in use */
    277     /*[|T---|------------]*/ {2, 0, 0, 4, -1, -1},
    278     /*[|-T---|-----------]*/ {2, 0, 0, 5, -1, -1},
    279     /*[|--|T---|---------]*/ {3, 1, 1, 2, 6, -1},
    280     /*[|---|T---|--------]*/ {3, 1, 1, 3, 7, -1},
    281     /*[|----|T---|-------]*/ {3, 1, 1, 4, 8, -1},
    282     /*[|-----|T---|------]*/ {3, 1, 1, 5, 9, -1},
    283     /*[|------|T---|-----]*/ {3, 1, 1, 6, 10, -1},
    284     /*[|-------|T---|----]*/ {3, 1, 1, 7, 11, -1},
    285     /*[|--------|T---|---]*/ {3, 1, 1, 8, 12, -1},
    286     /*[|---------|T---|--]*/ {3, 1, 1, 9, 13, -1},
    287     /*[|----------|T----|]*/ {2, 1, 1, 10, -1, -1},
    288     /*[|-----------|T---|]*/ {2, 1, 1, 11, -1, -1},
    289     /*[|------------|T--|]*/ {2, 1, 1, 12, -1, -1},
    290     /*[|-------------|T-|]*/ {2, 1, 1, 13, -1, -1},
    291     /*[|--------------|T|]*/ {2, 1, 1, 14, -1, -1},
    292 };
    293 
    294 static const int minFrameTranDistance = 4;
    295 
    296 static const FREQ_RES freqRes_table_8[] = {
    297     FREQ_RES_LOW,  FREQ_RES_LOW,  FREQ_RES_LOW,  FREQ_RES_LOW, FREQ_RES_LOW,
    298     FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH};
    299 
    300 static const FREQ_RES freqRes_table_16[16] = {
    301     /* size of envelope */
    302     /* 0-4 */ FREQ_RES_LOW,
    303     FREQ_RES_LOW,
    304     FREQ_RES_LOW,
    305     FREQ_RES_LOW,
    306     FREQ_RES_LOW,
    307     /* 5-9 */ FREQ_RES_LOW,
    308     FREQ_RES_HIGH,
    309     FREQ_RES_HIGH,
    310     FREQ_RES_HIGH,
    311     FREQ_RES_HIGH,
    312     /* 10-16 */ FREQ_RES_HIGH,
    313     FREQ_RES_HIGH,
    314     FREQ_RES_HIGH,
    315     FREQ_RES_HIGH,
    316     FREQ_RES_HIGH,
    317     FREQ_RES_HIGH};
    318 
    319 static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
    320                                HANDLE_SBR_GRID hSbrGrid, int tranPosInternal,
    321                                int numberTimeSlots, UCHAR fResTransIsLow);
    322 
    323 /*!
    324   Functionname: FDKsbrEnc_frameInfoGenerator
    325 
    326   Description:  produces the FRAME_INFO struct for the current frame
    327 
    328   Arguments:    hSbrEnvFrame          - pointer to sbr envelope handle
    329                 v_pre_transient_info  - pointer to transient info vector
    330                 v_transient_info      - pointer to previous transient info
    331 vector v_tuning              - pointer to tuning vector
    332 
    333  Return:      frame_info        - pointer to SBR_FRAME_INFO struct
    334 
    335 *******************************************************************************/
    336 HANDLE_SBR_FRAME_INFO
    337 FDKsbrEnc_frameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
    338                              UCHAR *v_transient_info, const INT rightBorderFIX,
    339                              UCHAR *v_transient_info_pre, int ldGrid,
    340                              const int *v_tuning) {
    341   INT numEnv, tranPosInternal = 0, bmin = 0, bmax = 0, parts, d, i_cmon = 0,
    342               i_tran = 0, nL;
    343   INT fmax = 0;
    344 
    345   INT *v_bord = hSbrEnvFrame->v_bord;
    346   INT *v_freq = hSbrEnvFrame->v_freq;
    347   INT *v_bordFollow = hSbrEnvFrame->v_bordFollow;
    348   INT *v_freqFollow = hSbrEnvFrame->v_freqFollow;
    349 
    350   INT *length_v_bordFollow = &hSbrEnvFrame->length_v_bordFollow;
    351   INT *length_v_freqFollow = &hSbrEnvFrame->length_v_freqFollow;
    352   INT *length_v_bord = &hSbrEnvFrame->length_v_bord;
    353   INT *length_v_freq = &hSbrEnvFrame->length_v_freq;
    354   INT *spreadFlag = &hSbrEnvFrame->spreadFlag;
    355   INT *i_tranFollow = &hSbrEnvFrame->i_tranFollow;
    356   INT *i_fillFollow = &hSbrEnvFrame->i_fillFollow;
    357   FRAME_CLASS *frameClassOld = &hSbrEnvFrame->frameClassOld;
    358   FRAME_CLASS frameClass = FIXFIX;
    359 
    360   INT allowSpread = hSbrEnvFrame->allowSpread;
    361   INT numEnvStatic = hSbrEnvFrame->numEnvStatic;
    362   INT staticFraming = hSbrEnvFrame->staticFraming;
    363   INT dmin = hSbrEnvFrame->dmin;
    364   INT dmax = hSbrEnvFrame->dmax;
    365 
    366   INT bufferFrameStart = hSbrEnvFrame->SbrGrid.bufferFrameStart;
    367   INT numberTimeSlots = hSbrEnvFrame->SbrGrid.numberTimeSlots;
    368   INT frameMiddleSlot = hSbrEnvFrame->frameMiddleSlot;
    369 
    370   INT tranPos = v_transient_info[0];
    371   INT tranFlag = v_transient_info[1];
    372 
    373   const int *v_tuningSegm = v_tuning;
    374   const int *v_tuningFreq = v_tuning + 3;
    375 
    376   hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
    377 
    378   if (ldGrid) {
    379     /* in case there was a transient at the very end of the previous frame,
    380      * start with a transient envelope */
    381     if (!tranFlag && v_transient_info_pre[1] &&
    382         (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)) {
    383       tranFlag = 1;
    384       tranPos = 0;
    385     }
    386   }
    387 
    388   /*
    389    * Synopsis:
    390    *
    391    * The frame generator creates the time-/frequency-grid for one SBR frame.
    392    * Input signals are provided by the transient detector and the frame
    393    * splitter (transientDetectNew() & FrameSplitter() in tran_det.c).  The
    394    * framing is controlled by adjusting tuning parameters stored in
    395    * FRAME_GEN_TUNING.  The parameter values are dependent on frame lengths
    396    * and bitrates, and may in the future be signal dependent.
    397    *
    398    * The envelope borders are stored for frame generator internal use in
    399    * aBorders.  The contents of aBorders represent positions along the time
    400    * axis given in the figures in fram_gen.h (the "frame-generator" rows).
    401    * The unit is "time slot".  The figures in fram_gen.h also define the
    402    * detection ranges for the transient detector.  For every border in
    403    * aBorders, there is a corresponding entry in aFreqRes, which defines the
    404    * frequency resolution of the envelope following (delimited by) the
    405    * border.
    406    *
    407    * When no transients are present, FIXFIX class frames are used.  The
    408    * frame splitter decides whether to use one or two envelopes in the
    409    * FIXFIX frame.  "Sparse transients" (separated by a few frames without
    410    * transients) are handeled by [FIXVAR, VARFIX] pairs or (depending on
    411    * tuning and transient position relative the nominal frame boundaries)
    412    * by [FIXVAR, VARVAR, VARFIX] triples.  "Tight transients" (in
    413    * consecutive frames) are handeled by [..., VARVAR, VARVAR, ...]
    414    * sequences.
    415    *
    416    * The generator assumes that transients are "sparse", and designs
    417    * borders for [FIXVAR, VARFIX] pairs right away, where the first frame
    418    * corresponds to the present frame.  At the next call of the generator
    419    * it is known whether the transient actually is "sparse" or not.  If
    420    * 'yes', the already calculated VARFIX borders are used.  If 'no', new
    421    * borders, meeting the requirements of the "tight" transient, are
    422    * calculated.
    423    *
    424    * The generator produces two outputs:  A "clear-text bitstream" stored in
    425    * SBR_GRID, and a straight-forward representation of the grid stored in
    426    * SBR_FRAME_INFO.  The former is subsequently converted to the actual
    427    * bitstream sbr_grid() (encodeSbrGrid() in bit_sbr.c).  The latter is
    428    * used by other encoder functions, such as the envelope estimator
    429    * (calculateSbrEnvelope() in env_est.c) and the noise floor and missing
    430    * harmonics detector (TonCorrParamExtr() in nf_est.c).
    431    */
    432 
    433   if (staticFraming) {
    434     /*--------------------------------------------------------------------------
    435       Ignore transient detector
    436     ---------------------------------------------------------------------------*/
    437 
    438     frameClass = FIXFIX;
    439     numEnv = numEnvStatic;   /* {1,2,4,8} */
    440     *frameClassOld = FIXFIX; /* for change to dyn */
    441     hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
    442     hSbrEnvFrame->SbrGrid.frameClass = frameClass;
    443   } else {
    444     /*--------------------------------------------------------------------------
    445       Calculate frame class to use
    446     ---------------------------------------------------------------------------*/
    447     if (rightBorderFIX) {
    448       tranFlag = 0;
    449       *spreadFlag = 0;
    450     }
    451     calcFrameClass(&frameClass, frameClassOld, tranFlag, spreadFlag);
    452 
    453     /* patch for new frame class FIXFIXonly for AAC LD */
    454     if (tranFlag && ldGrid) {
    455       frameClass = FIXFIXonly;
    456       *frameClassOld = FIXFIX;
    457     }
    458 
    459     /*
    460      * every transient is processed below by inserting
    461      *
    462      * - one border at the onset of the transient
    463      * - one or more "decay borders" (after the onset of the transient)
    464      * - optionally one "attack border" (before the onset of the transient)
    465      *
    466      * those borders are referred to as "mandatory borders" and are
    467      * defined by the 'segmentLength' array in FRAME_GEN_TUNING
    468      *
    469      * the frequency resolutions of the corresponding envelopes are
    470      * defined by the 'segmentRes' array in FRAME_GEN_TUNING
    471      */
    472 
    473     /*--------------------------------------------------------------------------
    474       Design frame (or follow-up old design)
    475     ---------------------------------------------------------------------------*/
    476     if (tranFlag) {
    477       /* Always for FixVar, often but not always for VarVar */
    478 
    479       /*--------------------------------------------------------------------------
    480         Design part of T/F-grid around the new transient
    481       ---------------------------------------------------------------------------*/
    482 
    483       tranPosInternal =
    484           frameMiddleSlot + tranPos + bufferFrameStart; /* FH 00-06-26 */
    485       /*
    486         add mandatory borders around transient
    487       */
    488 
    489       fillFrameTran(v_tuningSegm, v_tuningFreq, tranPosInternal, v_bord,
    490                     length_v_bord, v_freq, length_v_freq, &bmin, &bmax);
    491 
    492       /* make sure we stay within the maximum SBR frame overlap */
    493       fmax = calcFillLengthMax(tranPos, numberTimeSlots);
    494     }
    495 
    496     switch (frameClass) {
    497       case FIXFIXonly:
    498         FDK_ASSERT(ldGrid);
    499         tranPosInternal = tranPos;
    500         generateFixFixOnly(&(hSbrEnvFrame->SbrFrameInfo),
    501                            &(hSbrEnvFrame->SbrGrid), tranPosInternal,
    502                            numberTimeSlots, hSbrEnvFrame->fResTransIsLow);
    503 
    504         return &(hSbrEnvFrame->SbrFrameInfo);
    505 
    506       case FIXVAR:
    507 
    508         /*--------------------------------------------------------------------------
    509            Design remaining parts of T/F-grid (assuming next frame is VarFix)
    510         ---------------------------------------------------------------------------*/
    511 
    512         /*--------------------------------------------------------------------------
    513           Fill region before new transient:
    514         ---------------------------------------------------------------------------*/
    515         fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
    516                      bmin - bufferFrameStart); /* FH 00-06-26 */
    517 
    518         /*--------------------------------------------------------------------------
    519           Fill region after new transient:
    520         ---------------------------------------------------------------------------*/
    521         fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq,
    522                       length_v_freq, bmax, bufferFrameStart, numberTimeSlots,
    523                       fmax);
    524 
    525         /*--------------------------------------------------------------------------
    526           Take care of special case:
    527         ---------------------------------------------------------------------------*/
    528         if (parts == 1 && d < dmin) /* no fill, short last envelope */
    529           specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq,
    530                       length_v_freq, &parts, d);
    531 
    532         /*--------------------------------------------------------------------------
    533           Calculate common border (split-point)
    534         ---------------------------------------------------------------------------*/
    535         calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord, tranPosInternal,
    536                        bufferFrameStart, numberTimeSlots); /* FH 00-06-26 */
    537 
    538         /*--------------------------------------------------------------------------
    539           Extract data for proper follow-up in next frame
    540         ---------------------------------------------------------------------------*/
    541         keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow,
    542                         length_v_freqFollow, i_tranFollow, i_fillFollow, v_bord,
    543                         length_v_bord, v_freq, i_cmon, i_tran, parts,
    544                         numberTimeSlots); /* FH 00-06-26 */
    545 
    546         /*--------------------------------------------------------------------------
    547           Calculate control signal
    548         ---------------------------------------------------------------------------*/
    549         calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord,
    550                        *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran,
    551                        *spreadFlag, DC);
    552         break;
    553       case VARFIX:
    554         /*--------------------------------------------------------------------------
    555           Follow-up old transient - calculate control signal
    556         ---------------------------------------------------------------------------*/
    557         calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow,
    558                        *length_v_bordFollow, v_freqFollow, *length_v_freqFollow,
    559                        DC, *i_tranFollow, *spreadFlag, DC);
    560         break;
    561       case VARVAR:
    562         if (*spreadFlag) { /* spread across three frames */
    563           /*--------------------------------------------------------------------------
    564             Follow-up old transient - calculate control signal
    565           ---------------------------------------------------------------------------*/
    566           calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow,
    567                          *length_v_bordFollow, v_freqFollow,
    568                          *length_v_freqFollow, DC, *i_tranFollow, *spreadFlag,
    569                          DC);
    570 
    571           *spreadFlag = 0;
    572 
    573           /*--------------------------------------------------------------------------
    574             Extract data for proper follow-up in next frame
    575           ---------------------------------------------------------------------------*/
    576           v_bordFollow[0] = hSbrEnvFrame->SbrGrid.bs_abs_bord_1 -
    577                             numberTimeSlots; /* FH 00-06-26 */
    578           v_freqFollow[0] = 1;
    579           *length_v_bordFollow = 1;
    580           *length_v_freqFollow = 1;
    581 
    582           *i_tranFollow = -DC;
    583           *i_fillFollow = -DC;
    584         } else {
    585           /*--------------------------------------------------------------------------
    586             Design remaining parts of T/F-grid (assuming next frame is VarFix)
    587             adapt or fill region before new transient:
    588           ---------------------------------------------------------------------------*/
    589           fillFrameInter(&nL, v_tuningSegm, v_bord, length_v_bord, bmin, v_freq,
    590                          length_v_freq, v_bordFollow, length_v_bordFollow,
    591                          v_freqFollow, length_v_freqFollow, *i_fillFollow, dmin,
    592                          dmax, numberTimeSlots);
    593 
    594           /*--------------------------------------------------------------------------
    595             Fill after transient:
    596           ---------------------------------------------------------------------------*/
    597           fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq,
    598                         length_v_freq, bmax, bufferFrameStart, numberTimeSlots,
    599                         fmax);
    600 
    601           /*--------------------------------------------------------------------------
    602             Take care of special case:
    603           ---------------------------------------------------------------------------*/
    604           if (parts == 1 && d < dmin) /*% no fill, short last envelope */
    605             specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq,
    606                         length_v_freq, &parts, d);
    607 
    608           /*--------------------------------------------------------------------------
    609             Calculate common border (split-point)
    610           ---------------------------------------------------------------------------*/
    611           calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord,
    612                          tranPosInternal, bufferFrameStart, numberTimeSlots);
    613 
    614           /*--------------------------------------------------------------------------
    615             Extract data for proper follow-up in next frame
    616           ---------------------------------------------------------------------------*/
    617           keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow,
    618                           length_v_freqFollow, i_tranFollow, i_fillFollow,
    619                           v_bord, length_v_bord, v_freq, i_cmon, i_tran, parts,
    620                           numberTimeSlots);
    621 
    622           /*--------------------------------------------------------------------------
    623             Calculate control signal
    624           ---------------------------------------------------------------------------*/
    625           calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord,
    626                          *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran,
    627                          0, nL);
    628         }
    629         break;
    630       case FIXFIX:
    631         if (tranPos == 0)
    632           numEnv = 1;
    633         else
    634           numEnv = 2;
    635 
    636         hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
    637         hSbrEnvFrame->SbrGrid.frameClass = frameClass;
    638 
    639         break;
    640       default:
    641         FDK_ASSERT(0);
    642     }
    643   }
    644 
    645   /*-------------------------------------------------------------------------
    646     Convert control signal to frame info struct
    647   ---------------------------------------------------------------------------*/
    648   ctrlSignal2FrameInfo(&hSbrEnvFrame->SbrGrid, &hSbrEnvFrame->SbrFrameInfo,
    649                        hSbrEnvFrame->freq_res_fixfix);
    650 
    651   return &hSbrEnvFrame->SbrFrameInfo;
    652 }
    653 
    654 /***************************************************************************/
    655 /*!
    656   \brief    Gnerates frame info for FIXFIXonly frame class used for low delay
    657  version
    658 
    659   \return   nothing
    660  ****************************************************************************/
    661 static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
    662                                HANDLE_SBR_GRID hSbrGrid, int tranPosInternal,
    663                                int numberTimeSlots, UCHAR fResTransIsLow) {
    664   int nEnv, i, k = 0, tranIdx;
    665   const int *pTable = NULL;
    666   const FREQ_RES *freqResTable = NULL;
    667 
    668   switch (numberTimeSlots) {
    669     case 8: {
    670       pTable = envelopeTable_8[tranPosInternal];
    671     }
    672       freqResTable = freqRes_table_8;
    673       break;
    674     case 15:
    675       pTable = envelopeTable_15[tranPosInternal];
    676       freqResTable = freqRes_table_16;
    677       break;
    678     case 16:
    679       pTable = envelopeTable_16[tranPosInternal];
    680       freqResTable = freqRes_table_16;
    681       break;
    682   }
    683 
    684   /* look number of envolpes in table */
    685   nEnv = pTable[0];
    686   /* look up envolpe distribution in table */
    687   for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2];
    688 
    689   /* open and close frame border */
    690   hSbrFrameInfo->borders[0] = 0;
    691   hSbrFrameInfo->borders[nEnv] = numberTimeSlots;
    692 
    693   /* adjust segment-frequency-resolution according to the segment-length */
    694   for (i = 0; i < nEnv; i++) {
    695     k = hSbrFrameInfo->borders[i + 1] - hSbrFrameInfo->borders[i];
    696     if (!fResTransIsLow)
    697       hSbrFrameInfo->freqRes[i] = freqResTable[k];
    698     else
    699       hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
    700 
    701     hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i];
    702   }
    703 
    704   hSbrFrameInfo->nEnvelopes = nEnv;
    705   hSbrFrameInfo->shortEnv = pTable[2];
    706   /* transient idx */
    707   tranIdx = pTable[1];
    708 
    709   /* add noise floors */
    710   hSbrFrameInfo->bordersNoise[0] = 0;
    711   hSbrFrameInfo->bordersNoise[1] =
    712       hSbrFrameInfo->borders[tranIdx ? tranIdx : 1];
    713   hSbrFrameInfo->bordersNoise[2] = numberTimeSlots;
    714   hSbrFrameInfo->nNoiseEnvelopes = 2;
    715 
    716   hSbrGrid->frameClass = FIXFIXonly;
    717   hSbrGrid->bs_abs_bord = tranPosInternal;
    718   hSbrGrid->bs_num_env = nEnv;
    719 }
    720 
    721 /*******************************************************************************
    722  Functionname:  FDKsbrEnc_initFrameInfoGenerator
    723  *******************************************************************************
    724 
    725  Description:
    726 
    727  Arguments:   hSbrEnvFrame  - pointer to sbr envelope handle
    728               allowSpread   - commandline parameter
    729               numEnvStatic  - commandline parameter
    730               staticFraming - commandline parameter
    731 
    732  Return:      none
    733 
    734 *******************************************************************************/
    735 void FDKsbrEnc_initFrameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
    736                                       INT allowSpread, INT numEnvStatic,
    737                                       INT staticFraming, INT timeSlots,
    738                                       const FREQ_RES *freq_res_fixfix,
    739                                       UCHAR fResTransIsLow,
    740                                       INT ldGrid) { /* FH 00-06-26 */
    741 
    742   FDKmemclear(hSbrEnvFrame, sizeof(SBR_ENVELOPE_FRAME));
    743 
    744   /* Initialisation */
    745   hSbrEnvFrame->frameClassOld = FIXFIX;
    746   hSbrEnvFrame->spreadFlag = 0;
    747 
    748   hSbrEnvFrame->allowSpread = allowSpread;
    749   hSbrEnvFrame->numEnvStatic = numEnvStatic;
    750   hSbrEnvFrame->staticFraming = staticFraming;
    751   hSbrEnvFrame->freq_res_fixfix[0] = freq_res_fixfix[0];
    752   hSbrEnvFrame->freq_res_fixfix[1] = freq_res_fixfix[1];
    753   hSbrEnvFrame->fResTransIsLow = fResTransIsLow;
    754 
    755   hSbrEnvFrame->length_v_bord = 0;
    756   hSbrEnvFrame->length_v_bordFollow = 0;
    757 
    758   hSbrEnvFrame->length_v_freq = 0;
    759   hSbrEnvFrame->length_v_freqFollow = 0;
    760 
    761   hSbrEnvFrame->i_tranFollow = 0;
    762   hSbrEnvFrame->i_fillFollow = 0;
    763 
    764   hSbrEnvFrame->SbrGrid.numberTimeSlots = timeSlots;
    765 
    766   if (ldGrid) {
    767     /*case CODEC_AACLD:*/
    768     hSbrEnvFrame->dmin = 2;
    769     hSbrEnvFrame->dmax = 16;
    770     hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
    771     hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
    772   } else
    773     switch (timeSlots) {
    774       case NUMBER_TIME_SLOTS_1920:
    775         hSbrEnvFrame->dmin = 4;
    776         hSbrEnvFrame->dmax = 12;
    777         hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
    778         hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1920;
    779         break;
    780       case NUMBER_TIME_SLOTS_2048:
    781         hSbrEnvFrame->dmin = 4;
    782         hSbrEnvFrame->dmax = 12;
    783         hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
    784         hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2048;
    785         break;
    786       case NUMBER_TIME_SLOTS_1152:
    787         hSbrEnvFrame->dmin = 2;
    788         hSbrEnvFrame->dmax = 8;
    789         hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
    790         hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1152;
    791         break;
    792       case NUMBER_TIME_SLOTS_2304:
    793         hSbrEnvFrame->dmin = 4;
    794         hSbrEnvFrame->dmax = 15;
    795         hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
    796         hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2304;
    797         break;
    798       default:
    799         FDK_ASSERT(0);
    800     }
    801 }
    802 
    803 /*******************************************************************************
    804  Functionname:  fillFrameTran
    805  *******************************************************************************
    806 
    807  Description:  Add mandatory borders, as described by the tuning vector
    808                and the current transient position
    809 
    810  Arguments:
    811       modified:
    812               v_bord        - int pointer to v_bord vector
    813               length_v_bord - length of v_bord vector
    814               v_freq        - int pointer to v_freq vector
    815               length_v_freq - length of v_freq vector
    816               bmin          - int pointer to bmin (call by reference)
    817               bmax          - int pointer to bmax (call by reference)
    818       not modified:
    819               tran          - position of transient
    820               v_tuningSegm  - int pointer to v_tuningSegm vector
    821               v_tuningFreq  - int pointer to v_tuningFreq vector
    822 
    823  Return:      none
    824 
    825 *******************************************************************************/
    826 static void fillFrameTran(
    827     const int *v_tuningSegm, /*!< tuning: desired segment lengths */
    828     const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */
    829     int tran,                /*!< input : position of transient */
    830     int *v_bord,             /*!< memNew: borders */
    831     int *length_v_bord,      /*!< memNew: # borders */
    832     int *v_freq,             /*!< memNew: frequency resolutions */
    833     int *length_v_freq,      /*!< memNew: # frequency resolutions */
    834     int *bmin,               /*!< hlpNew: first mandatory border */
    835     int *bmax                /*!< hlpNew: last  mandatory border */
    836 ) {
    837   int bord, i;
    838 
    839   *length_v_bord = 0;
    840   *length_v_freq = 0;
    841 
    842   /* add attack env leading border (optional) */
    843   if (v_tuningSegm[0]) {
    844     /* v_bord = [(Ba)] start of attack env */
    845     FDKsbrEnc_AddRight(v_bord, length_v_bord, (tran - v_tuningSegm[0]));
    846 
    847     /* v_freq = [(Fa)] res of attack env */
    848     FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[0]);
    849   }
    850 
    851   /* add attack env trailing border/first decay env leading border */
    852   bord = tran;
    853   FDKsbrEnc_AddRight(v_bord, length_v_bord, tran); /* v_bord = [(Ba),Bd1] */
    854 
    855   /* add first decay env trailing border/2:nd decay env leading border */
    856   if (v_tuningSegm[1]) {
    857     bord += v_tuningSegm[1];
    858 
    859     /* v_bord = [(Ba),Bd1,Bd2] */
    860     FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
    861 
    862     /* v_freq = [(Fa),Fd1] */
    863     FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[1]);
    864   }
    865 
    866   /* add 2:nd decay env trailing border (optional) */
    867   if (v_tuningSegm[2] != 0) {
    868     bord += v_tuningSegm[2];
    869 
    870     /* v_bord = [(Ba),Bd1, Bd2,(Bd3)] */
    871     FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
    872 
    873     /* v_freq = [(Fa),Fd1,(Fd2)] */
    874     FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[2]);
    875   }
    876 
    877   /*  v_freq = [(Fa),Fd1,(Fd2),1] */
    878   FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
    879 
    880   /*  calc min and max values of mandatory borders */
    881   *bmin = v_bord[0];
    882   for (i = 0; i < *length_v_bord; i++)
    883     if (v_bord[i] < *bmin) *bmin = v_bord[i];
    884 
    885   *bmax = v_bord[0];
    886   for (i = 0; i < *length_v_bord; i++)
    887     if (v_bord[i] > *bmax) *bmax = v_bord[i];
    888 }
    889 
    890 /*******************************************************************************
    891  Functionname:  fillFramePre
    892  *******************************************************************************
    893 
    894  Description: Add borders before mandatory borders, if needed
    895 
    896  Arguments:
    897        modified:
    898               v_bord        - int pointer to v_bord vector
    899               length_v_bord - length of v_bord vector
    900               v_freq        - int pointer to v_freq vector
    901               length_v_freq - length of v_freq vector
    902        not modified:
    903               dmax          - int value
    904               bmin          - int value
    905               rest          - int value
    906 
    907  Return:      none
    908 
    909 *******************************************************************************/
    910 static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq,
    911                          INT *length_v_freq, INT bmin, INT rest) {
    912   /*
    913     input state:
    914     v_bord = [(Ba),Bd1, Bd2 ,(Bd3)]
    915     v_freq = [(Fa),Fd1,(Fd2),1 ]
    916   */
    917 
    918   INT parts, d, j, S, s = 0, segm, bord;
    919 
    920   /*
    921     start with one envelope
    922   */
    923 
    924   parts = 1;
    925   d = rest;
    926 
    927   /*
    928     calc # of additional envelopes and corresponding lengths
    929   */
    930 
    931   while (d > dmax) {
    932     parts++;
    933 
    934     segm = rest / parts;
    935     S = (segm - 2) >> 1;
    936     s = fixMin(8, 2 * S + 2);
    937     d = rest - (parts - 1) * s;
    938   }
    939 
    940   /*
    941     add borders before mandatory borders
    942   */
    943 
    944   bord = bmin;
    945 
    946   for (j = 0; j <= parts - 2; j++) {
    947     bord = bord - s;
    948 
    949     /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)] */
    950     FDKsbrEnc_AddLeft(v_bord, length_v_bord, bord);
    951 
    952     /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1   ] */
    953     FDKsbrEnc_AddLeft(v_freq, length_v_freq, 1);
    954   }
    955 }
    956 
    957 /***************************************************************************/
    958 /*!
    959   \brief Overlap control
    960 
    961   Calculate max length of trailing fill segments, such that we always get a
    962   border within the frame overlap region
    963 
    964   \return void
    965 
    966 ****************************************************************************/
    967 static int calcFillLengthMax(
    968     int tranPos,        /*!< input : transient position (ref: tran det) */
    969     int numberTimeSlots /*!< input : number of timeslots */
    970 ) {
    971   int fmax;
    972 
    973   /*
    974     calculate transient position within envelope buffer
    975   */
    976   switch (numberTimeSlots) {
    977     case NUMBER_TIME_SLOTS_2048:
    978       if (tranPos < 4)
    979         fmax = 6;
    980       else if (tranPos == 4 || tranPos == 5)
    981         fmax = 4;
    982       else
    983         fmax = 8;
    984       break;
    985 
    986     case NUMBER_TIME_SLOTS_1920:
    987       if (tranPos < 4)
    988         fmax = 5;
    989       else if (tranPos == 4 || tranPos == 5)
    990         fmax = 3;
    991       else
    992         fmax = 7;
    993       break;
    994 
    995     default:
    996       fmax = 8;
    997       break;
    998   }
    999 
   1000   return fmax;
   1001 }
   1002 
   1003 /*******************************************************************************
   1004  Functionname:  fillFramePost
   1005  *******************************************************************************
   1006 
   1007  Description: -Add borders after mandatory borders, if needed
   1008                Make a preliminary design of next frame,
   1009                assuming no transient is present there
   1010 
   1011  Arguments:
   1012        modified:
   1013               parts         - int pointer to parts (call by reference)
   1014               d             - int pointer to d (call by reference)
   1015               v_bord        - int pointer to v_bord vector
   1016               length_v_bord - length of v_bord vector
   1017               v_freq        - int pointer to v_freq vector
   1018               length_v_freq - length of v_freq vector
   1019         not modified:
   1020               bmax          - int value
   1021               dmax          - int value
   1022 
   1023  Return:      none
   1024 
   1025 *******************************************************************************/
   1026 static void fillFramePost(INT *parts, INT *d, INT dmax, INT *v_bord,
   1027                           INT *length_v_bord, INT *v_freq, INT *length_v_freq,
   1028                           INT bmax, INT bufferFrameStart, INT numberTimeSlots,
   1029                           INT fmax) {
   1030   INT j, rest, segm, S, s = 0, bord;
   1031 
   1032   /*
   1033     input state:
   1034     v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)]
   1035     v_freq = [...,(1 ),(Fa),Fd1,(Fd2),1    ]
   1036   */
   1037 
   1038   rest = bufferFrameStart + 2 * numberTimeSlots - bmax;
   1039   *d = rest;
   1040 
   1041   if (*d > 0) {
   1042     *parts = 1; /* start with one envelope */
   1043 
   1044     /* calc # of additional envelopes and corresponding lengths */
   1045 
   1046     while (*d > dmax) {
   1047       *parts = *parts + 1;
   1048 
   1049       segm = rest / (*parts);
   1050       S = (segm - 2) >> 1;
   1051       s = fixMin(fmax, 2 * S + 2);
   1052       *d = rest - (*parts - 1) * s;
   1053     }
   1054 
   1055     /* add borders after mandatory borders */
   1056 
   1057     bord = bmax;
   1058     for (j = 0; j <= *parts - 2; j++) {
   1059       bord += s;
   1060 
   1061       /* v_bord =  [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3),(Bf)] */
   1062       FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
   1063 
   1064       /* v_freq =  [...,(1 ),(Fa),Fd1,(Fd2), 1   , 1! ,1] */
   1065       FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
   1066     }
   1067   } else {
   1068     *parts = 1;
   1069 
   1070     /* remove last element from v_bord and v_freq */
   1071 
   1072     *length_v_bord = *length_v_bord - 1;
   1073     *length_v_freq = *length_v_freq - 1;
   1074   }
   1075 }
   1076 
   1077 /*******************************************************************************
   1078  Functionname:  fillFrameInter
   1079  *******************************************************************************
   1080 
   1081  Description:
   1082 
   1083  Arguments:   nL                  -
   1084               v_tuningSegm        -
   1085               v_bord              -
   1086               length_v_bord       -
   1087               bmin                -
   1088               v_freq              -
   1089               length_v_freq       -
   1090               v_bordFollow        -
   1091               length_v_bordFollow -
   1092               v_freqFollow        -
   1093               length_v_freqFollow -
   1094               i_fillFollow        -
   1095               dmin                -
   1096               dmax                -
   1097 
   1098  Return:      none
   1099 
   1100 *******************************************************************************/
   1101 static void fillFrameInter(INT *nL, const int *v_tuningSegm, INT *v_bord,
   1102                            INT *length_v_bord, INT bmin, INT *v_freq,
   1103                            INT *length_v_freq, INT *v_bordFollow,
   1104                            INT *length_v_bordFollow, INT *v_freqFollow,
   1105                            INT *length_v_freqFollow, INT i_fillFollow, INT dmin,
   1106                            INT dmax, INT numberTimeSlots) {
   1107   INT middle, b_new, numBordFollow, bordMaxFollow, i;
   1108 
   1109   if (numberTimeSlots != NUMBER_TIME_SLOTS_1152) {
   1110     /* % remove fill borders: */
   1111     if (i_fillFollow >= 1) {
   1112       *length_v_bordFollow = i_fillFollow;
   1113       *length_v_freqFollow = i_fillFollow;
   1114     }
   1115 
   1116     numBordFollow = *length_v_bordFollow;
   1117     bordMaxFollow = v_bordFollow[numBordFollow - 1];
   1118 
   1119     /* remove even more borders if needed */
   1120     middle = bmin - bordMaxFollow;
   1121     while (middle < 0) {
   1122       numBordFollow--;
   1123       bordMaxFollow = v_bordFollow[numBordFollow - 1];
   1124       middle = bmin - bordMaxFollow;
   1125     }
   1126 
   1127     *length_v_bordFollow = numBordFollow;
   1128     *length_v_freqFollow = numBordFollow;
   1129     *nL = numBordFollow - 1;
   1130 
   1131     b_new = *length_v_bord;
   1132 
   1133     if (middle <= dmax) {
   1134       if (middle >= dmin) { /* concatenate */
   1135         FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1136                              *length_v_bordFollow);
   1137         FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1138                              *length_v_freqFollow);
   1139       }
   1140 
   1141       else {
   1142         if (v_tuningSegm[0] != 0) { /* remove one new border and concatenate */
   1143           *length_v_bord = b_new - 1;
   1144           FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1145                                *length_v_bordFollow);
   1146 
   1147           *length_v_freq = b_new - 1;
   1148           FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow,
   1149                                *length_v_freqFollow);
   1150         } else {
   1151           if (*length_v_bordFollow >
   1152               1) { /* remove one old border and concatenate */
   1153             FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1154                                  *length_v_bordFollow - 1);
   1155             FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1156                                  *length_v_bordFollow - 1);
   1157 
   1158             *nL = *nL - 1;
   1159           } else { /* remove new "transient" border and concatenate */
   1160 
   1161             for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1];
   1162 
   1163             for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1];
   1164 
   1165             *length_v_bord = b_new - 1;
   1166             *length_v_freq = b_new - 1;
   1167 
   1168             FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1169                                  *length_v_bordFollow);
   1170             FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1171                                  *length_v_freqFollow);
   1172           }
   1173         }
   1174       }
   1175     } else { /* middle > dmax */
   1176 
   1177       fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
   1178                    middle);
   1179       FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1180                            *length_v_bordFollow);
   1181       FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1182                            *length_v_freqFollow);
   1183     }
   1184 
   1185   } else { /* numberTimeSlots==NUMBER_TIME_SLOTS_1152 */
   1186 
   1187     INT l, m;
   1188 
   1189     /*------------------------------------------------------------------------
   1190       remove fill borders
   1191       ------------------------------------------------------------------------*/
   1192     if (i_fillFollow >= 1) {
   1193       *length_v_bordFollow = i_fillFollow;
   1194       *length_v_freqFollow = i_fillFollow;
   1195     }
   1196 
   1197     numBordFollow = *length_v_bordFollow;
   1198     bordMaxFollow = v_bordFollow[numBordFollow - 1];
   1199 
   1200     /*------------------------------------------------------------------------
   1201       remove more borders if necessary to eliminate overlap
   1202       ------------------------------------------------------------------------*/
   1203 
   1204     /* check for overlap */
   1205     middle = bmin - bordMaxFollow;
   1206 
   1207     /* intervals:
   1208        i)             middle <  0     : overlap, must remove borders
   1209        ii)       0 <= middle <  dmin  : no overlap but too tight, must remove
   1210        borders iii)   dmin <= middle <= dmax  : ok, just concatenate iv)    dmax
   1211        <= middle          : too wide, must add borders
   1212      */
   1213 
   1214     /* first remove old non-fill-borders... */
   1215     while (middle < 0) {
   1216       /* ...but don't remove all of them */
   1217       if (numBordFollow == 1) break;
   1218 
   1219       numBordFollow--;
   1220       bordMaxFollow = v_bordFollow[numBordFollow - 1];
   1221       middle = bmin - bordMaxFollow;
   1222     }
   1223 
   1224     /* if this isn't enough, remove new non-fill borders */
   1225     if (middle < 0) {
   1226       for (l = 0, m = 0; l < *length_v_bord; l++) {
   1227         if (v_bord[l] > bordMaxFollow) {
   1228           v_bord[m] = v_bord[l];
   1229           v_freq[m] = v_freq[l];
   1230           m++;
   1231         }
   1232       }
   1233 
   1234       *length_v_bord = l;
   1235       *length_v_freq = l;
   1236 
   1237       bmin = v_bord[0];
   1238     }
   1239 
   1240     /*------------------------------------------------------------------------
   1241       update modified follow-up data
   1242       ------------------------------------------------------------------------*/
   1243 
   1244     *length_v_bordFollow = numBordFollow;
   1245     *length_v_freqFollow = numBordFollow;
   1246 
   1247     /* left relative borders correspond to follow-up */
   1248     *nL = numBordFollow - 1;
   1249 
   1250     /*------------------------------------------------------------------------
   1251       take care of intervals ii through iv
   1252       ------------------------------------------------------------------------*/
   1253 
   1254     /* now middle should be >= 0 */
   1255     middle = bmin - bordMaxFollow;
   1256 
   1257     if (middle <= dmin) /* (ii) */
   1258     {
   1259       b_new = *length_v_bord;
   1260 
   1261       if (v_tuningSegm[0] != 0) {
   1262         /* remove new "luxury" border and concatenate */
   1263         *length_v_bord = b_new - 1;
   1264         FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1265                              *length_v_bordFollow);
   1266 
   1267         *length_v_freq = b_new - 1;
   1268         FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow,
   1269                              *length_v_freqFollow);
   1270 
   1271       } else if (*length_v_bordFollow > 1) {
   1272         /* remove old border and concatenate */
   1273         FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1274                              *length_v_bordFollow - 1);
   1275         FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1276                              *length_v_bordFollow - 1);
   1277 
   1278         *nL = *nL - 1;
   1279       } else {
   1280         /* remove new border and concatenate */
   1281         for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1];
   1282 
   1283         for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1];
   1284 
   1285         *length_v_bord = b_new - 1;
   1286         *length_v_freq = b_new - 1;
   1287 
   1288         FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1289                              *length_v_bordFollow);
   1290         FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1291                              *length_v_freqFollow);
   1292       }
   1293     } else if ((middle >= dmin) && (middle <= dmax)) /* (iii) */
   1294     {
   1295       /* concatenate */
   1296       FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1297                            *length_v_bordFollow);
   1298       FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1299                            *length_v_freqFollow);
   1300 
   1301     } else /* (iv) */
   1302     {
   1303       fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
   1304                    middle);
   1305       FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
   1306                            *length_v_bordFollow);
   1307       FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
   1308                            *length_v_freqFollow);
   1309     }
   1310   }
   1311 }
   1312 
   1313 /*******************************************************************************
   1314  Functionname:  calcFrameClass
   1315  *******************************************************************************
   1316 
   1317  Description:
   1318 
   1319  Arguments:  INT* frameClass, INT* frameClassOld, INT tranFlag, INT* spreadFlag)
   1320 
   1321  Return:      none
   1322 
   1323 *******************************************************************************/
   1324 static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld,
   1325                            INT tranFlag, INT *spreadFlag) {
   1326   switch (*frameClassOld) {
   1327     case FIXFIXonly:
   1328     case FIXFIX:
   1329       if (tranFlag)
   1330         *frameClass = FIXVAR;
   1331       else
   1332         *frameClass = FIXFIX;
   1333       break;
   1334     case FIXVAR:
   1335       if (tranFlag) {
   1336         *frameClass = VARVAR;
   1337         *spreadFlag = 0;
   1338       } else {
   1339         if (*spreadFlag)
   1340           *frameClass = VARVAR;
   1341         else
   1342           *frameClass = VARFIX;
   1343       }
   1344       break;
   1345     case VARFIX:
   1346       if (tranFlag)
   1347         *frameClass = FIXVAR;
   1348       else
   1349         *frameClass = FIXFIX;
   1350       break;
   1351     case VARVAR:
   1352       if (tranFlag) {
   1353         *frameClass = VARVAR;
   1354         *spreadFlag = 0;
   1355       } else {
   1356         if (*spreadFlag)
   1357           *frameClass = VARVAR;
   1358         else
   1359           *frameClass = VARFIX;
   1360       }
   1361       break;
   1362   };
   1363 
   1364   *frameClassOld = *frameClass;
   1365 }
   1366 
   1367 /*******************************************************************************
   1368  Functionname:  specialCase
   1369  *******************************************************************************
   1370 
   1371  Description:
   1372 
   1373  Arguments:   spreadFlag
   1374               allowSpread
   1375               v_bord
   1376               length_v_bord
   1377               v_freq
   1378               length_v_freq
   1379               parts
   1380               d
   1381 
   1382  Return:      none
   1383 
   1384 *******************************************************************************/
   1385 static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord,
   1386                         INT *length_v_bord, INT *v_freq, INT *length_v_freq,
   1387                         INT *parts, INT d) {
   1388   INT L;
   1389 
   1390   L = *length_v_bord;
   1391 
   1392   if (allowSpread) { /* add one "step 8" */
   1393     *spreadFlag = 1;
   1394     FDKsbrEnc_AddRight(v_bord, length_v_bord, v_bord[L - 1] + 8);
   1395     FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
   1396     (*parts)++;
   1397   } else {
   1398     if (d == 1) { /*  stretch one slot */
   1399       *length_v_bord = L - 1;
   1400       *length_v_freq = L - 1;
   1401     } else {
   1402       if ((v_bord[L - 1] - v_bord[L - 2]) > 2) { /* compress one quant step */
   1403         v_bord[L - 1] = v_bord[L - 1] - 2;
   1404         v_freq[*length_v_freq - 1] = 0; /* use low res for short segment */
   1405       }
   1406     }
   1407   }
   1408 }
   1409 
   1410 /*******************************************************************************
   1411  Functionname:  calcCmonBorder
   1412  *******************************************************************************
   1413 
   1414  Description:
   1415 
   1416  Arguments:   i_cmon
   1417               i_tran
   1418               v_bord
   1419               length_v_bord
   1420               tran
   1421 
   1422  Return:      none
   1423 
   1424 *******************************************************************************/
   1425 static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord,
   1426                            INT *length_v_bord, INT tran, INT bufferFrameStart,
   1427                            INT numberTimeSlots) { /* FH 00-06-26 */
   1428   INT i;
   1429 
   1430   for (i = 0; i < *length_v_bord; i++)
   1431     if (v_bord[i] >= bufferFrameStart + numberTimeSlots) { /* FH 00-06-26 */
   1432       *i_cmon = i;
   1433       break;
   1434     }
   1435 
   1436   /* keep track of transient: */
   1437   for (i = 0; i < *length_v_bord; i++)
   1438     if (v_bord[i] >= tran) {
   1439       *i_tran = i;
   1440       break;
   1441     } else
   1442       *i_tran = EMPTY;
   1443 }
   1444 
   1445 /*******************************************************************************
   1446  Functionname:  keepForFollowUp
   1447  *******************************************************************************
   1448 
   1449  Description:
   1450 
   1451  Arguments:   v_bordFollow
   1452               length_v_bordFollow
   1453               v_freqFollow
   1454               length_v_freqFollow
   1455               i_tranFollow
   1456               i_fillFollow
   1457               v_bord
   1458               length_v_bord
   1459               v_freq
   1460               i_cmon
   1461               i_tran
   1462               parts)
   1463 
   1464  Return:      none
   1465 
   1466 *******************************************************************************/
   1467 static void keepForFollowUp(INT *v_bordFollow, INT *length_v_bordFollow,
   1468                             INT *v_freqFollow, INT *length_v_freqFollow,
   1469                             INT *i_tranFollow, INT *i_fillFollow, INT *v_bord,
   1470                             INT *length_v_bord, INT *v_freq, INT i_cmon,
   1471                             INT i_tran, INT parts,
   1472                             INT numberTimeSlots) { /* FH 00-06-26 */
   1473   INT L, i, j;
   1474 
   1475   L = *length_v_bord;
   1476 
   1477   (*length_v_bordFollow) = 0;
   1478   (*length_v_freqFollow) = 0;
   1479 
   1480   for (j = 0, i = i_cmon; i < L; i++, j++) {
   1481     v_bordFollow[j] = v_bord[i] - numberTimeSlots; /* FH 00-06-26 */
   1482     v_freqFollow[j] = v_freq[i];
   1483     (*length_v_bordFollow)++;
   1484     (*length_v_freqFollow)++;
   1485   }
   1486   if (i_tran != EMPTY)
   1487     *i_tranFollow = i_tran - i_cmon;
   1488   else
   1489     *i_tranFollow = EMPTY;
   1490   *i_fillFollow = L - (parts - 1) - i_cmon;
   1491 }
   1492 
   1493 /*******************************************************************************
   1494  Functionname:  calcCtrlSignal
   1495  *******************************************************************************
   1496 
   1497  Description:
   1498 
   1499  Arguments:   hSbrGrid
   1500               frameClass
   1501               v_bord
   1502               length_v_bord
   1503               v_freq
   1504               length_v_freq
   1505               i_cmon
   1506               i_tran
   1507               spreadFlag
   1508               nL
   1509 
   1510  Return:      none
   1511 
   1512 *******************************************************************************/
   1513 static void calcCtrlSignal(HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
   1514                            INT *v_bord, INT length_v_bord, INT *v_freq,
   1515                            INT length_v_freq, INT i_cmon, INT i_tran,
   1516                            INT spreadFlag, INT nL) {
   1517   INT i, r, a, n, p, b, aL, aR, ntot, nmax, nR;
   1518 
   1519   INT *v_f = hSbrGrid->v_f;
   1520   INT *v_fLR = hSbrGrid->v_fLR;
   1521   INT *v_r = hSbrGrid->bs_rel_bord;
   1522   INT *v_rL = hSbrGrid->bs_rel_bord_0;
   1523   INT *v_rR = hSbrGrid->bs_rel_bord_1;
   1524 
   1525   INT length_v_r = 0;
   1526   INT length_v_rR = 0;
   1527   INT length_v_rL = 0;
   1528 
   1529   switch (frameClass) {
   1530     case FIXVAR:
   1531       /* absolute border: */
   1532 
   1533       a = v_bord[i_cmon];
   1534 
   1535       /* relative borders: */
   1536       length_v_r = 0;
   1537       i = i_cmon;
   1538 
   1539       while (i >= 1) {
   1540         r = v_bord[i] - v_bord[i - 1];
   1541         FDKsbrEnc_AddRight(v_r, &length_v_r, r);
   1542         i--;
   1543       }
   1544 
   1545       /*  number of relative borders: */
   1546       n = length_v_r;
   1547 
   1548       /* freq res: */
   1549       for (i = 0; i < i_cmon; i++) v_f[i] = v_freq[i_cmon - 1 - i];
   1550       v_f[i_cmon] = 1;
   1551 
   1552       /* pointer: */
   1553       p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0);
   1554 
   1555       hSbrGrid->frameClass = frameClass;
   1556       hSbrGrid->bs_abs_bord = a;
   1557       hSbrGrid->n = n;
   1558       hSbrGrid->p = p;
   1559 
   1560       break;
   1561     case VARFIX:
   1562       /* absolute border: */
   1563       a = v_bord[0];
   1564 
   1565       /* relative borders: */
   1566       length_v_r = 0;
   1567 
   1568       for (i = 1; i < length_v_bord; i++) {
   1569         r = v_bord[i] - v_bord[i - 1];
   1570         FDKsbrEnc_AddRight(v_r, &length_v_r, r);
   1571       }
   1572 
   1573       /* number of relative borders: */
   1574       n = length_v_r;
   1575 
   1576       /* freq res: */
   1577       FDKmemcpy(v_f, v_freq, length_v_freq * sizeof(INT));
   1578 
   1579       /* pointer: */
   1580       p = (i_tran >= 0 && i_tran != EMPTY) ? (i_tran + 1) : (0);
   1581 
   1582       hSbrGrid->frameClass = frameClass;
   1583       hSbrGrid->bs_abs_bord = a;
   1584       hSbrGrid->n = n;
   1585       hSbrGrid->p = p;
   1586 
   1587       break;
   1588     case VARVAR:
   1589       if (spreadFlag) {
   1590         /* absolute borders: */
   1591         b = length_v_bord;
   1592 
   1593         aL = v_bord[0];
   1594         aR = v_bord[b - 1];
   1595 
   1596         /* number of relative borders:    */
   1597         ntot = b - 2;
   1598 
   1599         nmax = 2; /* n: {0,1,2} */
   1600         if (ntot > nmax) {
   1601           nL = nmax;
   1602           nR = ntot - nmax;
   1603         } else {
   1604           nL = ntot;
   1605           nR = 0;
   1606         }
   1607 
   1608         /* relative borders: */
   1609         length_v_rL = 0;
   1610         for (i = 1; i <= nL; i++) {
   1611           r = v_bord[i] - v_bord[i - 1];
   1612           FDKsbrEnc_AddRight(v_rL, &length_v_rL, r);
   1613         }
   1614 
   1615         length_v_rR = 0;
   1616         i = b - 1;
   1617         while (i >= b - nR) {
   1618           r = v_bord[i] - v_bord[i - 1];
   1619           FDKsbrEnc_AddRight(v_rR, &length_v_rR, r);
   1620           i--;
   1621         }
   1622 
   1623         /* pointer (only one due to constraint in frame info): */
   1624         p = (i_tran > 0 && i_tran != EMPTY) ? (b - i_tran) : (0);
   1625 
   1626         /* freq res: */
   1627 
   1628         for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i];
   1629       } else {
   1630         length_v_bord = i_cmon + 1;
   1631 
   1632         /* absolute borders: */
   1633         b = length_v_bord;
   1634 
   1635         aL = v_bord[0];
   1636         aR = v_bord[b - 1];
   1637 
   1638         /* number of relative borders:   */
   1639         ntot = b - 2;
   1640         nR = ntot - nL;
   1641 
   1642         /* relative borders: */
   1643         length_v_rL = 0;
   1644         for (i = 1; i <= nL; i++) {
   1645           r = v_bord[i] - v_bord[i - 1];
   1646           FDKsbrEnc_AddRight(v_rL, &length_v_rL, r);
   1647         }
   1648 
   1649         length_v_rR = 0;
   1650         i = b - 1;
   1651         while (i >= b - nR) {
   1652           r = v_bord[i] - v_bord[i - 1];
   1653           FDKsbrEnc_AddRight(v_rR, &length_v_rR, r);
   1654           i--;
   1655         }
   1656 
   1657         /* pointer (only one due to constraint in frame info): */
   1658         p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0);
   1659 
   1660         /* freq res: */
   1661         for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i];
   1662       }
   1663 
   1664       hSbrGrid->frameClass = frameClass;
   1665       hSbrGrid->bs_abs_bord_0 = aL;
   1666       hSbrGrid->bs_abs_bord_1 = aR;
   1667       hSbrGrid->bs_num_rel_0 = nL;
   1668       hSbrGrid->bs_num_rel_1 = nR;
   1669       hSbrGrid->p = p;
   1670 
   1671       break;
   1672 
   1673     default:
   1674       /* do nothing */
   1675       break;
   1676   }
   1677 }
   1678 
   1679 /*******************************************************************************
   1680  Functionname:  createDefFrameInfo
   1681  *******************************************************************************
   1682 
   1683  Description: Copies the default (static) frameInfo structs to the frameInfo
   1684               passed by reference; only used for FIXFIX frames
   1685 
   1686  Arguments:   hFrameInfo             - HANLDE_SBR_FRAME_INFO
   1687               nEnv                   - INT
   1688               nTimeSlots             - INT
   1689 
   1690  Return:      none; hSbrFrameInfo contains a copy of the default frameInfo
   1691 
   1692  Written:     Andreas Schneider
   1693  Revised:
   1694 *******************************************************************************/
   1695 static void createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv,
   1696                                INT nTimeSlots) {
   1697   switch (nEnv) {
   1698     case 1:
   1699       switch (nTimeSlots) {
   1700         case NUMBER_TIME_SLOTS_1920:
   1701           FDKmemcpy(hSbrFrameInfo, &frameInfo1_1920, sizeof(SBR_FRAME_INFO));
   1702           break;
   1703         case NUMBER_TIME_SLOTS_2048:
   1704           FDKmemcpy(hSbrFrameInfo, &frameInfo1_2048, sizeof(SBR_FRAME_INFO));
   1705           break;
   1706         case NUMBER_TIME_SLOTS_1152:
   1707           FDKmemcpy(hSbrFrameInfo, &frameInfo1_1152, sizeof(SBR_FRAME_INFO));
   1708           break;
   1709         case NUMBER_TIME_SLOTS_2304:
   1710           FDKmemcpy(hSbrFrameInfo, &frameInfo1_2304, sizeof(SBR_FRAME_INFO));
   1711           break;
   1712         case NUMBER_TIME_SLOTS_512LD:
   1713           FDKmemcpy(hSbrFrameInfo, &frameInfo1_512LD, sizeof(SBR_FRAME_INFO));
   1714           break;
   1715         default:
   1716           FDK_ASSERT(0);
   1717       }
   1718       break;
   1719     case 2:
   1720       switch (nTimeSlots) {
   1721         case NUMBER_TIME_SLOTS_1920:
   1722           FDKmemcpy(hSbrFrameInfo, &frameInfo2_1920, sizeof(SBR_FRAME_INFO));
   1723           break;
   1724         case NUMBER_TIME_SLOTS_2048:
   1725           FDKmemcpy(hSbrFrameInfo, &frameInfo2_2048, sizeof(SBR_FRAME_INFO));
   1726           break;
   1727         case NUMBER_TIME_SLOTS_1152:
   1728           FDKmemcpy(hSbrFrameInfo, &frameInfo2_1152, sizeof(SBR_FRAME_INFO));
   1729           break;
   1730         case NUMBER_TIME_SLOTS_2304:
   1731           FDKmemcpy(hSbrFrameInfo, &frameInfo2_2304, sizeof(SBR_FRAME_INFO));
   1732           break;
   1733         case NUMBER_TIME_SLOTS_512LD:
   1734           FDKmemcpy(hSbrFrameInfo, &frameInfo2_512LD, sizeof(SBR_FRAME_INFO));
   1735           break;
   1736         default:
   1737           FDK_ASSERT(0);
   1738       }
   1739       break;
   1740     case 4:
   1741       switch (nTimeSlots) {
   1742         case NUMBER_TIME_SLOTS_1920:
   1743           FDKmemcpy(hSbrFrameInfo, &frameInfo4_1920, sizeof(SBR_FRAME_INFO));
   1744           break;
   1745         case NUMBER_TIME_SLOTS_2048:
   1746           FDKmemcpy(hSbrFrameInfo, &frameInfo4_2048, sizeof(SBR_FRAME_INFO));
   1747           break;
   1748         case NUMBER_TIME_SLOTS_1152:
   1749           FDKmemcpy(hSbrFrameInfo, &frameInfo4_1152, sizeof(SBR_FRAME_INFO));
   1750           break;
   1751         case NUMBER_TIME_SLOTS_2304:
   1752           FDKmemcpy(hSbrFrameInfo, &frameInfo4_2304, sizeof(SBR_FRAME_INFO));
   1753           break;
   1754         case NUMBER_TIME_SLOTS_512LD:
   1755           FDKmemcpy(hSbrFrameInfo, &frameInfo4_512LD, sizeof(SBR_FRAME_INFO));
   1756           break;
   1757         default:
   1758           FDK_ASSERT(0);
   1759       }
   1760       break;
   1761     default:
   1762       FDK_ASSERT(0);
   1763   }
   1764 }
   1765 
   1766 /*******************************************************************************
   1767  Functionname:  ctrlSignal2FrameInfo
   1768  *******************************************************************************
   1769 
   1770  Description: Convert "clear-text" sbr_grid() to "frame info" used by the
   1771               envelope and noise floor estimators.
   1772               This is basically (except for "low level" calculations) the
   1773               bitstream decoder defined in the MPEG-4 standard, sub clause
   1774               4.6.18.3.3, Time / Frequency Grid.  See inline comments for
   1775               explanation of the shorten and noise border algorithms.
   1776 
   1777  Arguments:   hSbrGrid - source
   1778               hSbrFrameInfo - destination
   1779               freq_res_fixfix - frequency resolution for FIXFIX frames
   1780 
   1781  Return:      void; hSbrFrameInfo contains the updated FRAME_INFO struct
   1782 
   1783 *******************************************************************************/
   1784 static void ctrlSignal2FrameInfo(
   1785     HANDLE_SBR_GRID hSbrGrid,            /* input : the grid handle       */
   1786     HANDLE_SBR_FRAME_INFO hSbrFrameInfo, /* output: the frame info handle */
   1787     FREQ_RES
   1788         *freq_res_fixfix /* in/out: frequency resolution for FIXFIX frames */
   1789 ) {
   1790   INT frameSplit = 0;
   1791   INT nEnv = 0, border = 0, i, k, p /*?*/;
   1792   INT *v_r = hSbrGrid->bs_rel_bord;
   1793   INT *v_f = hSbrGrid->v_f;
   1794 
   1795   FRAME_CLASS frameClass = hSbrGrid->frameClass;
   1796   INT bufferFrameStart = hSbrGrid->bufferFrameStart;
   1797   INT numberTimeSlots = hSbrGrid->numberTimeSlots;
   1798 
   1799   switch (frameClass) {
   1800     case FIXFIX:
   1801       createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
   1802 
   1803       frameSplit = (hSbrFrameInfo->nEnvelopes > 1);
   1804       for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
   1805         hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] =
   1806             freq_res_fixfix[frameSplit];
   1807       }
   1808       break;
   1809 
   1810     case FIXVAR:
   1811     case VARFIX:
   1812       nEnv = hSbrGrid->n + 1; /* read n [SBR_NUM_BITS bits] */ /*? snd*/
   1813       FDK_ASSERT(nEnv <= MAX_ENVELOPES_FIXVAR_VARFIX);
   1814 
   1815       hSbrFrameInfo->nEnvelopes = nEnv;
   1816 
   1817       border = hSbrGrid->bs_abs_bord; /* read the absolute border */
   1818 
   1819       if (nEnv == 1)
   1820         hSbrFrameInfo->nNoiseEnvelopes = 1;
   1821       else
   1822         hSbrFrameInfo->nNoiseEnvelopes = 2;
   1823 
   1824       break;
   1825 
   1826     default:
   1827       /* do nothing */
   1828       break;
   1829   }
   1830 
   1831   switch (frameClass) {
   1832     case FIXVAR:
   1833       hSbrFrameInfo->borders[0] =
   1834           bufferFrameStart; /* start-position of 1st envelope */
   1835 
   1836       hSbrFrameInfo->borders[nEnv] = border;
   1837 
   1838       for (k = 0, i = nEnv - 1; k < nEnv - 1; k++, i--) {
   1839         border -= v_r[k];
   1840         hSbrFrameInfo->borders[i] = border;
   1841       }
   1842 
   1843       /* make either envelope nr. nEnv + 1 - p short; or don't shorten if p == 0
   1844        */
   1845       p = hSbrGrid->p;
   1846       if (p == 0) {
   1847         hSbrFrameInfo->shortEnv = 0;
   1848       } else {
   1849         hSbrFrameInfo->shortEnv = nEnv + 1 - p;
   1850       }
   1851 
   1852       for (k = 0, i = nEnv - 1; k < nEnv; k++, i--) {
   1853         hSbrFrameInfo->freqRes[i] = (FREQ_RES)v_f[k];
   1854       }
   1855 
   1856       /* if either there is no short envelope or the last envelope is short...
   1857        */
   1858       if (p == 0 || p == 1) {
   1859         hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
   1860       } else {
   1861         hSbrFrameInfo->bordersNoise[1] =
   1862             hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
   1863       }
   1864 
   1865       break;
   1866 
   1867     case VARFIX:
   1868       /* in this case 'border' indicates the start of the 1st envelope */
   1869       hSbrFrameInfo->borders[0] = border;
   1870 
   1871       for (k = 0; k < nEnv - 1; k++) {
   1872         border += v_r[k];
   1873         hSbrFrameInfo->borders[k + 1] = border;
   1874       }
   1875 
   1876       hSbrFrameInfo->borders[nEnv] = bufferFrameStart + numberTimeSlots;
   1877 
   1878       p = hSbrGrid->p;
   1879       if (p == 0 || p == 1) {
   1880         hSbrFrameInfo->shortEnv = 0;
   1881       } else {
   1882         hSbrFrameInfo->shortEnv = p - 1;
   1883       }
   1884 
   1885       for (k = 0; k < nEnv; k++) {
   1886         hSbrFrameInfo->freqRes[k] = (FREQ_RES)v_f[k];
   1887       }
   1888 
   1889       switch (p) {
   1890         case 0:
   1891           hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[1];
   1892           break;
   1893         case 1:
   1894           hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
   1895           break;
   1896         default:
   1897           hSbrFrameInfo->bordersNoise[1] =
   1898               hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
   1899           break;
   1900       }
   1901       break;
   1902 
   1903     case VARVAR:
   1904       nEnv = hSbrGrid->bs_num_rel_0 + hSbrGrid->bs_num_rel_1 + 1;
   1905       FDK_ASSERT(nEnv <= MAX_ENVELOPES_VARVAR); /* just to be sure */
   1906       hSbrFrameInfo->nEnvelopes = nEnv;
   1907 
   1908       hSbrFrameInfo->borders[0] = border = hSbrGrid->bs_abs_bord_0;
   1909 
   1910       for (k = 0, i = 1; k < hSbrGrid->bs_num_rel_0; k++, i++) {
   1911         border += hSbrGrid->bs_rel_bord_0[k];
   1912         hSbrFrameInfo->borders[i] = border;
   1913       }
   1914 
   1915       border = hSbrGrid->bs_abs_bord_1;
   1916       hSbrFrameInfo->borders[nEnv] = border;
   1917 
   1918       for (k = 0, i = nEnv - 1; k < hSbrGrid->bs_num_rel_1; k++, i--) {
   1919         border -= hSbrGrid->bs_rel_bord_1[k];
   1920         hSbrFrameInfo->borders[i] = border;
   1921       }
   1922 
   1923       p = hSbrGrid->p;
   1924       if (p == 0) {
   1925         hSbrFrameInfo->shortEnv = 0;
   1926       } else {
   1927         hSbrFrameInfo->shortEnv = nEnv + 1 - p;
   1928       }
   1929 
   1930       for (k = 0; k < nEnv; k++) {
   1931         hSbrFrameInfo->freqRes[k] = (FREQ_RES)hSbrGrid->v_fLR[k];
   1932       }
   1933 
   1934       if (nEnv == 1) {
   1935         hSbrFrameInfo->nNoiseEnvelopes = 1;
   1936         hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
   1937         hSbrFrameInfo->bordersNoise[1] = hSbrGrid->bs_abs_bord_1;
   1938       } else {
   1939         hSbrFrameInfo->nNoiseEnvelopes = 2;
   1940         hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
   1941 
   1942         if (p == 0 || p == 1) {
   1943           hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
   1944         } else {
   1945           hSbrFrameInfo->bordersNoise[1] =
   1946               hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
   1947         }
   1948         hSbrFrameInfo->bordersNoise[2] = hSbrGrid->bs_abs_bord_1;
   1949       }
   1950       break;
   1951 
   1952     default:
   1953       /* do nothing */
   1954       break;
   1955   }
   1956 
   1957   if (frameClass == VARFIX || frameClass == FIXVAR) {
   1958     hSbrFrameInfo->bordersNoise[0] = hSbrFrameInfo->borders[0];
   1959     if (nEnv == 1) {
   1960       hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv];
   1961     } else {
   1962       hSbrFrameInfo->bordersNoise[2] = hSbrFrameInfo->borders[nEnv];
   1963     }
   1964   }
   1965 }
   1966