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[16][31]; 59 extern const WORD32 ixheaacd_cos_table_Q31[16][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 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 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 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 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 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 c_l_temp = (ixheaacd_c_l_table_Q31[cld_idx]); 205 c_r_temp = (ixheaacd_c_l_table_Q31[30 - cld_idx]); 206 207 temp = ixheaacd_cos_table_Q31[icc_idx][cld_idx]; 208 *h_real++ = ixheaacd_mult32(temp, c_l_temp) >> 2; 209 210 temp = ixheaacd_cos_table_Q31[icc_idx][30 - cld_idx]; 211 *h_real++ = ixheaacd_mult32(temp, c_r_temp) >> 2; 212 213 temp = ixheaacd_sin_table_Q31[icc_idx][cld_idx]; 214 *h_real++ = ixheaacd_mult32(temp, c_l_temp) >> 2; 215 216 temp = -ixheaacd_sin_table_Q31[icc_idx][30 - cld_idx]; 217 *h_real++ = ixheaacd_mult32(temp, c_r_temp) >> 2; 218 219 h_real += 2; 220 } 221 } 222 223 VOID ixheaacd_mps_par2umx_ps(ia_mps_dec_state_struct *self, 224 ia_mps_bs_frame *curr_bit_stream, WORD32 *h_real, 225 WORD32 param_set_idx) { 226 ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx], 227 curr_bit_stream->icc_idx[param_set_idx], 228 self->bs_param_bands, h_real); 229 } 230 231 static VOID ixheaacd_mps_opd_calc(ia_mps_dec_state_struct *self, 232 ia_mps_bs_frame *curr_bit_stream, 233 WORD32 param_set_idx, 234 WORD32 opd[MAX_PARAMETER_BANDS]) { 235 WORD32 band; 236 237 for (band = 0; band < self->num_bands_ipd; band++) { 238 WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15; 239 WORD32 ipd_idx = (curr_bit_stream->ipd_idx[param_set_idx][band]) & 15; 240 WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band]; 241 242 if ((cld_idx == 15) && (ipd_idx == 8)) 243 opd[band] = 0; 244 else 245 opd[band] = ixheaacd_atan_table_Q28[ipd_idx][icc_idx][cld_idx]; 246 } 247 } 248 249 VOID ixheaacd_mps_par2umx_ps_ipd_opd(ia_mps_dec_state_struct *self, 250 ia_mps_bs_frame *curr_bit_stream, 251 WORD32 *h_real, WORD32 param_set_idx) { 252 WORD32 opd[MAX_PARAMETER_BANDS]; 253 WORD32 ott_band_count = self->bs_param_bands; 254 WORD32 num_bands_ipd = self->num_bands_ipd; 255 WORD32 band; 256 257 ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx], 258 curr_bit_stream->icc_idx[param_set_idx], 259 ott_band_count, h_real); 260 261 if (self->bs_phase_mode) { 262 ixheaacd_mps_opd_calc(self, curr_bit_stream, param_set_idx, opd); 263 264 for (band = 0; band < num_bands_ipd; band++) { 265 WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15; 266 WORD32 ipd = ixheaacd_ipd_de_quant_table_q28[ipd_idx]; 267 268 self->phase_l_fix[param_set_idx][band] = 269 ixheaacd_mps_phase_wraping(opd[band]); 270 self->phase_r_fix[param_set_idx][band] = 271 ixheaacd_mps_phase_wraping(opd[band] - ipd); 272 } 273 } else { 274 num_bands_ipd = 0; 275 } 276 277 for (band = num_bands_ipd; band < ott_band_count; band++) { 278 self->phase_l_fix[param_set_idx][band] = 0; 279 self->phase_r_fix[param_set_idx][band] = 0; 280 } 281 } 282 283 VOID ixheaacd_mps_par2umx_pred(ia_mps_dec_state_struct *self, 284 ia_mps_bs_frame *curr_bit_stream, WORD32 *h_imag, 285 WORD32 *h_real, WORD32 param_set_idx, 286 WORD32 res_bands) { 287 WORD32 band; 288 289 for (band = 0; band < self->bs_param_bands; band++) { 290 WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15; 291 WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band]; 292 WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15; 293 294 if ((band < self->num_bands_ipd) && (cld_idx == 15) && (icc_idx == 0) && 295 (ipd_idx == 8)) { 296 WORD32 gain = 111848107; 297 *h_imag++ = 0; 298 *h_imag++ = 0; 299 300 if (band < res_bands) { 301 *h_real++ = gain; 302 *h_real++ = gain; 303 h_real += 2; 304 305 *h_real++ = gain; 306 *h_real++ = -gain; 307 } else { 308 *h_real++ = gain; 309 *h_real++ = -gain; 310 311 h_real += 4; 312 } 313 } else { 314 WORD32 weight_fix, re_weight_fix, im_weight_fix; 315 316 weight_fix = ixheaacd_weight_Q28[ipd_idx][icc_idx][cld_idx]; 317 re_weight_fix = ixheaacd_re_weight_Q28[ipd_idx][icc_idx][cld_idx]; 318 im_weight_fix = ixheaacd_im_weight_Q28[ipd_idx][icc_idx][cld_idx]; 319 320 if (band < self->num_bands_ipd) { 321 weight_fix = ixheaacd_weight_Q28[ipd_idx][icc_idx][cld_idx]; 322 re_weight_fix = ixheaacd_re_weight_Q28[ipd_idx][icc_idx][cld_idx]; 323 im_weight_fix = ixheaacd_im_weight_Q28[ipd_idx][icc_idx][cld_idx]; 324 } else { 325 weight_fix = ixheaacd_weight_Q28[0][icc_idx][cld_idx]; 326 re_weight_fix = ixheaacd_re_weight_Q28[0][icc_idx][cld_idx]; 327 im_weight_fix = ixheaacd_im_weight_Q28[0][icc_idx][cld_idx]; 328 } 329 330 *h_real++ = weight_fix - re_weight_fix; 331 *h_imag++ = -im_weight_fix; 332 *h_real++ = weight_fix + re_weight_fix; 333 *h_imag++ = im_weight_fix; 334 335 if (band < res_bands) { 336 h_real += 2; 337 338 *h_real++ = weight_fix; 339 *h_real++ = -weight_fix; 340 } else { 341 WORD32 beta = ixheaacd_beta_Q28[ipd_idx][icc_idx][cld_idx]; 342 343 *h_real++ = beta; 344 *h_real++ = -beta; 345 h_real += 2; 346 } 347 } 348 } 349 } 350 351 VOID ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self) { 352 WORD32 ts, qs, row, col = 0; 353 354 ixheaacd_mps_upmix_interp( 355 self->m1_param_re, self->r_out_re_scratch_m1, self->m1_param_re_prev, 356 (self->dir_sig_count + self->decor_sig_count), 1, self); 357 ixheaacd_mps_upmix_interp( 358 self->m1_param_im, self->r_out_im_scratch_m1, self->m1_param_im_prev, 359 (self->dir_sig_count + self->decor_sig_count), 1, self); 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 } 421 422 VOID ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) { 423 WORD32 ts, qs, row, col; 424 WORD32 complex_m2 = ((self->config->bs_phase_coding != 0)); 425 WORD32 phase_interpolation = (self->config->bs_phase_coding == 1); 426 427 ixheaacd_mps_upmix_interp( 428 self->m2_decor_re, self->r_diff_out_re_fix_in_m2, self->m2_decor_re_prev, 429 self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self); 430 ixheaacd_mps_upmix_interp( 431 self->m2_resid_re, self->r_out_re_fix_in_m2, self->m2_resid_re_prev, 432 self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self); 433 ixheaacd_fix_to_float_int( 434 (WORD32 *)self->r_out_re_fix_in_m2, (FLOAT32 *)self->r_out_re_in_m2, 435 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT, 436 268435456); 437 ixheaacd_fix_to_float_int( 438 (WORD32 *)self->r_diff_out_re_fix_in_m2, 439 (FLOAT32 *)self->r_out_diff_re_in_m2, 440 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT, 441 268435456); 442 443 if (complex_m2 && !phase_interpolation) { 444 ixheaacd_mps_upmix_interp(self->m2_decor_im, self->r_diff_out_im_fix_in_m2, 445 self->m2_decor_im_prev, self->out_ch_count, 446 (self->dir_sig_count + self->decor_sig_count), 447 self); 448 ixheaacd_mps_upmix_interp(self->m2_resid_im, self->r_out_im_fix_in_m2, 449 self->m2_resid_im_prev, self->out_ch_count, 450 (self->dir_sig_count + self->decor_sig_count), 451 self); 452 ixheaacd_fix_to_float_int( 453 (WORD32 *)self->r_diff_out_im_fix_in_m2, 454 (FLOAT32 *)self->r_out_diff_im_in_m2, 455 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT, 456 268435456); 457 ixheaacd_fix_to_float_int( 458 (WORD32 *)self->r_out_im_fix_in_m2, (FLOAT32 *)self->r_out_im_in_m2, 459 MAX_TIME_SLOTS * MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT, 460 268435456); 461 } 462 463 if (phase_interpolation) { 464 ixheaacd_mps_phase_interpolation( 465 self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev, 466 self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self); 467 468 for (ts = 0; ts < self->time_slots; ts++) { 469 WORD32 pb; 470 for (pb = 0; pb < self->bs_param_bands; pb++) { 471 for (row = 0; row < self->out_ch_count; row++) { 472 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count); 473 col++) { 474 self->r_out_im_in_m2[ts][pb][row][col] = 475 self->r_out_re_in_m2[ts][pb][row][col] * 476 self->r_out_ph_im_in_m2[ts][pb][row]; 477 self->r_out_re_in_m2[ts][pb][row][col] = 478 self->r_out_re_in_m2[ts][pb][row][col] * 479 self->r_out_ph_re_in_m2[ts][pb][row]; 480 481 self->r_out_diff_im_in_m2[ts][pb][row][col] = 482 self->r_out_diff_re_in_m2[ts][pb][row][col] * 483 self->r_out_ph_im_in_m2[ts][pb][row]; 484 self->r_out_diff_re_in_m2[ts][pb][row][col] = 485 self->r_out_diff_re_in_m2[ts][pb][row][col] * 486 self->r_out_ph_re_in_m2[ts][pb][row]; 487 } 488 } 489 } 490 } 491 } 492 493 for (ts = 0; ts < self->time_slots; ts++) { 494 for (qs = 0; qs < self->hyb_band_count; qs++) { 495 WORD32 indx = self->hyb_band_to_processing_band_table[qs]; 496 for (row = 0; row < self->out_ch_count; row++) { 497 FLOAT32 sum_re_dir = 0; 498 FLOAT32 sum_re_diff = 0; 499 FLOAT32 sum_im_dir = 0; 500 FLOAT32 sum_im_diff = 0; 501 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count); 502 col++) { 503 sum_re_dir += self->w_dir[col][ts][qs].re * 504 self->r_out_re_in_m2[ts][indx][row][col]; 505 sum_im_dir += self->w_dir[col][ts][qs].im * 506 self->r_out_re_in_m2[ts][indx][row][col]; 507 sum_re_diff += self->w_diff[col][ts][qs].re * 508 self->r_out_diff_re_in_m2[ts][indx][row][col]; 509 sum_im_diff += self->w_diff[col][ts][qs].im * 510 self->r_out_diff_re_in_m2[ts][indx][row][col]; 511 } 512 self->hyb_dir_out[row][ts][qs].re = sum_re_dir; 513 self->hyb_dir_out[row][ts][qs].im = sum_im_dir; 514 self->hyb_diff_out[row][ts][qs].re = sum_re_diff; 515 self->hyb_diff_out[row][ts][qs].im = sum_im_diff; 516 } 517 } 518 } 519 520 if (complex_m2) { 521 for (ts = 0; ts < self->time_slots; ts++) { 522 for (qs = 0; qs < 2; qs++) { 523 WORD32 indx = self->hyb_band_to_processing_band_table[qs]; 524 for (row = 0; row < self->out_ch_count; row++) { 525 FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re; 526 FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im; 527 FLOAT32 sum_re_diff = self->hyb_diff_out[row][ts][qs].re; 528 FLOAT32 sum_im_diff = self->hyb_diff_out[row][ts][qs].im; 529 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count); 530 col++) { 531 sum_re_dir += self->w_dir[col][ts][qs].im * 532 self->r_out_im_in_m2[ts][indx][row][col]; 533 sum_im_dir -= self->w_dir[col][ts][qs].re * 534 self->r_out_im_in_m2[ts][indx][row][col]; 535 sum_re_diff += self->w_diff[col][ts][qs].im * 536 self->r_out_diff_im_in_m2[ts][indx][row][col]; 537 sum_im_diff -= self->w_diff[col][ts][qs].re * 538 self->r_out_diff_im_in_m2[ts][indx][row][col]; 539 } 540 self->hyb_dir_out[row][ts][qs].re = sum_re_dir; 541 self->hyb_dir_out[row][ts][qs].im = sum_im_dir; 542 self->hyb_diff_out[row][ts][qs].re = sum_re_diff; 543 self->hyb_diff_out[row][ts][qs].im = sum_im_diff; 544 } 545 } 546 for (qs = 2; qs < self->hyb_band_count; qs++) { 547 WORD32 indx = self->hyb_band_to_processing_band_table[qs]; 548 for (row = 0; row < self->out_ch_count; row++) { 549 FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re; 550 FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im; 551 FLOAT32 sum_re_diff = self->hyb_diff_out[row][ts][qs].re; 552 FLOAT32 sum_im_diff = self->hyb_diff_out[row][ts][qs].im; 553 for (col = 0; col < (self->dir_sig_count + self->decor_sig_count); 554 col++) { 555 sum_re_dir -= self->w_dir[col][ts][qs].im * 556 self->r_out_im_in_m2[ts][indx][row][col]; 557 sum_im_dir += self->w_dir[col][ts][qs].re * 558 self->r_out_im_in_m2[ts][indx][row][col]; 559 sum_re_diff -= self->w_diff[col][ts][qs].im * 560 self->r_out_diff_im_in_m2[ts][indx][row][col]; 561 sum_im_diff += self->w_diff[col][ts][qs].re * 562 self->r_out_diff_im_in_m2[ts][indx][row][col]; 563 } 564 self->hyb_dir_out[row][ts][qs].re = sum_re_dir; 565 self->hyb_dir_out[row][ts][qs].im = sum_im_dir; 566 self->hyb_diff_out[row][ts][qs].re = sum_re_diff; 567 self->hyb_diff_out[row][ts][qs].im = sum_im_diff; 568 } 569 } 570 } 571 } 572 } 573 574 static PLATFORM_INLINE WORD32 ixheaacd_mult32_shl2(WORD32 a, WORD32 b) { 575 WORD32 result; 576 WORD64 temp_result; 577 578 temp_result = (WORD64)a * (WORD64)b; 579 result = (WORD32)(temp_result >> 30); 580 581 return (result); 582 } 583 584 VOID ixheaacd_mps_upmix_interp( 585 WORD32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT] 586 [MAX_M_INPUT], 587 WORD32 r_matrix[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT] 588 [MAX_M_INPUT], 589 WORD32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT], 590 WORD32 num_rows, WORD32 num_cols, ia_mps_dec_state_struct *self) { 591 WORD32 ts, ps, pb, row, col, i; 592 593 for (pb = 0; pb < self->bs_param_bands; pb++) { 594 for (row = 0; row < num_rows; row++) { 595 for (col = 0; col < num_cols; col++) { 596 ps = 0; 597 ts = 0; 598 for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) { 599 WORD32 alpha = i * self->inv_param_slot_diff_Q30[ps]; 600 WORD32 one_minus_alpha = 1073741824 - alpha; 601 r_matrix[ts][pb][row][col] = 602 ((ixheaacd_mult32_shl2(m_matrix_prev[pb][row][col], 603 one_minus_alpha) + 604 ixheaacd_mult32_shl2(alpha, m_matrix[ps][pb][row][col]))); 605 ts++; 606 } 607 608 for (ps = 1; ps < self->num_parameter_sets; ps++) { 609 for (i = 1; i <= (WORD32)self->param_slot_diff[ps]; 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[ps - 1][pb][row][col], 614 one_minus_alpha) + 615 ixheaacd_mult32_shl2(alpha, m_matrix[ps][pb][row][col]))); 616 ts++; 617 } 618 } 619 } 620 } 621 } 622 } 623 624 static FLOAT32 ixheaacd_mps_angle_interpolation(FLOAT32 angle1, FLOAT32 angle2, 625 FLOAT32 alpha) { 626 while (angle2 - angle1 > (FLOAT32)P_PI) 627 angle1 = angle1 + 2.0f * (FLOAT32)P_PI; 628 while (angle1 - angle2 > (FLOAT32)P_PI) 629 angle2 = angle2 + 2.0f * (FLOAT32)P_PI; 630 631 return (1 - alpha) * angle1 + alpha * angle2; 632 } 633 634 VOID ixheaacd_mps_phase_interpolation( 635 FLOAT32 pl[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], 636 FLOAT32 pr[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], 637 FLOAT32 pl_prev[MAX_PARAMETER_BANDS], FLOAT32 pr_prev[MAX_PARAMETER_BANDS], 638 FLOAT32 r_re[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2], 639 FLOAT32 r_im[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2], 640 ia_mps_dec_state_struct *self) { 641 WORD32 ts, ps, pb; 642 WORD32 i; 643 for (pb = 0; pb < self->bs_param_bands; pb++) { 644 ps = 0; 645 ts = 0; 646 for (i = 1; i <= self->param_slot_diff[ps]; i++) { 647 FLOAT32 alpha = (FLOAT32)i * self->inv_param_slot_diff[ps]; 648 FLOAT32 t; 649 650 t = ixheaacd_mps_angle_interpolation(pl_prev[pb], pl[ps][pb], alpha); 651 r_re[ts][pb][0] = (FLOAT32)cos(t); 652 r_im[ts][pb][0] = (FLOAT32)sin(t); 653 654 t = ixheaacd_mps_angle_interpolation(pr_prev[pb], pr[ps][pb], alpha); 655 r_re[ts][pb][1] = (FLOAT32)cos(t); 656 r_im[ts][pb][1] = (FLOAT32)sin(t); 657 ts++; 658 } 659 660 for (ps = 1; ps < self->num_parameter_sets; ps++) { 661 for (i = 1; i <= self->param_slot_diff[ps]; i++) { 662 FLOAT32 alpha = (FLOAT32)i * self->inv_param_slot_diff[ps]; 663 FLOAT32 t; 664 665 t = ixheaacd_mps_angle_interpolation(pl[ps - 1][pb], pl[ps][pb], alpha); 666 r_re[ts][pb][0] = (FLOAT32)cos(t); 667 r_im[ts][pb][0] = (FLOAT32)sin(t); 668 669 t = ixheaacd_mps_angle_interpolation(pr[ps - 1][pb], pr[ps][pb], alpha); 670 r_re[ts][pb][1] = (FLOAT32)cos(t); 671 r_im[ts][pb][1] = (FLOAT32)sin(t); 672 ts++; 673 } 674 } 675 } 676 } 677 678 VOID ixheaacd_mps_init_pre_and_post_matrix(ia_mps_dec_state_struct *self) { 679 memset(self->m1_param_re_prev, 0, 680 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32)); 681 memset(self->m1_param_im_prev, 0, 682 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32)); 683 memset(self->m1_param_re_prev, 0, 684 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32)); 685 memset(self->m2_decor_re_prev, 0, 686 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32)); 687 memset(self->m2_resid_re_prev, 0, 688 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32)); 689 memset(self->m2_resid_im_prev, 0, 690 MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32)); 691 } 692