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