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): M. Multrus 98 99 Description: Parameter Extraction 100 101 *******************************************************************************/ 102 103 /* Includes ******************************************************************/ 104 #include "sacenc_paramextract.h" 105 #include "sacenc_tree.h" 106 #include "sacenc_vectorfunctions.h" 107 108 /* Defines *******************************************************************/ 109 #define LOG10_2_10 (3.01029995664f) /* 10.0f*log10(2.f) */ 110 #define SCALE_CLDE_SF (7) /* maxVal in Quant tab is +/- 50 */ 111 #define SCALE_CLDD_SF (8) /* maxVal in Quant tab is +/- 150 */ 112 113 /* Data Types ****************************************************************/ 114 typedef struct T_TTO_BOX { 115 FIXP_DBL pCld__FDK[MAX_NUM_PARAM_BANDS]; 116 FIXP_DBL pIcc__FDK[MAX_NUM_PARAM_BANDS]; 117 FIXP_DBL pCldQuant__FDK[MAX_NUM_PARAM_BANDS]; 118 119 const FIXP_DBL *pIccQuantTable__FDK; 120 const FIXP_DBL *pCldQuantTableDec__FDK; 121 const FIXP_DBL *pCldQuantTableEnc__FDK; 122 123 SCHAR pCldEbQIdx[MAX_NUM_PARAM_BANDS]; 124 SCHAR pIccDownmixIdx[MAX_NUM_PARAM_BANDS]; 125 126 UCHAR *pParameterBand2HybridBandOffset; 127 const INT *pSubbandImagSign; 128 UCHAR nHybridBandsMax; 129 UCHAR nParameterBands; 130 UCHAR bFrameKeep; 131 132 UCHAR iccCorrelationCoherenceBorder; 133 BOX_QUANTMODE boxQuantMode; 134 135 UCHAR nIccQuantSteps; 136 UCHAR nIccQuantOffset; 137 138 UCHAR nCldQuantSteps; 139 UCHAR nCldQuantOffset; 140 141 UCHAR bUseCoarseQuantCld; 142 UCHAR bUseCoarseQuantIcc; 143 144 } TTO_BOX; 145 146 struct BOX_SUBBAND_SETUP { 147 BOX_SUBBAND_CONFIG subbandConfig; 148 UCHAR nParameterBands; 149 const UCHAR *pSubband2ParameterIndexLd; 150 UCHAR iccCorrelationCoherenceBorder; 151 }; 152 153 /* Constants *****************************************************************/ 154 static const UCHAR subband2Parameter4_Ld[NUM_QMF_BANDS] = { 155 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 156 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 157 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; 158 159 static const UCHAR subband2Parameter5_Ld[NUM_QMF_BANDS] = { 160 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 161 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 162 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; 163 164 static const UCHAR subband2Parameter7_Ld[NUM_QMF_BANDS] = { 165 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 166 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 167 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}; 168 169 static const UCHAR subband2Parameter9_Ld[NUM_QMF_BANDS] = { 170 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 171 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 172 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; 173 174 static const UCHAR subband2Parameter12_Ld[NUM_QMF_BANDS] = { 175 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 176 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 177 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 178 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}; 179 180 static const UCHAR subband2Parameter15_Ld[NUM_QMF_BANDS] = { 181 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, 182 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 183 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 184 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}; 185 186 static const UCHAR subband2Parameter23_Ld[NUM_QMF_BANDS] = { 187 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 188 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 189 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 190 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22}; 191 192 static const INT subbandImagSign_Ld[NUM_QMF_BANDS] = { 193 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 194 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 195 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 196 }; 197 198 #define SCALE_CLDE(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDE_SF))) 199 static const FIXP_DBL cldQuantTableFineEnc__FDK[MAX_CLD_QUANT_FINE] = { 200 SCALE_CLDE(-50.0), SCALE_CLDE(-45.0), SCALE_CLDE(-40.0), SCALE_CLDE(-35.0), 201 SCALE_CLDE(-30.0), SCALE_CLDE(-25.0), SCALE_CLDE(-22.0), SCALE_CLDE(-19.0), 202 SCALE_CLDE(-16.0), SCALE_CLDE(-13.0), SCALE_CLDE(-10.0), SCALE_CLDE(-8.0), 203 SCALE_CLDE(-6.0), SCALE_CLDE(-4.0), SCALE_CLDE(-2.0), SCALE_CLDE(0.0), 204 SCALE_CLDE(2.0), SCALE_CLDE(4.0), SCALE_CLDE(6.0), SCALE_CLDE(8.0), 205 SCALE_CLDE(10.0), SCALE_CLDE(13.0), SCALE_CLDE(16.0), SCALE_CLDE(19.0), 206 SCALE_CLDE(22.0), SCALE_CLDE(25.0), SCALE_CLDE(30.0), SCALE_CLDE(35.0), 207 SCALE_CLDE(40.0), SCALE_CLDE(45.0), SCALE_CLDE(50.0)}; 208 209 static const FIXP_DBL cldQuantTableCoarseEnc__FDK[MAX_CLD_QUANT_COARSE] = { 210 SCALE_CLDE(-50.0), SCALE_CLDE(-35.0), SCALE_CLDE(-25.0), SCALE_CLDE(-19.0), 211 SCALE_CLDE(-13.0), SCALE_CLDE(-8.0), SCALE_CLDE(-4.0), SCALE_CLDE(0.0), 212 SCALE_CLDE(4.0), SCALE_CLDE(8.0), SCALE_CLDE(13.0), SCALE_CLDE(19.0), 213 SCALE_CLDE(25.0), SCALE_CLDE(35.0), SCALE_CLDE(50.0)}; 214 215 #define SCALE_CLDD(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDD_SF))) 216 static const FIXP_DBL cldQuantTableFineDec__FDK[MAX_CLD_QUANT_FINE] = { 217 SCALE_CLDD(-150.0), SCALE_CLDD(-45.0), SCALE_CLDD(-40.0), SCALE_CLDD(-35.0), 218 SCALE_CLDD(-30.0), SCALE_CLDD(-25.0), SCALE_CLDD(-22.0), SCALE_CLDD(-19.0), 219 SCALE_CLDD(-16.0), SCALE_CLDD(-13.0), SCALE_CLDD(-10.0), SCALE_CLDD(-8.0), 220 SCALE_CLDD(-6.0), SCALE_CLDD(-4.0), SCALE_CLDD(-2.0), SCALE_CLDD(0.0), 221 SCALE_CLDD(2.0), SCALE_CLDD(4.0), SCALE_CLDD(6.0), SCALE_CLDD(8.0), 222 SCALE_CLDD(10.0), SCALE_CLDD(13.0), SCALE_CLDD(16.0), SCALE_CLDD(19.0), 223 SCALE_CLDD(22.0), SCALE_CLDD(25.0), SCALE_CLDD(30.0), SCALE_CLDD(35.0), 224 SCALE_CLDD(40.0), SCALE_CLDD(45.0), SCALE_CLDD(150.0)}; 225 226 static const FIXP_DBL cldQuantTableCoarseDec__FDK[MAX_CLD_QUANT_COARSE] = { 227 SCALE_CLDD(-150.0), SCALE_CLDD(-35.0), SCALE_CLDD(-25.0), SCALE_CLDD(-19.0), 228 SCALE_CLDD(-13.0), SCALE_CLDD(-8.0), SCALE_CLDD(-4.0), SCALE_CLDD(0.0), 229 SCALE_CLDD(4.0), SCALE_CLDD(8.0), SCALE_CLDD(13.0), SCALE_CLDD(19.0), 230 SCALE_CLDD(25.0), SCALE_CLDD(35.0), SCALE_CLDD(150.0)}; 231 232 #define SCALE_ICC(a) (FL2FXCONST_DBL(a)) 233 static const FIXP_DBL iccQuantTableFine__FDK[MAX_ICC_QUANT_FINE] = { 234 SCALE_ICC(0.99999999953), SCALE_ICC(0.937f), SCALE_ICC(0.84118f), 235 SCALE_ICC(0.60092f), SCALE_ICC(0.36764f), SCALE_ICC(0.0f), 236 SCALE_ICC(-0.589f), SCALE_ICC(-0.99f)}; 237 238 static const FIXP_DBL iccQuantTableCoarse__FDK[MAX_ICC_QUANT_COARSE] = { 239 SCALE_ICC(0.99999999953), SCALE_ICC(0.84118f), SCALE_ICC(0.36764f), 240 SCALE_ICC(-0.5890f)}; 241 242 static const BOX_SUBBAND_SETUP boxSubbandSetup[] = { 243 {BOX_SUBBANDS_4, 4, subband2Parameter4_Ld, 1}, 244 {BOX_SUBBANDS_5, 5, subband2Parameter5_Ld, 2}, 245 {BOX_SUBBANDS_7, 7, subband2Parameter7_Ld, 3}, 246 {BOX_SUBBANDS_9, 9, subband2Parameter9_Ld, 4}, 247 {BOX_SUBBANDS_12, 12, subband2Parameter12_Ld, 4}, 248 {BOX_SUBBANDS_15, 15, subband2Parameter15_Ld, 5}, 249 {BOX_SUBBANDS_23, 23, subband2Parameter23_Ld, 8}}; 250 251 /* Function / Class Declarations *********************************************/ 252 253 /* Function / Class Definition ***********************************************/ 254 static const BOX_SUBBAND_SETUP *getBoxSubbandSetup( 255 const BOX_SUBBAND_CONFIG subbandConfig) { 256 int i; 257 const BOX_SUBBAND_SETUP *setup = NULL; 258 259 for (i = 0; i < (int)(sizeof(boxSubbandSetup) / sizeof(BOX_SUBBAND_SETUP)); 260 i++) { 261 if (boxSubbandSetup[i].subbandConfig == subbandConfig) { 262 setup = &boxSubbandSetup[i]; 263 break; 264 } 265 } 266 return setup; 267 } 268 269 static inline void ApplyBBCuesFDK(FIXP_DBL *const pData, 270 const INT nParamBands) { 271 int i, s; 272 FIXP_DBL tmp, invParamBands; 273 274 invParamBands = fDivNormHighPrec((FIXP_DBL)1, (FIXP_DBL)nParamBands, &s); 275 s = -s; 276 277 tmp = fMult(pData[0], invParamBands) >> s; 278 for (i = 1; i < nParamBands; i++) { 279 tmp += fMult(pData[i], invParamBands) >> s; 280 } 281 282 for (i = 0; i < nParamBands; i++) { 283 pData[i] = tmp; 284 } 285 } 286 287 static INT getNumberParameterBands(const BOX_SUBBAND_CONFIG subbandConfig) { 288 const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig); 289 return ((setup == NULL) ? 0 : setup->nParameterBands); 290 } 291 292 static const UCHAR *getSubband2ParameterIndex( 293 const BOX_SUBBAND_CONFIG subbandConfig) { 294 const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig); 295 296 return ((setup == NULL) ? NULL : (setup->pSubband2ParameterIndexLd)); 297 } 298 299 void fdk_sacenc_calcParameterBand2HybridBandOffset( 300 const BOX_SUBBAND_CONFIG subbandConfig, const INT nHybridBands, 301 UCHAR *pParameterBand2HybridBandOffset) { 302 const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig); 303 const UCHAR *pSubband2ParameterIndex; 304 305 int i, pb; 306 307 pSubband2ParameterIndex = setup->pSubband2ParameterIndexLd; 308 309 for (pb = 0, i = 0; i < nHybridBands - 1; i++) { 310 if (pSubband2ParameterIndex[i + 1] - pSubband2ParameterIndex[i]) { 311 pParameterBand2HybridBandOffset[pb++] = (i + 1); 312 } 313 } 314 pParameterBand2HybridBandOffset[pb++] = (i + 1); 315 } 316 317 const INT *fdk_sacenc_getSubbandImagSign() { 318 const INT *pImagSign = NULL; 319 320 pImagSign = subbandImagSign_Ld; 321 322 return (pImagSign); 323 } 324 325 static INT getIccCorrelationCoherenceBorder( 326 const BOX_SUBBAND_CONFIG subbandConfig, const INT bUseCoherenceOnly) { 327 const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig); 328 return ( 329 (setup == NULL) 330 ? 0 331 : ((bUseCoherenceOnly) ? 0 : setup->iccCorrelationCoherenceBorder)); 332 } 333 334 FDK_SACENC_ERROR fdk_sacenc_createTtoBox(HANDLE_TTO_BOX *hTtoBox) { 335 FDK_SACENC_ERROR error = SACENC_OK; 336 337 if (NULL == hTtoBox) { 338 error = SACENC_INVALID_HANDLE; 339 } else { 340 FDK_ALLOCATE_MEMORY_1D(*hTtoBox, 1, TTO_BOX); 341 } 342 return error; 343 344 bail: 345 fdk_sacenc_destroyTtoBox(hTtoBox); 346 return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error); 347 } 348 349 FDK_SACENC_ERROR fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox, 350 const TTO_BOX_CONFIG *const ttoBoxConfig, 351 UCHAR *pParameterBand2HybridBandOffset) { 352 FDK_SACENC_ERROR error = SACENC_OK; 353 354 if ((hTtoBox == NULL) || (ttoBoxConfig == NULL) || 355 (pParameterBand2HybridBandOffset == NULL)) { 356 error = SACENC_INVALID_HANDLE; 357 } else { 358 FDKmemclear(hTtoBox, sizeof(TTO_BOX)); 359 360 hTtoBox->bUseCoarseQuantCld = ttoBoxConfig->bUseCoarseQuantCld; 361 hTtoBox->bUseCoarseQuantIcc = ttoBoxConfig->bUseCoarseQuantIcc; 362 hTtoBox->boxQuantMode = ttoBoxConfig->boxQuantMode; 363 hTtoBox->iccCorrelationCoherenceBorder = getIccCorrelationCoherenceBorder( 364 ttoBoxConfig->subbandConfig, ttoBoxConfig->bUseCoherenceIccOnly); 365 hTtoBox->nHybridBandsMax = ttoBoxConfig->nHybridBandsMax; 366 hTtoBox->nParameterBands = 367 getNumberParameterBands(ttoBoxConfig->subbandConfig); 368 hTtoBox->bFrameKeep = ttoBoxConfig->bFrameKeep; 369 370 hTtoBox->nIccQuantSteps = 371 fdk_sacenc_getNumberIccQuantLevels(hTtoBox->bUseCoarseQuantIcc); 372 hTtoBox->nIccQuantOffset = 373 fdk_sacenc_getIccQuantOffset(hTtoBox->bUseCoarseQuantIcc); 374 375 hTtoBox->pIccQuantTable__FDK = hTtoBox->bUseCoarseQuantIcc 376 ? iccQuantTableCoarse__FDK 377 : iccQuantTableFine__FDK; 378 hTtoBox->pCldQuantTableDec__FDK = hTtoBox->bUseCoarseQuantCld 379 ? cldQuantTableCoarseDec__FDK 380 : cldQuantTableFineDec__FDK; 381 hTtoBox->pCldQuantTableEnc__FDK = hTtoBox->bUseCoarseQuantCld 382 ? cldQuantTableCoarseEnc__FDK 383 : cldQuantTableFineEnc__FDK; 384 385 hTtoBox->nCldQuantSteps = 386 fdk_sacenc_getNumberCldQuantLevels(hTtoBox->bUseCoarseQuantCld); 387 hTtoBox->nCldQuantOffset = 388 fdk_sacenc_getCldQuantOffset(hTtoBox->bUseCoarseQuantCld); 389 390 /* sanity */ 391 if (NULL == (hTtoBox->pParameterBand2HybridBandOffset = 392 pParameterBand2HybridBandOffset)) { 393 error = SACENC_INIT_ERROR; 394 goto bail; 395 } 396 397 if (NULL == (hTtoBox->pSubbandImagSign = fdk_sacenc_getSubbandImagSign())) { 398 error = SACENC_INIT_ERROR; 399 } 400 401 if ((hTtoBox->boxQuantMode != BOX_QUANTMODE_FINE) && 402 (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ1) && 403 (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ2)) { 404 error = SACENC_INIT_ERROR; 405 goto bail; 406 } 407 } 408 bail: 409 return error; 410 } 411 412 FDK_SACENC_ERROR fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX *hTtoBox) { 413 FDK_SACENC_ERROR error = SACENC_OK; 414 415 if (*hTtoBox != NULL) { 416 FDKfree(*hTtoBox); 417 *hTtoBox = NULL; 418 } 419 420 return error; 421 } 422 423 static FDK_SACENC_ERROR calculateIccFDK(const INT nParamBand, 424 const INT correlationCoherenceBorder, 425 const FIXP_DBL *const pPwr1, 426 const FIXP_DBL *const pPwr2, 427 const FIXP_DBL *const pProdReal, 428 FIXP_DBL const *const pProdImag, 429 FIXP_DBL *const pIcc) { 430 FDK_SACENC_ERROR error = SACENC_OK; 431 432 if ((pPwr1 == NULL) || (pPwr2 == NULL) || (pProdReal == NULL) || 433 (pProdImag == NULL) || (pIcc == NULL)) { 434 error = SACENC_INVALID_HANDLE; 435 } else { 436 /* sanity check border */ 437 if (correlationCoherenceBorder > nParamBand) { 438 error = SACENC_INVALID_CONFIG; 439 } else { 440 /* correlation */ 441 FDKcalcCorrelationVec(pIcc, pProdReal, pPwr1, pPwr2, 442 correlationCoherenceBorder); 443 444 /* coherence */ 445 calcCoherenceVec(&pIcc[correlationCoherenceBorder], 446 &pProdReal[correlationCoherenceBorder], 447 &pProdImag[correlationCoherenceBorder], 448 &pPwr1[correlationCoherenceBorder], 449 &pPwr2[correlationCoherenceBorder], 0, 0, 450 nParamBand - correlationCoherenceBorder); 451 452 } /* valid configuration */ 453 } /* valid handle */ 454 455 return error; 456 } 457 458 static void QuantizeCoefFDK(const FIXP_DBL *const input, const INT nBands, 459 const FIXP_DBL *const quantTable, 460 const INT idxOffset, const INT nQuantSteps, 461 SCHAR *const quantOut) { 462 int band; 463 const int reverse = (quantTable[0] > quantTable[1]); 464 465 for (band = 0; band < nBands; band++) { 466 FIXP_DBL qVal; 467 FIXP_DBL curVal = input[band]; 468 469 int lower = 0; 470 int upper = nQuantSteps - 1; 471 472 if (reverse) { 473 while (upper - lower > 1) { 474 int idx = (lower + upper) >> 1; 475 qVal = quantTable[idx]; 476 if (curVal >= qVal) { 477 upper = idx; 478 } else { 479 lower = idx; 480 } 481 } /* while */ 482 483 if ((curVal - quantTable[lower]) >= (quantTable[upper] - curVal)) { 484 quantOut[band] = lower - idxOffset; 485 } else { 486 quantOut[band] = upper - idxOffset; 487 } 488 } /* if reverse */ 489 else { 490 while (upper - lower > 1) { 491 int idx = (lower + upper) >> 1; 492 qVal = quantTable[idx]; 493 if (curVal <= qVal) { 494 upper = idx; 495 } else { 496 lower = idx; 497 } 498 } /* while */ 499 500 if ((curVal - quantTable[lower]) <= (quantTable[upper] - curVal)) { 501 quantOut[band] = lower - idxOffset; 502 } else { 503 quantOut[band] = upper - idxOffset; 504 } 505 } /* else reverse */ 506 } /* for band */ 507 } 508 509 static void deQuantizeCoefFDK(const SCHAR *const input, const INT nBands, 510 const FIXP_DBL *const quantTable, 511 const INT idxOffset, FIXP_DBL *const dequantOut) { 512 int band; 513 514 for (band = 0; band < nBands; band++) { 515 dequantOut[band] = quantTable[input[band] + idxOffset]; 516 } 517 } 518 519 static void CalculateCldFDK(FIXP_DBL *const pCld, const FIXP_DBL *const pPwr1, 520 const FIXP_DBL *const pPwr2, const INT scaleCh1, 521 const INT *const pbScaleCh1, const INT scaleCh2, 522 const INT *const pbScaleCh2, const int nParamBand) { 523 INT i; 524 FIXP_DBL ldPwr1, ldPwr2, cld; 525 FIXP_DBL maxPwr = FL2FXCONST_DBL( 526 30.0f / 527 (1 << (LD_DATA_SHIFT + 528 1))); /* consider SACENC_FLOAT_EPSILON in power calculation */ 529 530 for (i = 0; i < nParamBand; i++) { 531 ldPwr1 = 532 (CalcLdData(pPwr1[i]) >> 1) + ((FIXP_DBL)(scaleCh1 + pbScaleCh1[i]) 533 << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); 534 ldPwr2 = 535 (CalcLdData(pPwr2[i]) >> 1) + ((FIXP_DBL)(scaleCh2 + pbScaleCh2[i]) 536 << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); 537 538 ldPwr1 = fixMax(fixMin(ldPwr1, maxPwr), -maxPwr); 539 ldPwr2 = fixMax(fixMin(ldPwr2, maxPwr), -maxPwr); 540 541 /* ldPwr1 and ldPwr2 are scaled by LD_DATA_SHIFT and additional 1 bit; 1 bit 542 * scale by fMultDiv2() */ 543 cld = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / (1 << SCALE_CLDE_SF)), 544 ldPwr1 - ldPwr2); 545 546 cld = 547 fixMin(cld, (FIXP_DBL)(((FIXP_DBL)MAXVAL_DBL) >> (LD_DATA_SHIFT + 2))); 548 cld = 549 fixMax(cld, (FIXP_DBL)(((FIXP_DBL)MINVAL_DBL) >> (LD_DATA_SHIFT + 2))); 550 pCld[i] = cld << (LD_DATA_SHIFT + 2); 551 } 552 } 553 554 FDK_SACENC_ERROR fdk_sacenc_applyTtoBox( 555 HANDLE_TTO_BOX hTtoBox, const INT nTimeSlots, const INT startTimeSlot, 556 const INT nHybridBands, const FIXP_DPK *const *const ppHybridData1__FDK, 557 const FIXP_DPK *const *const ppHybridData2__FDK, SCHAR *const pIccIdx, 558 UCHAR *const pbIccQuantCoarse, SCHAR *const pCldIdx, 559 UCHAR *const pbCldQuantCoarse, const INT bUseBBCues, INT *scaleCh1, 560 INT *scaleCh2) { 561 FDK_SACENC_ERROR error = SACENC_OK; 562 563 C_ALLOC_SCRATCH_START(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 564 C_ALLOC_SCRATCH_START(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 565 C_ALLOC_SCRATCH_START(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 566 C_ALLOC_SCRATCH_START(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 567 568 C_ALLOC_SCRATCH_START(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 569 C_ALLOC_SCRATCH_START(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 570 C_ALLOC_SCRATCH_START(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS) 571 C_ALLOC_SCRATCH_START(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS) 572 573 if ((hTtoBox == NULL) || (pCldIdx == NULL) || (pbCldQuantCoarse == NULL) || 574 (ppHybridData1__FDK == NULL) || (ppHybridData2__FDK == NULL) || 575 (pIccIdx == NULL) || (pbIccQuantCoarse == NULL)) { 576 error = SACENC_INVALID_HANDLE; 577 } else { 578 int j, pb; 579 const int nParamBands = hTtoBox->nParameterBands; 580 const int bUseEbQ = (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ1) || 581 (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ2); 582 583 /* sanity check */ 584 if ((nHybridBands < 0) || (nHybridBands > hTtoBox->nHybridBandsMax)) { 585 error = SACENC_INVALID_CONFIG; 586 goto bail; 587 } 588 589 int outScale; /* scalefactor will not be evaluated */ 590 int inScale = 5; /* scale factor determined empirically */ 591 592 /* calculate the headroom of the hybrid data for each parameter band */ 593 FDKcalcPbScaleFactor(ppHybridData1__FDK, 594 hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh1, 595 startTimeSlot, nTimeSlots, nParamBands); 596 FDKcalcPbScaleFactor(ppHybridData2__FDK, 597 hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh2, 598 startTimeSlot, nTimeSlots, nParamBands); 599 600 for (j = 0, pb = 0; pb < nParamBands; pb++) { 601 FIXP_DBL data1, data2; 602 data1 = data2 = (FIXP_DBL)0; 603 for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) { 604 data1 += sumUpCplxPow2Dim2(ppHybridData1__FDK, SUM_UP_STATIC_SCALE, 605 inScale + pbScaleCh1[pb], &outScale, 606 startTimeSlot, nTimeSlots, j, j + 1); 607 data2 += sumUpCplxPow2Dim2(ppHybridData2__FDK, SUM_UP_STATIC_SCALE, 608 inScale + pbScaleCh2[pb], &outScale, 609 startTimeSlot, nTimeSlots, j, j + 1); 610 } /* for j */ 611 powerHybridData1__FDK[pb] = data1; 612 powerHybridData2__FDK[pb] = data2; 613 } /* pb */ 614 615 { 616 for (j = 0, pb = 0; pb < nParamBands; pb++) { 617 FIXP_DBL dataReal, dataImag; 618 dataReal = dataImag = (FIXP_DBL)0; 619 for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) { 620 FIXP_DPK scalarProd; 621 cplx_cplxScalarProduct(&scalarProd, ppHybridData1__FDK, 622 ppHybridData2__FDK, inScale + pbScaleCh1[pb], 623 inScale + pbScaleCh2[pb], &outScale, 624 startTimeSlot, nTimeSlots, j, j + 1); 625 dataReal += scalarProd.v.re; 626 if (hTtoBox->pSubbandImagSign[j] < 0) { 627 dataImag -= scalarProd.v.im; 628 } else { 629 dataImag += scalarProd.v.im; 630 } 631 } /* for j */ 632 prodHybridDataReal__FDK[pb] = dataReal; 633 prodHybridDataImag__FDK[pb] = dataImag; 634 } /* pb */ 635 636 if (SACENC_OK != (error = calculateIccFDK( 637 nParamBands, hTtoBox->iccCorrelationCoherenceBorder, 638 powerHybridData1__FDK, powerHybridData2__FDK, 639 prodHybridDataReal__FDK, prodHybridDataImag__FDK, 640 hTtoBox->pIcc__FDK))) { 641 goto bail; 642 } 643 644 /* calculate correlation based Icc for downmix */ 645 if (SACENC_OK != (error = calculateIccFDK( 646 nParamBands, nParamBands, powerHybridData1__FDK, 647 powerHybridData2__FDK, prodHybridDataReal__FDK, 648 prodHybridDataImag__FDK, IccDownmix__FDK))) { 649 goto bail; 650 } 651 } 652 653 if (!bUseEbQ) { 654 CalculateCldFDK(hTtoBox->pCld__FDK, powerHybridData1__FDK, 655 powerHybridData2__FDK, *scaleCh1 + inScale + 1, 656 pbScaleCh1, *scaleCh2 + inScale + 1, pbScaleCh2, 657 nParamBands); 658 } 659 660 if (bUseBBCues) { 661 ApplyBBCuesFDK(&hTtoBox->pCld__FDK[0], nParamBands); 662 663 { ApplyBBCuesFDK(&hTtoBox->pIcc__FDK[0], nParamBands); } 664 665 } /* bUseBBCues */ 666 667 /* quantize/de-quantize icc */ 668 { 669 QuantizeCoefFDK(hTtoBox->pIcc__FDK, nParamBands, 670 hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset, 671 hTtoBox->nIccQuantSteps, pIccIdx); 672 QuantizeCoefFDK(IccDownmix__FDK, nParamBands, 673 hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset, 674 hTtoBox->nIccQuantSteps, hTtoBox->pIccDownmixIdx); 675 deQuantizeCoefFDK(hTtoBox->pIccDownmixIdx, nParamBands, 676 hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset, 677 IccDownmixQuant__FDK); 678 679 *pbIccQuantCoarse = hTtoBox->bUseCoarseQuantIcc; 680 } 681 682 /* quantize/de-quantize cld */ 683 if (!bUseEbQ) { 684 QuantizeCoefFDK(hTtoBox->pCld__FDK, nParamBands, 685 hTtoBox->pCldQuantTableEnc__FDK, hTtoBox->nCldQuantOffset, 686 hTtoBox->nCldQuantSteps, pCldIdx); 687 deQuantizeCoefFDK(pCldIdx, nParamBands, hTtoBox->pCldQuantTableDec__FDK, 688 hTtoBox->nCldQuantOffset, hTtoBox->pCldQuant__FDK); 689 } else { 690 FDKmemcpy(pCldIdx, hTtoBox->pCldEbQIdx, nParamBands * sizeof(SCHAR)); 691 } 692 *pbCldQuantCoarse = hTtoBox->bUseCoarseQuantCld; 693 694 } /* valid handle */ 695 696 bail: 697 C_ALLOC_SCRATCH_END(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS) 698 C_ALLOC_SCRATCH_END(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS) 699 C_ALLOC_SCRATCH_END(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 700 C_ALLOC_SCRATCH_END(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 701 702 C_ALLOC_SCRATCH_END(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 703 C_ALLOC_SCRATCH_END(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 704 C_ALLOC_SCRATCH_END(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 705 C_ALLOC_SCRATCH_END(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS) 706 707 return error; 708 } 709 710 INT fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig, 711 const INT nSubband) { 712 INT nParamBand = -1; 713 const UCHAR *pSubband2ParameterIndex = 714 getSubband2ParameterIndex(boxSubbandConfig); 715 716 if (pSubband2ParameterIndex != NULL) { 717 const int hybrid_resolution = 64; 718 719 if ((nSubband > -1) && (nSubband < hybrid_resolution)) { 720 nParamBand = pSubband2ParameterIndex[nSubband]; 721 } 722 } 723 724 return nParamBand; 725 } 726