Coverage Report

Created: 2026-06-13 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_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 <math.h>
21
#include <stdio.h>
22
23
#include "ixheaac_type_def.h"
24
#include "ixheaacd_bitbuffer.h"
25
26
#include "ixheaacd_interface.h"
27
28
#include "ixheaacd_tns_usac.h"
29
#include "ixheaacd_cnst.h"
30
31
#include "ixheaacd_acelp_info.h"
32
33
#include "ixheaacd_sbrdecsettings.h"
34
#include "ixheaacd_info.h"
35
#include "ixheaacd_sbr_common.h"
36
#include "ixheaacd_drc_data_struct.h"
37
#include "ixheaacd_drc_dec.h"
38
#include "ixheaacd_sbrdecoder.h"
39
#include "ixheaacd_mps_polyphase.h"
40
#include "ixheaac_sbr_const.h"
41
42
#include "ixheaacd_ec_defines.h"
43
#include "ixheaacd_ec_struct_def.h"
44
#include "ixheaacd_main.h"
45
#include "ixheaacd_arith_dec.h"
46
#include "ixheaacd_function_selector.h"
47
#include "ixheaac_constants.h"
48
#include "ixheaac_basic_ops32.h"
49
#include "ixheaac_basic_ops40.h"
50
51
204k
#define sfb_offset(x) (((x) > 0) ? sfb_top[(x)-1] : 0)
52
53
static VOID ixheaacd_tns_dec_coef_usac(ia_usac_data_struct *usac_data,
54
                                       ia_tns_filter_struct *filter,
55
102k
                                       WORD32 coef_res, WORD32 *par_coeff) {
56
102k
  WORD32 resolution;
57
102k
  WORD32 *ptr_par_coeff = par_coeff;
58
102k
  const WORD32 *tns_coeff_ptr;
59
102k
  WORD32 ixheaacd_drc_offset = 4;
60
102k
  WORD16 *ptr_coeff = filter->coef;
61
102k
  WORD32 order;
62
63
102k
  resolution = coef_res - 3;
64
102k
  tns_coeff_ptr = usac_data->tns_coeff3_32;
65
102k
  if (resolution) {
66
79.9k
    tns_coeff_ptr = usac_data->tns_coeff4_32;
67
79.9k
    ixheaacd_drc_offset = ixheaacd_drc_offset << 1;
68
79.9k
  }
69
102k
  order = filter->order;
70
71
400k
  do {
72
400k
    WORD16 temp = *ptr_coeff++;
73
400k
    *ptr_par_coeff++ = tns_coeff_ptr[temp + ixheaacd_drc_offset];
74
400k
    order--;
75
400k
  } while (order != 0);
76
102k
}
77
78
static VOID ixheaacd_tns_parcor_lpc_convert_usac(WORD32 *parcor,
79
                                                 WORD32 *lpc_coeff,
80
                                                 WORD32 *scale, WORD order)
81
82
102k
{
83
102k
  WORD i, j, status;
84
102k
  WORD32 accu;
85
102k
  WORD32 temp_buf1[TNS_MAX_ORDER + 1];
86
102k
  WORD32 temp_buf2[TNS_MAX_ORDER + 1];
87
102k
  WORD32 accu1, accu2;
88
89
102k
  status = 1;
90
102k
  *scale = 1;
91
92
259k
  while (status) {
93
157k
    status = 0;
94
95
5.19M
    for (i = TNS_MAX_ORDER; i >= 0; i--) {
96
5.03M
      temp_buf1[i] = 0;
97
5.03M
      temp_buf2[i] = 0;
98
5.03M
    }
99
100
157k
    accu1 = (0x40000000 >> (*scale - 1));
101
102
1.03M
    for (i = 0; i <= order; i++) {
103
874k
      accu = accu1;
104
105
6.01M
      for (j = 0; j < order; j++) {
106
5.14M
        temp_buf2[j] = (accu1);
107
108
5.14M
        accu1 = ixheaac_add32_sat(
109
5.14M
            accu1, ixheaac_mult32_shl_sat(parcor[j], temp_buf1[j]));
110
5.14M
        if (ixheaac_abs32_sat(accu1) == 0x7fffffff) status = 1;
111
5.14M
      }
112
113
6.01M
      for (j = (order - 1); j >= 0; j--) {
114
5.14M
        accu2 = (temp_buf1[j]);
115
5.14M
        accu2 = ixheaac_add32_sat(
116
5.14M
            accu2, ixheaac_mult32_shl_sat(parcor[j], temp_buf2[j]));
117
5.14M
        temp_buf1[j + 1] = (accu2);
118
119
5.14M
        if (ixheaac_abs32_sat(accu2) == 0x7fffffff) status = 1;
120
5.14M
      }
121
122
874k
      temp_buf1[0] = (accu);
123
874k
      lpc_coeff[i] = (accu1);
124
874k
      accu1 = 0;
125
874k
    }
126
127
157k
    accu1 = (status - 1);
128
129
157k
    if (accu1 == 0) {
130
54.8k
      *scale = *scale + 1;
131
54.8k
    }
132
157k
  }
133
102k
}
134
135
static VOID ixheaacd_tns_ar_filter_usac(WORD32 *spectrum, WORD32 size,
136
                                        WORD32 inc, WORD32 *lpc_coeff,
137
                                        WORD32 order, WORD32 shift_value,
138
38.6k
                                        WORD32 *ptr_filter_state) {
139
38.6k
  WORD32 i, j;
140
38.6k
  WORD32 y;
141
38.6k
  WORD64 acc;
142
143
38.6k
  if ((order & 3) != 0) {
144
67.4k
    for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
145
34.0k
      lpc_coeff[i] = 0;
146
34.0k
    }
147
33.4k
    lpc_coeff[i] = 0;
148
33.4k
    order = ((order & 0xfffffffc) + 4);
149
33.4k
  }
