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