Coverage Report

Created: 2023-03-26 06:07

/src/aac/libSBRenc/src/fram_gen.cpp
Line
Count
Source (jump to first uncovered line)
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
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
0
                             const int *v_tuning) {
341
0
  INT numEnv, tranPosInternal = 0, bmin = 0, bmax = 0, parts, d, i_cmon = 0,
342
0
              i_tran = 0, nL;
343
0
  INT fmax = 0;
344
345
0
  INT *v_bord = hSbrEnvFrame->v_bord;
346
0
  INT *v_freq = hSbrEnvFrame->v_freq;
347
0
  INT *v_bordFollow = hSbrEnvFrame->v_bordFollow;
348
0
  INT *v_freqFollow = hSbrEnvFrame->v_freqFollow;
349
350
0
  INT *length_v_bordFollow = &hSbrEnvFrame->length_v_bordFollow;
351
0
  INT *length_v_freqFollow = &hSbrEnvFrame->length_v_freqFollow;
352
0
  INT *length_v_bord = &hSbrEnvFrame->length_v_bord;
353
0
  INT *length_v_freq = &hSbrEnvFrame->length_v_freq;
354
0
  INT *spreadFlag = &hSbrEnvFrame->spreadFlag;
355
0
  INT *i_tranFollow = &hSbrEnvFrame->i_tranFollow;
356
0
  INT *i_fillFollow = &hSbrEnvFrame->i_fillFollow;
357
0
  FRAME_CLASS *frameClassOld = &hSbrEnvFrame->frameClassOld;
358
0
  FRAME_CLASS frameClass = FIXFIX;
359
360
0
  INT allowSpread = hSbrEnvFrame->allowSpread;
361
0
  INT numEnvStatic = hSbrEnvFrame->numEnvStatic;
362
0
  INT staticFraming = hSbrEnvFrame->staticFraming;
363
0
  INT dmin = hSbrEnvFrame->dmin;
364
0
  INT dmax = hSbrEnvFrame->dmax;
365
366
0
  INT bufferFrameStart = hSbrEnvFrame->SbrGrid.bufferFrameStart;
367
0
  INT numberTimeSlots = hSbrEnvFrame->SbrGrid.numberTimeSlots;
368
0
  INT frameMiddleSlot = hSbrEnvFrame->frameMiddleSlot;
369
370
0
  INT tranPos = v_transient_info[0];
371
0
  INT tranFlag = v_transient_info[1];
372
373
0
  const int *v_tuningSegm = v_tuning;
374
0
  const int *v_tuningFreq = v_tuning + 3;
375
376
0
  hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
377
378
0
  if (ldGrid) {
379
    /* in case there was a transient at the very end of the previous frame,
380
     * start with a transient envelope */
381
0
    if (!tranFlag && v_transient_info_pre[1] &&
382
0
        (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)) {
383
0
      tranFlag = 1;
384
0
      tranPos = 0;
385
0
    }
386
0
  }
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
0
  if (staticFraming) {
434
    /*--------------------------------------------------------------------------
435
      Ignore transient detector
436
    ---------------------------------------------------------------------------*/
437
438
0
    frameClass = FIXFIX;
439
0
    numEnv = numEnvStatic;   /* {1,2,4,8} */
440
0
    *frameClassOld = FIXFIX; /* for change to dyn */
441
0
    hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
442
0
    hSbrEnvFrame->SbrGrid.frameClass = frameClass;
443
0
  } else {
444
    /*--------------------------------------------------------------------------
445
      Calculate frame class to use
446
    ---------------------------------------------------------------------------*/
447
0
    if (rightBorderFIX) {
448
0
      tranFlag = 0;
449
0
      *spreadFlag = 0;
450
0
    }
451
0
    calcFrameClass(&frameClass, frameClassOld, tranFlag, spreadFlag);
452
453
    /* patch for new frame class FIXFIXonly for AAC LD */
454
0
    if (tranFlag && ldGrid) {
455
0
      frameClass = FIXFIXonly;
456
0
      *frameClassOld = FIXFIX;
457
0
    }
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
0
    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
0
      tranPosInternal =
484
0
          frameMiddleSlot + tranPos + bufferFrameStart; /* FH 00-06-26 */
485
      /*
486
        add mandatory borders around transient
487
      */
488
489
0
      fillFrameTran(v_tuningSegm, v_tuningFreq, tranPosInternal, v_bord,
490
0
                    length_v_bord, v_freq, length_v_freq, &bmin, &bmax);
491
492
      /* make sure we stay within the maximum SBR frame overlap */
493
0
      fmax = calcFillLengthMax(tranPos, numberTimeSlots);
494
0
    }
495
496
0
    switch (frameClass) {
497
0
      case FIXFIXonly:
498
0
        FDK_ASSERT(ldGrid);
499
0
        tranPosInternal = tranPos;
500
0
        generateFixFixOnly(&(hSbrEnvFrame->SbrFrameInfo),
501
0
                           &(hSbrEnvFrame->SbrGrid), tranPosInternal,
502
0
                           numberTimeSlots, hSbrEnvFrame->fResTransIsLow);
503
504
0
        return &(hSbrEnvFrame->SbrFrameInfo);
505
506
0
      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
0
        fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
516
0
                     bmin - bufferFrameStart); /* FH 00-06-26 */
517
518
        /*--------------------------------------------------------------------------
519
          Fill region after new transient:
520
        ---------------------------------------------------------------------------*/
521
0
        fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq,
522
0
                      length_v_freq, bmax, bufferFrameStart, numberTimeSlots,
523
0
                      fmax);
524
525
        /*--------------------------------------------------------------------------
526
          Take care of special case:
527
        ---------------------------------------------------------------------------*/
528
0
        if (parts == 1 && d < dmin) /* no fill, short last envelope */
529
0
          specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq,
530
0
                      length_v_freq, &parts, d);
531
532
        /*--------------------------------------------------------------------------
533
          Calculate common border (split-point)
534
        ---------------------------------------------------------------------------*/
535
0
        calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord, tranPosInternal,
536
0
                       bufferFrameStart, numberTimeSlots); /* FH 00-06-26 */
537
538
        /*--------------------------------------------------------------------------
539
          Extract data for proper follow-up in next frame
540
        ---------------------------------------------------------------------------*/
541
0
        keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow,
542
0
                        length_v_freqFollow, i_tranFollow, i_fillFollow, v_bord,
