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