Home | History | Annotate | Download | only in src
      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