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