1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten 5 Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10 scheme for digital audio. This FDK AAC Codec software is intended to be used on 11 a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14 general perceptual audio codecs. AAC-ELD is considered the best-performing 15 full-bandwidth communications codec by independent studies and is widely 16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17 specifications. 18 19 Patent licenses for necessary patent claims for the FDK AAC Codec (including 20 those of Fraunhofer) may be obtained through Via Licensing 21 (www.vialicensing.com) or through the respective patent owners individually for 22 the purpose of encoding or decoding bit streams in products that are compliant 23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24 Android devices already license these patent claims through Via Licensing or 25 directly from the patent owners, and therefore FDK AAC Codec software may 26 already be covered under those patent licenses when it is used for those 27 licensed purposes only. 28 29 Commercially-licensed AAC software libraries, including floating-point versions 30 with enhanced sound quality, are also available from Fraunhofer. Users are 31 encouraged to check the Fraunhofer website for additional applications 32 information and documentation. 33 34 2. COPYRIGHT LICENSE 35 36 Redistribution and use in source and binary forms, with or without modification, 37 are permitted without payment of copyright license fees provided that you 38 satisfy the following conditions: 39 40 You must retain the complete text of this software license in redistributions of 41 the FDK AAC Codec or your modifications thereto in source code form. 42 43 You must retain the complete text of this software license in the documentation 44 and/or other materials provided with redistributions of the FDK AAC Codec or 45 your modifications thereto in binary form. You must make available free of 46 charge copies of the complete source code of the FDK AAC Codec and your 47 modifications thereto to recipients of copies in binary form. 48 49 The name of Fraunhofer may not be used to endorse or promote products derived 50 from this library without prior written permission. 51 52 You may not charge copyright license fees for anyone to use, copy or distribute 53 the FDK AAC Codec software or your modifications thereto. 54 55 Your modified versions of the FDK AAC Codec must carry prominent notices stating 56 that you changed the software and the date of any change. For modified versions 57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59 AAC Codec Library for Android." 60 61 3. NO PATENT LICENSE 62 63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65 Fraunhofer provides no warranty of patent non-infringement with respect to this 66 software. 67 68 You may use this FDK AAC Codec software or modifications thereto only for 69 purposes that are authorized by appropriate patent licenses. 70 71 4. DISCLAIMER 72 73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75 including but not limited to the implied warranties of merchantability and 76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78 or consequential damages, including but not limited to procurement of substitute 79 goods or services; loss of use, data, or profits, or business interruption, 80 however caused and on any theory of liability, whether in contract, strict 81 liability, or tort (including negligence), arising in any way out of the use of 82 this software, even if advised of the possibility of such damage. 83 84 5. CONTACT INFORMATION 85 86 Fraunhofer Institute for Integrated Circuits IIS 87 Attention: Audio and Multimedia Departments - FDK AAC LL 88 Am Wolfsmantel 33 89 91058 Erlangen, Germany 90 91 www.iis.fraunhofer.de/amm 92 amm-info (at) iis.fraunhofer.de 93 ----------------------------------------------------------------------------- */ 94 95 /*********************** MPEG surround encoder library ************************* 96 97 Author(s): 98 99 Description: Encoder Library Interface 100 Bitstream Writer 101 102 *******************************************************************************/ 103 104 /* Includes ******************************************************************/ 105 #include "sacenc_bitstream.h" 106 #include "sacenc_const.h" 107 108 #include "genericStds.h" 109 #include "common_fix.h" 110 111 #include "FDK_matrixCalloc.h" 112 #include "sacenc_nlc_enc.h" 113 114 /* Defines *******************************************************************/ 115 #define MAX_FREQ_RES_INDEX 8 116 #define MAX_SAMPLING_FREQUENCY_INDEX 13 117 #define SAMPLING_FREQUENCY_INDEX_ESCAPE 15 118 119 /* Data Types ****************************************************************/ 120 typedef struct { 121 SCHAR cld_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS]; 122 SCHAR icc_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS]; 123 UCHAR quantCoarseCldPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS]; 124 UCHAR quantCoarseIccPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS]; 125 126 } PREV_OTTDATA; 127 128 typedef struct { 129 PREV_OTTDATA prevOttData; 130 131 } STATIC_SPATIALFRAME; 132 133 typedef struct BSF_INSTANCE { 134 SPATIALSPECIFICCONFIG spatialSpecificConfig; 135 SPATIALFRAME frame; 136 STATIC_SPATIALFRAME prevFrameData; 137 138 } BSF_INSTANCE; 139 140 /* Constants *****************************************************************/ 141 static const INT SampleRateTable[MAX_SAMPLING_FREQUENCY_INDEX] = { 142 96000, 88200, 64000, 48000, 44100, 32000, 24000, 143 22050, 16000, 12000, 11025, 8000, 7350}; 144 145 static const UCHAR FreqResBinTable_LD[MAX_FREQ_RES_INDEX] = {0, 23, 15, 12, 146 9, 7, 5, 4}; 147 static const UCHAR FreqResStrideTable_LD[] = {1, 2, 5, 23}; 148 149 /* Function / Class Declarations *********************************************/ 150 151 /* Function / Class Definition ***********************************************/ 152 static FDK_SACENC_ERROR DuplicateLosslessData( 153 const INT startBox, const INT stopBox, 154 const LOSSLESSDATA *const hLosslessDataFrom, const INT setFrom, 155 LOSSLESSDATA *const hLosslessDataTo, const INT setTo) { 156 FDK_SACENC_ERROR error = SACENC_OK; 157 158 if ((NULL == hLosslessDataFrom) || (NULL == hLosslessDataTo)) { 159 error = SACENC_INVALID_HANDLE; 160 } else { 161 int i; 162 163 for (i = startBox; i < stopBox; i++) { 164 hLosslessDataTo->bsXXXDataMode[i][setTo] = 165 hLosslessDataFrom->bsXXXDataMode[i][setFrom]; 166 hLosslessDataTo->bsDataPair[i][setTo] = 167 hLosslessDataFrom->bsDataPair[i][setFrom]; 168 hLosslessDataTo->bsQuantCoarseXXX[i][setTo] = 169 hLosslessDataFrom->bsQuantCoarseXXX[i][setFrom]; 170 hLosslessDataTo->bsFreqResStrideXXX[i][setTo] = 171 hLosslessDataFrom->bsFreqResStrideXXX[i][setFrom]; 172 } 173 } 174 return error; 175 } 176 177 FDK_SACENC_ERROR fdk_sacenc_duplicateParameterSet( 178 const SPATIALFRAME *const hFrom, const INT setFrom, SPATIALFRAME *const hTo, 179 const INT setTo) { 180 FDK_SACENC_ERROR error = SACENC_OK; 181 182 if ((NULL == hFrom) || (NULL == hTo)) { 183 error = SACENC_INVALID_HANDLE; 184 } else { 185 int box; 186 /* Only Copy Parameter Set selective stuff */ 187 188 /* OTT-Data */ 189 for (box = 0; box < SACENC_MAX_NUM_BOXES; box++) { 190 FDKmemcpy(hTo->ottData.cld[box][setTo], hFrom->ottData.cld[box][setFrom], 191 sizeof(hFrom->ottData.cld[0][0])); 192 FDKmemcpy(hTo->ottData.icc[box][setTo], hFrom->ottData.icc[box][setFrom], 193 sizeof(hFrom->ottData.icc[0][0])); 194 } 195 196 /* LOSSLESSDATA */ 197 DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->CLDLosslessData, 198 setFrom, &hTo->CLDLosslessData, setTo); 199 DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->ICCLosslessData, 200 setFrom, &hTo->ICCLosslessData, setTo); 201 202 } /* valid handle */ 203 204 return error; 205 } 206 207 /* set frame defaults */ 208 static void clearFrame(SPATIALFRAME *const pFrame) { 209 FDKmemclear(pFrame, sizeof(SPATIALFRAME)); 210 211 pFrame->bsIndependencyFlag = 1; 212 pFrame->framingInfo.numParamSets = 1; 213 } 214 215 static void fine2coarse(SCHAR *const data, const DATA_TYPE dataType, 216 const INT startBand, const INT numBands) { 217 int i; 218 if (dataType == t_CLD) { 219 for (i = startBand; i < startBand + numBands; i++) { 220 data[i] /= 2; 221 } 222 } else { 223 for (i = startBand; i < startBand + numBands; i++) { 224 data[i] >>= 1; 225 } 226 } 227 } 228 229 static void coarse2fine(SCHAR *const data, const DATA_TYPE dataType, 230 const INT startBand, const INT numBands) { 231 int i; 232 233 for (i = startBand; i < startBand + numBands; i++) { 234 data[i] <<= 1; 235 } 236 237 if (dataType == t_CLD) { 238 for (i = startBand; i < startBand + numBands; i++) { 239 if (data[i] == -14) { 240 data[i] = -15; 241 } else if (data[i] == 14) { 242 data[i] = 15; 243 } 244 } 245 } /* (dataType == t_CLD) */ 246 } 247 248 static UCHAR getBsFreqResStride(const INT index) { 249 const UCHAR *pFreqResStrideTable = NULL; 250 int freqResStrideTableSize = 0; 251 252 pFreqResStrideTable = FreqResStrideTable_LD; 253 freqResStrideTableSize = 254 sizeof(FreqResStrideTable_LD) / sizeof(*FreqResStrideTable_LD); 255 256 return (((NULL != pFreqResStrideTable) && (index >= 0) && 257 (index < freqResStrideTableSize)) 258 ? pFreqResStrideTable[index] 259 : 1); 260 } 261 262 /* write data to bitstream */ 263 static void ecData(HANDLE_FDK_BITSTREAM bitstream, 264 SCHAR data[MAX_NUM_PARAMS][MAX_NUM_BINS], 265 SCHAR oldData[MAX_NUM_BINS], 266 UCHAR quantCoarseXXXprev[MAX_NUM_PARAMS], 267 LOSSLESSDATA *const losslessData, const DATA_TYPE dataType, 268 const INT paramIdx, const INT numParamSets, 269 const INT independencyFlag, const INT startBand, 270 const INT stopBand, const INT defaultValue) { 271 int ps, pb, strOffset, pbStride, dataBands, i; 272 int aStrides[MAX_NUM_BINS + 1] = {0}; 273 SHORT cmpIdxData[2][MAX_NUM_BINS] = {{0}}; 274 SHORT cmpOldData[MAX_NUM_BINS] = {0}; 275 276 /* bsXXXDataMode */ 277 if (independencyFlag || (losslessData->bsQuantCoarseXXX[paramIdx][0] != 278 quantCoarseXXXprev[paramIdx])) { 279 losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE; 280 } else { 281 losslessData->bsXXXDataMode[paramIdx][0] = KEEP; 282 for (i = startBand; i < stopBand; i++) { 283 if (data[0][i] != oldData[i]) { 284 losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE; 285 break; 286 } 287 } 288 } 289 290 FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][0], 2); 291 292 for (ps = 1; ps < numParamSets; ps++) { 293 if (losslessData->bsQuantCoarseXXX[paramIdx][ps] != 294 losslessData->bsQuantCoarseXXX[paramIdx][ps - 1]) { 295 losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE; 296 } else { 297 losslessData->bsXXXDataMode[paramIdx][ps] = KEEP; 298 for (i = startBand; i < stopBand; i++) { 299 if (data[ps][i] != data[ps - 1][i]) { 300 losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE; 301 break; 302 } 303 } 304 } 305 306 FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][ps], 2); 307 } /* for ps */ 308 309 /* Create data pairs if possible */ 310 for (ps = 0; ps < (numParamSets - 1); ps++) { 311 if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) { 312 /* Check if next parameter set is FINCOARSE */ 313 if (losslessData->bsXXXDataMode[paramIdx][ps + 1] == FINECOARSE) { 314 /* We have to check if ps and ps+1 use the same bsXXXQuantMode */ 315 /* and also have the same stride */ 316 if ((losslessData->bsQuantCoarseXXX[paramIdx][ps + 1] == 317 losslessData->bsQuantCoarseXXX[paramIdx][ps]) && 318 (losslessData->bsFreqResStrideXXX[paramIdx][ps + 1] == 319 losslessData->bsFreqResStrideXXX[paramIdx][ps])) { 320 losslessData->bsDataPair[paramIdx][ps] = 1; 321 losslessData->bsDataPair[paramIdx][ps + 1] = 1; 322 323 /* We have a data pair -> Jump to the ps after next ps*/ 324 ps++; 325 continue; 326 } 327 } 328 /* dataMode of next ps is not FINECOARSE or does not use the same 329 * bsXXXQuantMode/stride */ 330 /* -> no dataPair possible */ 331 losslessData->bsDataPair[paramIdx][ps] = 0; 332 333 /* Initialize ps after next ps to Zero (only important for the last 334 * parameter set) */ 335 losslessData->bsDataPair[paramIdx][ps + 1] = 0; 336 } else { 337 /* No FINECOARSE -> no data pair possible */ 338 losslessData->bsDataPair[paramIdx][ps] = 0; 339 340 /* Initialize ps after next ps to Zero (only important for the last 341 * parameter set) */ 342 losslessData->bsDataPair[paramIdx][ps + 1] = 0; 343 } 344 } /* for ps */ 345 346 for (ps = 0; ps < numParamSets; ps++) { 347 if (losslessData->bsXXXDataMode[paramIdx][ps] == DEFAULT) { 348 /* Prepare old data */ 349 for (i = startBand; i < stopBand; i++) { 350 oldData[i] = defaultValue; 351 } 352 quantCoarseXXXprev[paramIdx] = 0; /* Default data are always fine */ 353 } 354 355 if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) { 356 FDKwriteBits(bitstream, losslessData->bsDataPair[paramIdx][ps], 1); 357 FDKwriteBits(bitstream, losslessData->bsQuantCoarseXXX[paramIdx][ps], 1); 358 FDKwriteBits(bitstream, losslessData->bsFreqResStrideXXX[paramIdx][ps], 359 2); 360 361 if (losslessData->bsQuantCoarseXXX[paramIdx][ps] != 362 quantCoarseXXXprev[paramIdx]) { 363 if (quantCoarseXXXprev[paramIdx]) { 364 coarse2fine(oldData, dataType, startBand, stopBand - startBand); 365 } else { 366 fine2coarse(oldData, dataType, startBand, stopBand - startBand); 367 } 368 } 369 370 /* Handle strides */ 371 pbStride = 372 getBsFreqResStride(losslessData->bsFreqResStrideXXX[paramIdx][ps]); 373 dataBands = (stopBand - startBand - 1) / pbStride + 1; 374 375 aStrides[0] = startBand; 376 for (pb = 1; pb <= dataBands; pb++) { 377 aStrides[pb] = aStrides[pb - 1] + pbStride; 378 } 379 380 strOffset = 0; 381 while (aStrides[dataBands] > stopBand) { 382 if (strOffset < dataBands) { 383 strOffset++; 384 } 385 for (i = strOffset; i <= dataBands; i++) { 386 aStrides[i]--; 387 } 388 } /* while */ 389 390 for (pb = 0; pb < dataBands; pb++) { 391 cmpOldData[startBand + pb] = oldData[aStrides[pb]]; 392 cmpIdxData[0][startBand + pb] = data[ps][aStrides[pb]]; 393 394 if (losslessData->bsDataPair[paramIdx][ps]) { 395 cmpIdxData[1][startBand + pb] = data[ps + 1][aStrides[pb]]; 396 } 397 } /* for pb*/ 398 399 /* Finally encode */ 400 if (losslessData->bsDataPair[paramIdx][ps]) { 401 fdk_sacenc_ecDataPairEnc(bitstream, cmpIdxData, cmpOldData, dataType, 0, 402 startBand, dataBands, 403 losslessData->bsQuantCoarseXXX[paramIdx][ps], 404 independencyFlag && (ps == 0)); 405 } else { 406 fdk_sacenc_ecDataSingleEnc(bitstream, cmpIdxData, cmpOldData, dataType, 407 0, startBand, dataBands, 408 losslessData->bsQuantCoarseXXX[paramIdx][ps], 409 independencyFlag && (ps == 0)); 410 } 411 412 /* Overwrite old data */ 413 for (i = startBand; i < stopBand; i++) { 414 if (losslessData->bsDataPair[paramIdx][ps]) { 415 oldData[i] = data[ps + 1][i]; 416 } else { 417 oldData[i] = data[ps][i]; 418 } 419 } 420 421 quantCoarseXXXprev[paramIdx] = 422 losslessData->bsQuantCoarseXXX[paramIdx][ps]; 423 424 /* Jump forward if we have encoded a data pair */ 425 if (losslessData->bsDataPair[paramIdx][ps]) { 426 ps++; 427 } 428 429 } /* if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE ) */ 430 } /* for ps */ 431 } 432 433 /****************************************************************************/ 434 /* Bitstream formatter interface functions */ 435 /****************************************************************************/ 436 static FDK_SACENC_ERROR getBsFreqResIndex(const INT numBands, 437 INT *const pbsFreqResIndex) { 438 FDK_SACENC_ERROR error = SACENC_OK; 439 440 if (NULL == pbsFreqResIndex) { 441 error = SACENC_INVALID_HANDLE; 442 } else { 443 const UCHAR *pFreqResBinTable = FreqResBinTable_LD; 444 int i; 445 *pbsFreqResIndex = -1; 446 447 for (i = 0; i < MAX_FREQ_RES_INDEX; i++) { 448 if (numBands == pFreqResBinTable[i]) { 449 *pbsFreqResIndex = i; 450 break; 451 } 452 } 453 if (*pbsFreqResIndex < 0 || *pbsFreqResIndex >= MAX_FREQ_RES_INDEX) { 454 error = SACENC_INVALID_CONFIG; 455 } 456 } 457 return error; 458 } 459 460 static FDK_SACENC_ERROR getSamplingFrequencyIndex( 461 const INT bsSamplingFrequency, INT *const pbsSamplingFrequencyIndex) { 462 FDK_SACENC_ERROR error = SACENC_OK; 463 464 if (NULL == pbsSamplingFrequencyIndex) { 465 error = SACENC_INVALID_HANDLE; 466 } else { 467 int i; 468 *pbsSamplingFrequencyIndex = SAMPLING_FREQUENCY_INDEX_ESCAPE; 469 470 for (i = 0; i < MAX_SAMPLING_FREQUENCY_INDEX; i++) { 471 if (bsSamplingFrequency == SampleRateTable[i]) { /*spatial sampling rate*/ 472 *pbsSamplingFrequencyIndex = i; 473 break; 474 } 475 } 476 } 477 return error; 478 } 479 480 /* destroy encoder instance */ 481 FDK_SACENC_ERROR fdk_sacenc_destroySpatialBitstreamEncoder( 482 HANDLE_BSF_INSTANCE *selfPtr) { 483 FDK_SACENC_ERROR error = SACENC_OK; 484 485 if ((selfPtr == NULL) || (*selfPtr == NULL)) { 486 error = SACENC_INVALID_HANDLE; 487 } else { 488 if (*selfPtr != NULL) { 489 FDK_FREE_MEMORY_1D(*selfPtr); 490 } 491 } 492 return error; 493 } 494 495 /* create encoder instance */ 496 FDK_SACENC_ERROR fdk_sacenc_createSpatialBitstreamEncoder( 497 HANDLE_BSF_INSTANCE *selfPtr) { 498 FDK_SACENC_ERROR error = SACENC_OK; 499 500 if (NULL == selfPtr) { 501 error = SACENC_INVALID_HANDLE; 502 } else { 503 /* allocate encoder struct */ 504 FDK_ALLOCATE_MEMORY_1D(*selfPtr, 1, BSF_INSTANCE); 505 } 506 return error; 507 508 bail: 509 fdk_sacenc_destroySpatialBitstreamEncoder(selfPtr); 510 return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error); 511 } 512 513 /* init encoder instance */ 514 FDK_SACENC_ERROR fdk_sacenc_initSpatialBitstreamEncoder( 515 HANDLE_BSF_INSTANCE selfPtr) { 516 FDK_SACENC_ERROR error = SACENC_OK; 517 518 if (selfPtr == NULL) { 519 error = SACENC_INVALID_HANDLE; 520 } else { 521 /* init/clear */ 522 clearFrame(&selfPtr->frame); 523 524 } /* valid handle */ 525 return error; 526 } 527 528 /* get SpatialSpecificConfig struct */ 529 SPATIALSPECIFICCONFIG *fdk_sacenc_getSpatialSpecificConfig( 530 HANDLE_BSF_INSTANCE selfPtr) { 531 return ((selfPtr == NULL) ? NULL : &(selfPtr->spatialSpecificConfig)); 532 } 533 534 /* write SpatialSpecificConfig to stream */ 535 FDK_SACENC_ERROR fdk_sacenc_writeSpatialSpecificConfig( 536 SPATIALSPECIFICCONFIG *const spatialSpecificConfig, 537 UCHAR *const pOutputBuffer, const INT outputBufferSize, 538 INT *const pnOutputBits) { 539 FDK_SACENC_ERROR error = SACENC_OK; 540 INT bsSamplingFrequencyIndex = 0; 541 INT bsFreqRes = 0; 542 543 if ((spatialSpecificConfig == NULL) || (pOutputBuffer == NULL) || 544 (pnOutputBits == NULL)) { 545 error = SACENC_INVALID_HANDLE; 546 } else { 547 FDK_BITSTREAM bitstream; 548 549 /* Find FreqRes */ 550 if (SACENC_OK != (error = getBsFreqResIndex(spatialSpecificConfig->numBands, 551 &bsFreqRes))) 552 goto bail; 553 554 /* Find SamplingFrequencyIndex */ 555 if (SACENC_OK != (error = getSamplingFrequencyIndex( 556 spatialSpecificConfig->bsSamplingFrequency, 557 &bsSamplingFrequencyIndex))) 558 goto bail; 559 560 /* bind extern buffer to bitstream handle */ 561 FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER); 562 563 /****************************************************************************/ 564 /* write to bitstream */ 565 566 FDKwriteBits(&bitstream, bsSamplingFrequencyIndex, 4); 567 568 if (bsSamplingFrequencyIndex == 15) { 569 FDKwriteBits(&bitstream, spatialSpecificConfig->bsSamplingFrequency, 24); 570 } 571 572 FDKwriteBits(&bitstream, spatialSpecificConfig->bsFrameLength, 5); 573 574 FDKwriteBits(&bitstream, bsFreqRes, 3); 575 FDKwriteBits(&bitstream, spatialSpecificConfig->bsTreeConfig, 4); 576 FDKwriteBits(&bitstream, spatialSpecificConfig->bsQuantMode, 2); 577 578 FDKwriteBits(&bitstream, 0, 1); /* bsArbitraryDownmix */ 579 580 FDKwriteBits(&bitstream, spatialSpecificConfig->bsFixedGainDMX, 3); 581 582 FDKwriteBits(&bitstream, TEMPSHAPE_OFF, 2); 583 FDKwriteBits(&bitstream, spatialSpecificConfig->bsDecorrConfig, 2); 584 585 FDKbyteAlign(&bitstream, 0); /* byte alignment */ 586 587 /* return number of valid bits in bitstream */ 588 if ((*pnOutputBits = FDKgetValidBits(&bitstream)) > 589 (outputBufferSize * 8)) { 590 error = SACENC_INVALID_CONFIG; 591 goto bail; 592 } 593 594 /* terminate buffer with alignment */ 595 FDKbyteAlign(&bitstream, 0); 596 597 } /* valid handle */ 598 599 bail: 600 return error; 601 } 602 603 /* get SpatialFrame struct */ 604 SPATIALFRAME *fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr, 605 const SPATIALFRAME_TYPE frameType) { 606 int idx = -1; 607 608 switch (frameType) { 609 case READ_SPATIALFRAME: 610 case WRITE_SPATIALFRAME: 611 idx = 0; 612 break; 613 default: 614 idx = -1; /* invalid configuration */ 615 } /* switch frameType */ 616 617 return (((selfPtr == NULL) || (idx == -1)) ? NULL : &selfPtr->frame); 618 } 619 620 static FDK_SACENC_ERROR writeFramingInfo(HANDLE_FDK_BITSTREAM hBitstream, 621 const FRAMINGINFO *const pFramingInfo, 622 const INT frameLength) { 623 FDK_SACENC_ERROR error = SACENC_OK; 624 625 if ((hBitstream == NULL) || (pFramingInfo == NULL)) { 626 error = SACENC_INVALID_HANDLE; 627 } else { 628 FDKwriteBits(hBitstream, pFramingInfo->bsFramingType, 1); 629 FDKwriteBits(hBitstream, pFramingInfo->numParamSets - 1, 1); 630 631 if (pFramingInfo->bsFramingType) { 632 int ps = 0; 633 int numParamSets = pFramingInfo->numParamSets; 634 635 { 636 for (ps = 0; ps < numParamSets; ps++) { 637 int bitsParamSlot = 0; 638 while ((1 << bitsParamSlot) < (frameLength + 1)) bitsParamSlot++; 639 if (bitsParamSlot > 0) 640 FDKwriteBits(hBitstream, pFramingInfo->bsParamSlots[ps], 641 bitsParamSlot); 642 } 643 } 644 } /* pFramingInfo->bsFramingType */ 645 } /* valid handle */ 646 647 return error; 648 } 649 650 static FDK_SACENC_ERROR writeSmgData(HANDLE_FDK_BITSTREAM hBitstream, 651 const SMGDATA *const pSmgData, 652 const INT numParamSets, 653 const INT dataBands) { 654 FDK_SACENC_ERROR error = SACENC_OK; 655 656 if ((hBitstream == NULL) || (pSmgData == NULL)) { 657 error = SACENC_INVALID_HANDLE; 658 } else { 659 int i, j; 660 661 for (i = 0; i < numParamSets; i++) { 662 FDKwriteBits(hBitstream, pSmgData->bsSmoothMode[i], 2); 663 664 if (pSmgData->bsSmoothMode[i] >= 2) { 665 FDKwriteBits(hBitstream, pSmgData->bsSmoothTime[i], 2); 666 } 667 if (pSmgData->bsSmoothMode[i] == 3) { 668 const int stride = getBsFreqResStride(pSmgData->bsFreqResStride[i]); 669 FDKwriteBits(hBitstream, pSmgData->bsFreqResStride[i], 2); 670 for (j = 0; j < dataBands; j += stride) { 671 FDKwriteBits(hBitstream, pSmgData->bsSmgData[i][j], 1); 672 } 673 } 674 } /* for i */ 675 } /* valid handle */ 676 677 return error; 678 } 679 680 static FDK_SACENC_ERROR writeOttData( 681 HANDLE_FDK_BITSTREAM hBitstream, PREV_OTTDATA *const pPrevOttData, 682 OTTDATA *const pOttData, const OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES], 683 LOSSLESSDATA *const pCLDLosslessData, LOSSLESSDATA *const pICCLosslessData, 684 const INT numOttBoxes, const INT numBands, const INT numParamSets, 685 const INT bsIndependencyFlag) { 686 FDK_SACENC_ERROR error = SACENC_OK; 687 688 if ((hBitstream == NULL) || (pPrevOttData == NULL) || (pOttData == NULL) || 689 (ottConfig == NULL) || (pCLDLosslessData == NULL) || 690 (pICCLosslessData == NULL)) { 691 error = SACENC_INVALID_HANDLE; 692 } else { 693 int i; 694 for (i = 0; i < numOttBoxes; i++) { 695 ecData(hBitstream, pOttData->cld[i], pPrevOttData->cld_old[i], 696 pPrevOttData->quantCoarseCldPrev[i], pCLDLosslessData, t_CLD, i, 697 numParamSets, bsIndependencyFlag, 0, ottConfig[i].bsOttBands, 15); 698 } 699 { 700 for (i = 0; i < numOttBoxes; i++) { 701 { 702 ecData(hBitstream, pOttData->icc[i], pPrevOttData->icc_old[i], 703 pPrevOttData->quantCoarseIccPrev[i], pICCLosslessData, t_ICC, 704 i, numParamSets, bsIndependencyFlag, 0, numBands, 0); 705 } 706 } /* for i */ 707 } 708 } /* valid handle */ 709 710 return error; 711 } 712 713 /* write extension frame data to stream */ 714 static FDK_SACENC_ERROR WriteSpatialExtensionFrame( 715 HANDLE_FDK_BITSTREAM bitstream, HANDLE_BSF_INSTANCE self) { 716 FDK_SACENC_ERROR error = SACENC_OK; 717 718 if ((bitstream == NULL) || (self == NULL)) { 719 error = SACENC_INVALID_HANDLE; 720 } else { 721 FDKbyteAlign(bitstream, 0); 722 } /* valid handle */ 723 724 return error; 725 } 726 727 /* write frame data to stream */ 728 FDK_SACENC_ERROR fdk_sacenc_writeSpatialFrame(UCHAR *const pOutputBuffer, 729 const INT outputBufferSize, 730 INT *const pnOutputBits, 731 HANDLE_BSF_INSTANCE selfPtr) { 732 FDK_SACENC_ERROR error = SACENC_OK; 733 734 if ((pOutputBuffer == NULL) || (pnOutputBits == NULL) || (selfPtr == NULL)) { 735 error = SACENC_INVALID_HANDLE; 736 } else { 737 SPATIALFRAME *frame = NULL; 738 SPATIALSPECIFICCONFIG *config = NULL; 739 FDK_BITSTREAM bitstream; 740 741 int i, j, numParamSets, numOttBoxes; 742 743 if ((NULL == 744 (frame = fdk_sacenc_getSpatialFrame(selfPtr, READ_SPATIALFRAME))) || 745 (NULL == (config = &(selfPtr->spatialSpecificConfig)))) { 746 error = SACENC_INVALID_HANDLE; 747 goto bail; 748 } 749 750 numOttBoxes = selfPtr->spatialSpecificConfig.treeDescription.numOttBoxes; 751 752 numParamSets = frame->framingInfo.numParamSets; 753 754 if (frame->bUseBBCues) { 755 for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) { 756 /* If a transient was detected, force only the second ps broad band */ 757 if (numParamSets == 1) { 758 frame->CLDLosslessData.bsFreqResStrideXXX[i][0] = 3; 759 frame->ICCLosslessData.bsFreqResStrideXXX[i][0] = 3; 760 } else { 761 for (j = 1; j < MAX_NUM_PARAMS; j++) { 762 frame->CLDLosslessData.bsFreqResStrideXXX[i][j] = 3; 763 frame->ICCLosslessData.bsFreqResStrideXXX[i][j] = 3; 764 } 765 } 766 } 767 } /* frame->bUseBBCues */ 768 769 /* bind extern buffer to bitstream handle */ 770 FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER); 771 772 if (SACENC_OK != (error = writeFramingInfo( 773 &bitstream, &(frame->framingInfo), 774 selfPtr->spatialSpecificConfig.bsFrameLength))) { 775 goto bail; 776 } 777 778 /* write bsIndependencyFlag */ 779 FDKwriteBits(&bitstream, frame->bsIndependencyFlag, 1); 780 781 /* write spatial data to bitstream */ 782 if (SACENC_OK != 783 (error = writeOttData(&bitstream, &selfPtr->prevFrameData.prevOttData, 784 &frame->ottData, config->ottConfig, 785 &frame->CLDLosslessData, &frame->ICCLosslessData, 786 numOttBoxes, config->numBands, numParamSets, 787 frame->bsIndependencyFlag))) { 788 goto bail; 789 } 790 if (SACENC_OK != (error = writeSmgData(&bitstream, &frame->smgData, 791 numParamSets, config->numBands))) { 792 goto bail; 793 } 794 795 /* byte alignment */ 796 FDKbyteAlign(&bitstream, 0); 797 798 /* Write SpatialExtensionFrame */ 799 if (SACENC_OK != 800 (error = WriteSpatialExtensionFrame(&bitstream, selfPtr))) { 801 goto bail; 802 } 803 804 if (NULL == 805 (frame = fdk_sacenc_getSpatialFrame(selfPtr, WRITE_SPATIALFRAME))) { 806 error = SACENC_INVALID_HANDLE; 807 goto bail; 808 } 809 810 clearFrame(frame); 811 812 /* return number of valid bits in bitstream */ 813 if ((*pnOutputBits = FDKgetValidBits(&bitstream)) > 814 (outputBufferSize * 8)) { 815 error = SACENC_INVALID_CONFIG; 816 goto bail; 817 } 818 819 /* terminate buffer with alignment */ 820 FDKbyteAlign(&bitstream, 0); 821 822 } /* valid handle */ 823 824 bail: 825 return error; 826 } 827