Coverage Report

Created: 2026-08-13 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_aac_tns.c
Line
Count
Source
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 "ixheaac_type_def.h"
22
23
#include "ixheaac_constants.h"
24
#include "ixheaac_basic_ops32.h"
25
#include "ixheaac_basic_ops16.h"
26
#include "ixheaac_basic_ops40.h"
27
#include "ixheaac_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
58
static PLATFORM_INLINE WORD32 ixheaacd_mac32_tns_sat(WORD32 a, WORD32 b,
59
30.7M
                                                     WORD32 c) {
60
30.7M
  WORD32 result;
61
30.7M
  WORD64 temp_result;
62
63
30.7M
  temp_result = (WORD64)a * (WORD64)b;
64
30.7M
  result = (WORD32)(temp_result >> 32);
65
30.7M
  result = ixheaac_add32_sat(c, result);
66
30.7M
  return (result);
67
30.7M
}
68
69
VOID ixheaacd_tns_decode_coefficients(
70
    const ia_filter_info_struct *filter, WORD32 *a,
71
35.9k
    ia_aac_dec_tables_struct *ptr_aac_tables) {
72
35.9k
  WORD32 i;
73
35.9k
  WORD32 tmp;
74
35.9k
  WORD32 *aptr = a;
75
35.9k
  WORD32 *tns_coeff_ptr;
76
35.9k
  WORD8 ixheaacd_drc_offset;
77
78
35.9k
  tmp = filter->resolution;
79
35.9k
  if (tmp == 0) {
80
31.8k
    tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3;
81
31.8k
    ixheaacd_drc_offset = 4;
82
83
31.8k
  } else {
84
4.09k
    tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4;
85
4.09k
    ixheaacd_drc_offset = 8;
86
4.09k
  }
87
88
337k
  for (i = 0; i < filter->order; i++) {
89
301k
    *aptr++ = tns_coeff_ptr[filter->coef[i] + ixheaacd_drc_offset];
90
301k
  }
91
35.9k
}
92
93
VOID ixheaacd_tns_parcor_to_lpc(WORD32 *parcor, WORD32 *lpc, WORD16 *scale,
94
                                WORD32 order)
95
96
29.3k
{
97
29.3k
  WORD i, j, status;
98
29.3k
  WORD32 z1;
99
29.3k
  WORD32 z[MAX_ORDER + 1];
100
29.3k
  WORD32 w[MAX_ORDER + 1];
101
29.3k
  WORD32 accu1, accu2;
102
103
29.3k
  status = 1;
104
29.3k
  *scale = 1;
105
106
79.0k
  while (status) {
107
49.7k
    status = 0;
108
109
1.64M
    for (i = MAX_ORDER; i >= 0; i--) {
110
1.59M
      z[i] = 0;
111
1.59M
      w[i] = 0;
112
1.59M
    }
113
114
49.7k
    accu1 = (0x40000000 >> (*scale - 1));
115
116
585k
    for (i = 0; i <= order; i++) {
117
536k
      z1 = accu1;
118
119
6.19M
      for (j = 0; j < order; j++) {
120
5.65M
        w[j] = (accu1);
121
122
5.65M
        accu1 = ixheaac_add32_sat(accu1,
123
5.65M
                                   ixheaac_mult32_shl_sat(parcor[j], (z[j])));
124
5.65M
        if (ixheaac_abs32_sat(accu1) == 0x7fffffff) status = 1;
125
5.65M
      }
126
6.19M
      for (j = (order - 1); j >= 0; j--) {
127
5.65M
        accu2 = (z[j]);
128
5.65M
        accu2 = ixheaac_add32_sat(accu2,
129
5.65M
                                   ixheaac_mult32_shl_sat(parcor[j], (w[j])));
130
5.65M
        z[j + 1] = (accu2);
131
5.65M
        if (ixheaac_abs32_sat(accu2) == 0x7fffffff) status = 1;
132
5.65M
      }
133
134
536k
      z[0] = (z1);
135
536k
      lpc[i] = (accu1);
136
536k
      accu1 = 0;
137
536k
    }
138
139
49.7k
    accu1 = (status - 1);
140
141
49.7k
    if (accu1 == 0) {
142
20.3k
      *scale = *scale + 1;
143
20.3k
    }
144
49.7k
  }
145
29.3k
}
146
147
VOID ixheaacd_tns_parcor_lpc_convert_dec(WORD16 *parcor, WORD16 *lpc,
148
                                         WORD16 *scale, WORD order)
