• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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