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