543
0
                        length_v_bord, v_freq, i_cmon, i_tran, parts,
544
0
                        numberTimeSlots); /* FH 00-06-26 */
545
546
        /*--------------------------------------------------------------------------
547
          Calculate control signal
548
        ---------------------------------------------------------------------------*/
549
0
        calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord,
550
0
                       *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran,
551
0
                       *spreadFlag, DC);
552
0
        break;
553
0
      case VARFIX:
554
        /*--------------------------------------------------------------------------
555
          Follow-up old transient - calculate control signal
556
        ---------------------------------------------------------------------------*/
557
0
        calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow,
558
0
                       *length_v_bordFollow, v_freqFollow, *length_v_freqFollow,
559
0
                       DC, *i_tranFollow, *spreadFlag, DC);
560
0
        break;
561
0
      case VARVAR:
562
0
        if (*spreadFlag) { /* spread across three frames */
563
          /*--------------------------------------------------------------------------
564
            Follow-up old transient - calculate control signal
565
          ---------------------------------------------------------------------------*/
566
0
          calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow,
567
0
                         *length_v_bordFollow, v_freqFollow,
568
0
                         *length_v_freqFollow, DC, *i_tranFollow, *spreadFlag,
569
0
                         DC);
570
571
0
          *spreadFlag = 0;
572
573
          /*--------------------------------------------------------------------------
574
            Extract data for proper follow-up in next frame
575
          ---------------------------------------------------------------------------*/
576
0
          v_bordFollow[0] = hSbrEnvFrame->SbrGrid.bs_abs_bord_1 -
577
0
                            numberTimeSlots; /* FH 00-06-26 */
578
0
          v_freqFollow[0] = 1;
579
0
          *length_v_bordFollow = 1;
580
0
          *length_v_freqFollow = 1;
581
582
0
          *i_tranFollow = -DC;
583
0
          *i_fillFollow = -DC;
584
0
        } 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
0
          fillFrameInter(&nL, v_tuningSegm, v_bord, length_v_bord, bmin, v_freq,
590
0
                         length_v_freq, v_bordFollow, length_v_bordFollow,
591
0
                         v_freqFollow, length_v_freqFollow, *i_fillFollow, dmin,
592
0
                         dmax, numberTimeSlots);
593
594
          /*--------------------------------------------------------------------------
595
            Fill after transient:
596
          ---------------------------------------------------------------------------*/
597
0
          fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq,
598
0
                        length_v_freq, bmax, bufferFrameStart, numberTimeSlots,
599
0
                        fmax);
600
601
          /*--------------------------------------------------------------------------
602
            Take care of special case:
603
          ---------------------------------------------------------------------------*/
604
0
          if (parts == 1 && d < dmin) /*% no fill, short last envelope */
605
0
            specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq,
606
0
                        length_v_freq, &parts, d);
607
608
          /*--------------------------------------------------------------------------
609
            Calculate common border (split-point)
610
          ---------------------------------------------------------------------------*/
611
0
          calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord,
612
0
                         tranPosInternal, bufferFrameStart, numberTimeSlots);
613
614
          /*--------------------------------------------------------------------------
615
            Extract data for proper follow-up in next frame
616
          ---------------------------------------------------------------------------*/
617
0
          keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow,
618
0
                          length_v_freqFollow, i_tranFollow, i_fillFollow,
619
0
                          v_bord, length_v_bord, v_freq, i_cmon, i_tran, parts,
620
0
                          numberTimeSlots);
621
622
          /*--------------------------------------------------------------------------
623
            Calculate control signal
624
          ---------------------------------------------------------------------------*/
625
0
          calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord,
626
0
                         *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran,
627
0
                         0, nL);
628
0
        }
629
0
        break;
630
0
      case FIXFIX:
631
0
        if (tranPos == 0)
632
0
          numEnv = 1;
633
0
        else
634
0
          numEnv = 2;
635
636
0
        hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
637
0
        hSbrEnvFrame->SbrGrid.frameClass = frameClass;
638
639
0
        break;
640
0
      default:
641
0
        FDK_ASSERT(0);
642
0
    }
643
0
  }
644
645
  /*-------------------------------------------------------------------------
646
    Convert control signal to frame info struct
647
  ---------------------------------------------------------------------------*/
648
0
  ctrlSignal2FrameInfo(&hSbrEnvFrame->SbrGrid, &hSbrEnvFrame->SbrFrameInfo,
649
0
                       hSbrEnvFrame->freq_res_fixfix);
650
651
0
  return &hSbrEnvFrame->SbrFrameInfo;
652
0
}
653
654
/***************************************************************************/
655
/*!
656
  \brief    Gnerates frame info for FIXFIXonly frame class used for low delay
657
 version
658
659
  \return   nothing
660
 ****************************************************************************/
661
static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
662
                               HANDLE_SBR_GRID hSbrGrid, int tranPosInternal,
663
0
                               int numberTimeSlots, UCHAR fResTransIsLow) {
664
0
  int nEnv, i, k = 0, tranIdx;
665
0
  const int *pTable = NULL;
666
0
  const FREQ_RES *freqResTable = NULL;
667
668
0
  switch (numberTimeSlots) {
669
0
    case 8: {
670
0
      pTable = envelopeTable_8[tranPosInternal];
671
0
    }
672
0
      freqResTable = freqRes_table_8;
673
0
      break;
674
0
    case 15:
675
0
      pTable = envelopeTable_15[tranPosInternal];
676
0
      freqResTable = freqRes_table_16;
677
0
      break;
678
0
    case 16:
679
0
      pTable = envelopeTable_16[tranPosInternal];
680
0
      freqResTable = freqRes_table_16;
681
0
      break;
682
0
  }
683
684
  /* look number of envolpes in table */
685
0
  nEnv = pTable[0];
686
  /* look up envolpe distribution in table */
687
0
  for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2];
688
689
  /* open and close frame border */
690
0
  hSbrFrameInfo->borders[0] = 0;
691
0
  hSbrFrameInfo->borders[nEnv] = numberTimeSlots;
692
693
  /* adjust segment-frequency-resolution according to the segment-length */
694
0
  for (i = 0; i < nEnv; i++) {
695
0
    k = hSbrFrameInfo->borders[i + 1] - hSbrFrameInfo->borders[i];
696
0
    if (!fResTransIsLow)
697
0
      hSbrFrameInfo->freqRes[i] = freqResTable[k];
698
0
    else
699
0
      hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
700
701
0
    hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i];
