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