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