• 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 <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