• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung 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@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 *******************************************************************************/
SpatialDecGetResidualIndex(spatialDec * self,int row)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 *******************************************************************************/
updateAlpha(spatialDec * self)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 *******************************************************************************/
SpatialDecCalculateM1andM2(spatialDec * self,int ps,const SPATIAL_BS_FRAME * frame)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 *******************************************************************************/
SpatialDecCalculateM1andM2_212(spatialDec * self,int ps,const SPATIAL_BS_FRAME * frame)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 *******************************************************************************/
param2UMX_PS_Core__FDK(const SCHAR cld[MAX_PARAMETER_BANDS],const SCHAR icc[MAX_PARAMETER_BANDS],const int numOttBands,const int resBands,FIXP_DBL H11[MAX_PARAMETER_BANDS],FIXP_DBL H12[MAX_PARAMETER_BANDS],FIXP_DBL H21[MAX_PARAMETER_BANDS],FIXP_DBL H22[MAX_PARAMETER_BANDS],FIXP_DBL c_l[MAX_PARAMETER_BANDS],FIXP_DBL c_r[MAX_PARAMETER_BANDS])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 *******************************************************************************/
param2UMX_PS__FDK(spatialDec * self,FIXP_DBL H11[MAX_PARAMETER_BANDS],FIXP_DBL H12[MAX_PARAMETER_BANDS],FIXP_DBL H21[MAX_PARAMETER_BANDS],FIXP_DBL H22[MAX_PARAMETER_BANDS],FIXP_DBL c_l[MAX_PARAMETER_BANDS],FIXP_DBL c_r[MAX_PARAMETER_BANDS],int ottBoxIndx,int parameterSetIndx,int residualBands)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 
dequantIPD_CLD_ICC_splitAngle__FDK_Function(INT ipdIdx,INT cldIdx,INT iccIdx)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 
calculateOpd(spatialDec * self,INT ottBoxIndx,INT parameterSetIndx,FIXP_DBL opd[MAX_PARAMETER_BANDS])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 */
wrapPhase(FIXP_DBL phase)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 *******************************************************************************/
param2UMX_PS_IPD_OPD__FDK(spatialDec * self,const SPATIAL_BS_FRAME * frame,FIXP_DBL H11[MAX_PARAMETER_BANDS],FIXP_DBL H12[MAX_PARAMETER_BANDS],FIXP_DBL H21[MAX_PARAMETER_BANDS],FIXP_DBL H22[MAX_PARAMETER_BANDS],FIXP_DBL c_l[MAX_PARAMETER_BANDS],FIXP_DBL c_r[MAX_PARAMETER_BANDS],int ottBoxIndx,int parameterSetIndx,int residualBands)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 
param2UMX_Prediction_Core__FDK(FIXP_DBL * H11re,FIXP_DBL * H11im,FIXP_DBL * H12re,FIXP_DBL * H12im,FIXP_DBL * H21re,FIXP_DBL * H21im,FIXP_DBL * H22re,FIXP_DBL * H22im,int cldIdx,int iccIdx,int ipdIdx,int band,int numOttBandsIPD,int resBands)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 
param2UMX_Prediction__FDK(spatialDec * self,FIXP_DBL * H11re,FIXP_DBL * H11im,FIXP_DBL * H12re,FIXP_DBL * H12im,FIXP_DBL * H21re,FIXP_DBL * H21im,FIXP_DBL * H22re,FIXP_DBL * H22im,int ottBoxIndx,int parameterSetIndx,int resBands)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 
initM1andM2(spatialDec * self,int initStatesFlag,int configChanged)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