/src/libxaac/decoder/ixheaacd_hybrid.c
Line | Count | Source (jump to first uncovered line) |
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 "ixheaac_type_def.h" |
23 | | |
24 | | #include "ixheaac_constants.h" |
25 | | #include "ixheaac_basic_ops32.h" |
26 | | #include "ixheaac_basic_ops16.h" |
27 | | #include "ixheaac_basic_ops40.h" |
28 | | #include "ixheaac_basic_ops.h" |
29 | | |
30 | | #include "ixheaac_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 | 0 | ia_sbr_tables_struct *ptr_sbr_tables) { |
53 | 0 | WORD32 cum0, cum1, cum00, cum11; |
54 | 0 | WORD16 *p2_6 = ptr_sbr_tables->ps_tables_ptr->p2_6; |
55 | |
|
56 | 0 | cum0 = ptr_qmf[HYBRID_FILTER_DELAY] >> 1; |
57 | 0 | cum00 = ptr_qmf[HYBRID_FILTER_DELAY + 16] >> 1; |
58 | 0 | cum1 = 0L; |
59 | 0 | cum11 = 0L; |
60 | |
|
61 | 0 | { |
62 | 0 | cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[1], *p2_6)); |
63 | 0 | cum11 = |
64 | 0 | ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[17], *p2_6++)); |
65 | |
|
66 | 0 | cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[3], *p2_6)); |
67 | 0 | cum11 = |
68 | 0 | ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[19], *p2_6++)); |
69 | |
|
70 | 0 | cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[5], *p2_6)); |
71 | 0 | cum11 = |
72 | 0 | ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[21], *p2_6++)); |
73 | |
|
74 | 0 | cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[7], *p2_6)); |
75 | 0 | cum11 = |
76 | 0 | ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[23], *p2_6++)); |
77 | |
|
78 | 0 | cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[9], *p2_6)); |
79 | 0 | cum11 = |
80 | 0 | ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[25], *p2_6++)); |
81 | |
|
82 | 0 | cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[11], *p2_6)); |
83 | 0 | cum11 = |
84 | 0 | ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[27], *p2_6++)); |
85 | 0 | } |
86 | 0 | cum1 = ixheaac_shl32(cum1, 1); |
87 | 0 | cum11 = ixheaac_shl32(cum11, 1); |
88 | |
|
89 | 0 | ptr_hybrid[0] = ixheaac_add32_sat(cum0, cum1); |
90 | 0 | ptr_hybrid[1] = ixheaac_sub32_sat(cum0, cum1); |
91 | |
|
92 | 0 | ptr_hybrid[16] = ixheaac_add32_sat(cum00, cum11); |
93 | 0 | ptr_hybrid[17] = ixheaac_sub32_sat(cum00, cum11); |
94 | 0 | } |
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 | 0 | ia_sbr_tables_struct *ptr_sbr_tables) { |
100 | 0 | const WORD16 tcos = 0x7642; |
101 | 0 | const WORD16 tsin = 0x30fc; |
102 | 0 | const WORD16 tcom = 0x5a82; |
103 | 0 | WORD32 real, imag; |
104 | 0 | WORD32 cum[16]; |
105 | 0 | const WORD16 *p8_13 = ptr_sbr_tables->ps_tables_ptr->p8_13; |
106 | 0 | const WORD16 *p8_13_8 = ptr_sbr_tables->ps_tables_ptr->p8_13 + 8; |
107 | |
|
108 | 0 | real = ixheaac_shl32( |
109 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[0], *p8_13), |
110 | 0 | ixheaac_mult32x16in32(ptr_qmf_real[8], *p8_13_8)), |
111 | 0 | 1); |
112 | 0 | imag = ixheaac_shl32( |
113 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[0], *p8_13++), |
114 | 0 | ixheaac_mult32x16in32(ptr_qmf_imag[8], *p8_13_8++)), |
115 | 0 | 1); |
116 | |
|
117 | 0 | cum[12] = ixheaac_shl32( |
118 | 0 | ixheaac_mult32x16in32(ixheaac_add32_sat(imag, real), tcom), 1); |
119 | 0 | cum[13] = ixheaac_shl32( |
120 | 0 | ixheaac_mult32x16in32(ixheaac_sub32_sat(imag, real), tcom), 1); |
121 | |
|
122 | 0 | real = ixheaac_shl32( |
123 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[1], *p8_13), |
124 | 0 | ixheaac_mult32x16in32(ptr_qmf_real[9], *p8_13_8)), |
125 | 0 | 1); |
126 | 0 | imag = ixheaac_shl32( |
127 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[1], *p8_13++), |
128 | 0 | ixheaac_mult32x16in32(ptr_qmf_imag[9], *p8_13_8++)), |
129 | 0 | 1); |
130 | |
|
131 | 0 | cum[10] = |
132 | 0 | ixheaac_shl32(ixheaac_add32_sat(ixheaac_mult32x16in32(imag, tcos), |
133 | 0 | ixheaac_mult32x16in32(real, tsin)), |
134 | 0 | 1); |
135 | 0 | cum[11] = |
136 | 0 | ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(imag, tsin), |
137 | 0 | ixheaac_mult32x16in32(real, tcos)), |
138 | 0 | 1); |
139 | 0 | cum[9] = ixheaac_shl32( |
140 | 0 | ixheaac_mult32x16in32( |
141 | 0 | ixheaac_sub32_sat(ptr_qmf_real[2], ptr_qmf_real[10]), *p8_13_8++), |
142 | 0 | 1); |
143 | 0 | cum[8] = ixheaac_shl32( |
144 | 0 | ixheaac_mult32x16in32( |
145 | 0 | ixheaac_sub32_sat(ptr_qmf_imag[2], ptr_qmf_imag[10]), *p8_13++), |
146 | 0 | 1); |
147 | |
|
148 | 0 | real = ixheaac_shl32( |
149 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[3], *p8_13), |
150 | 0 | ixheaac_mult32x16in32(ptr_qmf_real[11], *p8_13_8)), |
151 | 0 | 1); |
152 | 0 | imag = ixheaac_shl32( |
153 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[3], *p8_13++), |
154 | 0 | ixheaac_mult32x16in32(ptr_qmf_imag[11], *p8_13_8++)), |
155 | 0 | 1); |
156 | |
|
157 | 0 | cum[6] = |
158 | 0 | ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(imag, tcos), |
159 | 0 | ixheaac_mult32x16in32(real, tsin)), |
160 | 0 | 1); |
161 | 0 | cum[7] = ixheaac_shl32(ixheaac_negate32_sat(ixheaac_add32_sat( |
162 | 0 | ixheaac_mult32x16in32(imag, tsin), |
163 | 0 | ixheaac_mult32x16in32(real, tcos))), |
164 | 0 | 1); |
165 | |
|
166 | 0 | real = ixheaac_shl32( |
167 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[4], *p8_13), |
168 | 0 | ixheaac_mult32x16in32(ptr_qmf_real[12], *p8_13_8)), |
169 | 0 | 1); |
170 | 0 | imag = ixheaac_shl32( |
171 | 0 | ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[4], *p8_13++), |
172 | 0 | ixheaac_mult32x16in32(ptr_qmf_imag[12], *p8_13_8++)), |
173 | 0 | 1); |
174 | |
|
175 | 0 | cum[4] = ixheaac_shl32( |
176 | 0 | ixheaac_mult32x16in32(ixheaac_sub32_sat(imag, real), tcom), 1); |
177 | 0 | cum[5] = ixheaac_shl32( |
178 | 0 | ixheaac_mult32x16in32( |
179 | 0 | ixheaac_negate32_sat(ixheaac_add32_sat(imag, real)), tcom), |
180 | 0 | 1); |
181 | |
|
182 | 0 | real = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_real[5], *p8_13), 1); |
183 | 0 | imag = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_imag[5], *p8_13++), 1); |
184 | |
|
185 | 0 | cum[2] = |
186 | 0 | ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(real, tcos), |
187 | 0 | ixheaac_mult32x16in32(imag, tsin)), |
188 | 0 | 1); |
189 | 0 | cum[3] = |
190 | 0 | ixheaac_shl32(ixheaac_add32_sat(ixheaac_mult32x16in32(real, tsin), |
191 | 0 | ixheaac_mult32x16in32(imag, tcos)), |
192 | 0 | 1); |
193 | |
|
194 | 0 | cum[0] = ixheaac_shl32( |
195 | 0 | ixheaac_mult32x16in32(ptr_qmf_real[HYBRID_FILTER_DELAY], *p8_13), 1); |
196 | 0 | cum[1] = ixheaac_shl32( |
197 | 0 | ixheaac_mult32x16in32(ptr_qmf_imag[HYBRID_FILTER_DELAY], *p8_13++), 1); |
198 | |
|
199 | 0 | real = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_real[7], *p8_13), 1); |
200 | 0 | imag = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_imag[7], *p8_13++), 1); |
201 | |
|
202 | 0 | cum[14] = |
203 | 0 | ixheaac_shl32(ixheaac_add32_sat(ixheaac_mult32x16in32(imag, tsin), |
204 | 0 | ixheaac_mult32x16in32(real, tcos)), |
205 | 0 | 1); |
206 | 0 | cum[15] = |
207 | 0 | ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(imag, tcos), |
208 | 0 | ixheaac_mult32x16in32(real, tsin)), |
209 | 0 | 1); |
210 | |
|
211 | 0 | (*ixheaacd_inv_dit_fft_8pt)(cum, ptr_hyb_real, ptr_hyb_imag); |
212 | 0 | } |
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 | 0 | { |
220 | 0 | WORD band, j; |
221 | 0 | WORD chn_offset = 0; |
222 | 0 | WORD32 *ptr_re, *ptr_im; |
223 | 0 | WORD32 *ptr_temp_real, *ptr_temp_imag; |
224 | |
|
225 | 0 | for (band = 0; band < NO_QMF_CHANNELS_IN_HYBRID; band++) { |
226 | 0 | ptr_re = ptr_hybrid->ptr_qmf_buf_re[band]; |
227 | 0 | ptr_im = ptr_hybrid->ptr_qmf_buf_im[band]; |
228 | |
|
229 | 0 | ptr_temp_real = &ptr_hybrid->ptr_work_re[0]; |
230 | 0 | ptr_temp_imag = &ptr_hybrid->ptr_work_im[0]; |
231 | |
|
232 | 0 | *ptr_temp_real = *ptr_re; |
233 | 0 | *ptr_temp_imag = *ptr_im; |
234 | |
|
235 | 0 | ptr_temp_real++; |
236 | 0 | ptr_re++; |
237 | 0 | ptr_temp_imag++; |
238 | 0 | ptr_im++; |
239 | |
|
240 | 0 | for (j = ptr_hybrid->ptr_qmf_buf - 2; j >= 0; j--) { |
241 | 0 | *ptr_temp_real++ = *ptr_re; |
242 | 0 | *(ptr_re - 1) = *ptr_re; |
243 | 0 | ptr_re++; |
244 | 0 | *ptr_temp_imag++ = *ptr_im; |
245 | 0 | *(ptr_im - 1) = *ptr_im; |
246 | 0 | ptr_im++; |
247 | 0 | } |
248 | |
|
249 | 0 | { |
250 | 0 | WORD32 temp_re = ptr_qmf_real[band]; |
251 | 0 | WORD32 temp_im = ptr_qmf_real[band + 0x40]; |
252 | |
|
253 | 0 | if (scale < 0) { |
254 | 0 | temp_re = ixheaac_shl32(temp_re, -scale); |
255 | 0 | temp_im = ixheaac_shl32(temp_im, -scale); |
256 | 0 | } else { |
257 | 0 | temp_re = ixheaac_shr32(temp_re, scale); |
258 | 0 | temp_im = ixheaac_shr32(temp_im, scale); |
259 | 0 | } |
260 | 0 | *ptr_temp_real = temp_re; |
261 | 0 | *--ptr_re = temp_re; |
262 | |
|
263 | 0 | *ptr_temp_imag = temp_im; |
264 | 0 | *--ptr_im = temp_im; |
265 | 0 | } |
266 | |
|
267 | 0 | switch (ptr_hybrid->ptr_resol[band]) { |
268 | 0 | case NO_HYBRID_CHANNELS_LOW: |
269 | |
|
270 | 0 | ixheaacd_filt_2_ch(ptr_hybrid->ptr_work_re, &ptr_hyb_real[chn_offset], |
271 | 0 | ptr_sbr_tables); |
272 | |
|
273 | 0 | chn_offset += 2; |
274 | |
|
275 | 0 | break; |
276 | 0 | case NO_HYBRID_CHANNELS_HIGH: |
277 | |
|
278 | 0 | ixheaacd_filt_8_ch(ptr_hybrid->ptr_work_re, ptr_hybrid->ptr_work_im, |
279 | 0 | &ptr_hyb_real[chn_offset], &ptr_hyb_imag[chn_offset], |
280 | 0 | ptr_sbr_tables); |
281 | |
|
282 | 0 | chn_offset += 6; |
283 | 0 | } |
284 | 0 | } |
285 | 0 | } |