702
0
  }
703
704
0
  hSbrFrameInfo->nEnvelopes = nEnv;
705
0
  hSbrFrameInfo->shortEnv = pTable[2];
706
  /* transient idx */
707
0
  tranIdx = pTable[1];
708
709
  /* add noise floors */
710
0
  hSbrFrameInfo->bordersNoise[0] = 0;
711
0
  hSbrFrameInfo->bordersNoise[1] =
712
0
      hSbrFrameInfo->borders[tranIdx ? tranIdx : 1];
713
0
  hSbrFrameInfo->bordersNoise[2] = numberTimeSlots;
714
0
  hSbrFrameInfo->nNoiseEnvelopes = 2;
715
716
0
  hSbrGrid->frameClass = FIXFIXonly;
717
0
  hSbrGrid->bs_abs_bord = tranPosInternal;
718
0
  hSbrGrid->bs_num_env = nEnv;
719
0
}
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
*******************************************************************************/
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
0
                                      INT ldGrid) { /* FH 00-06-26 */
741
742
0
  FDKmemclear(hSbrEnvFrame, sizeof(SBR_ENVELOPE_FRAME));
743
744
  /* Initialisation */
745
0
  hSbrEnvFrame->frameClassOld = FIXFIX;
746
0
  hSbrEnvFrame->spreadFlag = 0;
747
748
0
  hSbrEnvFrame->allowSpread = allowSpread;
749
0
  hSbrEnvFrame->numEnvStatic = numEnvStatic;
750
0
  hSbrEnvFrame->staticFraming = staticFraming;
751
0
  hSbrEnvFrame->freq_res_fixfix[0] = freq_res_fixfix[0];
752
0
  hSbrEnvFrame->freq_res_fixfix[1] = freq_res_fixfix[1];
753
0
  hSbrEnvFrame->fResTransIsLow = fResTransIsLow;
754
755
0
  hSbrEnvFrame->length_v_bord = 0;
756
0
  hSbrEnvFrame->length_v_bordFollow = 0;
757
758
0
  hSbrEnvFrame->length_v_freq = 0;
759
0
  hSbrEnvFrame->length_v_freqFollow = 0;
760
761
0
  hSbrEnvFrame->i_tranFollow = 0;
762
0
  hSbrEnvFrame->i_fillFollow = 0;
763
764
0
  hSbrEnvFrame->SbrGrid.numberTimeSlots = timeSlots;
765
766
0
  if (ldGrid) {
767
    /*case CODEC_AACLD:*/
768
0
    hSbrEnvFrame->dmin = 2;
769
0
    hSbrEnvFrame->dmax = 16;
770
0
    hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
771
0
    hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
772
0
  } else
773
0
    switch (timeSlots) {
774
0
      case NUMBER_TIME_SLOTS_1920:
775
0
        hSbrEnvFrame->dmin = 4;
776
0
        hSbrEnvFrame->dmax = 12;
777
0
        hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
778
0
        hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1920;
779
0
        break;
780
0
      case NUMBER_TIME_SLOTS_2048:
781
0
        hSbrEnvFrame->dmin = 4;
782
0
        hSbrEnvFrame->dmax = 12;
783
0
        hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
784
0
        hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2048;
785
0
        break;
786
0
      case NUMBER_TIME_SLOTS_1152:
787
0
        hSbrEnvFrame->dmin = 2;
788
0
        hSbrEnvFrame->dmax = 8;
789
0
        hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
790
0
        hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1152;
791
0
        break;
792
0
      case NUMBER_TIME_SLOTS_2304:
793
0
        hSbrEnvFrame->dmin = 4;
794
0
        hSbrEnvFrame->dmax = 15;
795
0
        hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
796
0
        hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2304;
797
0
        break;
798
0
      default:
799
0
        FDK_ASSERT(0);
800
0
    }
801
0
}
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
*******************************************************************************/
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
0
) {
837
0
  int bord, i;
838
839
0
  *length_v_bord = 0;
840
0
  *length_v_freq = 0;
841
842
  /* add attack env leading border (optional) */
843
0
  if (v_tuningSegm[0]) {
844
    /* v_bord = [(Ba)] start of attack env */
845
0
    FDKsbrEnc_AddRight(v_bord, length_v_bord, (tran - v_tuningSegm[0]));
846
847
    /* v_freq = [(Fa)] res of attack env */
848
0
    FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[0]);
849
0
  }
850
851
  /* add attack env trailing border/first decay env leading border */
852
0
  bord = tran;
853
0
  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
0
  if (v_tuningSegm[1]) {
857
0
    bord += v_tuningSegm[1];
858
859
    /* v_bord = [(Ba),Bd1,Bd2] */
860
0
    FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
861
862
    /* v_freq = [(Fa),Fd1] */
863
0
    FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[1]);
864
0
  }
865
866
  /* add 2:nd decay env trailing border (optional) */
867
0
  if (v_tuningSegm[2] != 0) {
868
0
    bord += v_tuningSegm[2];
869
870
    /* v_bord = [(Ba),Bd1, Bd2,(Bd3)] */
871
0
    FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
872
873
    /* v_freq = [(Fa),Fd1,(Fd2)] */
874
0
    FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[2]);
875
0
  }
876
877
  /*  v_freq = [(Fa),Fd1,(Fd2),1] */
878
0
  FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
879
880
  /*  calc min and max values of mandatory borders */
881
0
  *bmin = v_bord[0];
882
0
  for (i = 0; i < *length_v_bord; i++)
883
0
    if (v_bord[i] < *bmin) *bmin = v_bord[i];
884
885
0
  *bmax = v_bord[0];
886
0
  for (i = 0; i < *length_v_bord; i++)
887
0
    if (v_bord[i] > *bmax) *bmax = v_bord[i];
888
0
}
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
*******************************************************************************/
910
static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq,
911
0
                         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
0
  INT parts, d, j, S, s = 0, segm, bord;
919
920
  /*
921
    start with one envelope
922
  */
923
924
0
  parts = 1;
925
0
  d = rest;
926
927
  /*
928
    calc # of additional envelopes and corresponding lengths
929
  */
930
931
0
  while (d > dmax) {
932
0
    parts++;
933
934
0
    segm = rest / parts;
935
0
    S = (segm - 2) >> 1;
936
0
    s = fixMin(8, 2 * S + 2);
937
0
    d = rest - (parts - 1) * s;
938
0
  }
