Imported Debian version 0.1.3.1
[deb_fdk-aac.git] / libSBRenc / src / fram_gen.cpp
1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 © Copyright 1995 - 2013 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 INT 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 );
346
347
348 /*!
349 Functionname: FDKsbrEnc_frameInfoGenerator
350
351 Description: produces the FRAME_INFO struct for the current frame
352
353 Arguments: hSbrEnvFrame - pointer to sbr envelope handle
354 v_pre_transient_info - pointer to transient info vector
355 v_transient_info - pointer to previous transient info vector
356 v_tuning - pointer to tuning vector
357
358 Return: frame_info - pointer to SBR_FRAME_INFO struct
359
360 *******************************************************************************/
361 HANDLE_SBR_FRAME_INFO
362 FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
363 UCHAR *v_transient_info,
364 UCHAR *v_transient_info_pre,
365 int ldGrid,
366 const int *v_tuning)
367 {
368 INT numEnv, tranPosInternal=0, bmin=0, bmax=0, parts, d, i_cmon=0, i_tran=0, nL;
369 INT fmax = 0;
370
371 INT *v_bord = hSbrEnvFrame->v_bord;
372 INT *v_freq = hSbrEnvFrame->v_freq;
373 INT *v_bordFollow = hSbrEnvFrame->v_bordFollow;
374 INT *v_freqFollow = hSbrEnvFrame->v_freqFollow;
375
376
377 INT *length_v_bordFollow = &hSbrEnvFrame->length_v_bordFollow;
378 INT *length_v_freqFollow = &hSbrEnvFrame->length_v_freqFollow;
379 INT *length_v_bord = &hSbrEnvFrame->length_v_bord;
380 INT *length_v_freq = &hSbrEnvFrame->length_v_freq;
381 INT *spreadFlag = &hSbrEnvFrame->spreadFlag;
382 INT *i_tranFollow = &hSbrEnvFrame->i_tranFollow;
383 INT *i_fillFollow = &hSbrEnvFrame->i_fillFollow;
384 FRAME_CLASS *frameClassOld = &hSbrEnvFrame->frameClassOld;
385 FRAME_CLASS frameClass = FIXFIX;
386
387
388 INT allowSpread = hSbrEnvFrame->allowSpread;
389 INT numEnvStatic = hSbrEnvFrame->numEnvStatic;
390 INT staticFraming = hSbrEnvFrame->staticFraming;
391 INT dmin = hSbrEnvFrame->dmin;
392 INT dmax = hSbrEnvFrame->dmax;
393
394 INT bufferFrameStart = hSbrEnvFrame->SbrGrid.bufferFrameStart;
395 INT numberTimeSlots = hSbrEnvFrame->SbrGrid.numberTimeSlots;
396 INT frameMiddleSlot = hSbrEnvFrame->frameMiddleSlot;
397
398 INT tranPos = v_transient_info[0];
399 INT tranFlag = v_transient_info[1];
400
401 const int *v_tuningSegm = v_tuning;
402 const int *v_tuningFreq = v_tuning + 3;
403
404 hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
405 INT freq_res_fixfix = hSbrEnvFrame->freq_res_fixfix;
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(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 );
534
535 return &(hSbrEnvFrame->SbrFrameInfo);
536
537 case FIXVAR:
538
539 /*--------------------------------------------------------------------------
540 Design remaining parts of T/F-grid (assuming next frame is VarFix)
541 ---------------------------------------------------------------------------*/
542
543 /*--------------------------------------------------------------------------
544 Fill region before new transient:
545 ---------------------------------------------------------------------------*/
546 fillFramePre (dmax, v_bord, length_v_bord, v_freq, length_v_freq,
547 bmin, bmin - bufferFrameStart); /* FH 00-06-26 */
548
549 /*--------------------------------------------------------------------------
550 Fill region after new transient:
551 ---------------------------------------------------------------------------*/
552 fillFramePost (&parts, &d, dmax, v_bord, length_v_bord, v_freq,
553 length_v_freq, bmax, bufferFrameStart, numberTimeSlots, fmax);
554
555 /*--------------------------------------------------------------------------
556 Take care of special case:
557 ---------------------------------------------------------------------------*/
558 if (parts == 1 && d < dmin) /* no fill, short last envelope */
559 specialCase (spreadFlag, allowSpread, v_bord, length_v_bord,
560 v_freq, length_v_freq, &parts, d);
561
562 /*--------------------------------------------------------------------------
563 Calculate common border (split-point)
564 ---------------------------------------------------------------------------*/
565 calcCmonBorder (&i_cmon, &i_tran, v_bord, length_v_bord, tranPosInternal,
566 bufferFrameStart, numberTimeSlots); /* FH 00-06-26 */
567
568 /*--------------------------------------------------------------------------
569 Extract data for proper follow-up in next frame
570 ---------------------------------------------------------------------------*/
571 keepForFollowUp (v_bordFollow, length_v_bordFollow, v_freqFollow,
572 length_v_freqFollow, i_tranFollow, i_fillFollow,
573 v_bord, length_v_bord, v_freq, i_cmon, i_tran, parts, numberTimeSlots); /* FH 00-06-26 */
574
575 /*--------------------------------------------------------------------------
576 Calculate control signal
577 ---------------------------------------------------------------------------*/
578 calcCtrlSignal (&hSbrEnvFrame->SbrGrid, frameClass,
579 v_bord, *length_v_bord, v_freq, *length_v_freq,
580 i_cmon, i_tran, *spreadFlag, DC);
581 break;
582 case VARFIX:
583 /*--------------------------------------------------------------------------
584 Follow-up old transient - calculate control signal
585 ---------------------------------------------------------------------------*/
586 calcCtrlSignal (&hSbrEnvFrame->SbrGrid, frameClass,
587 v_bordFollow, *length_v_bordFollow, v_freqFollow,
588 *length_v_freqFollow, DC, *i_tranFollow,
589 *spreadFlag, DC);
590 break;
591 case VARVAR:
592 if (*spreadFlag) { /* spread across three frames */
593 /*--------------------------------------------------------------------------
594 Follow-up old transient - calculate control signal
595 ---------------------------------------------------------------------------*/
596 calcCtrlSignal (&hSbrEnvFrame->SbrGrid,
597 frameClass, v_bordFollow, *length_v_bordFollow,
598 v_freqFollow, *length_v_freqFollow, DC,
599 *i_tranFollow, *spreadFlag, DC);
600
601 *spreadFlag = 0;
602
603 /*--------------------------------------------------------------------------
604 Extract data for proper follow-up in next frame
605 ---------------------------------------------------------------------------*/
606 v_bordFollow[0] = hSbrEnvFrame->SbrGrid.bs_abs_bord_1 - numberTimeSlots; /* FH 00-06-26 */
607 v_freqFollow[0] = 1;
608 *length_v_bordFollow = 1;
609 *length_v_freqFollow = 1;
610
611 *i_tranFollow = -DC;
612 *i_fillFollow = -DC;
613 }
614 else {
615 /*--------------------------------------------------------------------------
616 Design remaining parts of T/F-grid (assuming next frame is VarFix)
617 adapt or fill region before new transient:
618 ---------------------------------------------------------------------------*/
619 fillFrameInter (&nL, v_tuningSegm, v_bord, length_v_bord, bmin,
620 v_freq, length_v_freq, v_bordFollow,
621 length_v_bordFollow, v_freqFollow,
622 length_v_freqFollow, *i_fillFollow, dmin, dmax,
623 numberTimeSlots);
624
625 /*--------------------------------------------------------------------------
626 Fill after transient:
627 ---------------------------------------------------------------------------*/
628 fillFramePost (&parts, &d, dmax, v_bord, length_v_bord, v_freq,
629 length_v_freq, bmax, bufferFrameStart, numberTimeSlots, fmax);
630
631 /*--------------------------------------------------------------------------
632 Take care of special case:
633 ---------------------------------------------------------------------------*/
634 if (parts == 1 && d < dmin) /*% no fill, short last envelope */
635 specialCase (spreadFlag, allowSpread, v_bord, length_v_bord,
636 v_freq, length_v_freq, &parts, d);
637
638 /*--------------------------------------------------------------------------
639 Calculate common border (split-point)
640 ---------------------------------------------------------------------------*/
641 calcCmonBorder (&i_cmon, &i_tran, v_bord, length_v_bord, tranPosInternal,
642 bufferFrameStart, numberTimeSlots);
643
644 /*--------------------------------------------------------------------------
645 Extract data for proper follow-up in next frame
646 ---------------------------------------------------------------------------*/
647 keepForFollowUp (v_bordFollow, length_v_bordFollow,
648 v_freqFollow, length_v_freqFollow,
649 i_tranFollow, i_fillFollow, v_bord,
650 length_v_bord, v_freq, i_cmon, i_tran, parts, numberTimeSlots);
651
652 /*--------------------------------------------------------------------------
653 Calculate control signal
654 ---------------------------------------------------------------------------*/
655 calcCtrlSignal (&hSbrEnvFrame->SbrGrid,
656 frameClass, v_bord, *length_v_bord, v_freq,
657 *length_v_freq, i_cmon, i_tran, 0, nL);
658 }
659 break;
660 case FIXFIX:
661 if (tranPos == 0)
662 numEnv = 1;
663 else
664 numEnv = 2;
665
666 hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
667 hSbrEnvFrame->SbrGrid.frameClass = frameClass;
668
669 break;
670 default:
671 FDK_ASSERT(0);
672 }
673 }
674
675 /*-------------------------------------------------------------------------
676 Convert control signal to frame info struct
677 ---------------------------------------------------------------------------*/
678 ctrlSignal2FrameInfo (&hSbrEnvFrame->SbrGrid,
679 &hSbrEnvFrame->SbrFrameInfo,
680 freq_res_fixfix);
681
682 return &hSbrEnvFrame->SbrFrameInfo;
683 }
684
685
686 /***************************************************************************/
687 /*!
688 \brief Gnerates frame info for FIXFIXonly frame class used for low delay version
689
690 \return nothing
691 ****************************************************************************/
692 static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
693 HANDLE_SBR_GRID hSbrGrid,
694 int tranPosInternal,
695 int numberTimeSlots
696 )
697 {
698 int nEnv, i, k=0, tranIdx;
699 const int *pTable = NULL;
700 const FREQ_RES *freqResTable = NULL;
701
702 switch (numberTimeSlots) {
703 case 8:
704 pTable = envelopeTable_8[tranPosInternal];
705 freqResTable = freqRes_table_8;
706 break;
707 case 15:
708 pTable = envelopeTable_15[tranPosInternal];
709 freqResTable = freqRes_table_16;
710 break;
711 case 16:
712 pTable = envelopeTable_16[tranPosInternal];
713 freqResTable = freqRes_table_16;
714 break;
715 }
716
717 /* look number of envolpes in table */
718 nEnv = pTable[0];
719 /* look up envolpe distribution in table */
720 for (i=1; i<nEnv; i++)
721 hSbrFrameInfo->borders[i] = pTable[i+2];
722
723 /* open and close frame border */
724 hSbrFrameInfo->borders[0] = 0;
725 hSbrFrameInfo->borders[nEnv] = numberTimeSlots;
726
727 /* adjust segment-frequency-resolution according to the segment-length */
728 for (i=0; i<nEnv; i++){
729 k = hSbrFrameInfo->borders[i+1] - hSbrFrameInfo->borders[i];
730 hSbrFrameInfo->freqRes[i] = freqResTable[k];
731 hSbrGrid->v_f[i] = freqResTable[k];
732 }
733
734 hSbrFrameInfo->nEnvelopes = nEnv;
735 hSbrFrameInfo->shortEnv = pTable[2];
736 /* transient idx */
737 tranIdx = pTable[1];
738
739 /* add noise floors */
740 hSbrFrameInfo->bordersNoise[0] = 0;
741 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[tranIdx?tranIdx:1];
742 hSbrFrameInfo->bordersNoise[2] = numberTimeSlots;
743 hSbrFrameInfo->nNoiseEnvelopes = 2;
744
745 hSbrGrid->frameClass = FIXFIXonly;
746 hSbrGrid->bs_abs_bord = tranPosInternal;
747 hSbrGrid->bs_num_env = nEnv;
748
749 }
750
751
752
753 /*******************************************************************************
754 Functionname: FDKsbrEnc_initFrameInfoGenerator
755 *******************************************************************************
756
757 Description:
758
759 Arguments: hSbrEnvFrame - pointer to sbr envelope handle
760 allowSpread - commandline parameter
761 numEnvStatic - commandline parameter
762 staticFraming - commandline parameter
763
764 Return: none
765
766 *******************************************************************************/
767 void
768 FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
769 INT allowSpread,
770 INT numEnvStatic,
771 INT staticFraming,
772 INT timeSlots,
773 INT freq_res_fixfix
774 ,int ldGrid
775 )
776
777 { /* FH 00-06-26 */
778
779 FDKmemclear(hSbrEnvFrame,sizeof(SBR_ENVELOPE_FRAME ));
780
781
782 /* Initialisation */
783 hSbrEnvFrame->frameClassOld = FIXFIX;
784 hSbrEnvFrame->spreadFlag = 0;
785
786 hSbrEnvFrame->allowSpread = allowSpread;
787 hSbrEnvFrame->numEnvStatic = numEnvStatic;
788 hSbrEnvFrame->staticFraming = staticFraming;
789 hSbrEnvFrame->freq_res_fixfix = freq_res_fixfix;
790
791 hSbrEnvFrame->length_v_bord = 0;
792 hSbrEnvFrame->length_v_bordFollow = 0;
793
794 hSbrEnvFrame->length_v_freq = 0;
795 hSbrEnvFrame->length_v_freqFollow = 0;
796
797 hSbrEnvFrame->i_tranFollow = 0;
798 hSbrEnvFrame->i_fillFollow = 0;
799
800 hSbrEnvFrame->SbrGrid.numberTimeSlots = timeSlots;
801
802 if (ldGrid) {
803 /*case CODEC_AACLD:*/
804 hSbrEnvFrame->dmin = 2;
805 hSbrEnvFrame->dmax = 16;
806 hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
807 } else
808 switch(timeSlots){
809 case NUMBER_TIME_SLOTS_1920:
810 hSbrEnvFrame->dmin = 4;
811 hSbrEnvFrame->dmax = 12;
812 hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
813 hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1920;
814 break;
815 case NUMBER_TIME_SLOTS_2048:
816 hSbrEnvFrame->dmin = 4;
817 hSbrEnvFrame->dmax = 12;
818 hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
819 hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2048;
820 break;
821 case NUMBER_TIME_SLOTS_1152:
822 hSbrEnvFrame->dmin = 2;
823 hSbrEnvFrame->dmax = 8;
824 hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
825 hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1152;
826 break;
827 case NUMBER_TIME_SLOTS_2304:
828 hSbrEnvFrame->dmin = 4;
829 hSbrEnvFrame->dmax = 15;
830 hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
831 hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2304;
832 break;
833 default:
834 FDK_ASSERT(0);
835 }
836
837 }
838
839
840 /*******************************************************************************
841 Functionname: fillFrameTran
842 *******************************************************************************
843
844 Description: Add mandatory borders, as described by the tuning vector
845 and the current transient position
846
847 Arguments:
848 modified:
849 v_bord - int pointer to v_bord vector
850 length_v_bord - length of v_bord vector
851 v_freq - int pointer to v_freq vector
852 length_v_freq - length of v_freq vector
853 bmin - int pointer to bmin (call by reference)
854 bmax - int pointer to bmax (call by reference)
855 not modified:
856 tran - position of transient
857 v_tuningSegm - int pointer to v_tuningSegm vector
858 v_tuningFreq - int pointer to v_tuningFreq vector
859
860 Return: none
861
862 *******************************************************************************/
863 static void
864 fillFrameTran (const int *v_tuningSegm, /*!< tuning: desired segment lengths */
865 const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */
866 int tran, /*!< input : position of transient */
867 int *v_bord, /*!< memNew: borders */
868 int *length_v_bord, /*!< memNew: # borders */
869 int *v_freq, /*!< memNew: frequency resolutions */
870 int *length_v_freq, /*!< memNew: # frequency resolutions */
871 int *bmin, /*!< hlpNew: first mandatory border */
872 int *bmax /*!< hlpNew: last mandatory border */
873 )
874 {
875 int bord, i;
876
877 *length_v_bord = 0;
878 *length_v_freq = 0;
879
880 /* add attack env leading border (optional) */
881 if (v_tuningSegm[0]) {
882 /* v_bord = [(Ba)] start of attack env */
883 FDKsbrEnc_AddRight (v_bord, length_v_bord, (tran - v_tuningSegm[0]));
884
885 /* v_freq = [(Fa)] res of attack env */
886 FDKsbrEnc_AddRight (v_freq, length_v_freq, v_tuningFreq[0]);
887 }
888
889 /* add attack env trailing border/first decay env leading border */
890 bord = tran;
891 FDKsbrEnc_AddRight (v_bord, length_v_bord, tran); /* v_bord = [(Ba),Bd1] */
892
893 /* add first decay env trailing border/2:nd decay env leading border */
894 if (v_tuningSegm[1]) {
895 bord += v_tuningSegm[1];
896
897 /* v_bord = [(Ba),Bd1,Bd2] */
898 FDKsbrEnc_AddRight (v_bord, length_v_bord, bord);
899
900 /* v_freq = [(Fa),Fd1] */
901 FDKsbrEnc_AddRight (v_freq, length_v_freq, v_tuningFreq[1]);
902 }
903
904 /* add 2:nd decay env trailing border (optional) */
905 if (v_tuningSegm[2] != 0) {
906 bord += v_tuningSegm[2];
907
908 /* v_bord = [(Ba),Bd1, Bd2,(Bd3)] */
909 FDKsbrEnc_AddRight (v_bord, length_v_bord, bord);
910
911 /* v_freq = [(Fa),Fd1,(Fd2)] */
912 FDKsbrEnc_AddRight (v_freq, length_v_freq, v_tuningFreq[2]);
913 }
914
915 /* v_freq = [(Fa),Fd1,(Fd2),1] */
916 FDKsbrEnc_AddRight (v_freq, length_v_freq, 1);
917
918
919 /* calc min and max values of mandatory borders */
920 *bmin = v_bord[0];
921 for (i = 0; i < *length_v_bord; i++)
922 if (v_bord[i] < *bmin)
923 *bmin = v_bord[i];
924
925 *bmax = v_bord[0];
926 for (i = 0; i < *length_v_bord; i++)
927 if (v_bord[i] > *bmax)
928 *bmax = v_bord[i];
929
930 }
931
932
933
934 /*******************************************************************************
935 Functionname: fillFramePre
936 *******************************************************************************
937
938 Description: Add borders before mandatory borders, if needed
939
940 Arguments:
941 modified:
942 v_bord - int pointer to v_bord vector
943 length_v_bord - length of v_bord vector
944 v_freq - int pointer to v_freq vector
945 length_v_freq - length of v_freq vector
946 not modified:
947 dmax - int value
948 bmin - int value
949 rest - int value
950
951 Return: none
952
953 *******************************************************************************/
954 static void
955 fillFramePre (INT dmax,
956 INT *v_bord, INT *length_v_bord,
957 INT *v_freq, INT *length_v_freq,
958 INT bmin, INT rest)
959 {
960 /*
961 input state:
962 v_bord = [(Ba),Bd1, Bd2 ,(Bd3)]
963 v_freq = [(Fa),Fd1,(Fd2),1 ]
964 */
965
966 INT parts, d, j, S, s = 0, segm, bord;
967
968 /*
969 start with one envelope
970 */
971
972 parts = 1;
973 d = rest;
974
975 /*
976 calc # of additional envelopes and corresponding lengths
977 */
978
979 while (d > dmax) {
980 parts++;
981
982 segm = rest / parts;
983 S = (segm - 2)>>1;
984 s = fixMin (8, 2 * S + 2);
985 d = rest - (parts - 1) * s;
986 }
987
988 /*
989 add borders before mandatory borders
990 */
991
992 bord = bmin;
993
994 for (j = 0; j <= parts - 2; j++) {
995 bord = bord - s;
996
997 /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)] */
998 FDKsbrEnc_AddLeft (v_bord, length_v_bord, bord);
999
1000 /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1 ] */
1001 FDKsbrEnc_AddLeft (v_freq, length_v_freq, 1);
1002 }
1003 }
1004
1005 /***************************************************************************/
1006 /*!
1007 \brief Overlap control
1008
1009 Calculate max length of trailing fill segments, such that we always get a
1010 border within the frame overlap region
1011
1012 \return void
1013
1014 ****************************************************************************/
1015 static int
1016 calcFillLengthMax (int tranPos, /*!< input : transient position (ref: tran det) */
1017 int numberTimeSlots /*!< input : number of timeslots */
1018 )
1019 {
1020 int fmax;
1021
1022 /*
1023 calculate transient position within envelope buffer
1024 */
1025 switch (numberTimeSlots)
1026 {
1027 case NUMBER_TIME_SLOTS_2048:
1028 if (tranPos < 4)
1029 fmax = 6;
1030 else if (tranPos == 4 || tranPos == 5)
1031 fmax = 4;
1032 else
1033 fmax = 8;
1034 break;
1035
1036 case NUMBER_TIME_SLOTS_1920:
1037 if (tranPos < 4)
1038 fmax = 5;
1039 else if (tranPos == 4 || tranPos == 5)
1040 fmax = 3;
1041 else
1042 fmax = 7;
1043 break;
1044
1045 default:
1046 fmax = 8;
1047 break;
1048 }
1049
1050 return fmax;
1051 }
1052
1053 /*******************************************************************************
1054 Functionname: fillFramePost
1055 *******************************************************************************
1056
1057 Description: -Add borders after mandatory borders, if needed
1058 Make a preliminary design of next frame,
1059 assuming no transient is present there
1060
1061 Arguments:
1062 modified:
1063 parts - int pointer to parts (call by reference)
1064 d - int pointer to d (call by reference)
1065 v_bord - int pointer to v_bord vector
1066 length_v_bord - length of v_bord vector
1067 v_freq - int pointer to v_freq vector
1068 length_v_freq - length of v_freq vector
1069 not modified:
1070 bmax - int value
1071 dmax - int value
1072
1073 Return: none
1074
1075 *******************************************************************************/
1076 static void
1077 fillFramePost (INT *parts, INT *d, INT dmax, INT *v_bord, INT *length_v_bord,
1078 INT *v_freq, INT *length_v_freq, INT bmax,
1079 INT bufferFrameStart, INT numberTimeSlots, INT fmax)
1080 {
1081 INT j, rest, segm, S, s = 0, bord;
1082
1083 /*
1084 input state:
1085 v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)]
1086 v_freq = [...,(1 ),(Fa),Fd1,(Fd2),1 ]
1087 */
1088
1089 rest = bufferFrameStart + 2 * numberTimeSlots - bmax;
1090 *d = rest;
1091
1092 if (*d > 0) {
1093 *parts = 1; /* start with one envelope */
1094
1095 /* calc # of additional envelopes and corresponding lengths */
1096
1097 while (*d > dmax) {
1098 *parts = *parts + 1;
1099
1100 segm = rest / (*parts);
1101 S = (segm - 2)>>1;
1102 s = fixMin (fmax, 2 * S + 2);
1103 *d = rest - (*parts - 1) * s;
1104 }
1105
1106 /* add borders after mandatory borders */
1107
1108 bord = bmax;
1109 for (j = 0; j <= *parts - 2; j++) {
1110 bord += s;
1111
1112 /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3),(Bf)] */
1113 FDKsbrEnc_AddRight (v_bord, length_v_bord, bord);
1114
1115 /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1 , 1! ,1] */
1116 FDKsbrEnc_AddRight (v_freq, length_v_freq, 1);
1117 }
1118 }
1119 else {
1120 *parts = 1;
1121
1122 /* remove last element from v_bord and v_freq */
1123
1124 *length_v_bord = *length_v_bord - 1;
1125 *length_v_freq = *length_v_freq - 1;
1126
1127 }
1128 }
1129
1130
1131
1132 /*******************************************************************************
1133 Functionname: fillFrameInter
1134 *******************************************************************************
1135
1136 Description:
1137
1138 Arguments: nL -
1139 v_tuningSegm -
1140 v_bord -
1141 length_v_bord -
1142 bmin -
1143 v_freq -
1144 length_v_freq -
1145 v_bordFollow -
1146 length_v_bordFollow -
1147 v_freqFollow -
1148 length_v_freqFollow -
1149 i_fillFollow -
1150 dmin -
1151 dmax -
1152
1153 Return: none
1154
1155 *******************************************************************************/
1156 static void
1157 fillFrameInter (INT *nL, const int *v_tuningSegm, INT *v_bord, INT *length_v_bord,
1158 INT bmin, INT *v_freq, INT *length_v_freq, INT *v_bordFollow,
1159 INT *length_v_bordFollow, INT *v_freqFollow,
1160 INT *length_v_freqFollow, INT i_fillFollow, INT dmin,
1161 INT dmax, INT numberTimeSlots)
1162 {
1163 INT middle, b_new, numBordFollow, bordMaxFollow, i;
1164
1165 if (numberTimeSlots != NUMBER_TIME_SLOTS_1152) {
1166
1167 /* % remove fill borders: */
1168 if (i_fillFollow >= 1) {
1169 *length_v_bordFollow = i_fillFollow;
1170 *length_v_freqFollow = i_fillFollow;
1171 }
1172
1173 numBordFollow = *length_v_bordFollow;
1174 bordMaxFollow = v_bordFollow[numBordFollow - 1];
1175
1176 /* remove even more borders if needed */
1177 middle = bmin - bordMaxFollow;
1178 while (middle < 0) {
1179 numBordFollow--;
1180 bordMaxFollow = v_bordFollow[numBordFollow - 1];
1181 middle = bmin - bordMaxFollow;
1182 }
1183
1184 *length_v_bordFollow = numBordFollow;
1185 *length_v_freqFollow = numBordFollow;
1186 *nL = numBordFollow - 1;
1187
1188 b_new = *length_v_bord;
1189
1190
1191 if (middle <= dmax) {
1192 if (middle >= dmin) { /* concatenate */
1193 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow, *length_v_bordFollow);
1194 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow, *length_v_freqFollow);
1195 }
1196
1197 else {
1198 if (v_tuningSegm[0] != 0) { /* remove one new border and concatenate */
1199 *length_v_bord = b_new - 1;
1200 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow,
1201 *length_v_bordFollow);
1202
1203 *length_v_freq = b_new - 1;
1204 FDKsbrEnc_AddVecLeft (v_freq + 1, length_v_freq, v_freqFollow,
1205 *length_v_freqFollow);
1206 }
1207 else {
1208 if (*length_v_bordFollow > 1) { /* remove one old border and concatenate */
1209 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow,
1210 *length_v_bordFollow - 1);
1211 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow,
1212 *length_v_bordFollow - 1);
1213
1214 *nL = *nL - 1;
1215 }
1216 else { /* remove new "transient" border and concatenate */
1217
1218 for (i = 0; i < *length_v_bord - 1; i++)
1219 v_bord[i] = v_bord[i + 1];
1220
1221 for (i = 0; i < *length_v_freq - 1; i++)
1222 v_freq[i] = v_freq[i + 1];
1223
1224 *length_v_bord = b_new - 1;
1225 *length_v_freq = b_new - 1;
1226
1227 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow,
1228 *length_v_bordFollow);
1229 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow,
1230 *length_v_freqFollow);
1231 }
1232 }
1233 }
1234 }
1235 else { /* middle > dmax */
1236
1237 fillFramePre (dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
1238 middle);
1239 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow, *length_v_bordFollow);
1240 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow, *length_v_freqFollow);
1241 }
1242
1243
1244 }
1245 else { /* numberTimeSlots==NUMBER_TIME_SLOTS_1152 */
1246
1247 INT l,m;
1248
1249
1250 /*------------------------------------------------------------------------
1251 remove fill borders
1252 ------------------------------------------------------------------------*/
1253 if (i_fillFollow >= 1) {
1254 *length_v_bordFollow = i_fillFollow;
1255 *length_v_freqFollow = i_fillFollow;
1256 }
1257
1258 numBordFollow = *length_v_bordFollow;
1259 bordMaxFollow = v_bordFollow[numBordFollow - 1];
1260
1261 /*------------------------------------------------------------------------
1262 remove more borders if necessary to eliminate overlap
1263 ------------------------------------------------------------------------*/
1264
1265 /* check for overlap */
1266 middle = bmin - bordMaxFollow;
1267
1268 /* intervals:
1269 i) middle < 0 : overlap, must remove borders
1270 ii) 0 <= middle < dmin : no overlap but too tight, must remove borders
1271 iii) dmin <= middle <= dmax : ok, just concatenate
1272 iv) dmax <= middle : too wide, must add borders
1273 */
1274
1275 /* first remove old non-fill-borders... */
1276 while (middle < 0) {
1277
1278 /* ...but don't remove all of them */
1279 if (numBordFollow == 1)
1280 break;
1281
1282 numBordFollow--;
1283 bordMaxFollow = v_bordFollow[numBordFollow - 1];
1284 middle = bmin - bordMaxFollow;
1285 }
1286
1287 /* if this isn't enough, remove new non-fill borders */
1288 if (middle < 0)
1289 {
1290 for (l = 0, m = 0 ; l < *length_v_bord ; l++)
1291 {
1292 if(v_bord[l]> bordMaxFollow)
1293 {
1294 v_bord[m] = v_bord[l];
1295 v_freq[m] = v_freq[l];
1296 m++;
1297 }
1298 }
1299
1300 *length_v_bord = l;
1301 *length_v_freq = l;
1302
1303 bmin = v_bord[0];
1304
1305 }
1306
1307 /*------------------------------------------------------------------------
1308 update modified follow-up data
1309 ------------------------------------------------------------------------*/
1310
1311 *length_v_bordFollow = numBordFollow;
1312 *length_v_freqFollow = numBordFollow;
1313
1314 /* left relative borders correspond to follow-up */
1315 *nL = numBordFollow - 1;
1316
1317 /*------------------------------------------------------------------------
1318 take care of intervals ii through iv
1319 ------------------------------------------------------------------------*/
1320
1321 /* now middle should be >= 0 */
1322 middle = bmin - bordMaxFollow;
1323
1324 if (middle <= dmin) /* (ii) */
1325 {
1326 b_new = *length_v_bord;
1327
1328 if (v_tuningSegm[0] != 0)
1329 {
1330 /* remove new "luxury" border and concatenate */
1331 *length_v_bord = b_new - 1;
1332 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow,
1333 *length_v_bordFollow);
1334
1335 *length_v_freq = b_new - 1;
1336 FDKsbrEnc_AddVecLeft (v_freq + 1, length_v_freq, v_freqFollow,
1337 *length_v_freqFollow);
1338
1339 }
1340 else if (*length_v_bordFollow > 1)
1341 {
1342 /* remove old border and concatenate */
1343 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow,
1344 *length_v_bordFollow - 1);
1345 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow,
1346 *length_v_bordFollow - 1);
1347
1348 *nL = *nL - 1;
1349 }
1350 else
1351 {
1352 /* remove new border and concatenate */
1353 for (i = 0; i < *length_v_bord - 1; i++)
1354 v_bord[i] = v_bord[i + 1];
1355
1356 for (i = 0; i < *length_v_freq - 1; i++)
1357 v_freq[i] = v_freq[i + 1];
1358
1359 *length_v_bord = b_new - 1;
1360 *length_v_freq = b_new - 1;
1361
1362 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow,
1363 *length_v_bordFollow);
1364 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow,
1365 *length_v_freqFollow);
1366 }
1367 }
1368 else if ((middle >= dmin) && (middle <= dmax)) /* (iii) */
1369 {
1370 /* concatenate */
1371 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow, *length_v_bordFollow);
1372 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow, *length_v_freqFollow);
1373
1374 }
1375 else /* (iv) */
1376 {
1377 fillFramePre (dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
1378 middle);
1379 FDKsbrEnc_AddVecLeft (v_bord, length_v_bord, v_bordFollow, *length_v_bordFollow);
1380 FDKsbrEnc_AddVecLeft (v_freq, length_v_freq, v_freqFollow, *length_v_freqFollow);
1381 }
1382 }
1383 }
1384
1385
1386
1387 /*******************************************************************************
1388 Functionname: calcFrameClass
1389 *******************************************************************************
1390
1391 Description:
1392
1393 Arguments: INT* frameClass, INT* frameClassOld, INT tranFlag, INT* spreadFlag)
1394
1395 Return: none
1396
1397 *******************************************************************************/
1398 static void
1399 calcFrameClass (FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld, INT tranFlag,
1400 INT *spreadFlag)
1401 {
1402
1403 switch (*frameClassOld) {
1404 case FIXFIXonly:
1405 case FIXFIX:
1406 if (tranFlag) *frameClass = FIXVAR;
1407 else *frameClass = FIXFIX;
1408 break;
1409 case FIXVAR:
1410 if (tranFlag) { *frameClass = VARVAR; *spreadFlag = 0; }
1411 else {
1412 if (*spreadFlag) *frameClass = VARVAR;
1413 else *frameClass = VARFIX;
1414 }
1415 break;
1416 case VARFIX:
1417 if (tranFlag) *frameClass = FIXVAR;
1418 else *frameClass = FIXFIX;
1419 break;
1420 case VARVAR:
1421 if (tranFlag) { *frameClass = VARVAR; *spreadFlag = 0; }
1422 else {
1423 if (*spreadFlag) *frameClass = VARVAR;
1424 else *frameClass = VARFIX;
1425 }
1426 break;
1427 };
1428
1429 *frameClassOld = *frameClass;
1430 }
1431
1432
1433
1434 /*******************************************************************************
1435 Functionname: specialCase
1436 *******************************************************************************
1437
1438 Description:
1439
1440 Arguments: spreadFlag
1441 allowSpread
1442 v_bord
1443 length_v_bord
1444 v_freq
1445 length_v_freq
1446 parts
1447 d
1448
1449 Return: none
1450
1451 *******************************************************************************/
1452 static void
1453 specialCase (INT *spreadFlag, INT allowSpread, INT *v_bord,
1454 INT *length_v_bord, INT *v_freq, INT *length_v_freq, INT *parts,
1455 INT d)
1456 {
1457 INT L;
1458
1459 L = *length_v_bord;
1460
1461 if (allowSpread) { /* add one "step 8" */
1462 *spreadFlag = 1;
1463 FDKsbrEnc_AddRight (v_bord, length_v_bord, v_bord[L - 1] + 8);
1464 FDKsbrEnc_AddRight (v_freq, length_v_freq, 1);
1465 (*parts)++;
1466 }
1467 else {
1468 if (d == 1) { /* stretch one slot */
1469 *length_v_bord = L - 1;
1470 *length_v_freq = L - 1;
1471 }
1472 else {
1473 if ((v_bord[L - 1] - v_bord[L - 2]) > 2) { /* compress one quant step */
1474 v_bord[L - 1] = v_bord[L - 1] - 2;
1475 v_freq[*length_v_freq - 1] = 0; /* use low res for short segment */
1476 }
1477 }
1478 }
1479 }
1480
1481
1482
1483 /*******************************************************************************
1484 Functionname: calcCmonBorder
1485 *******************************************************************************
1486
1487 Description:
1488
1489 Arguments: i_cmon
1490 i_tran
1491 v_bord
1492 length_v_bord
1493 tran
1494
1495 Return: none
1496
1497 *******************************************************************************/
1498 static void
1499 calcCmonBorder (INT *i_cmon, INT *i_tran, INT *v_bord, INT *length_v_bord,
1500 INT tran, INT bufferFrameStart, INT numberTimeSlots)
1501 { /* FH 00-06-26 */
1502 INT i;
1503
1504 for (i = 0; i < *length_v_bord; i++)
1505 if (v_bord[i] >= bufferFrameStart + numberTimeSlots) { /* FH 00-06-26 */
1506 *i_cmon = i;
1507 break;
1508 }
1509
1510 /* keep track of transient: */
1511 for (i = 0; i < *length_v_bord; i++)
1512 if (v_bord[i] >= tran) {
1513 *i_tran = i;
1514 break;
1515 }
1516 else
1517 *i_tran = EMPTY;
1518 }
1519
1520 /*******************************************************************************
1521 Functionname: keepForFollowUp
1522 *******************************************************************************
1523
1524 Description:
1525
1526 Arguments: v_bordFollow
1527 length_v_bordFollow
1528 v_freqFollow
1529 length_v_freqFollow
1530 i_tranFollow
1531 i_fillFollow
1532 v_bord
1533 length_v_bord
1534 v_freq
1535 i_cmon
1536 i_tran
1537 parts)
1538
1539 Return: none
1540
1541 *******************************************************************************/
1542 static void
1543 keepForFollowUp (INT *v_bordFollow, INT *length_v_bordFollow,
1544 INT *v_freqFollow, INT *length_v_freqFollow,
1545 INT *i_tranFollow, INT *i_fillFollow, INT *v_bord,
1546 INT *length_v_bord, INT *v_freq, INT i_cmon, INT i_tran,
1547 INT parts, INT numberTimeSlots)
1548 { /* FH 00-06-26 */
1549 INT L, i, j;
1550
1551 L = *length_v_bord;
1552
1553 (*length_v_bordFollow) = 0;
1554 (*length_v_freqFollow) = 0;
1555
1556 for (j = 0, i = i_cmon; i < L; i++, j++) {
1557 v_bordFollow[j] = v_bord[i] - numberTimeSlots; /* FH 00-06-26 */
1558 v_freqFollow[j] = v_freq[i];
1559 (*length_v_bordFollow)++;
1560 (*length_v_freqFollow)++;
1561 }
1562 if (i_tran != EMPTY)
1563 *i_tranFollow = i_tran - i_cmon;
1564 else
1565 *i_tranFollow = EMPTY;
1566 *i_fillFollow = L - (parts - 1) - i_cmon;
1567
1568 }
1569
1570 /*******************************************************************************
1571 Functionname: calcCtrlSignal
1572 *******************************************************************************
1573
1574 Description:
1575
1576 Arguments: hSbrGrid
1577 frameClass
1578 v_bord
1579 length_v_bord
1580 v_freq
1581 length_v_freq
1582 i_cmon
1583 i_tran
1584 spreadFlag
1585 nL
1586
1587 Return: none
1588
1589 *******************************************************************************/
1590 static void
1591 calcCtrlSignal (HANDLE_SBR_GRID hSbrGrid,
1592 FRAME_CLASS frameClass, INT *v_bord, INT length_v_bord, INT *v_freq,
1593 INT length_v_freq, INT i_cmon, INT i_tran, INT spreadFlag,
1594 INT nL)
1595 {
1596
1597
1598 INT i, r, a, n, p, b, aL, aR, ntot, nmax, nR;
1599
1600 INT *v_f = hSbrGrid->v_f;
1601 INT *v_fLR = hSbrGrid->v_fLR;
1602 INT *v_r = hSbrGrid->bs_rel_bord;
1603 INT *v_rL = hSbrGrid->bs_rel_bord_0;
1604 INT *v_rR = hSbrGrid->bs_rel_bord_1;
1605
1606 INT length_v_r = 0;
1607 INT length_v_rR = 0;
1608 INT length_v_rL = 0;
1609
1610 switch (frameClass) {
1611 case FIXVAR:
1612 /* absolute border: */
1613
1614 a = v_bord[i_cmon];
1615
1616 /* relative borders: */
1617 length_v_r = 0;
1618 i = i_cmon;
1619
1620 while (i >= 1) {
1621 r = v_bord[i] - v_bord[i - 1];
1622 FDKsbrEnc_AddRight (v_r, &length_v_r, r);
1623 i--;
1624 }
1625
1626
1627 /* number of relative borders: */
1628 n = length_v_r;
1629
1630
1631 /* freq res: */
1632 for (i = 0; i < i_cmon; i++)
1633 v_f[i] = v_freq[i_cmon - 1 - i];
1634 v_f[i_cmon] = 1;
1635
1636 /* pointer: */
1637 p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0) ;
1638
1639 hSbrGrid->frameClass = frameClass;
1640 hSbrGrid->bs_abs_bord = a;
1641 hSbrGrid->n = n;
1642 hSbrGrid->p = p;
1643
1644 break;
1645 case VARFIX:
1646 /* absolute border: */
1647 a = v_bord[0];
1648
1649 /* relative borders: */
1650 length_v_r = 0;
1651
1652 for (i = 1; i < length_v_bord; i++) {
1653 r = v_bord[i] - v_bord[i - 1];
1654 FDKsbrEnc_AddRight (v_r, &length_v_r, r);
1655 }
1656
1657 /* number of relative borders: */
1658 n = length_v_r;
1659
1660 /* freq res: */
1661 FDKmemcpy (v_f, v_freq, length_v_freq * sizeof (INT));
1662
1663
1664 /* pointer: */
1665 p = (i_tran >= 0 && i_tran != EMPTY) ? (i_tran + 1) : (0) ;
1666
1667 hSbrGrid->frameClass = frameClass;
1668 hSbrGrid->bs_abs_bord = a;
1669 hSbrGrid->n = n;
1670 hSbrGrid->p = p;
1671
1672 break;
1673 case VARVAR:
1674 if (spreadFlag) {
1675 /* absolute borders: */
1676 b = length_v_bord;
1677
1678 aL = v_bord[0];
1679 aR = v_bord[b - 1];
1680
1681
1682 /* number of relative borders: */
1683 ntot = b - 2;
1684
1685 nmax = 2; /* n: {0,1,2} */
1686 if (ntot > nmax) {
1687 nL = nmax;
1688 nR = ntot - nmax;
1689 }
1690 else {
1691 nL = ntot;
1692 nR = 0;
1693 }
1694
1695 /* relative borders: */
1696 length_v_rL = 0;
1697 for (i = 1; i <= nL; i++) {
1698 r = v_bord[i] - v_bord[i - 1];
1699 FDKsbrEnc_AddRight (v_rL, &length_v_rL, r);
1700 }
1701
1702 length_v_rR = 0;
1703 i = b - 1;
1704 while (i >= b - nR) {
1705 r = v_bord[i] - v_bord[i - 1];
1706 FDKsbrEnc_AddRight (v_rR, &length_v_rR, r);
1707 i--;
1708 }
1709
1710 /* pointer (only one due to constraint in frame info): */
1711 p = (i_tran > 0 && i_tran != EMPTY) ? (b - i_tran) : (0) ;
1712
1713 /* freq res: */
1714
1715 for (i = 0; i < b - 1; i++)
1716 v_fLR[i] = v_freq[i];
1717 }
1718 else {
1719
1720 length_v_bord = i_cmon + 1;
1721 length_v_freq = i_cmon + 1;
1722
1723
1724 /* absolute borders: */
1725 b = length_v_bord;
1726
1727 aL = v_bord[0];
1728 aR = v_bord[b - 1];
1729
1730 /* number of relative borders: */
1731 ntot = b - 2;
1732 nR = ntot - nL;
1733
1734 /* relative borders: */
1735 length_v_rL = 0;
1736 for (i = 1; i <= nL; i++) {
1737 r = v_bord[i] - v_bord[i - 1];
1738 FDKsbrEnc_AddRight (v_rL, &length_v_rL, r);
1739 }
1740
1741 length_v_rR = 0;
1742 i = b - 1;
1743 while (i >= b - nR) {
1744 r = v_bord[i] - v_bord[i - 1];
1745 FDKsbrEnc_AddRight (v_rR, &length_v_rR, r);
1746 i--;
1747 }
1748
1749 /* pointer (only one due to constraint in frame info): */
1750 p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0) ;
1751
1752 /* freq res: */
1753 for (i = 0; i < b - 1; i++)
1754 v_fLR[i] = v_freq[i];
1755 }
1756
1757 hSbrGrid->frameClass = frameClass;
1758 hSbrGrid->bs_abs_bord_0 = aL;
1759 hSbrGrid->bs_abs_bord_1 = aR;
1760 hSbrGrid->bs_num_rel_0 = nL;
1761 hSbrGrid->bs_num_rel_1 = nR;
1762 hSbrGrid->p = p;
1763
1764 break;
1765
1766 default:
1767 /* do nothing */
1768 break;
1769 }
1770 }
1771
1772 /*******************************************************************************
1773 Functionname: createDefFrameInfo
1774 *******************************************************************************
1775
1776 Description: Copies the default (static) frameInfo structs to the frameInfo
1777 passed by reference; only used for FIXFIX frames
1778
1779 Arguments: hFrameInfo - HANLDE_SBR_FRAME_INFO
1780 nEnv - INT
1781 nTimeSlots - INT
1782
1783 Return: none; hSbrFrameInfo contains a copy of the default frameInfo
1784
1785 Written: Andreas Schneider
1786 Revised:
1787 *******************************************************************************/
1788 static void
1789 createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv, INT nTimeSlots)
1790 {
1791 switch (nEnv) {
1792 case 1:
1793 switch (nTimeSlots) {
1794 case NUMBER_TIME_SLOTS_1920:
1795 FDKmemcpy (hSbrFrameInfo, &frameInfo1_1920, sizeof (SBR_FRAME_INFO));
1796 break;
1797 case NUMBER_TIME_SLOTS_2048:
1798 FDKmemcpy (hSbrFrameInfo, &frameInfo1_2048, sizeof (SBR_FRAME_INFO));
1799 break;
1800 case NUMBER_TIME_SLOTS_1152:
1801 FDKmemcpy (hSbrFrameInfo, &frameInfo1_1152, sizeof (SBR_FRAME_INFO));
1802 break;
1803 case NUMBER_TIME_SLOTS_2304:
1804 FDKmemcpy (hSbrFrameInfo, &frameInfo1_2304, sizeof (SBR_FRAME_INFO));
1805 break;
1806 case NUMBER_TIME_SLOTS_512LD:
1807 FDKmemcpy (hSbrFrameInfo, &frameInfo1_512LD, sizeof (SBR_FRAME_INFO));
1808 break;
1809 default:
1810 FDK_ASSERT(0);
1811 }
1812 break;
1813 case 2:
1814 switch (nTimeSlots) {
1815 case NUMBER_TIME_SLOTS_1920:
1816 FDKmemcpy (hSbrFrameInfo, &frameInfo2_1920, sizeof (SBR_FRAME_INFO));
1817 break;
1818 case NUMBER_TIME_SLOTS_2048:
1819 FDKmemcpy (hSbrFrameInfo, &frameInfo2_2048, sizeof (SBR_FRAME_INFO));
1820 break;
1821 case NUMBER_TIME_SLOTS_1152:
1822 FDKmemcpy (hSbrFrameInfo, &frameInfo2_1152, sizeof (SBR_FRAME_INFO));
1823 break;
1824 case NUMBER_TIME_SLOTS_2304:
1825 FDKmemcpy (hSbrFrameInfo, &frameInfo2_2304, sizeof (SBR_FRAME_INFO));
1826 break;
1827 case NUMBER_TIME_SLOTS_512LD:
1828 FDKmemcpy (hSbrFrameInfo, &frameInfo2_512LD, sizeof (SBR_FRAME_INFO));
1829 break;
1830 default:
1831 FDK_ASSERT(0);
1832 }
1833 break;
1834 case 4:
1835 switch (nTimeSlots) {
1836 case NUMBER_TIME_SLOTS_1920:
1837 FDKmemcpy (hSbrFrameInfo, &frameInfo4_1920, sizeof (SBR_FRAME_INFO));
1838 break;
1839 case NUMBER_TIME_SLOTS_2048:
1840 FDKmemcpy (hSbrFrameInfo, &frameInfo4_2048, sizeof (SBR_FRAME_INFO));
1841 break;
1842 case NUMBER_TIME_SLOTS_1152:
1843 FDKmemcpy (hSbrFrameInfo, &frameInfo4_1152, sizeof (SBR_FRAME_INFO));
1844 break;
1845 case NUMBER_TIME_SLOTS_2304:
1846 FDKmemcpy (hSbrFrameInfo, &frameInfo4_2304, sizeof (SBR_FRAME_INFO));
1847 break;
1848 case NUMBER_TIME_SLOTS_512LD:
1849 FDKmemcpy (hSbrFrameInfo, &frameInfo4_512LD, sizeof (SBR_FRAME_INFO));
1850 break;
1851 default:
1852 FDK_ASSERT(0);
1853 }
1854 break;
1855 default:
1856 FDK_ASSERT(0);
1857 }
1858 }
1859
1860
1861 /*******************************************************************************
1862 Functionname: ctrlSignal2FrameInfo
1863 *******************************************************************************
1864
1865 Description: Calculates frame_info struct from control signal.
1866
1867 Arguments: hSbrGrid - source
1868 hSbrFrameInfo - destination
1869
1870 Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct
1871
1872 *******************************************************************************/
1873 static void
1874 ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
1875 HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
1876 INT freq_res_fixfix)
1877 {
1878 INT nEnv = 0, border = 0, i, k, p /*?*/;
1879 INT *v_r = hSbrGrid->bs_rel_bord;
1880 INT *v_f = hSbrGrid->v_f;
1881
1882 FRAME_CLASS frameClass = hSbrGrid->frameClass;
1883 INT bufferFrameStart = hSbrGrid->bufferFrameStart;
1884 INT numberTimeSlots = hSbrGrid->numberTimeSlots;
1885
1886 switch (frameClass) {
1887 case FIXFIX:
1888 createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
1889
1890 /* At this point all frequency resolutions are set to FREQ_RES_HIGH, so
1891 * only if freq_res_fixfix is set to FREQ_RES_LOW, they all have to be
1892 * changed.
1893 * snd */
1894 if (freq_res_fixfix == FREQ_RES_LOW) {
1895 for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
1896 hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
1897 }
1898 }
1899 /* ELD: store current frequency resolution */
1900 hSbrGrid->v_f[0] = hSbrFrameInfo->freqRes[0];
1901 break;
1902
1903 case FIXVAR:
1904 case VARFIX:
1905 nEnv = hSbrGrid->n + 1; /* read n [SBR_NUM_BITS bits] */ /*? snd*/
1906 FDK_ASSERT(nEnv <= MAX_ENVELOPES_FIXVAR_VARFIX);
1907
1908 hSbrFrameInfo->nEnvelopes = nEnv;
1909
1910 border = hSbrGrid->bs_abs_bord; /* read the absolute border */
1911
1912 if (nEnv == 1)
1913 hSbrFrameInfo->nNoiseEnvelopes = 1;
1914 else
1915 hSbrFrameInfo->nNoiseEnvelopes = 2;
1916
1917 break;
1918
1919 default:
1920 /* do nothing */
1921 break;
1922 }
1923
1924 switch (frameClass) {
1925 case FIXVAR:
1926 hSbrFrameInfo->borders[0] = bufferFrameStart; /* start-position of 1st envelope */
1927
1928 hSbrFrameInfo->borders[nEnv] = border;
1929
1930 for (k = 0, i = nEnv - 1; k < nEnv - 1; k++, i--) {
1931 border -= v_r[k];
1932 hSbrFrameInfo->borders[i] = border;
1933 }
1934
1935 /* make either envelope nr. nEnv + 1 - p short; or don't shorten if p == 0 */
1936 p = hSbrGrid->p;
1937 if (p == 0) {
1938 hSbrFrameInfo->shortEnv = 0;
1939 } else {
1940 hSbrFrameInfo->shortEnv = nEnv + 1 - p;
1941 }
1942
1943 for (k = 0, i = nEnv - 1; k < nEnv; k++, i--) {
1944 hSbrFrameInfo->freqRes[i] = (FREQ_RES)v_f[k];
1945 }
1946
1947 /* if either there is no short envelope or the last envelope is short... */
1948 if (p == 0 || p == 1) {
1949 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
1950 } else {
1951 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
1952 }
1953
1954 break;
1955
1956 case VARFIX:
1957 /* in this case 'border' indicates the start of the 1st envelope */
1958 hSbrFrameInfo->borders[0] = border;
1959
1960 for (k = 0; k < nEnv - 1; k++) {
1961 border += v_r[k];
1962 hSbrFrameInfo->borders[k + 1] = border;
1963 }
1964
1965 hSbrFrameInfo->borders[nEnv] = bufferFrameStart + numberTimeSlots;
1966
1967 p = hSbrGrid->p;
1968 if (p == 0 || p == 1) {
1969 hSbrFrameInfo->shortEnv = 0;
1970 } else {
1971 hSbrFrameInfo->shortEnv = p - 1;
1972 }
1973
1974 for (k = 0; k < nEnv; k++) {
1975 hSbrFrameInfo->freqRes[k] = (FREQ_RES)v_f[k];
1976 }
1977
1978 switch (p) {
1979 case 0:
1980 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[1];
1981 break;
1982 case 1:
1983 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
1984 break;
1985 default:
1986 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
1987 break;
1988 }
1989 break;
1990
1991 case VARVAR:
1992 nEnv = hSbrGrid->bs_num_rel_0 + hSbrGrid->bs_num_rel_1 + 1;
1993 FDK_ASSERT(nEnv <= MAX_ENVELOPES_VARVAR); /* just to be sure */
1994 hSbrFrameInfo->nEnvelopes = nEnv;
1995
1996 hSbrFrameInfo->borders[0] = border = hSbrGrid->bs_abs_bord_0;
1997
1998 for (k = 0, i = 1; k < hSbrGrid->bs_num_rel_0; k++, i++) {
1999 border += hSbrGrid->bs_rel_bord_0[k];
2000 hSbrFrameInfo->borders[i] = border;
2001 }
2002
2003 border = hSbrGrid->bs_abs_bord_1;
2004 hSbrFrameInfo->borders[nEnv] = border;
2005
2006 for (k = 0, i = nEnv - 1; k < hSbrGrid->bs_num_rel_1; k++, i--) {
2007 border -= hSbrGrid->bs_rel_bord_1[k];
2008 hSbrFrameInfo->borders[i] = border;
2009 }
2010
2011 p = hSbrGrid->p;
2012 if (p == 0) {
2013 hSbrFrameInfo->shortEnv = 0;
2014 } else {
2015 hSbrFrameInfo->shortEnv = nEnv + 1 - p;
2016 }
2017
2018 for (k = 0; k < nEnv; k++) {
2019 hSbrFrameInfo->freqRes[k] = (FREQ_RES)hSbrGrid->v_fLR[k];
2020 }
2021
2022 if (nEnv == 1) {
2023 hSbrFrameInfo->nNoiseEnvelopes = 1;
2024 hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
2025 hSbrFrameInfo->bordersNoise[1] = hSbrGrid->bs_abs_bord_1;
2026 } else {
2027 hSbrFrameInfo->nNoiseEnvelopes = 2;
2028 hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
2029
2030 if (p == 0 || p == 1) {
2031 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
2032 } else {
2033 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
2034 }
2035 hSbrFrameInfo->bordersNoise[2] = hSbrGrid->bs_abs_bord_1;
2036 }
2037 break;
2038
2039 default:
2040 /* do nothing */
2041 break;
2042 }
2043
2044 if (frameClass == VARFIX || frameClass == FIXVAR) {
2045 hSbrFrameInfo->bordersNoise[0] = hSbrFrameInfo->borders[0];
2046 if (nEnv == 1) {
2047 hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv];
2048 } else {
2049 hSbrFrameInfo->bordersNoise[2] = hSbrFrameInfo->borders[nEnv];
2050 }
2051 }
2052 }
2053