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