1 /******************************************************************************
2 * *
3 * Copyright (C) 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <math.h>
21 #include <memory.h>
22
23 #include <assert.h>
24 #include "ixheaacd_type_def.h"
25 #include "ixheaacd_bitbuffer.h"
26 #include "ixheaacd_config.h"
27 #include "ixheaacd_mps_polyphase.h"
28
29 #include "ixheaacd_mps_dec.h"
30 #include "ixheaacd_mps_interface.h"
31
32 #include "ixheaacd_constants.h"
33 #include "ixheaacd_basic_ops32.h"
34 #include "ixheaacd_basic_ops40.h"
35
36 #undef ABS_THR
37 #define ABS_THR 1.0e-9f
38
39 #define ICC_FIX
40 #define UNSINGULARIZE_FIX
41 #define QUANTIZE_PARS_FIX
42
43 #define PI 3.14159265358979f
44
45 #define ONE_IN_Q28 (268435456)
46 #define MINUS_ONE_IN_Q28 (-268435456)
47 #define PI_Q28 (843314856)
48 #define PI_Q27 (421657428)
49 #define PI_BY_8_Q28 (105414352)
50
51 extern const WORD32 ixheaacd_im_weight_Q28[16][8][31];
52 extern const WORD32 ixheaacd_re_weight_Q28[16][8][31];
53 extern const WORD32 ixheaacd_beta_Q28[16][8][31];
54 extern const WORD32 ixheaacd_weight_Q28[16][8][31];
55 extern const WORD32 ixheaacd_c_l_table_Q31[31];
56 extern const WORD32 ixheaacd_sin_table_Q31[8][31];
57 extern const WORD32 ixheaacd_cos_table_Q31[8][31];
58 extern const WORD32 ixheaacd_atan_table_Q28[16][8][31];
59 extern const WORD32 ixheaacd_ipd_de_quant_table_q28[16];
60
61 #define P_PI 3.1415926535897932
62 #define PI_IN_Q28 843314880
63
64 #define P_PI 3.1415926535897932
65 #define PI_IN_Q28 843314880
66
ixheaacd_mps_phase_wraping(WORD32 phase)67 static WORD32 ixheaacd_mps_phase_wraping(WORD32 phase) {
68 const WORD32 pi_2 = 2 * PI_IN_Q28;
69
70 while (phase < 0) phase += pi_2;
71 while (phase >= pi_2) phase -= pi_2;
72 assert((phase >= 0) && (phase < pi_2));
73
74 return phase;
75 }
76
ixheaacd_mps_buffer_pre_and_mix_matrix(ia_mps_dec_state_struct * self)77 static VOID ixheaacd_mps_buffer_pre_and_mix_matrix(
78 ia_mps_dec_state_struct *self) {
79 WORD32 pb, row, col;
80
81 for (pb = 0; pb < self->bs_param_bands; pb++) {
82 for (row = 0; row < MAX_M_INPUT; row++) {
83 for (col = 0; col < MAX_M_OUTPUT; col++) {
84 self->m1_param_re_prev[pb][row][col] =
85 self->m1_param_re[self->num_parameter_sets_prev - 1][pb][row][col];
86 self->m1_param_im_prev[pb][row][col] =
87 self->m1_param_im[self->num_parameter_sets_prev - 1][pb][row][col];
88 self->m2_decor_re_prev[pb][row][col] =
89 self->m2_decor_re[self->num_parameter_sets_prev - 1][pb][row][col];
90 self->m2_decor_im_prev[pb][row][col] =
91 self->m2_decor_im[self->num_parameter_sets_prev - 1][pb][row][col];
92 self->m2_resid_re_prev[pb][row][col] =
93 self->m2_resid_re[self->num_parameter_sets_prev - 1][pb][row][col];
94 self->m2_resid_im_prev[pb][row][col] =
95 self->m2_resid_im[self->num_parameter_sets_prev - 1][pb][row][col];
96 }
97 }
98 }
99
100 for (pb = 0; pb < self->bs_param_bands; pb++) {
101 self->phase_l_prev[pb] =
102 self->phase_l[self->num_parameter_sets_prev - 1][pb];
103 self->phase_r_prev[pb] =
104 self->phase_r[self->num_parameter_sets_prev - 1][pb];
105 }
106 }
107
ixheaacd_fix_to_float_int(WORD32 * inp,FLOAT32 * out,WORD32 length,FLOAT32 q_fac)108 VOID ixheaacd_fix_to_float_int(WORD32 *inp, FLOAT32 *out, WORD32 length,
109 FLOAT32 q_fac) {
110 WORD32 i;
111 FLOAT32 m_qfac = 1.0f / q_fac;
112
113 for (i = 0; i < length; i++) out[i] = (FLOAT32)(inp[i]) * m_qfac;
114 }
115
ixheaacd_pre_and_mix_matrix_calculation(ia_mps_dec_state_struct * self)116 VOID ixheaacd_pre_and_mix_matrix_calculation(ia_mps_dec_state_struct *self) {
117 WORD32 ps, pb;
118 ia_mps_bs_frame *curr_bit_stream = &(self->bs_frame);
119 WORD32 h_imag[2 * MAX_PARAMETER_BANDS];
120 WORD32
121 h_real[6 * MAX_PARAMETER_BANDS];
122
123 ixheaacd_mps_buffer_pre_and_mix_matrix(self);
124
125 for (ps = 0; ps < self->num_parameter_sets; ps++) {
126 WORD32 *h_im = &h_imag[0];
127 WORD32 *h_re = &h_real[0];
128 memset(h_real, 0, 6 * MAX_PARAMETER_BANDS * sizeof(WORD32));
129 memset(h_imag, 0, 2 * MAX_PARAMETER_BANDS * sizeof(WORD32));
130
131 switch (self->config->bs_phase_coding) {
132 case 0:
133 if (self->residual_coding) {
134 ixheaacd_mps_par2umx_pred(self, curr_bit_stream, h_imag, h_real, ps,
135 self->res_bands);
136 } else {
137 ixheaacd_mps_par2umx_ps(self, curr_bit_stream, h_real, ps);
138 }
139
140 break;
141 case 1:
142 ixheaacd_mps_par2umx_ps_ipd_opd(self, curr_bit_stream, h_real, ps);
143 break;
144 case 2:
145 ixheaacd_mps_par2umx_pred(self, curr_bit_stream, h_imag, h_real, ps,
146 self->res_bands);
147 break;
148 }
149
150 for (pb = 0; pb < self->bs_param_bands; pb++) {
151 self->m1_param_re[ps][pb][0][0] = 1073741824;
152 self->m1_param_re[ps][pb][1][0] = 1073741824;
153
154 self->m1_param_im[ps][pb][0][0] = 0;
155 self->m1_param_im[ps][pb][1][0] = 0;
156
157 self->m2_resid_re[ps][pb][0][0] = *h_re++;
158 self->m2_resid_im[ps][pb][0][0] = *h_im++;
159 self->m2_resid_im[ps][pb][0][1] = 0;
160
161 self->m2_resid_re[ps][pb][1][0] = *h_re++;
162 self->m2_resid_im[ps][pb][1][0] = *h_im++;
163 self->m2_resid_im[ps][pb][1][1] = 0;
164
165 self->m2_decor_re[ps][pb][0][0] = 0;
166 self->m2_decor_im[ps][pb][0][0] = 0;
167 self->m2_decor_re[ps][pb][0][1] = *h_re++;
168 self->m2_decor_im[ps][pb][0][1] = 0;
169
170 self->m2_decor_re[ps][pb][1][0] = 0;
171 self->m2_decor_im[ps][pb][1][0] = 0;
172 self->m2_decor_re[ps][pb][1][1] = *h_re++;
173 self->m2_decor_im[ps][pb][1][1] = 0;
174
175 self->m2_resid_re[ps][pb][0][1] = *h_re++;
176 self->m2_resid_re[ps][pb][1][1] = *h_re++;
177 }
178 }
179 ixheaacd_mps_smoothing_opd(self);
180
181 ixheaacd_fix_to_float_int(&self->phase_l_fix[0][0], &self->phase_l[0][0],
182 MAX_PARAMETER_SETS_MPS * MAX_PARAMETER_BANDS,
183 268435456.0f);
184 ixheaacd_fix_to_float_int(&self->phase_r_fix[0][0], &self->phase_r[0][0],
185 MAX_PARAMETER_SETS_MPS * MAX_PARAMETER_BANDS,
186 268435456.0f);
187 }
188
ixheaacd_mps_par2umx_ps_core(WORD32 cld[MAX_PARAMETER_BANDS],WORD32 icc[MAX_PARAMETER_BANDS],WORD32 ott_band_count,WORD32 * h_real)189 static VOID ixheaacd_mps_par2umx_ps_core(WORD32 cld[MAX_PARAMETER_BANDS],
190 WORD32 icc[MAX_PARAMETER_BANDS],
191 WORD32 ott_band_count,
192 WORD32 *h_real) {
193 WORD32 band;
194 WORD32 c_l_temp, c_r_temp, cld_idx, icc_idx, temp;
195
196 for (band = 0; band < ott_band_count; band++) {
197 cld_idx = *cld++ + 15;
198 icc_idx = *icc++;
199
200 icc_idx = icc_idx & 7;
201
202 c_l_temp = (ixheaacd_c_l_table_Q31[cld_idx]);
203 c_r_temp = (ixheaacd_c_l_table_Q31[30 - cld_idx]);
204
205 temp = ixheaacd_cos_table_Q31[icc_idx][cld_idx];
206 *h_real++ = ixheaacd_mult32(temp, c_l_temp) >> 2;
207
208 temp = ixheaacd_cos_table_Q31[icc_idx][30 - cld_idx];
209 *h_real++ = ixheaacd_mult32(temp, c_r_temp) >> 2;
210
211 temp = ixheaacd_sin_table_Q31[icc_idx][cld_idx];
212 *h_real++ = ixheaacd_mult32(temp, c_l_temp) >> 2;
213
214 temp = -ixheaacd_sin_table_Q31[icc_idx][30 - cld_idx];
215 *h_real++ = ixheaacd_mult32(temp, c_r_temp) >> 2;
216
217 h_real += 2;
218 }
219 }
220
ixheaacd_mps_par2umx_ps(ia_mps_dec_state_struct * self,ia_mps_bs_frame * curr_bit_stream,WORD32 * h_real,WORD32 param_set_idx)221 VOID ixheaacd_mps_par2umx_ps(ia_mps_dec_state_struct *self,
222 ia_mps_bs_frame *curr_bit_stream, WORD32 *h_real,
223 WORD32 param_set_idx) {
224 ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx],
225 curr_bit_stream->icc_idx[param_set_idx],
226 self->bs_param_bands, h_real);
227 }
228
ixheaacd_mps_opd_calc(ia_mps_dec_state_struct * self,ia_mps_bs_frame * curr_bit_stream,WORD32 param_set_idx,WORD32 opd[MAX_PARAMETER_BANDS])229 static VOID ixheaacd_mps_opd_calc(ia_mps_dec_state_struct *self,
230 ia_mps_bs_frame *curr_bit_stream,
231 WORD32 param_set_idx,
232 WORD32 opd[MAX_PARAMETER_BANDS]) {
233 WORD32 band;
234
235 for (band = 0; band < self->num_bands_ipd; band++) {
236 WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15;
237 WORD32 ipd_idx = (curr_bit_stream->ipd_idx[param_set_idx][band]) & 15;
238 WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band];
239
240 if ((cld_idx == 15) && (ipd_idx == 8))
241 opd[band] = 0;
242 else
243 opd[band] = ixheaacd_atan_table_Q28[ipd_idx][icc_idx][cld_idx];
244 }
245 }
246
ixheaacd_mps_par2umx_ps_ipd_opd(ia_mps_dec_state_struct * self,ia_mps_bs_frame * curr_bit_stream,WORD32 * h_real,WORD32 param_set_idx)247 VOID ixheaacd_mps_par2umx_ps_ipd_opd(ia_mps_dec_state_struct *self,
248 ia_mps_bs_frame *curr_bit_stream,
249 WORD32 *h_real, WORD32 param_set_idx) {
250 WORD32 opd[MAX_PARAMETER_BANDS];
251 WORD32 ott_band_count = self->bs_param_bands;
252 WORD32 num_bands_ipd = self->num_bands_ipd;
253 WORD32 band;
254
255 ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx],
256 curr_bit_stream->icc_idx[param_set_idx],
257 ott_band_count, h_real);
258
259 if (self->bs_phase_mode) {
260 ixheaacd_mps_opd_calc(self, curr_bit_stream, param_set_idx, opd);
261
262 for (band = 0; band < num_bands_ipd; band++) {
263 WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15;
264 WORD32 ipd = ixheaacd_ipd_de_quant_table_q28[ipd_idx];
265
266 self->phase_l_fix[param_set_idx][band] =
267 ixheaacd_mps_phase_wraping(opd[band]);
268 self->phase_r_fix[param_set_idx][band] =
269 ixheaacd_mps_phase_wraping(opd[band] - ipd);
270 }
271 } else {
272 num_bands_ipd = 0;
273 }
274
275 for (band = num_bands_ipd; band < ott_band_count; band++) {
276 self->phase_l_fix[param_set_idx][band] = 0;
277 self->phase_r_fix[param_set_idx][band] = 0;
278 }
279 }
280
ixheaacd_mps_par2umx_pred(ia_mps_dec_state_struct * self,ia_mps_bs_frame * curr_bit_stream,WORD32 * h_imag,WORD32 * h_real,WORD32 param_set_idx,WORD32 res_bands)281 VOID ixheaacd_mps_par2umx_pred(ia_mps_dec_state_struct *self,
282 ia_mps_bs_frame *curr_bit_stream, WORD32 *h_imag,
283 WORD32 *h_real, WORD32 param_set_idx,
284 WORD32 res_bands) {
285 WORD32 band;
286
287 for (band = 0; band < self->bs_param_bands; band++) {
288 WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15;
289 WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band];
290 WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15;
291
292 if ((band < self->num_bands_ipd) && (cld_idx == 15) && (icc_idx == 0) &&
293 (ipd_idx == 8)) {
294 WORD32 gain = 111848107;
295 *h_imag++ = 0;
296 *h_imag++ = 0;
297
298 if (band < res_bands) {
299 *h_real++ = gain;
300 *h_real++ = gain;
301 h_real += 2;
302
303 *h_real++ = gain;
304 *h_real++ = -gain;
305 } else {
306 *h_real++ = gain;
307 *h_real++ = -gain;
308
309 h_real += 4;
310 }
311 } else {
312 WORD32 weight_fix, re_weight_fix, im_weight_fix;
313
314 weight_fix = ixheaacd_weight_Q28[ipd_idx][icc_idx][cld_idx];
315 re_weight_fix = ixheaacd_re_weight_Q28[ipd_idx][icc_idx][cld_idx];
316 im_weight_fix = ixheaacd_im_weight_Q28[ipd_idx][icc_idx][cld_idx];
317
318 if (band < self->num_bands_ipd) {
319 weight_fix = ixheaacd_weight_Q28[ipd_idx][icc_idx][cld_idx];
320 re_weight_fix = ixheaacd_re_weight_Q28[ipd_idx][icc_idx][cld_idx];
321 im_weight_fix = ixheaacd_im_weight_Q28[ipd_idx][icc_idx][cld_idx];
322 } else {
323 weight_fix = ixheaacd_weight_Q28[0][icc_idx][cld_idx];
324 re_weight_fix = ixheaacd_re_weight_Q28[0][icc_idx][cld_idx];
325 im_weight_fix = ixheaacd_im_weight_Q28[0][icc_idx][cld_idx];
326 }
327
328 *h_real++ = weight_fix - re_weight_fix;
329 *h_imag++ = -im_weight_fix;
330 *h_real++ = weight_fix + re_weight_fix;
331 *h_imag++ = im_weight_fix;
332
333 if (band < res_bands) {
334 h_real += 2;
335
336 *h_real++ = weight_fix;
337 *h_real++ = -weight_fix;
338 } else {
339 WORD32 beta = ixheaacd_beta_Q28[ipd_idx][icc_idx][cld_idx];
340
341 *h_real++ = beta;
342 *h_real++ = -beta;
343 h_real += 2;
344 }
345 }
346 }
347 }
348
ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct * self)349 WORD32 ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self) {
350 WORD32 ts, qs, row, col = 0;
351 WORD32 err = 0;
352 err = ixheaacd_mps_upmix_interp(
353 self->m1_param_re, self->r_out_re_scratch_m1, self->m1_param_re_prev,
354 (self->dir_sig_count + self->decor_sig_count), 1, self);
355 if (err < 0) return err;
356 err = ixheaacd_mps_upmix_interp(
357 self->m1_param_im, self->r_out_im_scratch_m1, self->m1_param_im_prev,
358 (self->dir_sig_count + self->decor_sig_count), 1, self);
359 if (err < 0) return err;
360
361 ixheaacd_fix_to_float_int(
362 (WORD32 *)(self->r_out_re_scratch_m1), (FLOAT32 *)(self->r_out_re_in_m1),
363 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT,
364 1073741824);
365 ixheaacd_fix_to_float_int(
366 (WORD32 *)self->r_out_im_scratch_m1, (FLOAT32 *)self->r_out_im_in_m1,
367 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT,
368 1073741824);
369
370 for (ts = 0; ts < self->time_slots; ts++) {
371 for (qs = 0; qs < 2; qs++) {
372 WORD32 sign = -1;
373 WORD32 indx = self->hyb_band_to_processing_band_table[qs];
374 for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
375 row++) {
376 FLOAT32 sum_real = 0.0f;
377 FLOAT32 sum_imag = 0.0f;
378
379 {
380 FLOAT32 real = self->hyb_in[0][ts][qs].re *
381 self->r_out_re_in_m1[ts][indx][row][col] -
382 self->hyb_in[0][ts][qs].im *
383 self->r_out_im_in_m1[ts][indx][row][col] * sign;
384 FLOAT32 imag = self->hyb_in[0][ts][qs].re *
385 self->r_out_im_in_m1[ts][indx][row][col] * sign +
386 self->hyb_in[0][ts][qs].im *
387 self->r_out_re_in_m1[ts][indx][row][col];
388 sum_real += real;
389 sum_imag += imag;
390 }
391 self->v[row][ts][qs].re = sum_real;
392 self->v[row][ts][qs].im = sum_imag;
393 }
394 }
395 for (qs = 2; qs < self->hyb_band_count; qs++) {
396 WORD32 sign = 1;
397 WORD32 indx = self->hyb_band_to_processing_band_table[qs];
398 for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
399 row++) {
400 FLOAT32 sum_real = 0.0f;
401 FLOAT32 sum_imag = 0.0f;
402
403 {
404 FLOAT32 real = self->hyb_in[0][ts][qs].re *
405 self->r_out_re_in_m1[ts][indx][row][col] -
406 self->hyb_in[0][ts][qs].im *
407 self->r_out_im_in_m1[ts][indx][row][col] * sign;
408 FLOAT32 imag = self->hyb_in[0][ts][qs].re *
409 self->r_out_im_in_m1[ts][indx][row][col] * sign +
410 self->hyb_in[0][ts][qs].im *
411 self->r_out_re_in_m1[ts][indx][row][col];
412 sum_real += real;
413 sum_imag += imag;
414 }
415 self->v[row][ts][qs].re = sum_real;
416 self->v[row][ts][qs].im = sum_imag;
417 }
418 }
419 }
420 return 0;
421 }
422
ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct * self)423 WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) {
424 WORD32 ts, qs, row, col;
425 WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
426 WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
427 WORD32 err = 0;
428 err = ixheaacd_mps_upmix_interp(
429 self->m2_decor_re, self->r_diff_out_re_fix_in_m2, self->m2_decor_re_prev,
430 self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self);
431 if (err < 0) return err;
432 err = ixheaacd_mps_upmix_interp(
433 self->m2_resid_re, self->r_out_re_fix_in_m2, self->m2_resid_re_prev,
434 self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self);
435 if (err < 0) return err;
436 ixheaacd_fix_to_float_int(
437 (WORD32 *)self->r_out_re_fix_in_m2, (FLOAT32 *)self->r_out_re_in_m2,
438 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT,
439 268435456);
440 ixheaacd_fix_to_float_int(
441 (WORD32 *)self->r_diff_out_re_fix_in_m2,
442 (FLOAT32 *)self->r_out_diff_re_in_m2,
443 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT,
444 268435456);
445
446 if (complex_m2 && !phase_interpolation) {
447 err = ixheaacd_mps_upmix_interp(
448 self->m2_decor_im, self->r_diff_out_im_fix_in_m2,
449 self->m2_decor_im_prev, self->out_ch_count,
450 (self->dir_sig_count + self->decor_sig_count), self);
451 if (err < 0) return err;
452 err = ixheaacd_mps_upmix_interp(
453 self->m2_resid_im, self->r_out_im_fix_in_m2, self->m2_resid_im_prev,
454 self->out_ch_count, (self->dir_sig_count + self->decor_sig_count),
455 self);
456 if (err < 0) return err;
457 ixheaacd_fix_to_float_int(
458 (WORD32 *)self->r_diff_out_im_fix_in_m2,
459 (FLOAT32 *)self->r_out_diff_im_in_m2,
460 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT,
461 268435456);
462 ixheaacd_fix_to_float_int(
463 (WORD32 *)self->r_out_im_fix_in_m2, (FLOAT32 *)self->r_out_im_in_m2,
464 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT,
465 268435456);
466 }
467
468 if (phase_interpolation) {
469 ixheaacd_mps_phase_interpolation(
470 self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
471 self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
472
473 for (ts = 0; ts < self->time_slots; ts++) {
474 WORD32 pb;
475 for (pb = 0; pb < self->bs_param_bands; pb++) {
476 for (row = 0; row < self->out_ch_count; row++) {
477 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count);
478 col++) {
479 self->r_out_im_in_m2[ts][pb][row][col] =
480 self->r_out_re_in_m2[ts][pb][row][col] *
481 self->r_out_ph_im_in_m2[ts][pb][row];
482 self->r_out_re_in_m2[ts][pb][row][col] =
483 self->r_out_re_in_m2[ts][pb][row][col] *
484 self->r_out_ph_re_in_m2[ts][pb][row];
485
486 self->r_out_diff_im_in_m2[ts][pb][row][col] =
487 self->r_out_diff_re_in_m2[ts][pb][row][col] *
488 self->r_out_ph_im_in_m2[ts][pb][row];
489 self->r_out_diff_re_in_m2[ts][pb][row][col] =
490 self->r_out_diff_re_in_m2[ts][pb][row][col] *
491 self->r_out_ph_re_in_m2[ts][pb][row];
492 }
493 }
494 }
495 }
496 }
497
498 for (ts = 0; ts < self->time_slots; ts++) {
499 for (qs = 0; qs < self->hyb_band_count; qs++) {
500 WORD32 indx = self->hyb_band_to_processing_band_table[qs];
501 for (row = 0; row < self->out_ch_count; row++) {
502 FLOAT32 sum_re_dir = 0;
503 FLOAT32 sum_re_diff = 0;
504 FLOAT32 sum_im_dir = 0;
505 FLOAT32 sum_im_diff = 0;
506 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count);
507 col++) {
508 sum_re_dir += self->w_dir[col][ts][qs].re *
509 self->r_out_re_in_m2[ts][indx][row][col];
510 sum_im_dir += self->w_dir[col][ts][qs].im *
511 self->r_out_re_in_m2[ts][indx][row][col];
512 sum_re_diff += self->w_diff[col][ts][qs].re *
513 self->r_out_diff_re_in_m2[ts][indx][row][col];
514 sum_im_diff += self->w_diff[col][ts][qs].im *
515 self->r_out_diff_re_in_m2[ts][indx][row][col];
516 }
517 self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
518 self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
519 self->hyb_diff_out[row][ts][qs].re = sum_re_diff;
520 self->hyb_diff_out[row][ts][qs].im = sum_im_diff;
521 }
522 }
523 }
524
525 if (complex_m2) {
526 for (ts = 0; ts < self->time_slots; ts++) {
527 for (qs = 0; qs < 2; qs++) {
528 WORD32 indx = self->hyb_band_to_processing_band_table[qs];
529 for (row = 0; row < self->out_ch_count; row++) {
530 FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
531 FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
532 FLOAT32 sum_re_diff = self->hyb_diff_out[row][ts][qs].re;
533 FLOAT32 sum_im_diff = self->hyb_diff_out[row][ts][qs].im;
534 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count);
535 col++) {
536 sum_re_dir += self->w_dir[col][ts][qs].im *
537 self->r_out_im_in_m2[ts][indx][row][col];
538 sum_im_dir -= self->w_dir[col][ts][qs].re *
539 self->r_out_im_in_m2[ts][indx][row][col];
540 sum_re_diff += self->w_diff[col][ts][qs].im *
541 self->r_out_diff_im_in_m2[ts][indx][row][col];
542 sum_im_diff -= self->w_diff[col][ts][qs].re *
543 self->r_out_diff_im_in_m2[ts][indx][row][col];
544 }
545 self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
546 self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
547 self->hyb_diff_out[row][ts][qs].re = sum_re_diff;
548 self->hyb_diff_out[row][ts][qs].im = sum_im_diff;
549 }
550 }
551 for (qs = 2; qs < self->hyb_band_count; qs++) {
552 WORD32 indx = self->hyb_band_to_processing_band_table[qs];
553 for (row = 0; row < self->out_ch_count; row++) {
554 FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
555 FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
556 FLOAT32 sum_re_diff = self->hyb_diff_out[row][ts][qs].re;
557 FLOAT32 sum_im_diff = self->hyb_diff_out[row][ts][qs].im;
558 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count);
559 col++) {
560 sum_re_dir -= self->w_dir[col][ts][qs].im *
561 self->r_out_im_in_m2[ts][indx][row][col];
562 sum_im_dir += self->w_dir[col][ts][qs].re *
563 self->r_out_im_in_m2[ts][indx][row][col];
564 sum_re_diff -= self->w_diff[col][ts][qs].im *
565 self->r_out_diff_im_in_m2[ts][indx][row][col];
566 sum_im_diff += self->w_diff[col][ts][qs].re *
567 self->r_out_diff_im_in_m2[ts][indx][row][col];
568 }
569 self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
570 self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
571 self->hyb_diff_out[row][ts][qs].re = sum_re_diff;
572 self->hyb_diff_out[row][ts][qs].im = sum_im_diff;
573 }
574 }
575 }
576 }
577 return 0;
578 }
579
ixheaacd_mult32_shl2(WORD32 a,WORD32 b)580 static PLATFORM_INLINE WORD32 ixheaacd_mult32_shl2(WORD32 a, WORD32 b) {
581 WORD32 result;
582 WORD64 temp_result;
583
584 temp_result = (WORD64)a * (WORD64)b;
585 result = (WORD32)(temp_result >> 30);
586
587 return (result);
588 }
589
ixheaacd_mps_upmix_interp(WORD32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],WORD32 r_matrix[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],WORD32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],WORD32 num_rows,WORD32 num_cols,ia_mps_dec_state_struct * self)590 WORD32 ixheaacd_mps_upmix_interp(
591 WORD32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
592 [MAX_M_INPUT],
593 WORD32 r_matrix[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
594 [MAX_M_INPUT],
595 WORD32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
596 WORD32 num_rows, WORD32 num_cols, ia_mps_dec_state_struct *self) {
597 WORD32 ts, ps, pb, row, col, i;
598
599 for (pb = 0; pb < self->bs_param_bands; pb++) {
600 for (row = 0; row < num_rows; row++) {
601 for (col = 0; col < num_cols; col++) {
602 ps = 0;
603 ts = 0;
604 if (MAX_TIME_SLOTS < (self->param_slot_diff[0])) return -1;
605 for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
606 WORD32 alpha = i * self->inv_param_slot_diff_Q30[ps];
607 WORD32 one_minus_alpha = 1073741824 - alpha;
608 r_matrix[ts][pb][row][col] =
609 ((ixheaacd_mult32_shl2(m_matrix_prev[pb][row][col],
610 one_minus_alpha) +
611 ixheaacd_mult32_shl2(alpha, m_matrix[ps][pb][row][col])));
612 ts++;
613 }
614
615 for (ps = 1; ps < self->num_parameter_sets; ps++) {
616 if (MAX_TIME_SLOTS < (ts + self->param_slot_diff[ps])) return -1;
617 for (i = 1; i <= (WORD32)self->param_slot_diff[ps]; i++) {
618 WORD32 alpha = i * self->inv_param_slot_diff_Q30[ps];
619 WORD32 one_minus_alpha = 1073741824 - alpha;
620 r_matrix[ts][pb][row][col] =
621 ((ixheaacd_mult32_shl2(m_matrix[ps - 1][pb][row][col],
622 one_minus_alpha) +
623 ixheaacd_mult32_shl2(alpha, m_matrix[ps][pb][row][col])));
624 ts++;
625 }
626 }
627 }
628 }
629 }
630 return 0;
631 }
632
ixheaacd_mps_angle_interpolation(FLOAT32 angle1,FLOAT32 angle2,FLOAT32 alpha)633 static FLOAT32 ixheaacd_mps_angle_interpolation(FLOAT32 angle1, FLOAT32 angle2,
634 FLOAT32 alpha) {
635 while (angle2 - angle1 > (FLOAT32)P_PI)
636 angle1 = angle1 + 2.0f * (FLOAT32)P_PI;
637 while (angle1 - angle2 > (FLOAT32)P_PI)
638 angle2 = angle2 + 2.0f * (FLOAT32)P_PI;
639
640 return (1 - alpha) * angle1 + alpha * angle2;
641 }
642
ixheaacd_mps_phase_interpolation(FLOAT32 pl[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],FLOAT32 pr[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],FLOAT32 pl_prev[MAX_PARAMETER_BANDS],FLOAT32 pr_prev[MAX_PARAMETER_BANDS],FLOAT32 r_re[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2],FLOAT32 r_im[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2],ia_mps_dec_state_struct * self)643 VOID ixheaacd_mps_phase_interpolation(
644 FLOAT32 pl[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
645 FLOAT32 pr[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
646 FLOAT32 pl_prev[MAX_PARAMETER_BANDS], FLOAT32 pr_prev[MAX_PARAMETER_BANDS],
647 FLOAT32 r_re[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2],
648 FLOAT32 r_im[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2],
649 ia_mps_dec_state_struct *self) {
650 WORD32 ts, ps, pb;
651 WORD32 i;
652 for (pb = 0; pb < self->bs_param_bands; pb++) {
653 ps = 0;
654 ts = 0;
655 for (i = 1; i <= self->param_slot_diff[ps]; i++) {
656 FLOAT32 alpha = (FLOAT32)i * self->inv_param_slot_diff[ps];
657 FLOAT32 t;
658
659 t = ixheaacd_mps_angle_interpolation(pl_prev[pb], pl[ps][pb], alpha);
660 r_re[ts][pb][0] = (FLOAT32)cos(t);
661 r_im[ts][pb][0] = (FLOAT32)sin(t);
662
663 t = ixheaacd_mps_angle_interpolation(pr_prev[pb], pr[ps][pb], alpha);
664 r_re[ts][pb][1] = (FLOAT32)cos(t);
665 r_im[ts][pb][1] = (FLOAT32)sin(t);
666 ts++;
667 }
668
669 for (ps = 1; ps < self->num_parameter_sets; ps++) {
670 for (i = 1; i <= self->param_slot_diff[ps]; i++) {
671 FLOAT32 alpha = (FLOAT32)i * self->inv_param_slot_diff[ps];
672 FLOAT32 t;
673
674 t = ixheaacd_mps_angle_interpolation(pl[ps - 1][pb], pl[ps][pb], alpha);
675 r_re[ts][pb][0] = (FLOAT32)cos(t);
676 r_im[ts][pb][0] = (FLOAT32)sin(t);
677
678 t = ixheaacd_mps_angle_interpolation(pr[ps - 1][pb], pr[ps][pb], alpha);
679 r_re[ts][pb][1] = (FLOAT32)cos(t);
680 r_im[ts][pb][1] = (FLOAT32)sin(t);
681 ts++;
682
683 if (ts > 71) {
684 ts = 0;
685 break;
686 }
687 if (pb > 27) {
688 pb = 0;
689 break;
690 }
691 }
692 }
693 }
694 }
695
ixheaacd_mps_init_pre_and_post_matrix(ia_mps_dec_state_struct * self)696 VOID ixheaacd_mps_init_pre_and_post_matrix(ia_mps_dec_state_struct *self) {
697 memset(self->m1_param_re_prev, 0,
698 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
699 memset(self->m1_param_im_prev, 0,
700 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
701 memset(self->m1_param_re_prev, 0,
702 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
703 memset(self->m2_decor_re_prev, 0,
704 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
705 memset(self->m2_resid_re_prev, 0,
706 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
707 memset(self->m2_resid_im_prev, 0,
708 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
709 }
710