• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }