1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2019 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 void calculateOpd(spatialDec* self, INT ottBoxIndx, INT parameterSetIndx, 478 FIXP_DBL opd[MAX_PARAMETER_BANDS]) { 479 INT band; 480 481 for (band = 0; band < self->numOttBandsIPD; band++) { 482 INT idxCld = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band]; 483 INT idxIpd = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band]; 484 INT idxIcc = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band]; 485 FIXP_DBL cld, ipd; 486 487 ipd = FX_CFG2FX_DBL(dequantIPD__FDK[idxIpd]); 488 489 SpatialDequantGetCLD2Values(idxCld, &cld); 490 491 /* ipd(idxIpd==8) == PI */ 492 if (((cld == FL2FXCONST_DBL(0.0f)) && (idxIpd == 8)) || (idxIpd == 0)) { 493 opd[2 * band] = FL2FXCONST_DBL(0.0f); 494 } else { 495 FDK_ASSERT(idxIpd > 0); 496 opd[2 * band] = 497 dequantIPD_CLD_ICC_splitAngle__FDK[idxIpd - 1][idxCld][idxIcc]; 498 } 499 opd[2 * band + 1] = opd[2 * band] - ipd; 500 } 501 } 502 503 /* wrap phase in rad to the range of 0 <= x < 2*pi */ 504 static FIXP_DBL wrapPhase(FIXP_DBL phase) { 505 while (phase < (FIXP_DBL)0) phase += PIx2__IPD; 506 while (phase >= PIx2__IPD) phase -= PIx2__IPD; 507 FDK_ASSERT((phase >= (FIXP_DBL)0) && (phase < PIx2__IPD)); 508 509 return phase; 510 } 511 512 /******************************************************************************* 513 Functionname: param2UMX_PS_IPD 514 ******************************************************************************* 515 516 Description: 517 518 Arguments: 519 520 Return: 521 522 *******************************************************************************/ 523 static void param2UMX_PS_IPD_OPD__FDK( 524 spatialDec* self, const SPATIAL_BS_FRAME* frame, 525 FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS], 526 FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS], 527 FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS], 528 int ottBoxIndx, int parameterSetIndx, int residualBands) { 529 INT band; 530 FIXP_DBL opd[2 * MAX_PARAMETER_BANDS]; 531 INT numOttBands = self->numOttBands[ottBoxIndx]; 532 INT numIpdBands; 533 534 numIpdBands = frame->phaseMode ? self->numOttBandsIPD : 0; 535 536 FDK_ASSERT(self->residualCoding == 0); 537 538 param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx], 539 self->ottICC__FDK[ottBoxIndx][parameterSetIndx], 540 self->numOttBands[ottBoxIndx], residualBands, H11, H12, 541 H21, H22, c_l, c_r); 542 543 for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands; 544 band++) { 545 H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f); 546 } 547 548 if (frame->phaseMode) { 549 calculateOpd(self, ottBoxIndx, parameterSetIndx, opd); 550 551 for (band = 0; band < numIpdBands; band++) { 552 self->PhaseLeft__FDK[band] = wrapPhase(opd[2 * band]); 553 self->PhaseRight__FDK[band] = wrapPhase(opd[2 * band + 1]); 554 } 555 } 556 557 for (band = numIpdBands; band < numOttBands; band++) { 558 self->PhaseLeft__FDK[band] = FL2FXCONST_DBL(0.0f); 559 self->PhaseRight__FDK[band] = FL2FXCONST_DBL(0.0f); 560 } 561 } 562 563 FDK_INLINE void param2UMX_Prediction_Core__FDK( 564 FIXP_DBL* H11re, FIXP_DBL* H11im, FIXP_DBL* H12re, FIXP_DBL* H12im, 565 FIXP_DBL* H21re, FIXP_DBL* H21im, FIXP_DBL* H22re, FIXP_DBL* H22im, 566 int cldIdx, int iccIdx, int ipdIdx, int band, int numOttBandsIPD, 567 int resBands) { 568 #define MAX_WEIGHT (1.2f) 569 FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */ 570 571 if ((band < numOttBandsIPD) && (cldIdx == 15) && (iccIdx == 0) && 572 (ipdIdx == 8)) { 573 const FIXP_DBL gain = 574 FL2FXCONST_DBL(0.5f / MAX_WEIGHT) >> SCALE_PARAM_M2_212_PRED; 575 576 *H11re = gain; 577 if (band < resBands) { 578 *H21re = gain; 579 *H12re = gain; 580 *H22re = -gain; 581 } else { 582 *H21re = -gain; 583 *H12re = (FIXP_DBL)0; 584 *H22re = (FIXP_DBL)0; 585 } 586 if ((H11im != NULL) && 587 (H21im != NULL) /*&& (H12im!=NULL) && (H22im!=NULL)*/) { 588 *H11im = (FIXP_DBL)0; 589 *H21im = (FIXP_DBL)0; 590 /* *H12im = (FIXP_DBL)0; */ 591 /* *H22im = (FIXP_DBL)0; */ 592 } 593 } else { 594 const FIXP_DBL one_m = (FIXP_DBL)MAXVAL_DBL; 595 const int one_e = 0; 596 /* iidLin = sqrt(cld); */ 597 FIXP_DBL iidLin_m = sqrt_CLD_m[cldIdx]; 598 int iidLin_e = sqrt_CLD_e[cldIdx]; 599 /* iidLin2 = cld; */ 600 FIXP_DBL iidLin2_m = CLD_m[cldIdx]; 601 int iidLin2_e = sqrt_CLD_e[cldIdx] << 1; 602 /* iidLin21 = iidLin2 + 1.0f; */ 603 int iidLin21_e; 604 FIXP_DBL iidLin21_m = 605 fAddNorm(iidLin2_m, iidLin2_e, one_m, one_e, &iidLin21_e); 606 /* iidIcc2 = iidLin * icc * 2.0f; */ 607 FIXP_CFG icc = dequantICC__FDK[iccIdx]; 608 int iidIcc2_e = iidLin_e + 1; 609 FIXP_DBL iidIcc2_m = fMult(iidLin_m, icc); 610 FIXP_DBL temp_m, sqrt_temp_m, inv_temp_m, weight_m; 611 int temp_e, sqrt_temp_e, inv_temp_e, weight_e, scale; 612 FIXP_DBL cosIpd, sinIpd; 613 614 cosIpd = COS_IPD((band < numOttBandsIPD) ? ipdIdx : 0); 615 sinIpd = SIN_IPD((band < numOttBandsIPD) ? ipdIdx : 0); 616 617 /* temp = iidLin21 + iidIcc2 * cosIpd; */ 618 temp_m = fAddNorm(iidLin21_m, iidLin21_e, fMult(iidIcc2_m, cosIpd), 619 iidIcc2_e, &temp_e); 620 621 /* calculate 1/temp needed later */ 622 inv_temp_e = temp_e; 623 inv_temp_m = invFixp(temp_m, &inv_temp_e); 624 625 /* 1/weight = sqrt(temp) * 1/sqrt(iidLin21) */ 626 if (temp_e & 1) { 627 sqrt_temp_m = temp_m >> 1; 628 sqrt_temp_e = (temp_e + 1) >> 1; 629 } else { 630 sqrt_temp_m = temp_m; 631 sqrt_temp_e = temp_e >> 1; 632 } 633 sqrt_temp_m = sqrtFixp(sqrt_temp_m); 634 if (iidLin21_e & 1) { 635 iidLin21_e += 1; 636 iidLin21_m >>= 1; 637 } 638 /* weight_[m,e] is actually 1/weight in the next few lines */ 639 weight_m = invSqrtNorm2(iidLin21_m, &weight_e); 640 weight_e -= iidLin21_e >> 1; 641 weight_m = fMult(sqrt_temp_m, weight_m); 642 weight_e += sqrt_temp_e; 643 scale = fNorm(weight_m); 644 weight_m = scaleValue(weight_m, scale); 645 weight_e -= scale; 646 /* weight = 0.5 * max(1/weight, 1/maxWeight) */ 647 if ((weight_e < 0) || 648 ((weight_e == 0) && (weight_m < FL2FXCONST_DBL(1.f / MAX_WEIGHT)))) { 649 weight_m = FL2FXCONST_DBL(1.f / MAX_WEIGHT); 650 weight_e = 0; 651 } 652 weight_e -= 1; 653 654 { 655 FIXP_DBL alphaRe_m, alphaIm_m, accu_m; 656 int alphaRe_e, alphaIm_e, accu_e; 657 /* alphaRe = (1.0f - iidLin2) / temp; */ 658 alphaRe_m = fAddNorm(one_m, one_e, -iidLin2_m, iidLin2_e, &alphaRe_e); 659 alphaRe_m = fMult(alphaRe_m, inv_temp_m); 660 alphaRe_e += inv_temp_e; 661 662 /* H11re = weight - alphaRe * weight; */ 663 /* H21re = weight + alphaRe * weight; */ 664 accu_m = fMult(alphaRe_m, weight_m); 665 accu_e = alphaRe_e + weight_e; 666 { 667 int accu2_e; 668 FIXP_DBL accu2_m; 669 accu2_m = fAddNorm(weight_m, weight_e, -accu_m, accu_e, &accu2_e); 670 *H11re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED); 671 accu2_m = fAddNorm(weight_m, weight_e, accu_m, accu_e, &accu2_e); 672 *H21re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED); 673 } 674 675 if ((H11im != NULL) && 676 (H21im != NULL) /*&& (H12im != NULL) && (H22im != NULL)*/) { 677 /* alphaIm = -iidIcc2 * sinIpd / temp; */ 678 alphaIm_m = fMult(-iidIcc2_m, sinIpd); 679 alphaIm_m = fMult(alphaIm_m, inv_temp_m); 680 alphaIm_e = iidIcc2_e + inv_temp_e; 681 /* H11im = -alphaIm * weight; */ 682 /* H21im = alphaIm * weight; */ 683 accu_m = fMult(alphaIm_m, weight_m); 684 accu_e = alphaIm_e + weight_e; 685 accu_m = scaleValue(accu_m, accu_e - SCALE_PARAM_M2_212_PRED); 686 *H11im = -accu_m; 687 *H21im = accu_m; 688 689 /* *H12im = (FIXP_DBL)0; */ 690 /* *H22im = (FIXP_DBL)0; */ 691 } 692 } 693 if (band < resBands) { 694 FIXP_DBL weight = 695 scaleValue(weight_m, weight_e - SCALE_PARAM_M2_212_PRED); 696 *H12re = weight; 697 *H22re = -weight; 698 } else { 699 /* beta = 2.0f * iidLin * (float) sqrt(1.0f - icc * icc) * weight / temp; 700 */ 701 FIXP_DBL beta_m; 702 int beta_e; 703 beta_m = FX_SGL2FX_DBL(sqrt_one_minus_ICC2[iccIdx]); 704 beta_e = 1; /* multipication with 2.0f */ 705 beta_m = fMult(beta_m, weight_m); 706 beta_e += weight_e; 707 beta_m = fMult(beta_m, iidLin_m); 708 beta_e += iidLin_e; 709 beta_m = fMult(beta_m, inv_temp_m); 710 beta_e += inv_temp_e; 711 712 beta_m = scaleValue(beta_m, beta_e - SCALE_PARAM_M2_212_PRED); 713 *H12re = beta_m; 714 *H22re = -beta_m; 715 } 716 } 717 } 718 719 static void param2UMX_Prediction__FDK(spatialDec* self, FIXP_DBL* H11re, 720 FIXP_DBL* H11im, FIXP_DBL* H12re, 721 FIXP_DBL* H12im, FIXP_DBL* H21re, 722 FIXP_DBL* H21im, FIXP_DBL* H22re, 723 FIXP_DBL* H22im, int ottBoxIndx, 724 int parameterSetIndx, int resBands) { 725 int band; 726 FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */ 727 728 for (band = 0; band < self->numParameterBands; band++) { 729 int cldIdx = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band]; 730 int iccIdx = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band]; 731 int ipdIdx = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band]; 732 733 param2UMX_Prediction_Core__FDK( 734 &H11re[band], (H11im ? &H11im[band] : NULL), &H12re[band], NULL, 735 &H21re[band], (H21im ? &H21im[band] : NULL), &H22re[band], NULL, cldIdx, 736 iccIdx, ipdIdx, band, self->numOttBandsIPD, resBands); 737 } 738 } 739 740 /******************************************************************************* 741 Functionname: initM1andM2 742 ******************************************************************************* 743 744 Description: 745 746 Arguments: 747 748 Return: 749 750 *******************************************************************************/ 751 752 SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag, 753 int configChanged) { 754 SACDEC_ERROR err = MPS_OK; 755 756 self->bOverwriteM1M2prev = (configChanged && !initStatesFlag) ? 1 : 0; 757 758 { self->numM2rows = self->numOutputChannels; } 759 760 if (initStatesFlag) { 761 int i, j, k; 762 763 for (i = 0; i < self->numM2rows; i++) { 764 for (j = 0; j < self->numVChannels; j++) { 765 for (k = 0; k < MAX_PARAMETER_BANDS; k++) { 766 self->M2Real__FDK[i][j][k] = FL2FXCONST_DBL(0); 767 self->M2RealPrev__FDK[i][j][k] = FL2FXCONST_DBL(0); 768 } 769 } 770 } 771 } 772 773 return err; 774 } 775