939
940
  /*
941
    add borders before mandatory borders
942
  */
943
944
0
  bord = bmin;
945
946
0
  for (j = 0; j <= parts - 2; j++) {
947
0
    bord = bord - s;
948
949
    /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)] */
950
0
    FDKsbrEnc_AddLeft(v_bord, length_v_bord, bord);
951
952
    /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1   ] */
953
0
    FDKsbrEnc_AddLeft(v_freq, length_v_freq, 1);
954
0
  }
955
0
}
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
****************************************************************************/
967
static int calcFillLengthMax(
968
    int tranPos,        /*!< input : transient position (ref: tran det) */
969
    int numberTimeSlots /*!< input : number of timeslots */
970
0
) {
971
0
  int fmax;
972
973
  /*
974
    calculate transient position within envelope buffer
975
  */
976
0
  switch (numberTimeSlots) {
977
0
    case NUMBER_TIME_SLOTS_2048:
978
0
      if (tranPos < 4)
979
0
        fmax = 6;
980
0
      else if (tranPos == 4 || tranPos == 5)
981
0
        fmax = 4;
982
0
      else
983
0
        fmax = 8;
984
0
      break;
985
986
0
    case NUMBER_TIME_SLOTS_1920:
987
0
      if (tranPos < 4)
988
0
        fmax = 5;
989
0
      else if (tranPos == 4 || tranPos == 5)
990
0
        fmax = 3;
991
0
      else
992
0
        fmax = 7;
993
0
      break;
994
995
0
    default:
996
0
      fmax = 8;
997
0
      break;
998
0
  }
999
1000
0
  return fmax;
1001
0
}
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
*******************************************************************************/
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
0
                          INT fmax) {
1030
0
  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
0
  rest = bufferFrameStart + 2 * numberTimeSlots - bmax;
1039
0
  *d = rest;
1040
1041
0
  if (*d > 0) {
1042
0
    *parts = 1; /* start with one envelope */
1043
1044
    /* calc # of additional envelopes and corresponding lengths */
1045
1046
0
    while (*d > dmax) {
1047
0
      *parts = *parts + 1;
1048
1049
0
      segm = rest / (*parts);
1050
0
      S = (segm - 2) >> 1;
1051
0
      s = fixMin(fmax, 2 * S + 2);
1052
0
      *d = rest - (*parts - 1) * s;
1053
0
    }
1054
1055
    /* add borders after mandatory borders */
1056
1057
0
    bord = bmax;
1058
0
    for (j = 0; j <= *parts - 2; j++) {
1059
0
      bord += s;
1060
1061
      /* v_bord =  [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3),(Bf)] */
1062
0
      FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
1063
1064
      /* v_freq =  [...,(1 ),(Fa),Fd1,(Fd2), 1   , 1! ,1] */
1065
0
      FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
1066
0
    }
1067
0
  } else {
1068
0
    *parts = 1;
1069
1070
    /* remove last element from v_bord and v_freq */
1071
1072
0
    *length_v_bord = *length_v_bord - 1;
1073
0
    *length_v_freq = *length_v_freq - 1;
1074
0
  }
1075
0
}
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
*******************************************************************************/
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
0
                           INT dmax, INT numberTimeSlots) {
1107
0
  INT middle, b_new, numBordFollow, bordMaxFollow, i;
1108
1109
0
  if (numberTimeSlots != NUMBER_TIME_SLOTS_1152) {
1110
    /* % remove fill borders: */
1111
0
    if (i_fillFollow >= 1) {
1112
0
      *length_v_bordFollow = i_fillFollow;
1113
0
      *length_v_freqFollow = i_fillFollow;
1114
0
    }
1115
1116
0
    numBordFollow = *length_v_bordFollow;
1117
0
    bordMaxFollow = v_bordFollow[numBordFollow - 1];
1118
1119
    /* remove even more borders if needed */
1120
0
    middle = bmin - bordMaxFollow;
1121
0
    while (middle < 0) {
1122
0
      numBordFollow--;
1123
0
      bordMaxFollow = v_bordFollow[numBordFollow - 1];
1124
0
      middle = bmin - bordMaxFollow;
1125
0
    }
1126
1127
0
    *length_v_bordFollow = numBordFollow;
1128
0
    *length_v_freqFollow = numBordFollow;
1129
0
    *nL = numBordFollow - 1;
1130
1131
0
    b_new = *length_v_bord;
1132
1133
0
    if (middle <= dmax) {
1134
0
      if (middle >= dmin) { /* concatenate */
1135
0
        FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1136
0
                             *length_v_bordFollow);
1137
0
        FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1138
0
                             *length_v_freqFollow);
1139
0
      }
1140
1141
0
      else {
1142
0
        if (v_tuningSegm[0] != 0) { /* remove one new border and concatenate */
1143
0
          *length_v_bord = b_new - 1;
1144
0
          FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1145
0
                               *length_v_bordFollow);
1146
1147
0
          *length_v_freq = b_new - 1;
1148
0
          FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow,
1149
0
                               *length_v_freqFollow);
1150
0
        } else {
1151
0
          if (*length_v_bordFollow >
1152
0
              1) { /* remove one old border and concatenate */
1153
0
            FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1154
0
                                 *length_v_bordFollow - 1);
1155
0
            FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1156
0
                                 *length_v_bordFollow - 1);
1157
1158
0
            *nL = *nL - 1;
1159
0
          } else { /* remove new "transient" border and concatenate */
1160
1161
0
            for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1];
1162
1163
0
            for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1];
1164
1165
0
            *length_v_bord = b_new - 1;
1166
0
            *length_v_freq = b_new - 1;
1167
1168
0
            FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1169
0
                                 *length_v_bordFollow);
1170
0
            FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1171
0
                                 *length_v_freqFollow);
1172
0
          }
1173
0
        }
1174
0
      }
1175
0
    } else { /* middle > dmax */
1176
1177
0
      fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
1178
0
                   middle);
1179
0
      FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1180
0
                           *length_v_bordFollow);
1181
0
      FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1182
0
                           *length_v_freqFollow);
1183
0
    }