150
151
332k
  for (i = 0; i < order; i++) {
152
293k
    y = *spectrum;
153
293k
    acc = 0;
154
155
1.42M
    for (j = i; j > 0; j--) {
156
1.13M
      acc = ixheaac_add64_sat(
157
1.13M
          acc, ixheaac_mult64(ptr_filter_state[j - 1], lpc_coeff[j]));
158
1.13M
      ptr_filter_state[j] = ptr_filter_state[j - 1];
159
1.13M
    }
160
161
293k
    y = ixheaac_sub32_sat(y, (WORD32)(acc >> 31));
162
293k
    ptr_filter_state[0] = ixheaac_shl32(y, shift_value);
163
293k
    *spectrum = y;
164
293k
    spectrum += inc;
165
293k
  }
166
167
3.42M
  for (i = order; i < size; i++) {
168
3.38M
    y = *spectrum;
169
3.38M
    acc = 0;
170
27.0M
    for (j = order; j > 0; j--) {
171
23.6M
      acc = ixheaac_add64_sat(
172
23.6M
          acc, ixheaac_mult64(ptr_filter_state[j - 1], lpc_coeff[j]));
173
23.6M
      ;
174
23.6M
      ptr_filter_state[j] = ptr_filter_state[j - 1];
175
23.6M
    }
176
3.38M
    y = ixheaac_sub32_sat(y, (WORD32)(acc >> 31));
177
3.38M
    ptr_filter_state[0] = ixheaac_shl32(y, shift_value);
178
3.38M
    *spectrum = y;
179
3.38M
    spectrum += inc;
180
3.38M
  }
