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 <string.h> 21 22 #include "ixheaacd_sbr_common.h" 23 #include <ixheaacd_type_def.h> 24 25 #include "ixheaacd_constants.h" 26 #include "ixheaacd_basic_ops32.h" 27 #include "ixheaacd_basic_ops16.h" 28 #include "ixheaacd_basic_ops40.h" 29 #include "ixheaacd_basic_ops.h" 30 31 #include "ixheaacd_intrinsics.h" 32 #include "ixheaacd_common_rom.h" 33 #include "ixheaacd_bitbuffer.h" 34 #include "ixheaacd_sbrdecsettings.h" 35 #include "ixheaacd_sbr_scale.h" 36 #include "ixheaacd_lpp_tran.h" 37 #include "ixheaacd_env_extr_part.h" 38 #include "ixheaacd_sbr_rom.h" 39 #include "ixheaacd_hybrid.h" 40 #include "ixheaacd_ps_dec.h" 41 #include "ixheaacd_env_extr.h" 42 #include "ixheaacd_qmf_dec.h" 43 44 #include <ixheaacd_basic_op.h> 45 #include "ixheaacd_env_calc.h" 46 47 #include "ixheaacd_interface.h" 48 49 #include "ixheaacd_function_selector.h" 50 #include "ixheaacd_audioobjtypes.h" 51 52 #define mult16x16_16(a, b) ixheaacd_mult16((a), (b)) 53 #define mac16x16(a, b, c) ixheaacd_mac16x16in32((a), (b), (c)) 54 #define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b)) 55 #define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b)) 56 #define mpy_32x32(a, b) ixheaacd_mult32((a), (b)) 57 #define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b)) 58 #define msu16x16(a, b, c) msu16x16in32((a), (b), (c)) 59 60 #define DCT3_LEN (32) 61 #define DCT2_LEN (64) 62 63 #define LP_SHIFT_VAL 7 64 #define HQ_SHIFT_64 4 65 #define RADIXSHIFT 1 66 #define ROUNDING_SPECTRA 1 67 #define HQ_SHIFT_VAL 4 68 69 VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, 70 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, 71 WORD16 *filter_states) { 72 ixheaacd_pretwdct2(x, X); 73 74 ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x, 75 qmf_dec_tables_ptr->dig_rev_table2_128, 76 qmf_dec_tables_ptr->dig_rev_table2_128, 77 qmf_dec_tables_ptr->dig_rev_table2_128, 78 qmf_dec_tables_ptr->dig_rev_table2_128); 79 80 ixheaacd_fftposttw(x, qmf_dec_tables_ptr); 81 82 ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr); 83 84 return; 85 } 86 87 VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf, 88 ia_sbr_scale_fact_struct *sbr_scale_factor, 89 WORD32 **qmf_real, WORD32 **qmf_imag, 90 ia_sbr_qmf_filter_bank_struct *qmf_bank, 91 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, 92 WORD32 ch_fac, WORD32 low_pow_flag, 93 WORD audio_object_type) { 94 WORD32 i, k; 95 WORD32 num_time_slots = qmf_bank->num_time_slots; 96 97 WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS]; 98 WORD16 *filter_states = qmf_bank->core_samples_buffer; 99 100 WORD16 *fp1, *fp2, *tmp; 101 102 WORD16 *filter_1; 103 WORD16 *filter_2; 104 WORD16 *filt_ptr; 105 if (audio_object_type != AOT_ER_AAC_ELD && 106 audio_object_type != AOT_ER_AAC_LD) { 107 qmf_bank->filter_pos += 108 (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff); 109 qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c; 110 } else { 111 qmf_bank->filter_pos += 112 (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff); 113 qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3; 114 } 115 116 filter_1 = qmf_bank->filter_pos; 117 118 if (audio_object_type != AOT_ER_AAC_ELD && 119 audio_object_type != AOT_ER_AAC_LD) { 120 filter_2 = filter_1 + 64; 121 } else { 122 filter_2 = filter_1 + 32; 123 } 124 125 sbr_scale_factor->st_lb_scale = 0; 126 sbr_scale_factor->lb_scale = -10; 127 if (!low_pow_flag) { 128 if (audio_object_type != AOT_ER_AAC_ELD && 129 audio_object_type != AOT_ER_AAC_LD) { 130 sbr_scale_factor->lb_scale = -8; 131 } else { 132 sbr_scale_factor->lb_scale = -9; 133 } 134 qmf_bank->cos_twiddle = 135 (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32; 136 qmf_bank->alt_sin_twiddle = 137 (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32; 138 if (audio_object_type != AOT_ER_AAC_ELD && 139 audio_object_type != AOT_ER_AAC_LD) { 140 qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32; 141 } else { 142 qmf_bank->t_cos = 143 (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld; 144 } 145 } 146 147 fp1 = qmf_bank->anal_filter_states; 148 fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS; 149 150 if (audio_object_type == AOT_ER_AAC_ELD || 151 audio_object_type == AOT_ER_AAC_LD) { 152 filter_2 = qmf_bank->filter_2; 153 fp1 = qmf_bank->fp1_anal; 154 fp2 = qmf_bank->fp2_anal; 155 } 156 157 for (i = 0; i < num_time_slots; i++) { 158 for (k = 0; k < NO_ANALYSIS_CHANNELS; k++) 159 filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k]; 160 161 if (audio_object_type != AOT_ER_AAC_ELD && 162 audio_object_type != AOT_ER_AAC_LD) { 163 ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2, 164 analysis_buffer, filter_states, 165 time_sample_buf, ch_fac); 166 } else { 167 ixheaacd_sbr_qmfanal32_winadds_eld(fp1, fp2, filter_1, filter_2, 168 analysis_buffer, filter_states, 169 time_sample_buf, ch_fac); 170 } 171 172 time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac; 173 174 filter_states -= NO_ANALYSIS_CHANNELS; 175 if (filter_states < qmf_bank->anal_filter_states) { 176 filter_states = qmf_bank->anal_filter_states + 288; 177 } 178 179 tmp = fp1; 180 fp1 = fp2; 181 fp2 = tmp; 182 if (audio_object_type != AOT_ER_AAC_ELD && 183 audio_object_type != AOT_ER_AAC_LD) { 184 filter_1 += 64; 185 filter_2 += 64; 186 } else { 187 filter_1 += 32; 188 filter_2 += 32; 189 } 190 191 filt_ptr = filter_1; 192 filter_1 = filter_2; 193 filter_2 = filt_ptr; 194 if (audio_object_type != AOT_ER_AAC_ELD && 195 audio_object_type != AOT_ER_AAC_LD) { 196 if (filter_2 > (qmf_bank->analy_win_coeff + 640)) { 197 filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; 198 filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64; 199 } 200 } else { 201 if (filter_2 > (qmf_bank->analy_win_coeff + 320)) { 202 filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; 203 filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32; 204 } 205 } 206 207 if (!low_pow_flag) { 208 ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], 209 qmf_bank, qmf_dec_tables_ptr); 210 } else { 211 ixheaacd_dct3_32( 212 (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw, 213 qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16, 214 qmf_dec_tables_ptr->dig_rev_table4_16); 215 } 216 } 217 218 qmf_bank->filter_pos = filter_1; 219 qmf_bank->core_samples_buffer = filter_states; 220 221 if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) 222 223 { 224 qmf_bank->fp1_anal = fp1; 225 qmf_bank->fp2_anal = fp2; 226 qmf_bank->filter_2 = filter_2; 227 } 228 } 229 230 VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, 231 ia_sbr_qmf_filter_bank_struct *syn_qmf, 232 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 233 WORD32 L = syn_qmf->no_channels; 234 const WORD32 M = (L >> 1); 235 WORD32 *dct_in = qmf_real; 236 WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS]; 237 238 WORD32 ui_rem = ((WORD32)(&time_out[0]) % 8); 239 WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem); 240 241 if (L == 64) 242 ixheaacd_dec_DCT2_64_asm(dct_in, ptime_out, qmf_dec_tables_ptr->w1024, 243 qmf_dec_tables_ptr->dig_rev_table2_128, 244 qmf_dec_tables_ptr->post_fft_tbl, 245 qmf_dec_tables_ptr->dct23_tw, filter_states + M); 246 else 247 ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states); 248 249 filter_states[3 * M] = 0; 250 } 251 252 VOID ixheaacd_inv_emodulation(WORD32 *qmf_real, 253 ia_sbr_qmf_filter_bank_struct *syn_qmf, 254 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { 255 ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024, 256 (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); 257 } 258 259 VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, 260 ia_sbr_qmf_filter_bank_struct *qmf_bank, 261 WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) { 262 WORD32 z; 263 WORD32 temp[128]; 264 WORD32 scaleshift = 0; 265 266 WORD32 M_2; 267 WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); 268 269 const WORD32 *p_sin; 270 const WORD32 *p_sin_cos; 271 272 WORD32 subband_tmp[128]; 273 274 p_sin_cos = qmf_bank->esbr_cos_twiddle; 275 ixheaacd_esbr_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp); 276 277 M_2 = ixheaacd_shr32(M, 1); 278 if (M == 32) { 279 ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8); 280 ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); 281 ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); 282 283 ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); 284 ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); 285 ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl, 286 32); 287 288 } 289 290 else if (M == 16) { 291 ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4); 292 ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); 293 294 ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); 295 ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl, 296 16); 297 298 } 299 300 else if (M == 12) { 301 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 302 temp[z] = subband_tmp[2 * z]; 303 temp[12 + z] = subband_tmp[2 * z + 1]; 304 } 305 306 ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); 307 308 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 309 subband[2 * z] = temp[z]; 310 subband[2 * z + 1] = temp[z + 12]; 311 } 312 scaleshift = 0; 313 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 314 temp[z] = subband_tmp[64 + 2 * z]; 315 temp[12 + z] = subband_tmp[64 + 2 * z + 1]; 316 } 317 318 ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); 319 320 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 321 subband[64 + 2 * z] = temp[z]; 322 subband[64 + 2 * z + 1] = temp[z + 12]; 323 } 324 325 } 326 327 else { 328 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 329 temp[z] = subband_tmp[2 * z]; 330 temp[8 + z] = subband_tmp[2 * z + 1]; 331 } 332 333 (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); 334 335 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 336 subband[2 * z] = temp[z] << scaleshift; 337 subband[2 * z + 1] = temp[z + 8] << scaleshift; 338 } 339 scaleshift = 0; 340 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 341 temp[z] = subband_tmp[64 + 2 * z]; 342 temp[8 + z] = subband_tmp[64 + 2 * z + 1]; 343 } 344 345 (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); 346 347 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { 348 subband[64 + 2 * z] = temp[z] << scaleshift; 349 subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift; 350 } 351 } 352 p_sin = qmf_bank->esbr_alt_sin_twiddle; 353 ixheaacd_esbr_cos_sin_mod_loop2(subband, p_sin, M); 354 } 355