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_sbr_common.h"
21 #include "ixheaacd_type_def.h"
22
23 #include "ixheaacd_constants.h"
24 #include "ixheaacd_basic_ops32.h"
25 #include "ixheaacd_basic_ops16.h"
26 #include "ixheaacd_basic_ops40.h"
27 #include "ixheaacd_basic_ops.h"
28
29 #include "ixheaacd_defines.h"
30 #include "ixheaacd_bitbuffer.h"
31
32 #include "ixheaacd_error_codes.h"
33 #include "ixheaacd_aac_rom.h"
34 #include "ixheaacd_pulsedata.h"
35
36 #include "ixheaacd_pns.h"
37 #include "ixheaacd_drc_data_struct.h"
38
39 #include "ixheaacd_lt_predict.h"
40
41 #include "ixheaacd_channelinfo.h"
42 #include "ixheaacd_drc_dec.h"
43 #include "ixheaacd_sbrdecoder.h"
44 #include "ixheaacd_tns.h"
45 #include "ixheaacd_intrinsics.h"
46
47 #include "ixheaacd_common_rom.h"
48 #include "ixheaacd_block.h"
49 #include "ixheaacd_channel.h"
50 #include "ixheaacd_audioobjtypes.h"
51 #include "ixheaacd_latmdemux.h"
52
53 #include "ixheaacd_aacdec.h"
54
ixheaacd_mac32_tns_sat(WORD32 a,WORD32 b,WORD32 c)55 static PLATFORM_INLINE WORD32 ixheaacd_mac32_tns_sat(WORD32 a, WORD32 b,
56 WORD32 c) {
57 WORD32 result;
58 WORD64 temp_result;
59
60 temp_result = (WORD64)a * (WORD64)b;
61 result = (WORD32)(temp_result >> 32);
62 result = ixheaacd_add32_sat(c, result);
63 return (result);
64 }
65
ixheaacd_tns_decode_coefficients(const ia_filter_info_struct * filter,WORD32 * a,ia_aac_dec_tables_struct * ptr_aac_tables)66 VOID ixheaacd_tns_decode_coefficients(
67 const ia_filter_info_struct *filter, WORD32 *a,
68 ia_aac_dec_tables_struct *ptr_aac_tables) {
69 WORD32 i;
70 WORD32 tmp;
71 WORD32 *aptr = a;
72 WORD32 *tns_coeff_ptr;
73 WORD8 ixheaacd_drc_offset;
74
75 tmp = filter->resolution;
76 if (tmp == 0) {
77 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3;
78 ixheaacd_drc_offset = 4;
79
80 } else {
81 tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4;
82 ixheaacd_drc_offset = 8;
83 }
84
85 for (i = 0; i < filter->order; i++) {
86 *aptr++ = tns_coeff_ptr[filter->coef[i] + ixheaacd_drc_offset];
87 }
88 }
89
ixheaacd_tns_parcor_to_lpc(WORD32 * parcor,WORD32 * lpc,WORD16 * scale,WORD32 order)90 VOID ixheaacd_tns_parcor_to_lpc(WORD32 *parcor, WORD32 *lpc, WORD16 *scale,
91 WORD32 order)
92
93 {
94 WORD i, j, status;
95 WORD32 z1;
96 WORD32 z[MAX_ORDER + 1];
97 WORD32 w[MAX_ORDER + 1];
98 WORD32 accu1, accu2;
99
100 status = 1;
101 *scale = 1;
102
103 while (status) {
104 status = 0;
105
106 for (i = MAX_ORDER; i >= 0; i--) {
107 z[i] = 0;
108 w[i] = 0;
109 }
110
111 accu1 = (0x40000000 >> (*scale - 1));
112
113 for (i = 0; i <= order; i++) {
114 z1 = accu1;
115
116 for (j = 0; j < order; j++) {
117 w[j] = (accu1);
118
119 accu1 = ixheaacd_add32_sat(accu1,
120 ixheaacd_mult32_shl_sat(parcor[j], (z[j])));
121 if (ixheaacd_abs32_sat(accu1) == 0x7fffffff) status = 1;
122 }
123 for (j = (order - 1); j >= 0; j--) {
124 accu2 = (z[j]);
125 accu2 = ixheaacd_add32_sat(accu2,
126 ixheaacd_mult32_shl_sat(parcor[j], (w[j])));
127 z[j + 1] = (accu2);
128 if (ixheaacd_abs32_sat(accu2) == 0x7fffffff) status = 1;
129 }
130
131 z[0] = (z1);
132 lpc[i] = (accu1);
133 accu1 = 0;
134 }
135
136 accu1 = (status - 1);
137
138 if (accu1 == 0) {
139 *scale = *scale + 1;
140 }
141 }
142 }
143
ixheaacd_tns_parcor_lpc_convert_dec(WORD16 * parcor,WORD16 * lpc,WORD16 * scale,WORD order)144 VOID ixheaacd_tns_parcor_lpc_convert_dec(WORD16 *parcor, WORD16 *lpc,
145 WORD16 *scale, WORD order)
146
147 {
148 WORD i, j, status;
149 WORD32 accu;
150 WORD16 temp_buf1[MAX_ORDER + 1];
151 WORD16 temp_buf2[MAX_ORDER + 1];
152 WORD32 accu1, accu2;
153
154 status = 1;
155 *scale = 0;
156
157 while (status) {
158 status = 0;
159
160 for (i = MAX_ORDER; i >= 0; i--) {
161 temp_buf1[i] = 0;
162 temp_buf2[i] = 0;
163 }
164
165 accu1 = (0x7fffffff >> *scale);
166
167 for (i = 0; i <= order; i++) {
168 accu = accu1;
169
170 for (j = 0; j < order; j++) {
171 temp_buf2[j] = ixheaacd_round16(accu1);
172 accu1 = ixheaacd_mac16x16in32_shl_sat(accu1, parcor[j], temp_buf1[j]);
173
174 if (ixheaacd_abs32_sat(accu1) == 0x7fffffff) {
175 status = 1;
176 }
177 }
178
179 for (j = (order - 1); j >= 0; j--) {
180 accu2 = ixheaacd_deposit16h_in32(temp_buf1[j]);
181 accu2 = ixheaacd_mac16x16in32_shl_sat(accu2, parcor[j], temp_buf2[j]);
182 temp_buf1[j + 1] = ixheaacd_round16(accu2);
183 if (ixheaacd_abs32_sat(accu2) == 0x7fffffff) {
184 status = 1;
185 }
186 }
187
188 temp_buf1[0] = ixheaacd_round16(accu);
189 lpc[i] = ixheaacd_round16(accu1);
190 accu1 = 0;
191 }
192
193 accu1 = (status - 1);
194
195 if (accu1 == 0) {
196 *scale = *scale + 1;
197 }
198 }
199 }
200
ixheaacd_tns_ar_filter_fixed_dec(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD32 * lpc,WORD32 order,WORD32 shift_value,WORD scale_spec)201 VOID ixheaacd_tns_ar_filter_fixed_dec(WORD32 *spectrum, WORD32 size, WORD32 inc,
202 WORD32 *lpc, WORD32 order,
203 WORD32 shift_value, WORD scale_spec)
204
205 {
206 WORD32 i, j;
207 WORD32 y, state[MAX_ORDER + 1];
208 WORD32 acc;
209
210 if ((order & 3) != 0) {
211 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
212 lpc[i] = 0;
213 }
214 lpc[i] = 0;
215 order = ((order & 0xfffffffc) + 4);
216 }
217 {
218 WORD32 temp_lo = 0;
219 for (i = 0; i < order; i++) {
220 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
221 acc = 0;
222
223 for (j = i; j > 0; j--) {
224 acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
225 state[j] = state[j - 1];
226 }
227 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc, 1));
228 state[0] = ixheaacd_shl32_sat(y, shift_value);
229
230 *spectrum = y >> scale_spec;
231 spectrum += inc;
232 }
233 temp_lo = 0;
234 for (i = order; i < size; i++) {
235 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
236 acc = 0;
237 for (j = order; j > 0; j--) {
238 acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
239 state[j] = state[j - 1];
240 }
241 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc, 1));
242 state[0] = ixheaacd_shl32_sat(y, shift_value);
243
244 *spectrum = y >> scale_spec;
245 spectrum += inc;
246 }
247 }
248 }
249
ixheaacd_tns_ar_filter_fixed_non_neon_armv7(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD32 * lpc,WORD32 order,WORD32 shift_value,WORD scale_spec)250 VOID ixheaacd_tns_ar_filter_fixed_non_neon_armv7(WORD32 *spectrum, WORD32 size,
251 WORD32 inc, WORD32 *lpc,
252 WORD32 order,
253 WORD32 shift_value,
254 WORD scale_spec) {
255 WORD32 i, j;
256 WORD32 y, state[MAX_ORDER + 1];
257 WORD32 acc;
258
259 if ((order & 3) != 0) {
260 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
261 lpc[i] = 0;
262 }
263 lpc[i] = 0;
264 order = ((order & 0xfffffffc) + 4);
265 }
266 {
267 WORD32 temp_lo = 0;
268 for (i = 0; i < order; i++) {
269 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
270 acc = 0;
271
272 for (j = i; j > 0; j--) {
273 acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
274 state[j] = state[j - 1];
275 }
276 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc, 1));
277 state[0] = ixheaacd_shl32_sat(y, shift_value);
278
279 *spectrum = y >> scale_spec;
280 spectrum += inc;
281 }
282 temp_lo = 0;
283 for (i = order; i < size; i++) {
284 WORD64 acc = 0;
285 WORD32 acc1;
286 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
287 for (j = order; j > 0; j--) {
288 acc = ixheaacd_mac32x32in64_dual(state[j - 1], lpc[j], acc);
289 state[j] = state[j - 1];
290 }
291 acc1 = (WORD32)(acc >> 32);
292
293 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc1, 1));
294 state[0] = ixheaacd_shl32_sat(y, shift_value);
295
296 *spectrum = y >> scale_spec;
297 spectrum += inc;
298 }
299 }
300 }
301
ixheaacd_tns_ar_filter_fixed_armv8(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD32 * lpc,WORD32 order,WORD32 shift_value,WORD scale_spec)302 VOID ixheaacd_tns_ar_filter_fixed_armv8(WORD32 *spectrum, WORD32 size,
303 WORD32 inc, WORD32 *lpc, WORD32 order,
304 WORD32 shift_value, WORD scale_spec) {
305 WORD32 i, j;
306 WORD32 y, state[MAX_ORDER + 1];
307 WORD32 acc;
308
309 if ((order & 3) != 0) {
310 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
311 lpc[i] = 0;
312 }
313 lpc[i] = 0;
314 order = ((order & 0xfffffffc) + 4);
315 }
316 {
317 WORD32 temp_lo = 0;
318 for (i = 0; i < order; i++) {
319 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
320 acc = 0;
321
322 for (j = i; j > 0; j--) {
323 acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
324 state[j] = state[j - 1];
325 }
326 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc, 1));
327 state[0] = ixheaacd_shl32_sat(y, shift_value);
328
329 *spectrum = y >> scale_spec;
330 spectrum += inc;
331 }
332 temp_lo = 0;
333 for (i = order; i < size; i++) {
334 WORD64 acc = 0;
335 WORD32 acc1;
336 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
337 for (j = order; j > 0; j--) {
338 acc = ixheaacd_mac32x32in64_dual(state[j - 1], lpc[j], acc);
339 state[j] = state[j - 1];
340 }
341 acc1 = (WORD32)(acc >> 32);
342
343 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc1, 1));
344 state[0] = ixheaacd_shl32_sat(y, shift_value);
345
346 *spectrum = y >> scale_spec;
347 spectrum += inc;
348 }
349 }
350 }
351
ixheaacd_tns_ma_filter_fixed_ld(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD32 * lpc,WORD32 order,WORD16 shift_value)352 void ixheaacd_tns_ma_filter_fixed_ld(WORD32 *spectrum, WORD32 size, WORD32 inc,
353 WORD32 *lpc, WORD32 order,
354 WORD16 shift_value) {
355 WORD32 i, j;
356 WORD32 y, state[MAX_ORDER];
357
358 for (i = 0; i < order; i++) state[i] = 0;
359
360 for (i = 0; i < size; i++) {
361 y = *spectrum;
362
363 for (j = 0; j < order; j++) y += ixheaacd_mult32_shl(state[j], lpc[j + 1]);
364
365 for (j = order - 1; j > 0; j--) state[j] = state[j - 1];
366
367 state[0] = ixheaacd_shl32_dir_sat(*spectrum, shift_value);
368 *spectrum = y;
369 spectrum += inc;
370 }
371 }
372
ixheaacd_tns_ar_filter_dec(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD16 * lpc,WORD32 order,WORD32 shift_value,WORD scale_spec,WORD32 * ptr_filter_state)373 VOID ixheaacd_tns_ar_filter_dec(WORD32 *spectrum, WORD32 size, WORD32 inc,
374 WORD16 *lpc, WORD32 order, WORD32 shift_value,
375 WORD scale_spec, WORD32 *ptr_filter_state) {
376 WORD32 i, j;
377 WORD32 y;
378 WORD32 acc;
379
380 if ((order & 3) != 0) {
381 for (i = order + 1; i < ((WORD32)(order & (~3)) + 4); i++) {
382 lpc[i] = 0;
383 }
384 if (i < (MAX_ORDER + 1)) {
385 lpc[i] = 0;
386 order = ((order & (~3)) + 4);
387 } else {
388 order = MAX_ORDER;
389 }
390 }
391
392 for (i = 0; i < order; i++) {
393 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
394 acc = 0;
395
396 for (j = i; j > 0; j--) {
397 acc = ixheaacd_add32_sat(
398 acc, ixheaacd_mult32x16in32(ptr_filter_state[j - 1], lpc[j]));
399 ptr_filter_state[j] = ptr_filter_state[j - 1];
400 }
401
402 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc, 1));
403 ptr_filter_state[0] = ixheaacd_shl32_sat(y, shift_value);
404 *spectrum = y >> scale_spec;
405 spectrum += inc;
406 }
407
408 for (i = order; i < size; i++) {
409 y = ixheaacd_shl32_sat((*spectrum), scale_spec);
410 acc = 0;
411 for (j = order; j > 0; j--) {
412 acc = ixheaacd_add32_sat(
413 acc, ixheaacd_mult32x16in32(ptr_filter_state[j - 1], lpc[j]));
414 ptr_filter_state[j] = ptr_filter_state[j - 1];
415 }
416
417 y = ixheaacd_sub32_sat(y, ixheaacd_shl32_sat(acc, 1));
418 ptr_filter_state[0] = ixheaacd_shl32_sat(y, shift_value);
419 *spectrum = y >> scale_spec;
420 spectrum += inc;
421 }
422 }
423
ixheaacd_calc_max_spectral_line_dec(WORD32 * ptr_tmp,WORD32 size)424 WORD32 ixheaacd_calc_max_spectral_line_dec(WORD32 *ptr_tmp, WORD32 size) {
425 WORD32 max_spec_line = 0, i;
426 WORD unroll_cnt, rem;
427
428 unroll_cnt = size >> 3;
429 for (i = unroll_cnt; i--;) {
430 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
431 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
432 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
433 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
434
435 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
436 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
437 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
438 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
439 }
440
441 rem = size - (unroll_cnt << 3);
442
443 if (rem) {
444 for (i = rem; i--;) {
445 max_spec_line = ixheaacd_abs32_nrm(*ptr_tmp++) | max_spec_line;
446 }
447 }
448
449 return ixheaacd_norm32(max_spec_line);
450 }