1184
1185
0
  } else { /* numberTimeSlots==NUMBER_TIME_SLOTS_1152 */
1186
1187
0
    INT l, m;
1188
1189
    /*------------------------------------------------------------------------
1190
      remove fill borders
1191
      ------------------------------------------------------------------------*/
1192
0
    if (i_fillFollow >= 1) {
1193
0
      *length_v_bordFollow = i_fillFollow;
1194
0
      *length_v_freqFollow = i_fillFollow;
1195
0
    }
1196
1197
0
    numBordFollow = *length_v_bordFollow;
1198
0
    bordMaxFollow = v_bordFollow[numBordFollow - 1];
1199
1200
    /*------------------------------------------------------------------------
1201
      remove more borders if necessary to eliminate overlap
1202
      ------------------------------------------------------------------------*/
1203
1204
    /* check for overlap */
1205
0
    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
0
    while (middle < 0) {
1216
      /* ...but don't remove all of them */
1217
0
      if (numBordFollow == 1) break;
1218
1219
0
      numBordFollow--;
1220
0
      bordMaxFollow = v_bordFollow[numBordFollow - 1];
1221
0
      middle = bmin - bordMaxFollow;
1222
0
    }
1223
1224
    /* if this isn't enough, remove new non-fill borders */
1225
0
    if (middle < 0) {
1226
0
      for (l = 0, m = 0; l < *length_v_bord; l++) {
1227
0
        if (v_bord[l] > bordMaxFollow) {
1228
0
          v_bord[m] = v_bord[l];
1229
0
          v_freq[m] = v_freq[l];
1230
0
          m++;
1231
0
        }
1232
0
      }
1233
1234
0
      *length_v_bord = l;
1235
0
      *length_v_freq = l;
1236
1237
0
      bmin = v_bord[0];
1238
0
    }
1239
1240
    /*------------------------------------------------------------------------
1241
      update modified follow-up data
1242
      ------------------------------------------------------------------------*/
1243
1244
0
    *length_v_bordFollow = numBordFollow;
1245
0
    *length_v_freqFollow = numBordFollow;
1246
1247
    /* left relative borders correspond to follow-up */
1248
0
    *nL = numBordFollow - 1;
1249
1250
    /*------------------------------------------------------------------------
1251
      take care of intervals ii through iv
1252
      ------------------------------------------------------------------------*/
1253
1254
    /* now middle should be >= 0 */
1255
0
    middle = bmin - bordMaxFollow;
1256
1257
0
    if (middle <= dmin) /* (ii) */
1258
0
    {
1259
0
      b_new = *length_v_bord;
1260
1261
0
      if (v_tuningSegm[0] != 0) {
1262
        /* remove new "luxury" border and concatenate */
1263
0
        *length_v_bord = b_new - 1;
1264
0
        FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1265
0
                             *length_v_bordFollow);
1266
1267
0
        *length_v_freq = b_new - 1;
1268
0
        FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow,
1269
0
                             *length_v_freqFollow);
1270
1271
0
      } else if (*length_v_bordFollow > 1) {
1272
        /* remove old border and concatenate */
1273
0
        FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1274
0
                             *length_v_bordFollow - 1);
1275
0
        FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1276
0
                             *length_v_bordFollow - 1);
1277
1278
0
        *nL = *nL - 1;
1279
0
      } else {
1280
        /* remove new border and concatenate */
1281
0
        for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1];
1282
1283
0
        for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1];
1284
1285
0
        *length_v_bord = b_new - 1;
1286
0
        *length_v_freq = b_new - 1;
1287
1288
0
        FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1289
0
                             *length_v_bordFollow);
1290
0
        FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1291
0
                             *length_v_freqFollow);
1292
0
      }
1293
0
    } else if ((middle >= dmin) && (middle <= dmax)) /* (iii) */
1294
0
    {
1295
      /* concatenate */
1296
0
      FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1297
0
                           *length_v_bordFollow);
1298
0
      FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1299
0
                           *length_v_freqFollow);
1300
1301
0
    } else /* (iv) */
1302
0
    {
1303
0
      fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
1304
0
                   middle);
1305
0
      FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
1306
0
                           *length_v_bordFollow);
1307
0
      FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
1308
0
                           *length_v_freqFollow);
1309
0
    }
1310
0
  }
1311
0
}
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
*******************************************************************************/
1324
static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld,
1325
0
                           INT tranFlag, INT *spreadFlag) {
1326
0
  switch (*frameClassOld) {
1327
0
    case FIXFIXonly:
1328
0
    case FIXFIX:
1329
0
      if (tranFlag)
1330
0
        *frameClass = FIXVAR;
1331
0
      else
1332
0
        *frameClass = FIXFIX;
1333
0
      break;
1334
0
    case FIXVAR:
1335
0
      if (tranFlag) {
1336
0
        *frameClass = VARVAR;
1337
0
        *spreadFlag = 0;
1338
0
      } else {
1339
0
        if (*spreadFlag)
1340
0
          *frameClass = VARVAR;
1341
0
        else
1342
0
          *frameClass = VARFIX;
1343
0
      }
1344
0
      break;
1345
0
    case VARFIX:
1346
0
      if (tranFlag)
1347
0
        *frameClass = FIXVAR;
1348
0
      else
1349
0
        *frameClass = FIXFIX;
1350
0
      break;
1351
0
    case VARVAR:
1352
0
      if (tranFlag) {
1353
0
        *frameClass = VARVAR;
1354
0
        *spreadFlag = 0;
1355
0
      } else {
1356
0
        if (*spreadFlag)
1357
0
          *frameClass = VARVAR;
1358
0
        else
1359
0
          *frameClass = VARFIX;
1360
0
      }
1361
0
      break;
1362
0
  };
1363
1364
0
  *frameClassOld = *frameClass;
1365
0
}
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
*******************************************************************************/
1385
static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord,
1386
                        INT *length_v_bord, INT *v_freq, INT *length_v_freq,
1387
0
                        INT *parts, INT d) {
1388
0
  INT L;
1389
1390
0
  L = *length_v_bord;
1391
1392
0
  if (allowSpread) { /* add one "step 8" */
1393
0
    *spreadFlag = 1;
1394
0
    FDKsbrEnc_AddRight(v_bord, length_v_bord, v_bord[L - 1] + 8);
1395
0
    FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
1396
0
    (*parts)++;
1397
0
  } else {
1398
0
    if (d == 1) { /*  stretch one slot */
1399
0
      *length_v_bord = L - 1;
1400
0
      *length_v_freq = L - 1;
1401
0
    } else {
1402
0
      if ((v_bord[L - 1] - v_bord[L - 2]) > 2) { /* compress one quant step */
1403
0
        v_bord[L - 1] = v_bord[L - 1] - 2;
1404
0
        v_freq[*length_v_freq - 1] = 0; /* use low res for short segment */
1405
0
      }
1406
0
    }
1407
0
  }
1408
0
}
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
*******************************************************************************/
1425
static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord,
1426
                           INT *length_v_bord, INT tran, INT bufferFrameStart,