149
150
37.4k
{
151
37.4k
  WORD i, j, status;
152
37.4k
  WORD32 accu;
153
37.4k
  WORD16 temp_buf1[MAX_ORDER + 1];
154
37.4k
  WORD16 temp_buf2[MAX_ORDER + 1];
155
37.4k
  WORD32 accu1, accu2;
156
157
37.4k
  status = 1;
158
37.4k
  *scale = 0;
159
160
114k
  while (status) {
161
76.5k
    status = 0;
162
163
2.52M
    for (i = MAX_ORDER; i >= 0; i--) {
164
2.45M
      temp_buf1[i] = 0;
165
2.45M
      temp_buf2[i] = 0;
166
2.45M
    }
167
168
76.5k
    accu1 = (0x7fffffff >> *scale);
169
170
639k
    for (i = 0; i <= order; i++) {
171
562k
      accu = accu1;
172
173
4.41M
      for (j = 0; j < order; j++) {
174
3.85M
        temp_buf2[j] = ixheaac_round16(accu1);
175
3.85M
        accu1 = ixheaac_mac16x16in32_shl_sat(accu1, parcor[j], temp_buf1[j]);
176
177
3.85M
        if (ixheaac_abs32_sat(accu1) == 0x7fffffff) {
178
279k
          status = 1;
179
279k
        }
180
3.85M
      }
181
182
4.41M
      for (j = (order - 1); j >= 0; j--) {
183
3.85M
        accu2 = ixheaac_deposit16h_in32(temp_buf1[j]);
184
3.85M
        accu2 = ixheaac_mac16x16in32_shl_sat(accu2, parcor[j], temp_buf2[j]);
185
3.85M
        temp_buf1[j + 1] = ixheaac_round16(accu2);
186
3.85M
        if (ixheaac_abs32_sat(accu2) == 0x7fffffff) {
187
40.7k
          status = 1;
188
40.7k
        }
189
3.85M
      }
190
191
562k
      temp_buf1[0] = ixheaac_round16(accu);
192
562k
      lpc[i] = ixheaac_round16(accu1);
193
562k
      accu1 = 0;
194
562k
    }
195
196
76.5k
    accu1 = (status - 1);
197
198
76.5k
    if (accu1 == 0) {
199
39.1k
      *scale = *scale + 1;
200
39.1k
    }
201
76.5k
  }
202
37.4k
}
203
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
15.1k
{
209
15.1k
  WORD32 i, j;
210
15.1k
  WORD32 y, state[MAX_ORDER + 1];
211
15.1k
  WORD32 acc;
212
213
15.1k
  if ((order & 3) != 0) {
214
16.4k
    for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
215
8.67k
      lpc[i] = 0;
216
8.67k
    }
217
7.82k
    lpc[i] = 0;
218
7.82k
    order = ((order & 0xfffffffc) + 4);
219
7.82k
    order = order & 31;
220
7.82k
  }
221
15.1k
  {
222
163k
    for (i = 0; i < order; i++) {
223
148k
      y = ixheaac_shl32_sat((*spectrum), scale_spec);
224
148k
      acc = 0;
225
226
856k
      for (j = i; j > 0; j--) {
227
708k
        acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
228
708k
        state[j] = state[j - 1];
229
708k
      }
230
148k
      y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc, 1));
231
148k
      state[0] = ixheaac_shl32_sat(y, shift_value);
232
233
148k
      *spectrum = y >> scale_spec;
234
148k
      spectrum += inc;
235
148k
    }
236
2.99M
    for (i = order; i < size; i++) {
237
2.97M
      y = ixheaac_shl32_sat((*spectrum), scale_spec);
238
2.97M
      acc = 0;
239
33.0M
      for (j = order; j > 0; j--) {
240
30.0M
        acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
241
30.0M
        state[j] = state[j - 1];
242
30.0M
      }
243
2.97M
      y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc, 1));
244
2.97M
      state[0] = ixheaac_shl32_sat(y, shift_value);
245
246
2.97M
      *spectrum = y >> scale_spec;
