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