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