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 #include "ixheaacd_sbr_common.h" 22 #include "ixheaacd_type_def.h" 23 24 #include "ixheaacd_constants.h" 25 #include "ixheaacd_basic_ops32.h" 26 #include "ixheaacd_basic_ops16.h" 27 #include "ixheaacd_basic_ops40.h" 28 #include "ixheaacd_basic_ops.h" 29 30 #include "ixheaacd_basic_op.h" 31 #include "ixheaacd_intrinsics.h" 32 #include "ixheaacd_common_rom.h" 33 #include "ixheaacd_basic_funcs.h" 34 35 #include "ixheaacd_bitbuffer.h" 36 #include "ixheaacd_sbrdecsettings.h" 37 #include "ixheaacd_sbr_scale.h" 38 #include "ixheaacd_lpp_tran.h" 39 #include "ixheaacd_env_extr_part.h" 40 #include "ixheaacd_sbr_rom.h" 41 #include "ixheaacd_hybrid.h" 42 43 #include "ixheaacd_ps_dec.h" 44 45 #include "ixheaacd_env_extr.h" 46 47 #include "ixheaacd_dsp_fft32x32s.h" 48 49 #include "ixheaacd_function_selector.h" 50 51 static VOID ixheaacd_filt_2_ch(const WORD32 *ptr_qmf, WORD32 *ptr_hybrid, 52 ia_sbr_tables_struct *ptr_sbr_tables) { 53 WORD32 cum0, cum1, cum00, cum11; 54 WORD16 *p2_6 = ptr_sbr_tables->ps_tables_ptr->p2_6; 55 56 cum0 = ptr_qmf[HYBRID_FILTER_DELAY] >> 1; 57 cum00 = ptr_qmf[HYBRID_FILTER_DELAY + 16] >> 1; 58 cum1 = 0L; 59 cum11 = 0L; 60 61 { 62 cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[1], *p2_6)); 63 cum11 = 64 ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[17], *p2_6++)); 65 66 cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[3], *p2_6)); 67 cum11 = 68 ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[19], *p2_6++)); 69 70 cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[5], *p2_6)); 71 cum11 = 72 ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[21], *p2_6++)); 73 74 cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[7], *p2_6)); 75 cum11 = 76 ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[23], *p2_6++)); 77 78 cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[9], *p2_6)); 79 cum11 = 80 ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[25], *p2_6++)); 81 82 cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[11], *p2_6)); 83 cum11 = 84 ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[27], *p2_6++)); 85 } 86 cum1 = ixheaacd_shl32(cum1, 1); 87 cum11 = ixheaacd_shl32(cum11, 1); 88 89 ptr_hybrid[0] = ixheaacd_add32_sat(cum0, cum1); 90 ptr_hybrid[1] = ixheaacd_sub32_sat(cum0, cum1); 91 92 ptr_hybrid[16] = ixheaacd_add32_sat(cum00, cum11); 93 ptr_hybrid[17] = ixheaacd_sub32_sat(cum00, cum11); 94 } 95 96 static VOID ixheaacd_filt_8_ch(const WORD32 *ptr_qmf_real, 97 const WORD32 *ptr_qmf_imag, WORD32 *ptr_hyb_real, 98 WORD32 *ptr_hyb_imag, 99 ia_sbr_tables_struct *ptr_sbr_tables) { 100 const WORD16 tcos = 0x7642; 101 const WORD16 tsin = 0x30fc; 102 const WORD16 tcom = 0x5a82; 103 WORD32 real, imag; 104 WORD32 cum[16]; 105 const WORD16 *p8_13 = ptr_sbr_tables->ps_tables_ptr->p8_13; 106 const WORD16 *p8_13_8 = ptr_sbr_tables->ps_tables_ptr->p8_13 + 8; 107 108 real = ixheaacd_shl32( 109 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[0], *p8_13), 110 ixheaacd_mult32x16in32(ptr_qmf_real[8], *p8_13_8)), 111 1); 112 imag = ixheaacd_shl32( 113 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[0], *p8_13++), 114 ixheaacd_mult32x16in32(ptr_qmf_imag[8], *p8_13_8++)), 115 1); 116 117 cum[12] = ixheaacd_shl32( 118 ixheaacd_mult32x16in32(ixheaacd_add32_sat(imag, real), tcom), 1); 119 cum[13] = ixheaacd_shl32( 120 ixheaacd_mult32x16in32(ixheaacd_sub32_sat(imag, real), tcom), 1); 121 122 real = ixheaacd_shl32( 123 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[1], *p8_13), 124 ixheaacd_mult32x16in32(ptr_qmf_real[9], *p8_13_8)), 125 1); 126 imag = ixheaacd_shl32( 127 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[1], *p8_13++), 128 ixheaacd_mult32x16in32(ptr_qmf_imag[9], *p8_13_8++)), 129 1); 130 131 cum[10] = 132 ixheaacd_shl32(ixheaacd_add32_sat(ixheaacd_mult32x16in32(imag, tcos), 133 ixheaacd_mult32x16in32(real, tsin)), 134 1); 135 cum[11] = 136 ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(imag, tsin), 137 ixheaacd_mult32x16in32(real, tcos)), 138 1); 139 cum[9] = ixheaacd_shl32( 140 ixheaacd_mult32x16in32( 141 ixheaacd_sub32_sat(ptr_qmf_real[2], ptr_qmf_real[10]), *p8_13_8++), 142 1); 143 cum[8] = ixheaacd_shl32( 144 ixheaacd_mult32x16in32( 145 ixheaacd_sub32_sat(ptr_qmf_imag[2], ptr_qmf_imag[10]), *p8_13++), 146 1); 147 148 real = ixheaacd_shl32( 149 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[3], *p8_13), 150 ixheaacd_mult32x16in32(ptr_qmf_real[11], *p8_13_8)), 151 1); 152 imag = ixheaacd_shl32( 153 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[3], *p8_13++), 154 ixheaacd_mult32x16in32(ptr_qmf_imag[11], *p8_13_8++)), 155 1); 156 157 cum[6] = 158 ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(imag, tcos), 159 ixheaacd_mult32x16in32(real, tsin)), 160 1); 161 cum[7] = ixheaacd_shl32(ixheaacd_negate32_sat(ixheaacd_add32_sat( 162 ixheaacd_mult32x16in32(imag, tsin), 163 ixheaacd_mult32x16in32(real, tcos))), 164 1); 165 166 real = ixheaacd_shl32( 167 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[4], *p8_13), 168 ixheaacd_mult32x16in32(ptr_qmf_real[12], *p8_13_8)), 169 1); 170 imag = ixheaacd_shl32( 171 ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[4], *p8_13++), 172 ixheaacd_mult32x16in32(ptr_qmf_imag[12], *p8_13_8++)), 173 1); 174 175 cum[4] = ixheaacd_shl32( 176 ixheaacd_mult32x16in32(ixheaacd_sub32_sat(imag, real), tcom), 1); 177 cum[5] = ixheaacd_shl32( 178 ixheaacd_mult32x16in32( 179 ixheaacd_negate32_sat(ixheaacd_add32_sat(imag, real)), tcom), 180 1); 181 182 real = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_real[5], *p8_13), 1); 183 imag = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_imag[5], *p8_13++), 1); 184 185 cum[2] = 186 ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(real, tcos), 187 ixheaacd_mult32x16in32(imag, tsin)), 188 1); 189 cum[3] = 190 ixheaacd_shl32(ixheaacd_add32_sat(ixheaacd_mult32x16in32(real, tsin), 191 ixheaacd_mult32x16in32(imag, tcos)), 192 1); 193 194 cum[0] = ixheaacd_shl32( 195 ixheaacd_mult32x16in32(ptr_qmf_real[HYBRID_FILTER_DELAY], *p8_13), 1); 196 cum[1] = ixheaacd_shl32( 197 ixheaacd_mult32x16in32(ptr_qmf_imag[HYBRID_FILTER_DELAY], *p8_13++), 1); 198 199 real = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_real[7], *p8_13), 1); 200 imag = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_imag[7], *p8_13++), 1); 201 202 cum[14] = 203 ixheaacd_shl32(ixheaacd_add32_sat(ixheaacd_mult32x16in32(imag, tsin), 204 ixheaacd_mult32x16in32(real, tcos)), 205 1); 206 cum[15] = 207 ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(imag, tcos), 208 ixheaacd_mult32x16in32(real, tsin)), 209 1); 210 211 (*ixheaacd_inv_dit_fft_8pt)(cum, ptr_hyb_real, ptr_hyb_imag); 212 } 213 214 VOID ixheaacd_hybrid_analysis(const WORD32 *ptr_qmf_real, WORD32 *ptr_hyb_real, 215 WORD32 *ptr_hyb_imag, 216 ia_hybrid_struct *ptr_hybrid, WORD16 scale, 217 ia_sbr_tables_struct *ptr_sbr_tables) 218 219 { 220 WORD band, j; 221 WORD chn_offset = 0; 222 WORD32 *ptr_re, *ptr_im; 223 WORD32 *ptr_temp_real, *ptr_temp_imag; 224 225 for (band = 0; band < NO_QMF_CHANNELS_IN_HYBRID; band++) { 226 ptr_re = ptr_hybrid->ptr_qmf_buf_re[band]; 227 ptr_im = ptr_hybrid->ptr_qmf_buf_im[band]; 228 229 ptr_temp_real = &ptr_hybrid->ptr_work_re[0]; 230 ptr_temp_imag = &ptr_hybrid->ptr_work_im[0]; 231 232 *ptr_temp_real = *ptr_re; 233 *ptr_temp_imag = *ptr_im; 234 235 ptr_temp_real++; 236 ptr_re++; 237 ptr_temp_imag++; 238 ptr_im++; 239 240 for (j = ptr_hybrid->ptr_qmf_buf - 2; j >= 0; j--) { 241 *ptr_temp_real++ = *ptr_re; 242 *(ptr_re - 1) = *ptr_re; 243 ptr_re++; 244 *ptr_temp_imag++ = *ptr_im; 245 *(ptr_im - 1) = *ptr_im; 246 ptr_im++; 247 } 248 249 { 250 WORD32 temp_re = ptr_qmf_real[band]; 251 WORD32 temp_im = ptr_qmf_real[band + 0x40]; 252 253 if (scale < 0) { 254 temp_re = ixheaacd_shl32(temp_re, -scale); 255 temp_im = ixheaacd_shl32(temp_im, -scale); 256 } else { 257 temp_re = ixheaacd_shr32(temp_re, scale); 258 temp_im = ixheaacd_shr32(temp_im, scale); 259 } 260 *ptr_temp_real = temp_re; 261 *--ptr_re = temp_re; 262 263 *ptr_temp_imag = temp_im; 264 *--ptr_im = temp_im; 265 } 266 267 switch (ptr_hybrid->ptr_resol[band]) { 268 case NO_HYBRID_CHANNELS_LOW: 269 270 ixheaacd_filt_2_ch(ptr_hybrid->ptr_work_re, &ptr_hyb_real[chn_offset], 271 ptr_sbr_tables); 272 273 chn_offset += 2; 274 275 break; 276 case NO_HYBRID_CHANNELS_HIGH: 277 278 ixheaacd_filt_8_ch(ptr_hybrid->ptr_work_re, ptr_hybrid->ptr_work_im, 279 &ptr_hyb_real[chn_offset], &ptr_hyb_imag[chn_offset], 280 ptr_sbr_tables); 281 282 chn_offset += 6; 283 } 284 } 285 } 286