1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 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 ****************************************************************************/ 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 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 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 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 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 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 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 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 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 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 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 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 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 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