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