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