1427
0
                           INT numberTimeSlots) { /* FH 00-06-26 */
1428
0
  INT i;
1429
1430
0
  for (i = 0; i < *length_v_bord; i++)
1431
0
    if (v_bord[i] >= bufferFrameStart + numberTimeSlots) { /* FH 00-06-26 */
1432
0
      *i_cmon = i;
1433
0
      break;
1434
0
    }
1435
1436
  /* keep track of transient: */
1437
0
  for (i = 0; i < *length_v_bord; i++)
1438
0
    if (v_bord[i] >= tran) {
1439
0
      *i_tran = i;
1440
0
      break;
1441
0
    } else
1442
0
      *i_tran = EMPTY;
1443
0
}
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
*******************************************************************************/
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
0
                            INT numberTimeSlots) { /* FH 00-06-26 */
1473
0
  INT L, i, j;
1474
1475
0
  L = *length_v_bord;
1476
1477
0
  (*length_v_bordFollow) = 0;
1478
0
  (*length_v_freqFollow) = 0;
1479
1480
0
  for (j = 0, i = i_cmon; i < L; i++, j++) {
1481
0
    v_bordFollow[j] = v_bord[i] - numberTimeSlots; /* FH 00-06-26 */
1482
0
    v_freqFollow[j] = v_freq[i];
1483
0
    (*length_v_bordFollow)++;
1484
0
    (*length_v_freqFollow)++;
1485
0
  }
1486
0
  if (i_tran != EMPTY)
1487
0
    *i_tranFollow = i_tran - i_cmon;
1488
0
  else
1489
0
    *i_tranFollow = EMPTY;
1490
0
  *i_fillFollow = L - (parts - 1) - i_cmon;
1491
0
}
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
*******************************************************************************/
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
0
                           INT spreadFlag, INT nL) {
1517
0
  INT i, r, a, n, p, b, aL, aR, ntot, nmax, nR;
1518
1519
0
  INT *v_f = hSbrGrid->v_f;
1520
0
  INT *v_fLR = hSbrGrid->v_fLR;
1521
0
  INT *v_r = hSbrGrid->bs_rel_bord;
1522
0
  INT *v_rL = hSbrGrid->bs_rel_bord_0;
1523
0
  INT *v_rR = hSbrGrid->bs_rel_bord_1;
1524
1525
0
  INT length_v_r = 0;
1526
0
  INT length_v_rR = 0;
1527
0
  INT length_v_rL = 0;
1528
1529
0
  switch (frameClass) {
1530
0
    case FIXVAR:
1531
      /* absolute border: */
1532
1533
0
      a = v_bord[i_cmon];
1534
1535
      /* relative borders: */
1536
0
      length_v_r = 0;
1537
0
      i = i_cmon;
1538
1539
0
      while (i >= 1) {
1540
0
        r = v_bord[i] - v_bord[i - 1];
1541
0
        FDKsbrEnc_AddRight(v_r, &length_v_r, r);
1542
0
        i--;
1543
0
      }
1544
1545
      /*  number of relative borders: */
1546
0
      n = length_v_r;
1547
1548
      /* freq res: */
1549
0
      for (i = 0; i < i_cmon; i++) v_f[i] = v_freq[i_cmon - 1 - i];
1550
0
      v_f[i_cmon] = 1;
1551
1552
      /* pointer: */
1553
0
      p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0);
1554
1555
0
      hSbrGrid->frameClass = frameClass;
1556
0
      hSbrGrid->bs_abs_bord = a;
1557
0
      hSbrGrid->n = n;
1558
0
      hSbrGrid->p = p;
1559
1560
0
      break;
1561
0
    case VARFIX:
1562
      /* absolute border: */
1563
0
      a = v_bord[0];
1564
1565
      /* relative borders: */
1566
0
      length_v_r = 0;
1567
1568
0
      for (i = 1; i < length_v_bord; i++) {
1569
0
        r = v_bord[i] - v_bord[i - 1];
1570
0
        FDKsbrEnc_AddRight(v_r, &length_v_r, r);
1571
0
      }
1572
1573
      /* number of relative borders: */
1574
0
      n = length_v_r;
1575
1576
      /* freq res: */
1577
0
      FDKmemcpy(v_f, v_freq, length_v_freq * sizeof(INT));
1578
1579
      /* pointer: */
1580
0
      p = (i_tran >= 0 && i_tran != EMPTY) ? (i_tran + 1) : (0);
1581
1582
0
      hSbrGrid->frameClass = frameClass;
1583
0
      hSbrGrid->bs_abs_bord = a;
1584
0
      hSbrGrid->n = n;
1585
0
      hSbrGrid->p = p;
1586
1587
0
      break;
1588
0
    case VARVAR:
1589
0
      if (spreadFlag) {
1590
        /* absolute borders: */
1591
0
        b = length_v_bord;
1592
1593
0
        aL = v_bord[0];
1594
0
        aR = v_bord[b - 1];
1595
1596
        /* number of relative borders:    */
1597
0
        ntot = b - 2;
1598
1599
0
        nmax = 2; /* n: {0,1,2} */
1600
0
        if (ntot > nmax) {
1601
0
          nL = nmax;
1602
0
          nR = ntot - nmax;
1603
0
        } else {
1604
0
          nL = ntot;
1605
0
          nR = 0;
1606
0
        }
1607
1608
        /* relative borders: */
1609
0
        length_v_rL = 0;
1610
0
        for (i = 1; i <= nL; i++) {
1611
0
          r = v_bord[i] - v_bord[i - 1];
1612
0
          FDKsbrEnc_AddRight(v_rL, &length_v_rL, r);
1613
0
        }
1614
1615
0
        length_v_rR = 0;
1616
0
        i = b - 1;
1617
0
        while (i >= b - nR) {
1618
0
          r = v_bord[i] - v_bord[i - 1];
1619
0
          FDKsbrEnc_AddRight(v_rR, &length_v_rR, r);
1620
0
          i--;
1621
0
        }
1622
1623
        /* pointer (only one due to constraint in frame info): */
1624
0
        p = (i_tran > 0 && i_tran != EMPTY) ? (b - i_tran) : (0);
1625
1626
        /* freq res: */
1627
1628
0
        for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i];
1629
0
      } else {
1630
0
        length_v_bord = i_cmon + 1;
1631
1632
        /* absolute borders: */
1633
0
        b = length_v_bord;
1634
1635
0
        aL = v_bord[0];
1636
0
        aR = v_bord[b - 1];
1637
1638
        /* number of relative borders:   */
1639
0
        ntot = b - 2;
1640
0
        nR = ntot - nL;
1641
1642
        /* relative borders: */
1643
0
        length_v_rL = 0;
1644
0
        for (i = 1; i <= nL; i++) {
1645
0
          r = v_bord[i] - v_bord[i - 1];
1646
0
          FDKsbrEnc_AddRight(v_rL, &length_v_rL, r);
1647
0
        }
1648
1649
0
        length_v_rR = 0;
1650
0
        i = b - 1;
1651
0
        while (i >= b - nR) {
1652
0
          r = v_bord[i] - v_bord[i - 1];
1653
0
          FDKsbrEnc_AddRight(v_rR, &length_v_rR, r);
1654
0
          i--;
1655
0
        }
1656
1657
        /* pointer (only one due to constraint in frame info): */
1658
0
        p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0);
