fram_gen.cpp revision 4f0d97057c5c640b25518358886f8c47da9fc052
1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84#include "fram_gen.h"
85#include "sbr_misc.h"
86
87#include "genericStds.h"
88
89static const SBR_FRAME_INFO frameInfo1_2048 = {
90            1,
91            { 0, 16},
92            {FREQ_RES_HIGH},
93             0,
94             1,
95             {0, 16} };
96
97static 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
105static 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
113static const SBR_FRAME_INFO frameInfo1_2304 = {
114            1,
115            { 0, 18},
116            {FREQ_RES_HIGH},
117            0,
118            1,
119            { 0, 18} };
120
121static 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
129static 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
137static const SBR_FRAME_INFO frameInfo1_1920 = {
138            1,
139            { 0, 15},
140            {FREQ_RES_HIGH},
141            0,
142            1,
143            { 0, 15} };
144
145static 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
153static 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
161static const SBR_FRAME_INFO frameInfo1_1152 = {
162            1,
163            { 0,  9},
164            {FREQ_RES_HIGH},
165            0,
166            1,
167            { 0,  9} };
168
169static 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
177static 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 */
188static const SBR_FRAME_INFO frameInfo1_512LD = {
189                   1,
190                   {0, 8},
191                   {FREQ_RES_HIGH},
192                   0,
193                   1,
194                   {0, 8}};
195
196static 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
204static 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
212static int
213calcFillLengthMax (int tranPos,          /*!< input : transient position (ref: tran det) */
214                   int numberTimeSlots   /*!< input : number of timeslots */
215                   );
216
217static void
218fillFrameTran (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
229static 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
233static 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
238static 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
245static void calcFrameClass (FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld, INT tranFlag,
246                            INT *spreadFlag);
247
248static 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
252static void calcCmonBorder (INT *i_cmon, INT *i_tran, INT *v_bord,
253                            INT *length_v_bord, INT tran,
254                            INT bufferFrameStart, INT numberTimeSlots);
255
256static 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
262static 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
267static 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 */
273static 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 */
287static 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 */
309static 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
329static const int minFrameTranDistance = 4;
330
331static 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
334static 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
341static 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*******************************************************************************/
361HANDLE_SBR_FRAME_INFO
362FDKsbrEnc_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 ****************************************************************************/
692static 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*******************************************************************************/
767void
768FDKsbrEnc_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*******************************************************************************/
863static void
864fillFrameTran (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*******************************************************************************/
954static void
955fillFramePre (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****************************************************************************/
1015static int
1016calcFillLengthMax (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*******************************************************************************/
1076static void
1077fillFramePost (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*******************************************************************************/
1156static void
1157fillFrameInter (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*******************************************************************************/
1398static void
1399calcFrameClass (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*******************************************************************************/
1452static void
1453specialCase (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*******************************************************************************/
1498static void
1499calcCmonBorder (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*******************************************************************************/
1542static void
1543keepForFollowUp (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*******************************************************************************/
1590static void
1591calcCtrlSignal (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*******************************************************************************/
1788static void
1789createDefFrameInfo(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*******************************************************************************/
1873static void
1874ctrlSignal2FrameInfo (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