181
38.6k
}
182
183
IA_ERRORCODE ixheaacd_tns_apply(ia_usac_data_struct *usac_data, WORD32 *spec,
184
                                WORD32 nbands,
185
                                ia_sfb_info_struct *pstr_sfb_info,
186
227k
                                ia_tns_frame_info_struct *pstr_tns) {
187
227k
  WORD32 f, start, stop, size, inc;
188
227k
  WORD32 n_filt, coef_res, order, direction;
189
227k
  WORD32 *ptr_spec;
190
227k
  WORD32 scale_spec;
191
227k
  WORD32 scale_lpc;
192
227k
  WORD32 guard_band;
193
227k
  WORD32 shift;
194
227k
  WORD32 lpc_coeff[TNS_MAX_ORDER + 1];
195
227k
  WORD32 par_coeff[TNS_MAX_ORDER + 1];
196
227k
  ia_tns_filter_struct *filt;
197
198
227k
  const WORD16 *sfb_top;
199
200
227k
  WORD32 nbins = (pstr_sfb_info->islong) ? 1024 : 128;
201
227k
  WORD32 i, j, idx;
202
203
227k
  idx = (pstr_sfb_info->islong) ? 0 : 1;
204
205
227k
  ptr_spec = &usac_data->scratch_buffer[0];
206
207
1.02M
  for (j = 0; j < pstr_tns->n_subblocks; j++) {
208
799k
    sfb_top = pstr_sfb_info->ptr_sfb_tbl;
209
210
233M
    for (i = 0; i < nbins; i++) {
211
232M
      ptr_spec[i] = spec[i];
212
232M
    }
213
214
799k
    if (pstr_tns->str_tns_info[j].n_filt) {
215
99.9k
      n_filt = pstr_tns->str_tns_info[j].n_filt;
216
217
208k
      for (f = 0; f < n_filt; f++) {
218
108k
        WORD32 tmp;
219
220
108k
        coef_res = pstr_tns->str_tns_info[j].coef_res;
221
108k
        filt = &pstr_tns->str_tns_info[j].str_filter[f];
222
108k
        order = filt->order;
223
108k
        direction = filt->direction;
224
108k
        start = filt->start_band;
225
108k
        stop = filt->stop_band;
226
227
108k
        if (!order) continue;
228
229
102k
        ixheaacd_tns_dec_coef_usac(usac_data, filt, coef_res,
230
102k
                                   (WORD32 *)par_coeff);
231
232
102k
        ixheaacd_tns_parcor_lpc_convert_usac(par_coeff, lpc_coeff, &scale_lpc,
233
102k
                                             filt->order);
234
235
102k
        tmp = (*usac_data->tns_max_bands_tbl_usac)[usac_data->sampling_rate_idx]
236
102k
                                                  [idx];
237
238
102k
        start = ixheaac_min32(start, tmp);
239
240
102k
        start = ixheaac_min32(start, nbands);
241
102k
        if (start > pstr_sfb_info->sfb_per_sbk) return -1;
242
102k
        start = sfb_offset(start);
243
244
102k
        stop = ixheaac_min32(stop, tmp);
245
102k
        stop = ixheaac_min32(stop, nbands);
246
102k
        if (stop > pstr_sfb_info->sfb_per_sbk) return -1;
247
102k
        stop = sfb_offset(stop);
248
249
102k
        guard_band = 31 - ixheaac_norm32(filt->order);
250
251
102k
        if ((size = stop - start) <= 0) continue;
252
253
38.6k
        if (direction) {
254
16.9k
          inc = -1;
255
16.9k
          shift = stop - 1;
256
16.9k
        }
257
258
21.6k
        else {
259
21.6k
          inc = 1;
260
21.6k
          shift = start;
261
21.6k
        }
262
263
38.6k
        {
264
38.6k
          WORD32 *ptr_temp = ptr_spec + start;
265
38.6k
          scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_temp, size);
266
38.6k
        }
267
268
38.6k
        scale_spec = ((scale_spec - guard_band) - scale_lpc);
269
270
38.6k
        if (scale_spec > 0) {
271
19.5k
          ixheaacd_tns_ar_filter_usac(&ptr_spec[shift], size, inc, lpc_coeff,
272
19.5k
                                      filt->order, scale_lpc,
273
19.5k
                                      usac_data->x_ac_dec);
274
19.5k
        }
275
276
19.1k
        else {
277
19.1k
          WORD32 *ptr_temp = ptr_spec + start;
278
279
19.1k
          scale_spec = -scale_spec;
280
19.1k
          scale_spec = ixheaac_min32(scale_spec, 31);
281
282
2.09M
          for (i = size; i != 0; i--) {
283
2.07M
            *ptr_temp = *ptr_temp >> scale_spec;
284
2.07M
            ptr_temp++;
285
2.07M
          }
286
287
19.1k
          {
288
19.1k
            ixheaacd_tns_ar_filter_usac(&ptr_spec[shift], size, inc, lpc_coeff,
289
19.1k
                                        filt->order, scale_lpc,
290
19.1k
                                        usac_data->x_ac_dec);
291
19.1k
          }
292
293
19.1k
          {
294
19.1k
            ptr_temp = ptr_spec + start;
295
19.1k
            i = size;
296
297
2.07M
            do {
298
2.07M
              *ptr_temp = *ptr_temp << scale_spec;
299
2.07M
              ptr_temp++;
300
2.07M
              i--;
301
2.07M
            } while (i != 0);
302
19.1k
          }
303
19.1k
        }
304
305
3.71M
        for (i = start; i <= stop - 1; i++) {
306
3.67M
          spec[i] = ptr_spec[i];
307
3.67M
        }
308
38.6k
      }
309
99.9k
    }
310
311
799k
    spec += pstr_sfb_info->bins_per_sbk;
312
799k
  }
313
227k
  return 0;
314
227k
}