1659
1660
        /* freq res: */
1661
0
        for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i];
1662
0
      }
1663
1664
0
      hSbrGrid->frameClass = frameClass;
1665
0
      hSbrGrid->bs_abs_bord_0 = aL;
1666
0
      hSbrGrid->bs_abs_bord_1 = aR;
1667
0
      hSbrGrid->bs_num_rel_0 = nL;
1668
0
      hSbrGrid->bs_num_rel_1 = nR;
1669
0
      hSbrGrid->p = p;
1670
1671
0
      break;
1672
1673
0
    default:
1674
      /* do nothing */
1675
0
      break;
1676
0
  }
1677
0
}
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
*******************************************************************************/
1695
static void createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv,
1696
0
                               INT nTimeSlots) {
1697
0
  switch (nEnv) {
1698
0
    case 1:
1699
0
      switch (nTimeSlots) {
1700
0
        case NUMBER_TIME_SLOTS_1920:
1701
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo1_1920, sizeof(SBR_FRAME_INFO));
1702
0
          break;
1703
0
        case NUMBER_TIME_SLOTS_2048:
1704
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo1_2048, sizeof(SBR_FRAME_INFO));
1705
0
          break;
1706
0
        case NUMBER_TIME_SLOTS_1152:
1707
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo1_1152, sizeof(SBR_FRAME_INFO));
1708
0
          break;
1709
0
        case NUMBER_TIME_SLOTS_2304:
1710
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo1_2304, sizeof(SBR_FRAME_INFO));
1711
0
          break;
1712
0
        case NUMBER_TIME_SLOTS_512LD:
1713
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo1_512LD, sizeof(SBR_FRAME_INFO));
1714
0
          break;
1715
0
        default:
1716
0
          FDK_ASSERT(0);
1717
0
      }
1718
0
      break;
1719
0
    case 2:
1720
0
      switch (nTimeSlots) {
1721
0
        case NUMBER_TIME_SLOTS_1920:
1722
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo2_1920, sizeof(SBR_FRAME_INFO));
1723
0
          break;
1724
0
        case NUMBER_TIME_SLOTS_2048:
1725
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo2_2048, sizeof(SBR_FRAME_INFO));
1726
0
          break;
1727
0
        case NUMBER_TIME_SLOTS_1152:
1728
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo2_1152, sizeof(SBR_FRAME_INFO));
1729
0
          break;
1730
0
        case NUMBER_TIME_SLOTS_2304:
1731
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo2_2304, sizeof(SBR_FRAME_INFO));
1732
0
          break;
1733
0
        case NUMBER_TIME_SLOTS_512LD:
1734
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo2_512LD, sizeof(SBR_FRAME_INFO));
1735
0
          break;
1736
0
        default:
1737
0
          FDK_ASSERT(0);
1738
0
      }
1739
0
      break;
1740
0
    case 4:
1741
0
      switch (nTimeSlots) {
1742
0
        case NUMBER_TIME_SLOTS_1920:
1743
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo4_1920, sizeof(SBR_FRAME_INFO));
1744
0
          break;
1745
0
        case NUMBER_TIME_SLOTS_2048:
1746
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo4_2048, sizeof(SBR_FRAME_INFO));
1747
0
          break;
1748
0
        case NUMBER_TIME_SLOTS_1152:
1749
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo4_1152, sizeof(SBR_FRAME_INFO));
1750
0
          break;
1751
0
        case NUMBER_TIME_SLOTS_2304:
1752
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo4_2304, sizeof(SBR_FRAME_INFO));
1753
0
          break;
1754
0
        case NUMBER_TIME_SLOTS_512LD:
1755
0
          FDKmemcpy(hSbrFrameInfo, &frameInfo4_512LD, sizeof(SBR_FRAME_INFO));
1756
0
          break;
1757
0
        default:
1758
0
          FDK_ASSERT(0);
1759
0
      }
1760
0
      break;
1761
0
    default:
1762
0
      FDK_ASSERT(0);
1763
0
  }
1764
0
}
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
*******************************************************************************/
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
0
) {
1790
0
  INT frameSplit = 0;
1791
0
  INT nEnv = 0, border = 0, i, k, p /*?*/;
1792
0
  INT *v_r = hSbrGrid->bs_rel_bord;
1793
0
  INT *v_f = hSbrGrid->v_f;
1794
1795
0
  FRAME_CLASS frameClass = hSbrGrid->frameClass;
1796
0
  INT bufferFrameStart = hSbrGrid->bufferFrameStart;
1797
0
  INT numberTimeSlots = hSbrGrid->numberTimeSlots;
1798
1799
0
  switch (frameClass) {
1800
0
    case FIXFIX:
1801
0
      createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
1802
1803
0
      frameSplit = (hSbrFrameInfo->nEnvelopes > 1);
1804
0
      for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
1805
0
        hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] =
1806
0
            freq_res_fixfix[frameSplit];
1807
0
      }
1808
0
      break;
1809
1810
0
    case FIXVAR:
1811
0
    case VARFIX:
1812
0
      nEnv = hSbrGrid->n + 1; /* read n [SBR_NUM_BITS bits] */ /*? snd*/
1813
0
      FDK_ASSERT(nEnv <= MAX_ENVELOPES_FIXVAR_VARFIX);