247
2.97M
      spectrum += inc;
248
2.97M
    }
249
15.1k
  }
250
15.1k
}
251
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
0
                                                 WORD scale_spec) {
257
0
  WORD32 i, j;
258
0
  WORD32 y, state[MAX_ORDER + 1];
259
0
  WORD32 acc;
260
261
0
  if ((order & 3) != 0) {
262
0
    for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
263
0
      lpc[i] = 0;
264
0
    }
265
0
    lpc[i] = 0;
266
0
    order = ((order & 0xfffffffc) + 4);
267
0
  }
268
0
  {
269
0
    for (i = 0; i < order; i++) {
270
0
      y = ixheaac_shl32_sat((*spectrum), scale_spec);
271
0
      acc = 0;
272
273
0
      for (j = i; j > 0; j--) {
274
0
        acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
275
0
        state[j] = state[j - 1];
276
0
      }
277
0
      y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc, 1));
278
0
      state[0] = ixheaac_shl32_sat(y, shift_value);
279
280
0
      *spectrum = y >> scale_spec;
281
0
      spectrum += inc;
282
0
    }
283
0
    for (i = order; i < size; i++) {
284
0
      WORD64 acc = 0;
285
0
      WORD32 acc1;
286
0
      y = ixheaac_shl32_sat((*spectrum), scale_spec);
287
0
      for (j = order; j > 0; j--) {
288
0
        acc = ixheaac_mac32x32in64_dual(state[j - 1], lpc[j], acc);
289
0
        state[j] = state[j - 1];
290
0
      }
291
0
      acc1 = (WORD32)(acc >> 32);
292
293
0
      y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc1, 1));
294
0
      state[0] = ixheaac_shl32_sat(y, shift_value);
295
296
0
      *spectrum = y >> scale_spec;
297
0
      spectrum += inc;
298
0
    }
299
0
  }
300
0
}
301
302
VOID ixheaacd_tns_ar_filter_fixed_armv8(WORD32 *spectrum, WORD32 size,
303
                                        WORD32 inc, WORD32 *lpc, WORD32 order,
304
0
                                        WORD32 shift_value, WORD scale_spec) {
305
0
  WORD32 i, j;
306
0
  WORD32 y, state[MAX_ORDER + 1];
307
0
  WORD32 acc;
308
309
0
  if ((order & 3) != 0) {
310
0
    for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
311
0
      lpc[i] = 0;
312
0
    }
313
0
    lpc[i] = 0;
314
0
    order = ((order & 0xfffffffc) + 4);
315
0
  }
316
0
  {
317
0
    for (i = 0; i < order; i++) {
318
0
      y = ixheaac_shl32_sat((*spectrum), scale_spec);
319
0
      acc = 0;
320
321
0
      for (j = i; j > 0; j--) {
322
0
        acc = ixheaacd_mac32_tns_sat(state[j - 1], lpc[j], acc);
323
0
        state[j] = state[j - 1];
324
0
      }
325
0
      y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc, 1));
326
0
      state[0] = ixheaac_shl32_sat(y, shift_value);
327
328
0
      *spectrum = y >> scale_spec;
329
0
      spectrum += inc;
330
0
    }
331
0
    for (i = order; i < size; i++) {
332
0
      WORD64 acc = 0;
333
0
      WORD32 acc1;
334
0
      y = ixheaac_shl32_sat((*spectrum), scale_spec);
335
0
      for (j = order; j > 0; j--) {
336
0
        acc = ixheaac_mac32x32in64_dual(state[j - 1], lpc[j], acc);
337
0
        state[j] = state[j - 1];
338
0
      }
339
0
      acc1 = (WORD32)(acc >> 32);
340
341
0
      y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc1, 1));
342
0
      state[0] = ixheaac_shl32_sat(y, shift_value);
343
344
0
      *spectrum = y >> scale_spec;
345
0
      spectrum += inc;
346
0
    }
347
0
  }
