/src/aac/libSACdec/src/sac_calcM1andM2.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | *******************************************************************************/ |
164 | 0 | int SpatialDecGetResidualIndex(spatialDec* self, int row) { |
165 | 0 | return row2residual[self->treeConfig][row]; |
166 | 0 | } |
167 | | |
168 | | /******************************************************************************* |
169 | | Functionname: UpdateAlpha |
170 | | ******************************************************************************* |
171 | | |
172 | | Description: |
173 | | |
174 | | Arguments: |
175 | | |
176 | | Input: |
177 | | |
178 | | Output: |
179 | | |
180 | | *******************************************************************************/ |
181 | 0 | static void updateAlpha(spatialDec* self) { |
182 | 0 | int nChIn = self->numInputChannels; |
183 | 0 | int ch; |
184 | |
|
185 | 0 | for (ch = 0; ch < nChIn; ch++) { |
186 | 0 | FIXP_DBL alpha = /* FL2FXCONST_DBL(1.0f) */ (FIXP_DBL)MAXVAL_DBL; |
187 | |
|
188 | 0 | self->arbdmxAlphaPrev__FDK[ch] = self->arbdmxAlpha__FDK[ch]; |
189 | |
|
190 | 0 | self->arbdmxAlpha__FDK[ch] = alpha; |
191 | 0 | } |
192 | 0 | } |
193 | | |
194 | | /******************************************************************************* |
195 | | Functionname: SpatialDecCalculateM1andM2 |
196 | | ******************************************************************************* |
197 | | Description: |
198 | | Arguments: |
199 | | *******************************************************************************/ |
200 | | SACDEC_ERROR SpatialDecCalculateM1andM2(spatialDec* self, int ps, |
201 | 0 | const SPATIAL_BS_FRAME* frame) { |
202 | 0 | SACDEC_ERROR err = MPS_OK; |
203 | |
|
204 | 0 | if ((self->arbitraryDownmix != 0) && (ps == 0)) { |
205 | 0 | updateAlpha(self); |
206 | 0 | } |
207 | |
|
208 | 0 | self->pActivM2ParamBands = NULL; |
209 | |
|
210 | 0 | switch (self->upmixType) { |
211 | 0 | case UPMIXTYPE_BYPASS: |
212 | 0 | case UPMIXTYPE_NORMAL: |
213 | 0 | switch (self->treeConfig) { |
214 | 0 | case TREE_212: |
215 | 0 | err = SpatialDecCalculateM1andM2_212(self, ps, frame); |
216 | 0 | break; |
217 | 0 | default: |
218 | 0 | err = MPS_WRONG_TREECONFIG; |
219 | 0 | }; |
220 | 0 | break; |
221 | | |
222 | 0 | default: |
223 | 0 | err = MPS_WRONG_TREECONFIG; |
224 | 0 | } |
225 | | |
226 | 0 | if (err != MPS_OK) { |
227 | 0 | goto bail; |
228 | 0 | } |
229 | | |
230 | 0 | bail: |
231 | 0 | return err; |
232 | 0 | } |
233 | | |
234 | | /******************************************************************************* |
235 | | Functionname: SpatialDecCalculateM1andM2_212 |
236 | | ******************************************************************************* |
237 | | |
238 | | Description: |
239 | | |
240 | | Arguments: |
241 | | |
242 | | Return: |
243 | | |
244 | | *******************************************************************************/ |
245 | | static SACDEC_ERROR SpatialDecCalculateM1andM2_212( |
246 | 0 | spatialDec* self, int ps, const SPATIAL_BS_FRAME* frame) { |
247 | 0 | SACDEC_ERROR err = MPS_OK; |
248 | 0 | int pb; |
249 | |
|
250 | 0 | FIXP_DBL H11re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; |
251 | 0 | FIXP_DBL H12re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; |
252 | 0 | FIXP_DBL H21re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; |
253 | 0 | FIXP_DBL H22re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; |
254 | 0 | FIXP_DBL H11im[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; |
255 | 0 | FIXP_DBL H21im[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)}; |
256 | |
|
257 | 0 | INT phaseCoding = self->phaseCoding; |
258 | |
|
259 | 0 | switch (phaseCoding) { |
260 | 0 | case 1: |
261 | | /* phase coding: yes; residuals: no */ |
262 | 0 | param2UMX_PS_IPD_OPD__FDK(self, frame, H11re, H12re, H21re, H22re, NULL, |
263 | 0 | NULL, 0, ps, self->residualBands[0]); |
264 | 0 | break; |
265 | 0 | case 3: |
266 | | /* phase coding: yes; residuals: yes */ |
267 | 0 | param2UMX_Prediction__FDK(self, H11re, H11im, H12re, NULL, H21re, H21im, |
268 | 0 | H22re, NULL, 0, ps, self->residualBands[0]); |
269 | 0 | break; |
270 | 0 | default: |
271 | 0 | if (self->residualCoding) { |
272 | | /* phase coding: no; residuals: yes */ |
273 | 0 | param2UMX_Prediction__FDK(self, H11re, NULL, H12re, NULL, H21re, NULL, |
274 | 0 | H22re, NULL, 0, ps, self->residualBands[0]); |
275 | 0 | } else { |
276 | | /* phase coding: no; residuals: no */ |
277 | 0 | param2UMX_PS__FDK(self, H11re, H12re, H21re, H22re, NULL, NULL, 0, ps, |
278 | 0 | 0); |
279 | 0 | } |
280 | 0 | break; |
281 | 0 | } |
282 | | |
283 | 0 | for (pb = 0; pb < self->numParameterBands; pb++) { |
284 | 0 | self->M2Real__FDK[0][0][pb] = (H11re[pb]); |
285 | 0 | self->M2Real__FDK[0][1][pb] = (H12re[pb]); |
286 | |
|
287 | 0 | self->M2Real__FDK[1][0][pb] = (H21re[pb]); |
288 | 0 | self->M2Real__FDK[1][1][pb] = (H22re[pb]); |
289 | 0 | } |
290 | 0 | if (phaseCoding == 3) { |
291 | 0 | for (pb = 0; pb < self->numParameterBands; pb++) { |
292 | 0 | self->M2Imag__FDK[0][0][pb] = (H11im[pb]); |
293 | 0 | self->M2Imag__FDK[1][0][pb] = (H21im[pb]); |
294 | 0 | self->M2Imag__FDK[0][1][pb] = (FIXP_DBL)0; // H12im[pb]; |
295 | 0 | self->M2Imag__FDK[1][1][pb] = (FIXP_DBL)0; // H22im[pb]; |
296 | 0 | } |
297 | 0 | } |
298 | |
|
299 | 0 | if (self->phaseCoding == 1) { |
300 | 0 | SpatialDecSmoothOPD( |
301 | 0 | self, frame, |
302 | 0 | ps); /* INPUT: PhaseLeft, PhaseRight, (opdLeftState, opdRightState) */ |
303 | 0 | } |
304 | |
|
305 | 0 | return err; |
306 | 0 | } |
307 | | |
308 | | /******************************************************************************* |
309 | | Functionname: param2UMX_PS_Core |
310 | | ******************************************************************************* |
311 | | |
312 | | Description: |
313 | | |
314 | | Arguments: |
315 | | |
316 | | Return: |
317 | | |
318 | | *******************************************************************************/ |
319 | | static void param2UMX_PS_Core__FDK( |
320 | | const SCHAR cld[MAX_PARAMETER_BANDS], const SCHAR icc[MAX_PARAMETER_BANDS], |
321 | | const int numOttBands, const int resBands, |
322 | | FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS], |
323 | | FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS], |
324 | 0 | FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS]) { |
325 | 0 | int band; |
326 | |
|
327 | 0 | if ((c_l != NULL) && (c_r != NULL)) { |
328 | 0 | for (band = 0; band < numOttBands; band++) { |
329 | 0 | SpatialDequantGetCLDValues(cld[band], &c_l[band], &c_r[band]); |
330 | 0 | } |
331 | 0 | } |
332 | |
|
333 | 0 | band = 0; |
334 | 0 | FDK_ASSERT(resBands == 0); |
335 | 0 | for (; band < numOttBands; band++) { |
336 | | /* compute mixing variables: */ |
337 | 0 | const int idx1 = cld[band]; |
338 | 0 | const int idx2 = icc[band]; |
339 | 0 | H11[band] = FX_CFG2FX_DBL(H11_nc[idx1][idx2]); |
340 | 0 | H21[band] = FX_CFG2FX_DBL(H11_nc[30 - idx1][idx2]); |
341 | 0 | H12[band] = FX_CFG2FX_DBL(H12_nc[idx1][idx2]); |
342 | 0 | H22[band] = FX_CFG2FX_DBL(-H12_nc[30 - idx1][idx2]); |
343 | 0 | } |
344 | 0 | } |
345 | | |
346 | | /******************************************************************************* |
347 | | Functionname: param2UMX_PS |
348 | | ******************************************************************************* |
349 | | |
350 | | Description: |
351 | | |
352 | | Arguments: |
353 | | |
354 | | Return: |
355 | | |
356 | | *******************************************************************************/ |
357 | | static void param2UMX_PS__FDK(spatialDec* self, |
358 | | FIXP_DBL H11[MAX_PARAMETER_BANDS], |
359 | | FIXP_DBL H12[MAX_PARAMETER_BANDS], |
360 | | FIXP_DBL H21[MAX_PARAMETER_BANDS], |
361 | | FIXP_DBL H22[MAX_PARAMETER_BANDS], |
362 | | FIXP_DBL c_l[MAX_PARAMETER_BANDS], |
363 | | FIXP_DBL c_r[MAX_PARAMETER_BANDS], int ottBoxIndx, |
364 | 0 | int parameterSetIndx, int residualBands) { |
365 | 0 | int band; |
366 | 0 | param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx], |
367 | 0 | self->ottICC__FDK[ottBoxIndx][parameterSetIndx], |
368 | 0 | self->numOttBands[ottBoxIndx], residualBands, H11, H12, |
369 | 0 | H21, H22, c_l, c_r); |
370 | |
|
371 | 0 | for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands; |
372 | 0 | band++) { |
373 | 0 | H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f); |
374 | 0 | } |
375 | 0 | } |
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 | 0 | #define SIN_IPD(a) (sinIpd_tab[(a)]) |
391 | 0 | #define COS_IPD(a) (sinIpd_tab[((a) + 4) & 15]) //(cosIpd_tab[(a)]) |
392 | | |
393 | | static const FIXP_SGL sqrt_one_minus_ICC2[8] = { |
394 | | FL2FXCONST_SGL(0.0f), |
395 | | FL2FXCONST_SGL(0.349329357483736f), |
396 | | FL2FXCONST_SGL(0.540755219669676f), |
397 | | FL2FXCONST_SGL(0.799309172723546f), |
398 | | FL2FXCONST_SGL(0.929968187843004f), |
399 | | FX_DBL2FXCONST_SGL(MAXVAL_DBL), |
400 | | FL2FXCONST_SGL(0.80813303360276f), |
401 | | FL2FXCONST_SGL(0.141067359796659f), |
402 | | }; |
403 | | |
404 | | /* exponent of sqrt(CLD) */ |
405 | | static const SCHAR sqrt_CLD_e[N_CLD] = { |
406 | | -24, -7, -6, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 1, |
407 | | 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 25}; |
408 | | |
409 | | static const FIXP_DBL sqrt_CLD_m[N_CLD] = { |
410 | | FL2FXCONST_DBL(0.530542153566195f), |
411 | | FL2FXCONST_DBL(0.719796896243647f), |
412 | | FL2FXCONST_DBL(0.64f), |
413 | | FL2FXCONST_DBL(0.569049411212455f), |
414 | | FL2FXCONST_DBL(0.505964425626941f), |
415 | | FL2FXCONST_DBL(0.899746120304559f), |
416 | | FL2FXCONST_DBL(0.635462587779425f), |
417 | | FL2FXCONST_DBL(0.897614763441571f), |
418 | | FL2FXCONST_DBL(0.633957276984445f), |
419 | | FL2FXCONST_DBL(0.895488455427336f), |
420 | | FL2FXCONST_DBL(0.632455532033676f), |
421 | | FL2FXCONST_DBL(0.796214341106995f), |
422 | | FL2FXCONST_DBL(0.501187233627272f), |
423 | | FL2FXCONST_DBL(0.630957344480193f), |
424 | | FL2FXCONST_DBL(0.794328234724281f), |
425 | | FL2FXCONST_DBL(0.5f), |
426 | | FL2FXCONST_DBL(0.629462705897084f), |
427 | | FL2FXCONST_DBL(0.792446596230557f), |
428 | | FL2FXCONST_DBL(0.99763115748444f), |
429 | | FL2FXCONST_DBL(0.627971607877395f), |
430 | | FL2FXCONST_DBL(0.790569415042095f), |
431 | | FL2FXCONST_DBL(0.558354490188704f), |
432 | | FL2FXCONST_DBL(0.788696680600242f), |
433 | | FL2FXCONST_DBL(0.557031836333591f), |
434 | | FL2FXCONST_DBL(0.786828382371355f), |
435 | | FL2FXCONST_DBL(0.555712315637163f), |
436 | | FL2FXCONST_DBL(0.988211768802619f), |
437 | | FL2FXCONST_DBL(0.87865832060992f), |
438 | | FL2FXCONST_DBL(0.78125f), |
439 | | FL2FXCONST_DBL(0.694640394546454f), |
440 | | FL2FXCONST_DBL(0.942432183077448f), |
441 | | }; |
442 | | |
443 | | static const FIXP_DBL CLD_m[N_CLD] = { |
444 | | FL2FXCONST_DBL(0.281474976710656f), |
445 | | FL2FXCONST_DBL(0.518107571841987f), |
446 | | FL2FXCONST_DBL(0.4096f), |
447 | | FL2FXCONST_DBL(0.323817232401242f), |
448 | | FL2FXCONST_DBL(0.256f), |
449 | | FL2FXCONST_DBL(0.809543081003105f), |
450 | | FL2FXCONST_DBL(0.403812700467324f), |
451 | | FL2FXCONST_DBL(0.805712263548267f), |
452 | | FL2FXCONST_DBL(0.401901829041533f), |
453 | | FL2FXCONST_DBL(0.801899573803636f), |
454 | | FL2FXCONST_DBL(0.4f), |
455 | | FL2FXCONST_DBL(0.633957276984445f), |
456 | | FL2FXCONST_DBL(0.251188643150958f), |
457 | | FL2FXCONST_DBL(0.398107170553497f), |
458 | | FL2FXCONST_DBL(0.630957344480193f), |
459 | | FL2FXCONST_DBL(0.25f), |
460 | | FL2FXCONST_DBL(0.396223298115278f), |
461 | | FL2FXCONST_DBL(0.627971607877395f), |
462 | | FL2FXCONST_DBL(0.995267926383743f), |
463 | | FL2FXCONST_DBL(0.394348340300121f), |
464 | | FL2FXCONST_DBL(0.625f), |
465 | | FL2FXCONST_DBL(0.311759736713887f), |
466 | | FL2FXCONST_DBL(0.62204245398984f), |
467 | | FL2FXCONST_DBL(0.310284466689172f), |
468 | | FL2FXCONST_DBL(0.619098903305123f), |
469 | | FL2FXCONST_DBL(0.308816177750818f), |
470 | | FL2FXCONST_DBL(0.9765625f), |
471 | | FL2FXCONST_DBL(0.772040444377046f), |
472 | | FL2FXCONST_DBL(0.6103515625f), |
473 | | FL2FXCONST_DBL(0.482525277735654f), |
474 | | FL2FXCONST_DBL(0.888178419700125), |
475 | | }; |
476 | | |
477 | | static void calculateOpd(spatialDec* self, INT ottBoxIndx, INT parameterSetIndx, |
478 | 0 | FIXP_DBL opd[MAX_PARAMETER_BANDS]) { |
479 | 0 | INT band; |
480 | |
|
481 | 0 | for (band = 0; band < self->numOttBandsIPD; band++) { |
482 | 0 | INT idxCld = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band]; |
483 | 0 | INT idxIpd = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band]; |
484 | 0 | INT idxIcc = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band]; |
485 | 0 | FIXP_DBL cld, ipd; |
486 | |
|
487 | 0 | ipd = FX_CFG2FX_DBL(dequantIPD__FDK[idxIpd]); |
488 | |
|
489 | 0 | SpatialDequantGetCLD2Values(idxCld, &cld); |
490 | | |
491 | | /* ipd(idxIpd==8) == PI */ |
492 | 0 | if (((cld == FL2FXCONST_DBL(0.0f)) && (idxIpd == 8)) || (idxIpd == 0)) { |
493 | 0 | opd[2 * band] = FL2FXCONST_DBL(0.0f); |
494 | 0 | } else { |
495 | 0 | FDK_ASSERT(idxIpd > 0); |
496 | 0 | opd[2 * band] = |
497 | 0 | dequantIPD_CLD_ICC_splitAngle__FDK[idxIpd - 1][idxCld][idxIcc]; |
498 | 0 | } |
499 | 0 | opd[2 * band + 1] = opd[2 * band] - ipd; |
500 | 0 | } |
501 | 0 | } |
502 | | |
503 | | /* wrap phase in rad to the range of 0 <= x < 2*pi */ |
504 | 0 | static FIXP_DBL wrapPhase(FIXP_DBL phase) { |
505 | 0 | while (phase < (FIXP_DBL)0) phase += PIx2__IPD; |
506 | 0 | while (phase >= PIx2__IPD) phase -= PIx2__IPD; |
507 | 0 | FDK_ASSERT((phase >= (FIXP_DBL)0) && (phase < PIx2__IPD)); |
508 | | |
509 | 0 | return phase; |
510 | 0 | } |
511 | | |
512 | | /******************************************************************************* |
513 | | Functionname: param2UMX_PS_IPD |
514 | | ******************************************************************************* |
515 | | |
516 | | Description: |
517 | | |
518 | | Arguments: |
519 | | |
520 | | Return: |
521 | | |
522 | | *******************************************************************************/ |
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 | 0 | int ottBoxIndx, int parameterSetIndx, int residualBands) { |
529 | 0 | INT band; |
530 | 0 | FIXP_DBL opd[2 * MAX_PARAMETER_BANDS]; |
531 | 0 | INT numOttBands = self->numOttBands[ottBoxIndx]; |
532 | 0 | INT numIpdBands; |
533 | |
|
534 | 0 | numIpdBands = frame->phaseMode ? self->numOttBandsIPD : 0; |
535 | |
|
536 | 0 | FDK_ASSERT(self->residualCoding == 0); |
537 | | |
538 | 0 | param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx], |
539 | 0 | self->ottICC__FDK[ottBoxIndx][parameterSetIndx], |
540 | 0 | self->numOttBands[ottBoxIndx], residualBands, H11, H12, |
541 | 0 | H21, H22, c_l, c_r); |
542 | |
|
543 | 0 | for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands; |
544 | 0 | band++) { |
545 | 0 | H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f); |
546 | 0 | } |
547 | |
|
548 | 0 | if (frame->phaseMode) { |
549 | 0 | calculateOpd(self, ottBoxIndx, parameterSetIndx, opd); |
550 | |
|
551 | 0 | for (band = 0; band < numIpdBands; band++) { |
552 | 0 | self->PhaseLeft__FDK[band] = wrapPhase(opd[2 * band]); |
553 | 0 | self->PhaseRight__FDK[band] = wrapPhase(opd[2 * band + 1]); |
554 | 0 | } |
555 | 0 | } |
556 | |
|
557 | 0 | for (band = numIpdBands; band < numOttBands; band++) { |
558 | 0 | self->PhaseLeft__FDK[band] = FL2FXCONST_DBL(0.0f); |
559 | 0 | self->PhaseRight__FDK[band] = FL2FXCONST_DBL(0.0f); |
560 | 0 | } |
561 | 0 | } |
562 | | |
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 | 0 | int resBands) { |
568 | 0 | #define MAX_WEIGHT (1.2f) |
569 | 0 | FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */ |
570 | | |
571 | 0 | if ((band < numOttBandsIPD) && (cldIdx == 15) && (iccIdx == 0) && |
572 | 0 | (ipdIdx == 8)) { |
573 | 0 | const FIXP_DBL gain = |
574 | 0 | FL2FXCONST_DBL(0.5f / MAX_WEIGHT) >> SCALE_PARAM_M2_212_PRED; |
575 | |
|
576 | 0 | *H11re = gain; |
577 | 0 | if (band < resBands) { |
578 | 0 | *H21re = gain; |
579 | 0 | *H12re = gain; |
580 | 0 | *H22re = -gain; |
581 | 0 | } else { |
582 | 0 | *H21re = -gain; |
583 | 0 | *H12re = (FIXP_DBL)0; |
584 | 0 | *H22re = (FIXP_DBL)0; |
585 | 0 | } |
586 | 0 | if ((H11im != NULL) && |
587 | 0 | (H21im != NULL) /*&& (H12im!=NULL) && (H22im!=NULL)*/) { |
588 | 0 | *H11im = (FIXP_DBL)0; |
589 | 0 | *H21im = (FIXP_DBL)0; |
590 | | /* *H12im = (FIXP_DBL)0; */ |
591 | | /* *H22im = (FIXP_DBL)0; */ |
592 | 0 | } |
593 | 0 | } else { |
594 | 0 | const FIXP_DBL one_m = (FIXP_DBL)MAXVAL_DBL; |
595 | 0 | const int one_e = 0; |
596 | | /* iidLin = sqrt(cld); */ |
597 | 0 | FIXP_DBL iidLin_m = sqrt_CLD_m[cldIdx]; |
598 | 0 | int iidLin_e = sqrt_CLD_e[cldIdx]; |
599 | | /* iidLin2 = cld; */ |
600 | 0 | FIXP_DBL iidLin2_m = CLD_m[cldIdx]; |
601 | 0 | int iidLin2_e = sqrt_CLD_e[cldIdx] << 1; |
602 | | /* iidLin21 = iidLin2 + 1.0f; */ |
603 | 0 | int iidLin21_e; |
604 | 0 | FIXP_DBL iidLin21_m = |
605 | 0 | fAddNorm(iidLin2_m, iidLin2_e, one_m, one_e, &iidLin21_e); |
606 | | /* iidIcc2 = iidLin * icc * 2.0f; */ |
607 | 0 | FIXP_CFG icc = dequantICC__FDK[iccIdx]; |
608 | 0 | int iidIcc2_e = iidLin_e + 1; |
609 | 0 | FIXP_DBL iidIcc2_m = fMult(iidLin_m, icc); |
610 | 0 | FIXP_DBL temp_m, sqrt_temp_m, inv_temp_m, weight_m; |
611 | 0 | int temp_e, sqrt_temp_e, inv_temp_e, weight_e, scale; |
612 | 0 | FIXP_DBL cosIpd, sinIpd; |
613 | |
|
614 | 0 | cosIpd = COS_IPD((band < numOttBandsIPD) ? ipdIdx : 0); |
615 | 0 | sinIpd = SIN_IPD((band < numOttBandsIPD) ? ipdIdx : 0); |
616 | | |
617 | | /* temp = iidLin21 + iidIcc2 * cosIpd; */ |
618 | 0 | temp_m = fAddNorm(iidLin21_m, iidLin21_e, fMult(iidIcc2_m, cosIpd), |
619 | 0 | iidIcc2_e, &temp_e); |
620 | | |
621 | | /* calculate 1/temp needed later */ |
622 | 0 | inv_temp_e = temp_e; |
623 | 0 | inv_temp_m = invFixp(temp_m, &inv_temp_e); |
624 | | |
625 | | /* 1/weight = sqrt(temp) * 1/sqrt(iidLin21) */ |
626 | 0 | if (temp_e & 1) { |
627 | 0 | sqrt_temp_m = temp_m >> 1; |
628 | 0 | sqrt_temp_e = (temp_e + 1) >> 1; |
629 | 0 | } else { |
630 | 0 | sqrt_temp_m = temp_m; |
631 | 0 | sqrt_temp_e = temp_e >> 1; |
632 | 0 | } |
633 | 0 | sqrt_temp_m = sqrtFixp(sqrt_temp_m); |
634 | 0 | if (iidLin21_e & 1) { |
635 | 0 | iidLin21_e += 1; |
636 | 0 | iidLin21_m >>= 1; |
637 | 0 | } |
638 | | /* weight_[m,e] is actually 1/weight in the next few lines */ |
639 | 0 | weight_m = invSqrtNorm2(iidLin21_m, &weight_e); |
640 | 0 | weight_e -= iidLin21_e >> 1; |
641 | 0 | weight_m = fMult(sqrt_temp_m, weight_m); |
642 | 0 | weight_e += sqrt_temp_e; |
643 | 0 | scale = fNorm(weight_m); |
644 | 0 | weight_m = scaleValue(weight_m, scale); |
645 | 0 | weight_e -= scale; |
646 | | /* weight = 0.5 * max(1/weight, 1/maxWeight) */ |
647 | 0 | if ((weight_e < 0) || |
648 | 0 | ((weight_e == 0) && (weight_m < FL2FXCONST_DBL(1.f / MAX_WEIGHT)))) { |
649 | 0 | weight_m = FL2FXCONST_DBL(1.f / MAX_WEIGHT); |
650 | 0 | weight_e = 0; |
651 | 0 | } |
652 | 0 | weight_e -= 1; |
653 | |
|
654 | 0 | { |
655 | 0 | FIXP_DBL alphaRe_m, alphaIm_m, accu_m; |
656 | 0 | int alphaRe_e, alphaIm_e, accu_e; |
657 | | /* alphaRe = (1.0f - iidLin2) / temp; */ |
658 | 0 | alphaRe_m = fAddNorm(one_m, one_e, -iidLin2_m, iidLin2_e, &alphaRe_e); |
659 | 0 | alphaRe_m = fMult(alphaRe_m, inv_temp_m); |
660 | 0 | alphaRe_e += inv_temp_e; |
661 | | |
662 | | /* H11re = weight - alphaRe * weight; */ |
663 | | /* H21re = weight + alphaRe * weight; */ |
664 | 0 | accu_m = fMult(alphaRe_m, weight_m); |
665 | 0 | accu_e = alphaRe_e + weight_e; |
666 | 0 | { |
667 | 0 | int accu2_e; |
668 | 0 | FIXP_DBL accu2_m; |
669 | 0 | accu2_m = fAddNorm(weight_m, weight_e, -accu_m, accu_e, &accu2_e); |
670 | 0 | *H11re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED); |
671 | 0 | accu2_m = fAddNorm(weight_m, weight_e, accu_m, accu_e, &accu2_e); |
672 | 0 | *H21re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED); |
673 | 0 | } |
674 | |
|
675 | 0 | if ((H11im != NULL) && |
676 | 0 | (H21im != NULL) /*&& (H12im != NULL) && (H22im != NULL)*/) { |
677 | | /* alphaIm = -iidIcc2 * sinIpd / temp; */ |
678 | 0 | alphaIm_m = fMult(-iidIcc2_m, sinIpd); |
679 | 0 | alphaIm_m = fMult(alphaIm_m, inv_temp_m); |
680 | 0 | alphaIm_e = iidIcc2_e + inv_temp_e; |
681 | | /* H11im = -alphaIm * weight; */ |
682 | | /* H21im = alphaIm * weight; */ |
683 | 0 | accu_m = fMult(alphaIm_m, weight_m); |
684 | 0 | accu_e = alphaIm_e + weight_e; |
685 | 0 | accu_m = scaleValue(accu_m, accu_e - SCALE_PARAM_M2_212_PRED); |
686 | 0 | *H11im = -accu_m; |
687 | 0 | *H21im = accu_m; |
688 | | |
689 | | /* *H12im = (FIXP_DBL)0; */ |
690 | | /* *H22im = (FIXP_DBL)0; */ |
691 | 0 | } |
692 | 0 | } |
693 | 0 | if (band < resBands) { |
694 | 0 | FIXP_DBL weight = |
695 | 0 | scaleValue(weight_m, weight_e - SCALE_PARAM_M2_212_PRED); |
696 | 0 | *H12re = weight; |
697 | 0 | *H22re = -weight; |
698 | 0 | } else { |
699 | | /* beta = 2.0f * iidLin * (float) sqrt(1.0f - icc * icc) * weight / temp; |
700 | | */ |
701 | 0 | FIXP_DBL beta_m; |
702 | 0 | int beta_e; |
703 | 0 | beta_m = FX_SGL2FX_DBL(sqrt_one_minus_ICC2[iccIdx]); |
704 | 0 | beta_e = 1; /* multipication with 2.0f */ |
705 | 0 | beta_m = fMult(beta_m, weight_m); |
706 | 0 | beta_e += weight_e; |
707 | 0 | beta_m = fMult(beta_m, iidLin_m); |
708 | 0 | beta_e += iidLin_e; |
709 | 0 | beta_m = fMult(beta_m, inv_temp_m); |
710 | 0 | beta_e += inv_temp_e; |
711 | |
|
712 | 0 | beta_m = scaleValue(beta_m, beta_e - SCALE_PARAM_M2_212_PRED); |
713 | 0 | *H12re = beta_m; |
714 | 0 | *H22re = -beta_m; |
715 | 0 | } |
716 | 0 | } |
717 | 0 | } |
718 | | |
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 | 0 | int parameterSetIndx, int resBands) { |
725 | 0 | int band; |
726 | 0 | FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */ |
727 | | |
728 | 0 | for (band = 0; band < self->numParameterBands; band++) { |
729 | 0 | int cldIdx = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band]; |
730 | 0 | int iccIdx = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band]; |
731 | 0 | int ipdIdx = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band]; |
732 | |
|
733 | 0 | param2UMX_Prediction_Core__FDK( |
734 | 0 | &H11re[band], (H11im ? &H11im[band] : NULL), &H12re[band], NULL, |
735 | 0 | &H21re[band], (H21im ? &H21im[band] : NULL), &H22re[band], NULL, cldIdx, |
736 | 0 | iccIdx, ipdIdx, band, self->numOttBandsIPD, resBands); |
737 | 0 | } |
738 | 0 | } |
739 | | |
740 | | /******************************************************************************* |
741 | | Functionname: initM1andM2 |
742 | | ******************************************************************************* |
743 | | |
744 | | Description: |
745 | | |
746 | | Arguments: |
747 | | |
748 | | Return: |
749 | | |
750 | | *******************************************************************************/ |
751 | | |
752 | | SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag, |
753 | 0 | int configChanged) { |
754 | 0 | SACDEC_ERROR err = MPS_OK; |
755 | |
|
756 | 0 | self->bOverwriteM1M2prev = (configChanged && !initStatesFlag) ? 1 : 0; |
757 | |
|
758 | 0 | { self->numM2rows = self->numOutputChannels; } |
759 | |
|
760 | 0 | if (initStatesFlag) { |
761 | 0 | int i, j, k; |
762 | |
|
763 | 0 | for (i = 0; i < self->numM2rows; i++) { |
764 | 0 | for (j = 0; j < self->numVChannels; j++) { |
765 | 0 | for (k = 0; k < MAX_PARAMETER_BANDS; k++) { |
766 | 0 | self->M2Real__FDK[i][j][k] = FL2FXCONST_DBL(0); |
767 | 0 | self->M2RealPrev__FDK[i][j][k] = FL2FXCONST_DBL(0); |
768 | 0 | } |
769 | 0 | } |
770 | 0 | } |
771 | 0 | } |
772 | |
|
773 | 0 | return err; |
774 | 0 | } |