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 decoder library ************************* 96 97 Author(s): 98 99 Description: SAC Dec M1 and M2 calculation 100 101 *******************************************************************************/ 102 103 #include "sac_calcM1andM2.h" 104 #include "sac_bitdec.h" 105 #include "sac_process.h" 106 #include "sac_rom.h" 107 #include "sac_smoothing.h" 108 #include "FDK_trigFcts.h" 109 110 /* assorted definitions and constants */ 111 112 #define ABS_THR2 1.0e-9 113 #define SQRT2_FDK \ 114 ((FIXP_DBL)FL2FXCONST_DBL(0.70710678118f)) /* FDKsqrt(2.0) scaled by 0.5 */ 115 116 static void param2UMX_PS__FDK(spatialDec* self, 117 FIXP_DBL H11[MAX_PARAMETER_BANDS], 118 FIXP_DBL H12[MAX_PARAMETER_BANDS], 119 FIXP_DBL H21[MAX_PARAMETER_BANDS], 120 FIXP_DBL H22[MAX_PARAMETER_BANDS], 121 FIXP_DBL c_l[MAX_PARAMETER_BANDS], 122 FIXP_DBL c_r[MAX_PARAMETER_BANDS], int ottBoxIndx, 123 int parameterSetIndx, int resBands); 124 125 static void param2UMX_PS_Core__FDK( 126 const SCHAR cld[MAX_PARAMETER_BANDS], const SCHAR icc[MAX_PARAMETER_BANDS], 127 const int numOttBands, const int resBands, 128 FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS], 129 FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS], 130 FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS]); 131 132 static void param2UMX_PS_IPD_OPD__FDK( 133 spatialDec* self, const SPATIAL_BS_FRAME* frame, 134 FIXP_DBL H11re[MAX_PARAMETER_BANDS], FIXP_DBL H12re[MAX_PARAMETER_BANDS], 135 FIXP_DBL H21re[MAX_PARAMETER_BANDS], FIXP_DBL H22re[MAX_PARAMETER_BANDS], 136 FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS], 137 int ottBoxIndx, int parameterSetIndx, int residualBands); 138 139 static void param2UMX_Prediction__FDK( 140 spatialDec* self, FIXP_DBL H11re[MAX_PARAMETER_BANDS], 141 FIXP_DBL H11im[MAX_PARAMETER_BANDS], FIXP_DBL H12re[MAX_PARAMETER_BANDS], 142 FIXP_DBL H12im[MAX_PARAMETER_BANDS], FIXP_DBL H21re[MAX_PARAMETER_BANDS], 143 FIXP_DBL H21im[MAX_PARAMETER_BANDS], FIXP_DBL H22re[MAX_PARAMETER_BANDS], 144 FIXP_DBL H22im[MAX_PARAMETER_BANDS], int ottBoxIndx, int parameterSetIndx, 145 int resBands); 146 147 /* static void SpatialDecCalculateM0(spatialDec* self,int ps); */ 148 static SACDEC_ERROR SpatialDecCalculateM1andM2_212( 149 spatialDec* self, int ps, const SPATIAL_BS_FRAME* frame); 150 151 /******************************************************************************* 152 Functionname: SpatialDecGetResidualIndex 153 ******************************************************************************* 154 155 Description: 156 157 Arguments: 158 159 Input: 160 161 Output: 162 163 *******************************************************************************/ 164 int SpatialDecGetResidualIndex(spatialDec* self, int row) { 165 return row2residual[self->treeConfig][row]; 166 } 167 168 /******************************************************************************* 169 Functionname: UpdateAlpha 170 ******************************************************************************* 171 172 Description: 173 174 Arguments: 175 176 Input: 177 178 Output: 179 180 *******************************************************************************/ 181 static void updateAlpha(spatialDec* self) { 182 int nChIn = self->numInputChannels; 183 int ch; 184 185 for (ch = 0; ch < nChIn; ch++) { 186 FIXP_DBL alpha = /* FL2FXCONST_DBL(1.0f) */ (FIXP_DBL)MAXVAL_DBL; 187 188 self->arbdmxAlphaPrev__FDK[ch] = self->arbdmxAlpha__FDK[ch]; 189 190 self->arbdmxAlpha__FDK[ch] = alpha; 191 } 192 } 193 194 /******************************************************************************* 195 Functionname: SpatialDecCalculateM1andM2 196 ******************************************************************************* 197 Description: 198 Arguments: 199 *******************************************************************************/ 200 SACDEC_ERROR SpatialDecCalculateM1andM2(spatialDec* self, int ps, 201 const SPATIAL_BS_FRAME* frame) { 202 SACDEC_ERROR err = MPS_OK; 203 204 if ((self->arbitraryDownmix != 0) && (ps == 0)) { 205 updateAlpha(self); 206 } 207 208 self->pActivM2ParamBands = NULL; 209 210 switch (self->upmixType) { 211 case UPMIXTYPE_BYPASS: 212 case UPMIXTYPE_NORMAL: 213 switch (self->treeConfig) { 214 case TREE_212: 215 err = SpatialDecCalculateM1andM2_212(self, ps, frame); 216 break; 217 default: 218 err = MPS_WRONG_TREECONFIG; 219 }; 220 break; 221 222 default: 223 err = MPS_WRONG_TREECONFIG; 224 } 225 226 if (err != MPS_OK) { 227 goto bail; 228 } 229 230 bail: 231 return err; 232 } 233 234 /******************************************************************************* 235 Functionname: SpatialDecCalculateM1andM2_212 236 ******************************************************************************* 237 238 Description: 239 240 Arguments: 241 242 Return: 243 244 *******************************************************************************/ 245 static SACDEC_ERROR SpatialDecCalculateM1andM2_212( 246 spatialDec* self, int ps, const SPATIAL_BS_FRAME* frame) { 247 SACDEC_ERROR err = MPS_OK; 248 int pb; 249 250 FIXP_DBL H11re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; 251 FIXP_DBL H12re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; 252 FIXP_DBL H21re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; 253 FIXP_DBL H22re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; 254 FIXP_DBL H11im[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; 255 FIXP_DBL H21im[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; 256 257 INT phaseCoding = self->phaseCoding; 258 259 switch (phaseCoding) { 260 case 1: 261 /* phase coding: yes; residuals: no */ 262 param2UMX_PS_IPD_OPD__FDK(self, frame, H11re, H12re, H21re, H22re, NULL, 263 NULL, 0, ps, self->residualBands[0]); 264 break; 265 case 3: 266 /* phase coding: yes; residuals: yes */ 267 param2UMX_Prediction__FDK(self, H11re, H11im, H12re, NULL, H21re, H21im, 268 H22re, NULL, 0, ps, self->residualBands[0]); 269 break; 270 default: 271 if (self->residualCoding) { 272 /* phase coding: no; residuals: yes */ 273 param2UMX_Prediction__FDK(self, H11re, NULL, H12re, NULL, H21re, NULL, 274 H22re, NULL, 0, ps, self->residualBands[0]); 275 } else { 276 /* phase coding: no; residuals: no */ 277 param2UMX_PS__FDK(self, H11re, H12re, H21re, H22re, NULL, NULL, 0, ps, 278 0); 279 } 280 break; 281 } 282 283 for (pb = 0; pb < self->numParameterBands; pb++) { 284 self->M2Real__FDK[0][0][pb] = (H11re[pb]); 285 self->M2Real__FDK[0][1][pb] = (H12re[pb]); 286 287 self->M2Real__FDK[1][0][pb] = (H21re[pb]); 288 self->M2Real__FDK[1][1][pb] = (H22re[pb]); 289 } 290 if (phaseCoding == 3) { 291 for (pb = 0; pb < self->numParameterBands; pb++) { 292 self->M2Imag__FDK[0][0][pb] = (H11im[pb]); 293 self->M2Imag__FDK[1][0][pb] = (H21im[pb]); 294 self->M2Imag__FDK[0][1][pb] = (FIXP_DBL)0; // H12im[pb]; 295 self->M2Imag__FDK[1][1][pb] = (FIXP_DBL)0; // H22im[pb]; 296 } 297 } 298 299 if (self->phaseCoding == 1) { 300 SpatialDecSmoothOPD( 301 self, frame, 302 ps); /* INPUT: PhaseLeft, PhaseRight, (opdLeftState, opdRightState) */ 303 } 304 305 return err; 306 } 307 308 /******************************************************************************* 309 Functionname: param2UMX_PS_Core 310 ******************************************************************************* 311 312 Description: 313 314 Arguments: 315 316 Return: 317 318 *******************************************************************************/ 319 static void param2UMX_PS_Core__FDK( 320 const SCHAR cld[MAX_PARAMETER_BANDS], const SCHAR icc[MAX_PARAMETER_BANDS], 321 const int numOttBands, const int resBands, 322 FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS], 323 FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS], 324 FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS]) { 325 int band; 326 327 if ((c_l != NULL) && (c_r != NULL)) { 328 for (band = 0; band < numOttBands; band++) { 329 SpatialDequantGetCLDValues(cld[band], &c_l[band], &c_r[band]); 330 } 331 } 332 333 band = 0; 334 FDK_ASSERT(resBands == 0); 335 for (; band < numOttBands; band++) { 336 /* compute mixing variables: */ 337 const int idx1 = cld[band]; 338 const int idx2 = icc[band]; 339 H11[band] = FX_CFG2FX_DBL(H11_nc[idx1][idx2]); 340 H21[band] = FX_CFG2FX_DBL(H11_nc[30 - idx1][idx2]); 341 H12[band] = FX_CFG2FX_DBL(H12_nc[idx1][idx2]); 342 H22[band] = FX_CFG2FX_DBL(-H12_nc[30 - idx1][idx2]); 343 } 344 } 345 346 /******************************************************************************* 347 Functionname: param2UMX_PS 348 ******************************************************************************* 349 350 Description: 351 352 Arguments: 353 354 Return: 355 356 *******************************************************************************/ 357 static void param2UMX_PS__FDK(spatialDec* self, 358 FIXP_DBL H11[MAX_PARAMETER_BANDS], 359 FIXP_DBL H12[MAX_PARAMETER_BANDS], 360 FIXP_DBL H21[MAX_PARAMETER_BANDS], 361 FIXP_DBL H22[MAX_PARAMETER_BANDS], 362 FIXP_DBL c_l[MAX_PARAMETER_BANDS], 363 FIXP_DBL c_r[MAX_PARAMETER_BANDS], int ottBoxIndx, 364 int parameterSetIndx, int residualBands) { 365 int band; 366 param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx], 367 self->ottICC__FDK[ottBoxIndx][parameterSetIndx], 368 self->numOttBands[ottBoxIndx], residualBands, H11, H12, 369 H21, H22, c_l, c_r); 370 371 for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands; 372 band++) { 373 H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f); 374 } 375 } 376 377 #define N_CLD (31) 378 #define N_IPD (16) 379 380 static const FIXP_DBL sinIpd_tab[N_IPD] = { 381 FIXP_DBL(0x00000000), FIXP_DBL(0x30fbc54e), FIXP_DBL(0x5a827999), 382 FIXP_DBL(0x7641af3d), FIXP_DBL(0x7fffffff), FIXP_DBL(0x7641af3d), 383 FIXP_DBL(0x5a82799a), FIXP_DBL(0x30fbc54d), FIXP_DBL(0xffffffff), 384 FIXP_DBL(0xcf043ab3), FIXP_DBL(0xa57d8666), FIXP_DBL(0x89be50c3), 385 FIXP_DBL(0x80000000), FIXP_DBL(0x89be50c3), FIXP_DBL(0xa57d8666), 386 FIXP_DBL(0xcf043ab2), 387 }; 388 389 /* cosIpd[i] = sinIpd[(i+4)&15] */ 390 #define SIN_IPD(a) (sinIpd_tab[(a)]) 391 #define COS_IPD(a) (sinIpd_tab[((a) + 4) & 15]) //(cosIpd_tab[(a)]) 392 393 static const FIXP_SGL sqrt_one_minus_ICC2[8] = { 394 FL2FXCONST_SGL(0.0f), 395 FL2FXCONST_SGL(0.349329357483736f), 396 FL2FXCONST_SGL(0.540755219669676f), 397 FL2FXCONST_SGL(0.799309172723546f), 398 FL2FXCONST_SGL(0.929968187843004f), 399 FX_DBL2FXCONST_SGL(MAXVAL_DBL), 400 FL2FXCONST_SGL(0.80813303360276f), 401 FL2FXCONST_SGL(0.141067359796659f), 402 }; 403 404 /* exponent of sqrt(CLD) */ 405 static const SCHAR sqrt_CLD_e[N_CLD] = { 406 -24, -7, -6, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 1, 407 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 25}; 408 409 static const FIXP_DBL sqrt_CLD_m[N_CLD] = { 410 FL2FXCONST_DBL(0.530542153566195f), 411 FL2FXCONST_DBL(0.719796896243647f), 412 FL2FXCONST_DBL(0.64f), 413 FL2FXCONST_DBL(0.569049411212455f), 414 FL2FXCONST_DBL(0.505964425626941f), 415 FL2FXCONST_DBL(0.899746120304559f), 416 FL2FXCONST_DBL(0.635462587779425f), 417 FL2FXCONST_DBL(0.897614763441571f), 418 FL2FXCONST_DBL(0.633957276984445f), 419 FL2FXCONST_DBL(0.895488455427336f), 420 FL2FXCONST_DBL(0.632455532033676f), 421 FL2FXCONST_DBL(0.796214341106995f), 422 FL2FXCONST_DBL(0.501187233627272f), 423 FL2FXCONST_DBL(0.630957344480193f), 424 FL2FXCONST_DBL(0.794328234724281f), 425 FL2FXCONST_DBL(0.5f), 426 FL2FXCONST_DBL(0.629462705897084f), 427 FL2FXCONST_DBL(0.792446596230557f), 428 FL2FXCONST_DBL(0.99763115748444f), 429 FL2FXCONST_DBL(0.627971607877395f), 430 FL2FXCONST_DBL(0.790569415042095f), 431 FL2FXCONST_DBL(0.558354490188704f), 432 FL2FXCONST_DBL(0.788696680600242f), 433 FL2FXCONST_DBL(0.557031836333591f), 434 FL2FXCONST_DBL(0.786828382371355f), 435 FL2FXCONST_DBL(0.555712315637163f), 436 FL2FXCONST_DBL(0.988211768802619f), 437 FL2FXCONST_DBL(0.87865832060992f), 438 FL2FXCONST_DBL(0.78125f), 439 FL2FXCONST_DBL(0.694640394546454f), 440 FL2FXCONST_DBL(0.942432183077448f), 441 }; 442 443 static const FIXP_DBL CLD_m[N_CLD] = { 444 FL2FXCONST_DBL(0.281474976710656f), 445 FL2FXCONST_DBL(0.518107571841987f), 446 FL2FXCONST_DBL(0.4096f), 447 FL2FXCONST_DBL(0.323817232401242f), 448 FL2FXCONST_DBL(0.256f), 449 FL2FXCONST_DBL(0.809543081003105f), 450 FL2FXCONST_DBL(0.403812700467324f), 451 FL2FXCONST_DBL(0.805712263548267f), 452 FL2FXCONST_DBL(0.401901829041533f), 453 FL2FXCONST_DBL(0.801899573803636f), 454 FL2FXCONST_DBL(0.4f), 455 FL2FXCONST_DBL(0.633957276984445f), 456 FL2FXCONST_DBL(0.251188643150958f), 457 FL2FXCONST_DBL(0.398107170553497f), 458 FL2FXCONST_DBL(0.630957344480193f), 459 FL2FXCONST_DBL(0.25f), 460 FL2FXCONST_DBL(0.396223298115278f), 461 FL2FXCONST_DBL(0.627971607877395f), 462 FL2FXCONST_DBL(0.995267926383743f), 463 FL2FXCONST_DBL(0.394348340300121f), 464 FL2FXCONST_DBL(0.625f), 465 FL2FXCONST_DBL(0.311759736713887f), 466 FL2FXCONST_DBL(0.62204245398984f), 467 FL2FXCONST_DBL(0.310284466689172f), 468 FL2FXCONST_DBL(0.619098903305123f), 469 FL2FXCONST_DBL(0.308816177750818f), 470 FL2FXCONST_DBL(0.9765625f), 471 FL2FXCONST_DBL(0.772040444377046f), 472 FL2FXCONST_DBL(0.6103515625f), 473 FL2FXCONST_DBL(0.482525277735654f), 474 FL2FXCONST_DBL(0.888178419700125), 475 }; 476 477 static FIXP_DBL dequantIPD_CLD_ICC_splitAngle__FDK_Function(INT ipdIdx, 478 INT cldIdx, 479 INT iccIdx) { 480 FIXP_DBL cld; 481 SpatialDequantGetCLD2Values(cldIdx, &cld); 482 483 /*const FIXP_DBL one_m = (FIXP_DBL)MAXVAL_DBL; 484 const int one_e = 0;*/ 485 const FIXP_DBL one_m = FL2FXCONST_DBL(0.5f); 486 const int one_e = 1; 487 /* iidLin = sqrt(cld); */ 488 FIXP_DBL iidLin_m = sqrt_CLD_m[cldIdx]; 489 int iidLin_e = sqrt_CLD_e[cldIdx]; 490 /* iidLin2 = cld; */ 491 FIXP_DBL iidLin2_m = CLD_m[cldIdx]; 492 int iidLin2_e = sqrt_CLD_e[cldIdx] << 1; 493 /* iidLin21 = iidLin2 + 1.0f; */ 494 int iidLin21_e; 495 FIXP_DBL iidLin21_m = 496 fAddNorm(iidLin2_m, iidLin2_e, one_m, one_e, &iidLin21_e); 497 /* iidIcc2 = iidLin * icc * 2.0f; */ 498 FIXP_CFG icc = dequantICC__FDK[iccIdx]; 499 FIXP_DBL temp1_m, temp1c_m; 500 int temp1_e, temp1c_e; 501 temp1_m = fMult(iidLin_m, icc); 502 temp1_e = iidLin_e + 1; 503 504 FIXP_DBL cosIpd, sinIpd; 505 cosIpd = COS_IPD(ipdIdx); 506 sinIpd = SIN_IPD(ipdIdx); 507 508 temp1c_m = fMult(temp1_m, cosIpd); 509 temp1c_e = temp1_e; //+cosIpd_e; 510 511 int temp2_e, temp3_e, inv_temp3_e, ratio_e; 512 FIXP_DBL temp2_m = 513 fAddNorm(iidLin21_m, iidLin21_e, temp1c_m, temp1c_e, &temp2_e); 514 FIXP_DBL temp3_m = 515 fAddNorm(iidLin21_m, iidLin21_e, temp1_m, temp1_e, &temp3_e); 516 /* calculate 1/temp3 needed later */ 517 inv_temp3_e = temp3_e; 518 FIXP_DBL inv_temp3_m = invFixp(temp3_m, &inv_temp3_e); 519 FIXP_DBL ratio_m = 520 fAddNorm(fMult(inv_temp3_m, temp2_m), (inv_temp3_e + temp2_e), 521 FL2FXCONST_DBL(1e-9f), 0, &ratio_e); 522 523 int weight2_e, tempb_atan2_e; 524 FIXP_DBL weight2_m = 525 fPow(ratio_m, ratio_e, FL2FXCONST_DBL(0.5f), -1, &weight2_e); 526 /* atan2(w2*sinIpd, w1*iidLin + w2*cosIpd) = atan2(w2*sinIpd, (2 - w2)*iidLin 527 * + w2*cosIpd) = atan2(w2*sinIpd, 2*iidLin + w2*(cosIpd - iidLin)); */ 528 /* tmpa_atan2 = w2*sinIpd; tmpb_atan2 = 2*iidLin + w2*(cosIpd - iidLin); */ 529 FIXP_DBL tempb_atan2_m = iidLin_m; 530 tempb_atan2_e = iidLin_e + 1; 531 int add_tmp1_e = 0; 532 FIXP_DBL add_tmp1_m = fAddNorm(cosIpd, 0, -iidLin_m, iidLin_e, &add_tmp1_e); 533 FIXP_DBL add_tmp2_m = fMult(add_tmp1_m, weight2_m); 534 int add_tmp2_e = add_tmp1_e + weight2_e; 535 tempb_atan2_m = fAddNorm(tempb_atan2_m, tempb_atan2_e, add_tmp2_m, add_tmp2_e, 536 &tempb_atan2_e); 537 538 FIXP_DBL tempa_atan2_m = fMult(weight2_m, sinIpd); 539 int tempa_atan2_e = weight2_e; // + sinIpd_e; 540 541 if (tempa_atan2_e > tempb_atan2_e) { 542 tempb_atan2_m = (tempb_atan2_m >> (tempa_atan2_e - tempb_atan2_e)); 543 tempb_atan2_e = tempa_atan2_e; 544 } else if (tempb_atan2_e > tempa_atan2_e) { 545 tempa_atan2_m = (tempa_atan2_m >> (tempb_atan2_e - tempa_atan2_e)); 546 } 547 548 return fixp_atan2(tempa_atan2_m, tempb_atan2_m); 549 } 550 551 static void calculateOpd(spatialDec* self, INT ottBoxIndx, INT parameterSetIndx, 552 FIXP_DBL opd[MAX_PARAMETER_BANDS]) { 553 INT band; 554 555 for (band = 0; band < self->numOttBandsIPD; band++) { 556 INT idxCld = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band]; 557 INT idxIpd = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band]; 558 INT idxIcc = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band]; 559 FIXP_DBL cld, ipd; 560 561 ipd = FX_CFG2FX_DBL(dequantIPD__FDK[idxIpd]); 562 563 SpatialDequantGetCLD2Values(idxCld, &cld); 564 565 /* ipd(idxIpd==8) == PI */ 566 if ((cld == FL2FXCONST_DBL(0.0f)) && (idxIpd == 8)) { 567 opd[2 * band] = FL2FXCONST_DBL(0.0f); 568 } else { 569 opd[2 * band] = (dequantIPD_CLD_ICC_splitAngle__FDK_Function( 570 idxIpd, idxCld, idxIcc) >> 571 (IPD_SCALE - AT2O_SF)); 572 } 573 opd[2 * band + 1] = opd[2 * band] - ipd; 574 } 575 } 576 577 /* wrap phase in rad to the range of 0 <= x < 2*pi */ 578 static FIXP_DBL wrapPhase(FIXP_DBL phase) { 579 while (phase < (FIXP_DBL)0) phase += PIx2__IPD; 580 while (phase >= PIx2__IPD) phase -= PIx2__IPD; 581 FDK_ASSERT((phase >= (FIXP_DBL)0) && (phase < PIx2__IPD)); 582 583 return phase; 584 } 585 586 /******************************************************************************* 587 Functionname: param2UMX_PS_IPD 588 ******************************************************************************* 589 590 Description: 591 592 Arguments: 593 594 Return: 595 596 *******************************************************************************/ 597 static void param2UMX_PS_IPD_OPD__FDK( 598 spatialDec* self, const SPATIAL_BS_FRAME* frame, 599 FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS], 600 FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS], 601 FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS], 602 int ottBoxIndx, int parameterSetIndx, int residualBands) { 603 INT band; 604 FIXP_DBL opd[2 * MAX_PARAMETER_BANDS]; 605 INT numOttBands = self->numOttBands[ottBoxIndx]; 606 INT numIpdBands; 607 608 numIpdBands = frame->phaseMode ? self->numOttBandsIPD : 0; 609 610 FDK_ASSERT(self->residualCoding == 0); 611 612 param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx], 613 self->ottICC__FDK[ottBoxIndx][parameterSetIndx], 614 self->numOttBands[ottBoxIndx], residualBands, H11, H12, 615 H21, H22, c_l, c_r); 616 617 for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands; 618 band++) { 619 H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f); 620 } 621 622 if (frame->phaseMode) { 623 calculateOpd(self, ottBoxIndx, parameterSetIndx, opd); 624 625 for (band = 0; band < numIpdBands; band++) { 626 self->PhaseLeft__FDK[band] = wrapPhase(opd[2 * band]); 627 self->PhaseRight__FDK[band] = wrapPhase(opd[2 * band + 1]); 628 } 629 } 630 631 for (band = numIpdBands; band < numOttBands; band++) { 632 self->PhaseLeft__FDK[band] = FL2FXCONST_DBL(0.0f); 633 self->PhaseRight__FDK[band] = FL2FXCONST_DBL(0.0f); 634 } 635 } 636 637 FDK_INLINE void param2UMX_Prediction_Core__FDK( 638 FIXP_DBL* H11re, FIXP_DBL* H11im, FIXP_DBL* H12re, FIXP_DBL* H12im, 639 FIXP_DBL* H21re, FIXP_DBL* H21im, FIXP_DBL* H22re, FIXP_DBL* H22im, 640 int cldIdx, int iccIdx, int ipdIdx, int band, int numOttBandsIPD, 641 int resBands) { 642 #define MAX_WEIGHT (1.2f) 643 FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */ 644 645 if ((band < numOttBandsIPD) && (cldIdx == 15) && (iccIdx == 0) && 646 (ipdIdx == 8)) { 647 const FIXP_DBL gain = 648 FL2FXCONST_DBL(0.5f / MAX_WEIGHT) >> SCALE_PARAM_M2_212_PRED; 649 650 *H11re = gain; 651 if (band < resBands) { 652 *H21re = gain; 653 *H12re = gain; 654 *H22re = -gain; 655 } else { 656 *H21re = -gain; 657 *H12re = (FIXP_DBL)0; 658 *H22re = (FIXP_DBL)0; 659 } 660 if ((H11im != NULL) && 661 (H21im != NULL) /*&& (H12im!=NULL) && (H22im!=NULL)*/) { 662 *H11im = (FIXP_DBL)0; 663 *H21im = (FIXP_DBL)0; 664 /* *H12im = (FIXP_DBL)0; */ 665 /* *H22im = (FIXP_DBL)0; */ 666 } 667 } else { 668 const FIXP_DBL one_m = (FIXP_DBL)MAXVAL_DBL; 669 const int one_e = 0; 670 /* iidLin = sqrt(cld); */ 671 FIXP_DBL iidLin_m = sqrt_CLD_m[cldIdx]; 672 int iidLin_e = sqrt_CLD_e[cldIdx]; 673 /* iidLin2 = cld; */ 674 FIXP_DBL iidLin2_m = CLD_m[cldIdx]; 675 int iidLin2_e = sqrt_CLD_e[cldIdx] << 1; 676 /* iidLin21 = iidLin2 + 1.0f; */ 677 int iidLin21_e; 678 FIXP_DBL iidLin21_m = 679 fAddNorm(iidLin2_m, iidLin2_e, one_m, one_e, &iidLin21_e); 680 /* iidIcc2 = iidLin * icc * 2.0f; */ 681 FIXP_CFG icc = dequantICC__FDK[iccIdx]; 682 int iidIcc2_e = iidLin_e + 1; 683 FIXP_DBL iidIcc2_m = fMult(iidLin_m, icc); 684 FIXP_DBL temp_m, sqrt_temp_m, inv_temp_m, weight_m; 685 int temp_e, sqrt_temp_e, inv_temp_e, weight_e, scale; 686 FIXP_DBL cosIpd, sinIpd; 687 688 cosIpd = COS_IPD((band < numOttBandsIPD) ? ipdIdx : 0); 689 sinIpd = SIN_IPD((band < numOttBandsIPD) ? ipdIdx : 0); 690 691 /* temp = iidLin21 + iidIcc2 * cosIpd; */ 692 temp_m = fAddNorm(iidLin21_m, iidLin21_e, fMult(iidIcc2_m, cosIpd), 693 iidIcc2_e, &temp_e); 694 695 /* calculate 1/temp needed later */ 696 inv_temp_e = temp_e; 697 inv_temp_m = invFixp(temp_m, &inv_temp_e); 698 699 /* 1/weight = sqrt(temp) * 1/sqrt(iidLin21) */ 700 if (temp_e & 1) { 701 sqrt_temp_m = temp_m >> 1; 702 sqrt_temp_e = (temp_e + 1) >> 1; 703 } else { 704 sqrt_temp_m = temp_m; 705 sqrt_temp_e = temp_e >> 1; 706 } 707 sqrt_temp_m = sqrtFixp(sqrt_temp_m); 708 if (iidLin21_e & 1) { 709 iidLin21_e += 1; 710 iidLin21_m >>= 1; 711 } 712 /* weight_[m,e] is actually 1/weight in the next few lines */ 713 weight_m = invSqrtNorm2(iidLin21_m, &weight_e); 714 weight_e -= iidLin21_e >> 1; 715 weight_m = fMult(sqrt_temp_m, weight_m); 716 weight_e += sqrt_temp_e; 717 scale = fNorm(weight_m); 718 weight_m = scaleValue(weight_m, scale); 719 weight_e -= scale; 720 /* weight = 0.5 * max(1/weight, 1/maxWeight) */ 721 if ((weight_e < 0) || 722 ((weight_e == 0) && (weight_m < FL2FXCONST_DBL(1.f / MAX_WEIGHT)))) { 723 weight_m = FL2FXCONST_DBL(1.f / MAX_WEIGHT); 724 weight_e = 0; 725 } 726 weight_e -= 1; 727 728 { 729 FIXP_DBL alphaRe_m, alphaIm_m, accu_m; 730 int alphaRe_e, alphaIm_e, accu_e; 731 /* alphaRe = (1.0f - iidLin2) / temp; */ 732 alphaRe_m = fAddNorm(one_m, one_e, -iidLin2_m, iidLin2_e, &alphaRe_e); 733 alphaRe_m = fMult(alphaRe_m, inv_temp_m); 734 alphaRe_e += inv_temp_e; 735 736 /* H11re = weight - alphaRe * weight; */ 737 /* H21re = weight + alphaRe * weight; */ 738 accu_m = fMult(alphaRe_m, weight_m); 739 accu_e = alphaRe_e + weight_e; 740 { 741 int accu2_e; 742 FIXP_DBL accu2_m; 743 accu2_m = fAddNorm(weight_m, weight_e, -accu_m, accu_e, &accu2_e); 744 *H11re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED); 745 accu2_m = fAddNorm(weight_m, weight_e, accu_m, accu_e, &accu2_e); 746 *H21re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED); 747 } 748 749 if ((H11im != NULL) && 750 (H21im != NULL) /*&& (H12im != NULL) && (H22im != NULL)*/) { 751 /* alphaIm = -iidIcc2 * sinIpd / temp; */ 752 alphaIm_m = fMult(-iidIcc2_m, sinIpd); 753 alphaIm_m = fMult(alphaIm_m, inv_temp_m); 754 alphaIm_e = iidIcc2_e + inv_temp_e; 755 /* H11im = -alphaIm * weight; */ 756 /* H21im = alphaIm * weight; */ 757 accu_m = fMult(alphaIm_m, weight_m); 758 accu_e = alphaIm_e + weight_e; 759 accu_m = scaleValue(accu_m, accu_e - SCALE_PARAM_M2_212_PRED); 760 *H11im = -accu_m; 761 *H21im = accu_m; 762 763 /* *H12im = (FIXP_DBL)0; */ 764 /* *H22im = (FIXP_DBL)0; */ 765 } 766 } 767 if (band < resBands) { 768 FIXP_DBL weight = 769 scaleValue(weight_m, weight_e - SCALE_PARAM_M2_212_PRED); 770 *H12re = weight; 771 *H22re = -weight; 772 } else { 773 /* beta = 2.0f * iidLin * (float) sqrt(1.0f - icc * icc) * weight / temp; 774 */ 775 FIXP_DBL beta_m; 776 int beta_e; 777 beta_m = FX_SGL2FX_DBL(sqrt_one_minus_ICC2[iccIdx]); 778 beta_e = 1; /* multipication with 2.0f */ 779 beta_m = fMult(beta_m, weight_m); 780 beta_e += weight_e; 781 beta_m = fMult(beta_m, iidLin_m); 782 beta_e += iidLin_e; 783 beta_m = fMult(beta_m, inv_temp_m); 784 beta_e += inv_temp_e; 785 786 beta_m = scaleValue(beta_m, beta_e - SCALE_PARAM_M2_212_PRED); 787 *H12re = beta_m; 788 *H22re = -beta_m; 789 } 790 } 791 } 792 793 static void param2UMX_Prediction__FDK(spatialDec* self, FIXP_DBL* H11re, 794 FIXP_DBL* H11im, FIXP_DBL* H12re, 795 FIXP_DBL* H12im, FIXP_DBL* H21re, 796 FIXP_DBL* H21im, FIXP_DBL* H22re, 797 FIXP_DBL* H22im, int ottBoxIndx, 798 int parameterSetIndx, int resBands) { 799 int band; 800 FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */ 801 802 for (band = 0; band < self->numParameterBands; band++) { 803 int cldIdx = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band]; 804 int iccIdx = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band]; 805 int ipdIdx = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band]; 806 807 param2UMX_Prediction_Core__FDK( 808 &H11re[band], (H11im ? &H11im[band] : NULL), &H12re[band], NULL, 809 &H21re[band], (H21im ? &H21im[band] : NULL), &H22re[band], NULL, cldIdx, 810 iccIdx, ipdIdx, band, self->numOttBandsIPD, resBands); 811 } 812 } 813 814 /******************************************************************************* 815 Functionname: initM1andM2 816 ******************************************************************************* 817 818 Description: 819 820 Arguments: 821 822 Return: 823 824 *******************************************************************************/ 825 826 SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag, 827 int configChanged) { 828 SACDEC_ERROR err = MPS_OK; 829 830 self->bOverwriteM1M2prev = (configChanged && !initStatesFlag) ? 1 : 0; 831 832 { self->numM2rows = self->numOutputChannels; } 833 834 if (initStatesFlag) { 835 int i, j, k; 836 837 for (i = 0; i < self->numM2rows; i++) { 838 for (j = 0; j < self->numVChannels; j++) { 839 for (k = 0; k < MAX_PARAMETER_BANDS; k++) { 840 self->M2Real__FDK[i][j][k] = FL2FXCONST_DBL(0); 841 self->M2RealPrev__FDK[i][j][k] = FL2FXCONST_DBL(0); 842 } 843 } 844 } 845 } 846 847 return err; 848 } 849