348
0
}
349
350
void ixheaacd_tns_ma_filter_fixed_ld(WORD32 *spectrum, WORD32 size, WORD32 inc,
351
                                     WORD32 *lpc, WORD32 order,
352
14.1k
                                     WORD16 shift_value) {
353
14.1k
  WORD32 i, j;
354
14.1k
  WORD32 y, state[MAX_ORDER];
355
356
139k
  for (i = 0; i < order; i++) state[i] = 0;
357
358
3.01M
  for (i = 0; i < size; i++) {
359
3.00M
    y = *spectrum;
360
361
31.1M
    for (j = 0; j < order; j++) y += ixheaac_mult32_shl(state[j], lpc[j + 1]);
362
363
28.1M
    for (j = order - 1; j > 0; j--) state[j] = state[j - 1];
364
365
3.00M
    state[0] = ixheaac_shl32_dir_sat(*spectrum, shift_value);
366
3.00M
    *spectrum = y;
367
3.00M
    spectrum += inc;
368
3.00M
  }
369
14.1k
}
370
371
VOID ixheaacd_tns_ar_filter_dec(WORD32 *spectrum, WORD32 size, WORD32 inc,
372
                                WORD16 *lpc, WORD32 order, WORD32 shift_value,
373
33.6k
                                WORD scale_spec, WORD32 *ptr_filter_state) {
374
33.6k
  WORD32 i, j;
375
33.6k
  WORD32 y;
376
33.6k
  WORD32 acc;
377
378
33.6k
  if ((order & 3) != 0) {
379
34.9k
    for (i = order + 1; i < ((WORD32)(order & (~3)) + 4); i++) {
380
6.15k
      lpc[i] = 0;
381
6.15k
    }
382
28.8k
    if (i < (MAX_ORDER + 1)) {
383
28.8k
      lpc[i] = 0;
384
28.8k
      order = ((order & (~3)) + 4);
385
28.8k
    } else {
386
0
      order = MAX_ORDER;
387
0
    }
388
28.8k
  }
389
390
278k
  for (i = 0; i < order; i++) {
391
244k
    y = ixheaac_shl32_sat((*spectrum), scale_spec);
392
244k
    acc = 0;
393
394
1.06M
    for (j = i; j > 0; j--) {
395
822k
      acc = ixheaac_add32_sat(
396
822k
          acc, ixheaac_mult32x16in32(ptr_filter_state[j - 1], lpc[j]));
397
822k
      ptr_filter_state[j] = ptr_filter_state[j - 1];
398
822k
    }
399
400
244k
    y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc, 1));
401
244k
    ptr_filter_state[0] = ixheaac_shl32_sat(y, shift_value);
402
244k
    *spectrum = y >> scale_spec;
403
244k
    spectrum += inc;
404
244k
  }
405
406
1.77M
  for (i = order; i < size; i++) {
407
1.73M
    y = ixheaac_shl32_sat((*spectrum), scale_spec);
408
1.73M
    acc = 0;
409
13.6M
    for (j = order; j > 0; j--) {
410
11.9M
      acc = ixheaac_add32_sat(
411
11.9M
          acc, ixheaac_mult32x16in32(ptr_filter_state[j - 1], lpc[j]));
412
11.9M
      ptr_filter_state[j] = ptr_filter_state[j - 1];
413
11.9M
    }
414
415
1.73M
    y = ixheaac_sub32_sat(y, ixheaac_shl32_sat(acc, 1));
416
1.73M
    ptr_filter_state[0] = ixheaac_shl32_sat(y, shift_value);
417
1.73M
    *spectrum = y >> scale_spec;
418
1.73M
    spectrum += inc;
419
1.73M
  }
420
33.6k
}
421
422
453k
WORD32 ixheaacd_calc_max_spectral_line_dec(WORD32 *ptr_tmp, WORD32 size) {
423
453k
  WORD32 max_spec_line = 0, i;
424
453k
  WORD unroll_cnt, rem;
425
426
453k
  unroll_cnt = size >> 3;
427
35.4M
  for (i = unroll_cnt; i--;) {
428
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
429
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
430
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
431
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
432
433
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
434
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
435
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
436
34.9M
    max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
437
34.9M
  }
438
439
453k
  rem = size - (unroll_cnt << 3);
440
441
453k
  if (rem) {
442
326k
    for (i = rem; i--;) {
443
261k
      max_spec_line = ixheaac_abs32_nrm(*ptr_tmp++) | max_spec_line;
444
261k
    }
445
65.3k
  }
446
447
453k
  return ixheaac_norm32(max_spec_line);
448
453k
}