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