• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2019 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 
calculateOpd(spatialDec * self,INT ottBoxIndx,INT parameterSetIndx,FIXP_DBL opd[MAX_PARAMETER_BANDS])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 */
wrapPhase(FIXP_DBL phase)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 *******************************************************************************/
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)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 
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)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 
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)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 
initM1andM2(spatialDec * self,int initStatesFlag,int configChanged)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