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