1814
1815
0
      hSbrFrameInfo->nEnvelopes = nEnv;
1816
1817
0
      border = hSbrGrid->bs_abs_bord; /* read the absolute border */
1818
1819
0
      if (nEnv == 1)
1820
0
        hSbrFrameInfo->nNoiseEnvelopes = 1;
1821
0
      else
1822
0
        hSbrFrameInfo->nNoiseEnvelopes = 2;
1823
1824
0
      break;
1825
1826
0
    default:
1827
      /* do nothing */
1828
0
      break;
1829
0
  }
1830
1831
0
  switch (frameClass) {
1832
0
    case FIXVAR:
1833
0
      hSbrFrameInfo->borders[0] =
1834
0
          bufferFrameStart; /* start-position of 1st envelope */
1835
1836
0
      hSbrFrameInfo->borders[nEnv] = border;
1837
1838
0
      for (k = 0, i = nEnv - 1; k < nEnv - 1; k++, i--) {
1839
0
        border -= v_r[k];
1840
0
        hSbrFrameInfo->borders[i] = border;
1841
0
      }
1842
1843
      /* make either envelope nr. nEnv + 1 - p short; or don't shorten if p == 0
1844
       */
1845
0
      p = hSbrGrid->p;
1846
0
      if (p == 0) {
1847
0
        hSbrFrameInfo->shortEnv = 0;
1848
0
      } else {
1849
0
        hSbrFrameInfo->shortEnv = nEnv + 1 - p;
1850
0
      }
1851
1852
0
      for (k = 0, i = nEnv - 1; k < nEnv; k++, i--) {
1853
0
        hSbrFrameInfo->freqRes[i] = (FREQ_RES)v_f[k];
1854
0
      }
1855
1856
      /* if either there is no short envelope or the last envelope is short...
1857
       */
1858
0
      if (p == 0 || p == 1) {
1859
0
        hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
1860
0
      } else {
1861
0
        hSbrFrameInfo->bordersNoise[1] =
1862
0
            hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
1863
0
      }
1864
1865
0
      break;
1866
1867
0
    case VARFIX:
1868
      /* in this case 'border' indicates the start of the 1st envelope */
1869
0
      hSbrFrameInfo->borders[0] = border;
1870
1871
0
      for (k = 0; k < nEnv - 1; k++) {
1872
0
        border += v_r[k];
1873
0
        hSbrFrameInfo->borders[k + 1] = border;
1874
0
      }
1875
1876
0
      hSbrFrameInfo->borders[nEnv] = bufferFrameStart + numberTimeSlots;
1877
1878
0
      p = hSbrGrid->p;
1879
0
      if (p == 0 || p == 1) {
1880
0
        hSbrFrameInfo->shortEnv = 0;
1881
0
      } else {
1882
0
        hSbrFrameInfo->shortEnv = p - 1;
1883
0
      }
1884
1885
0
      for (k = 0; k < nEnv; k++) {
1886
0
        hSbrFrameInfo->freqRes[k] = (FREQ_RES)v_f[k];
1887
0
      }
1888
1889
0
      switch (p) {
1890
0
        case 0:
1891
0
          hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[1];
1892
0
          break;
1893
0
        case 1:
1894
0
          hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
1895
0
          break;
1896
0
        default:
1897
0
          hSbrFrameInfo->bordersNoise[1] =
1898
0
              hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
1899
0
          break;
1900
0
      }
1901
0
      break;
1902
1903
0
    case VARVAR:
1904
0
      nEnv = hSbrGrid->bs_num_rel_0 + hSbrGrid->bs_num_rel_1 + 1;
1905
0
      FDK_ASSERT(nEnv <= MAX_ENVELOPES_VARVAR); /* just to be sure */
1906
0
      hSbrFrameInfo->nEnvelopes = nEnv;
1907
1908
0
      hSbrFrameInfo->borders[0] = border = hSbrGrid->bs_abs_bord_0;
1909
1910
0
      for (k = 0, i = 1; k < hSbrGrid->bs_num_rel_0; k++, i++) {
1911
0
        border += hSbrGrid->bs_rel_bord_0[k];
1912
0
        hSbrFrameInfo->borders[i] = border;
1913
0
      }
1914
1915
0
      border = hSbrGrid->bs_abs_bord_1;
1916
0
      hSbrFrameInfo->borders[nEnv] = border;
1917
1918
0
      for (k = 0, i = nEnv - 1; k < hSbrGrid->bs_num_rel_1; k++, i--) {
1919
0
        border -= hSbrGrid->bs_rel_bord_1[k];
1920
0
        hSbrFrameInfo->borders[i] = border;
1921
0
      }
1922
1923
0
      p = hSbrGrid->p;
1924
0
      if (p == 0) {
1925
0
        hSbrFrameInfo->shortEnv = 0;
1926
0
      } else {
1927
0
        hSbrFrameInfo->shortEnv = nEnv + 1 - p;
1928
0
      }
1929
1930
0
      for (k = 0; k < nEnv; k++) {
1931
0
        hSbrFrameInfo->freqRes[k] = (FREQ_RES)hSbrGrid->v_fLR[k];
1932
0
      }
1933
1934
0
      if (nEnv == 1) {
1935
0
        hSbrFrameInfo->nNoiseEnvelopes = 1;
1936
0
        hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
1937
0
        hSbrFrameInfo->bordersNoise[1] = hSbrGrid->bs_abs_bord_1;
1938
0
      } else {
1939
0
        hSbrFrameInfo->nNoiseEnvelopes = 2;
1940
0
        hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
1941
1942
0
        if (p == 0 || p == 1) {
1943
0
          hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
1944
0
        } else {
1945
0
          hSbrFrameInfo->bordersNoise[1] =
1946
0
              hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
1947
0
        }
1948
0
        hSbrFrameInfo->bordersNoise[2] = hSbrGrid->bs_abs_bord_1;
1949
0
      }
1950
0
      break;
1951
1952
0
    default:
1953
      /* do nothing */
1954
0
      break;
1955
0
  }
1956
1957
0
  if (frameClass == VARFIX || frameClass == FIXVAR) {
1958
0
    hSbrFrameInfo->bordersNoise[0] = hSbrFrameInfo->borders[0];
1959
0
    if (nEnv == 1) {
1960
0
      hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv];
1961
0
    } else {
1962
0
      hSbrFrameInfo->bordersNoise[2] = hSbrFrameInfo->borders[nEnv];
1963
0
    }
1964
0
  }
1965
0
}