Coverage Report

Created: 2026-05-30 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/iusace_tns_usac.c
Line
Count
Source
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 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
21
#include <math.h>
22
#include <string.h>
23
#include "ixheaace_mps_common_define.h"
24
#include "ixheaac_constants.h"
25
#include "iusace_cnst.h"
26
#include "ixheaac_type_def.h"
27
#include "iusace_bitbuffer.h"
28
#include "iusace_tns_usac.h"
29
#include "iusace_psy_mod.h"
30
#include "ixheaac_basic_ops32.h"
31
#include "ixheaac_basic_ops40.h"
32
#include "ixheaac_basic_ops.h"
33
#include "ixheaac_error_standards.h"
34
#include "ixheaace_error_codes.h"
35
36
static const WORD32 iusace_tns_supported_sampling_rates[13] = {
37
    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0};
38
39
static const UWORD16 iusace_tns_min_band_number_long[12] = {11, 12, 15, 16, 17, 20,
40
                                                            25, 26, 24, 28, 30, 31};
41
42
static const UWORD16 iusace_tns_min_band_number_short[12] = {2, 2, 2, 3,  3,  4,
43
                                                             6, 6, 8, 10, 10, 12};
44
45
static const WORD32 iusace_tns_max_bands_table[16][2] = {{31, 9},  /**< 96000 */
46
                                                         {31, 9},  /**< 88200 */
47
                                                         {34, 10}, /**< 64000 */
48
                                                         {40, 14}, /**< 48000 */
49
                                                         {42, 14}, /**< 44100 */
50
                                                         {51, 14}, /**< 32000 */
51
                                                         {47, 15}, /**< 24000 */
52
                                                         {47, 15}, /**< 22050 */
53
                                                         {43, 15}, /**< 16000 */
54
                                                         {43, 15}, /**< 12000 */
55
                                                         {43, 15}, /**< 11025 */
56
                                                         {40, 15}, /**< 8000  */
57
                                                         {40, 15}, /**< 7350  */
58
                                                         {0, 0},   {0, 0}, {0, 0}};
59
60
static WORD32 iusace_freq_to_band_mapping(WORD32 freq, WORD32 sample_rate, WORD32 num_bands,
61
10.7k
                                          const WORD32 *ptr_band_start_offset) {
62
10.7k
  WORD32 line_num, band;
63
64
10.7k
  line_num = (freq * ptr_band_start_offset[num_bands] * 4 / sample_rate + 1) / 2;
65
66
10.7k
  if (line_num >= ptr_band_start_offset[num_bands]) {
67
4.38k
    return num_bands;
68
4.38k
  }
69
70
117k
  for (band = 0; band < num_bands; band++) {
71
117k
    if (ptr_band_start_offset[band + 1] > line_num) break;
72
117k
  }
73
74
6.40k
  if (line_num - ptr_band_start_offset[band] > ptr_band_start_offset[band + 1] - line_num) {
75
1.87k
    band++;
76
1.87k
  }
77
78
6.40k
  return band;
79
10.7k
};
80
81
static VOID iusace_calc_gauss_win(FLOAT64 *ptr_win, const WORD32 length, const WORD32 sample_rate,
82
5.39k
                                  const WORD32 win_seq, const FLOAT32 time_resolution) {
83
5.39k
  WORD32 i;
84
5.39k
  FLOAT32 gauss_exp = 3.14159265358979323f * sample_rate * 0.001f * (FLOAT32)time_resolution /
85
5.39k
                      (win_seq != EIGHT_SHORT_SEQUENCE ? 1024.0f : 128.0f);
86
87
5.39k
  gauss_exp = -0.5f * gauss_exp * gauss_exp;
88
89
70.1k
  for (i = 0; i < length; i++) {
90
64.7k
    ptr_win[i] = (FLOAT32)exp(gauss_exp * (i + 0.5) * (i + 0.5));
91
64.7k
  }
92
5.39k
  return;
93
5.39k
}
94
95
IA_ERRORCODE iusace_tns_init(WORD32 sampling_rate, WORD32 bit_rate, ia_tns_info *tns_info,
96
2.72k
                             WORD32 num_channels) {
97
2.72k
  IA_ERRORCODE err_code = IA_NO_ERROR;
98
2.72k
  WORD32 fs_index = 0;
99
2.72k
  WORD32 lpc_stop_freq = 16000;
100
2.72k
  WORD32 lpc_start_freq_long = 2500, lpc_start_freq_short = 3750;
101
2.72k
  tns_info->threshold = 1.41f;
102
2.72k
  tns_info->tns_time_res_short = 0.6f;
103
2.72k
  tns_info->tns_time_res_long = 0.6f;
104
105
2.72k
  if (sampling_rate == 14700) {
106
0
    sampling_rate = 16000;
107
0
  }
108
2.72k
  if (sampling_rate == 29400) {
109
0
    sampling_rate = 32000;
110
0
  }
111
112
2.72k
  if (bit_rate < 32000) {
113
7
    if (num_channels == 1) {
114
4
      tns_info->threshold = 1.2f;
115
4
      lpc_start_freq_long = 2000;
116
4
    }
117
2.71k
  } else if (bit_rate < 36000) {
118
180
    if (num_channels == 1) {
119
1
      tns_info->tns_time_res_long = 0.8f;
120
179
    } else {
121
179
      tns_info->tns_time_res_long = 0.5f;
122
179
    }
123
180
    tns_info->tns_time_res_short = 0.3f;
124
2.53k
  } else {
125
2.53k
    tns_info->tns_time_res_long = 0.5f;
126
2.53k
    tns_info->tns_time_res_short = 0.3f;
127
2.53k
  }
128
129
  /** Determine if sampling rate is supported
130
   */
131
19.4k
  while (sampling_rate != iusace_tns_supported_sampling_rates[fs_index]) {
132
16.7k
    if (!iusace_tns_supported_sampling_rates[fs_index]) {
133
21
      return IA_EXHEAACE_INIT_FATAL_USAC_INVALID_CORE_SAMPLE_RATE;
134
21
    }
135
16.7k
    fs_index++;
136
16.7k
  }
137
138
2.69k
  tns_info->tns_max_bands_long = iusace_tns_max_bands_table[fs_index][0];
139
2.69k
  tns_info->tns_max_bands_short = iusace_tns_max_bands_table[fs_index][1];
140
2.69k
  tns_info->tns_max_order_long = 15;
141
2.69k
  tns_info->tns_max_order_short = 7;
142
143
2.69k
  tns_info->tns_min_band_number_long = iusace_tns_min_band_number_long[fs_index];
144
2.69k
  tns_info->tns_min_band_number_short = iusace_tns_min_band_number_short[fs_index];
145
146
2.69k
  tns_info->lpc_start_band_long =
147
2.69k
      iusace_freq_to_band_mapping(lpc_start_freq_long, sampling_rate, tns_info->max_sfb_long,
148
2.69k
                                  tns_info->sfb_offset_table_long);
149
150
2.69k
  tns_info->lpc_start_band_short =
151
2.69k
      iusace_freq_to_band_mapping(lpc_start_freq_short, sampling_rate, tns_info->max_sfb_short,
152
2.69k
                                  tns_info->sfb_offset_table_short);
153
154
2.69k
  tns_info->lpc_stop_band_long = iusace_freq_to_band_mapping(
155
2.69k
      lpc_stop_freq, sampling_rate, tns_info->max_sfb_long, tns_info->sfb_offset_table_long);
156
157
2.69k
  tns_info->lpc_stop_band_short = iusace_freq_to_band_mapping(
158
2.69k
      lpc_stop_freq, sampling_rate, tns_info->max_sfb_short, tns_info->sfb_offset_table_short);
159
160
2.69k
  iusace_calc_gauss_win(tns_info->win_long, tns_info->tns_max_order_long + 1, sampling_rate,
161
2.69k
                        ONLY_LONG_SEQUENCE, tns_info->tns_time_res_long);
162
163
2.69k
  iusace_calc_gauss_win(tns_info->win_short, tns_info->tns_max_order_short + 1, sampling_rate,
164
2.69k
                        EIGHT_SHORT_SEQUENCE, tns_info->tns_time_res_short);
165
2.69k
  return err_code;
166
2.72k
}
167
168
VOID iusace_tns_filter(WORD32 length, FLOAT64 *spec, ia_tns_filter_data *filter,
169
245k
                       FLOAT64 *scratch_tns_filter) {
170
245k
  WORD32 i, j, k = 0;
171
245k
  WORD32 order = filter->order;
172
245k
  FLOAT64 *a = filter->a_coeffs;
173
245k
  FLOAT64 *temp = scratch_tns_filter;
174
175
  /** Determine loop parameters for given direction
176
   */
177
245k
  if (filter->direction) {
178
    /** Startup, initial state is zero
179
     */
180
0
    temp[length - 1] = spec[length - 1];
181
0
    for (i = length - 2; i > (length - 1 - order); i--) {
182
0
      temp[i] = spec[i];
183
0
      k++;
184
0
      for (j = 1; j <= k; j++) {
185
0
        spec[i] += temp[i + j] * a[j];
186
0
      }
187
0
    }
188
189
    /** Now filter the rest
190
     */
191
0
    for (i = length - 1 - order; i >= 0; i--) {
192
0
      temp[i] = spec[i];
193
0
      for (j = 1; j <= order; j++) {
194
0
        spec[i] += temp[i + j] * a[j];
195
0
      }
196
0
    }
197
245k
  } else {
198
    /** Startup, initial state is zero
199
     */
200
245k
    temp[0] = spec[0];
201
1.19M
    for (i = 1; i < order; i++) {
202
948k
      temp[i] = spec[i];
203
5.08M
      for (j = 1; j <= i; j++) {
204
4.13M
        spec[i] += temp[i - j] * a[j];
205
4.13M
      }
206
948k
    }
207
208
    /** Now filter the rest
209
     */
210
74.4M
    for (i = order; i < length; i++) {
211
74.2M
      temp[i] = spec[i];
212
681M
      for (j = 1; j <= order; j++) {
213
607M
        spec[i] += temp[i - j] * a[j];
214
607M
      }
215
74.2M
    }
216
245k
  }
217
218
245k
  return;
219
245k
}
220
221
245k
static WORD32 iusace_truncate_coeffs(WORD32 f_order, FLOAT64 threshold, FLOAT64 *k_array) {
222
245k
  WORD32 i;
223
1.44M
  for (i = f_order; i >= 0; i--) {
224
1.44M
    k_array[i] = (fabs(k_array[i]) > threshold) ? k_array[i] : 0.0;
225
1.44M
    if (k_array[i] != 0.0) {
226
245k
      return i;
227
245k
    }
228
1.44M
  }
229
0
  return 0;
230
245k
}
231
232
VOID iusace_quantize_reflection_coeffs(WORD32 f_order, WORD32 coeff_res, FLOAT64 *k_array,
233
245k
                                       WORD32 *index_array) {
234
245k
  FLOAT64 iqfac, iqfac_m;
235
245k
  WORD32 i;
236
237
245k
  iqfac = (((SIZE_T)1 << (coeff_res - 1)) - 0.5) / (PI / 2);
238
245k
  iqfac_m = (((SIZE_T)1 << (coeff_res - 1)) + 0.5) / (PI / 2);
239
240
  /* Quantize and inverse quantize */
241
2.64M
  for (i = 1; i <= f_order; i++) {
242
2.39M
    index_array[i] = (WORD32)(0.5 + (asin(k_array[i]) * ((k_array[i] >= 0) ? iqfac : iqfac_m)));
243
2.39M
    k_array[i] = sin((FLOAT64)index_array[i] / ((index_array[i] >= 0) ? iqfac : iqfac_m));
244
2.39M
  }
245
245k
  return;
246
245k
}
247
248
613k
VOID iusace_tns_auto_corr(WORD32 max_order, WORD32 data_size, FLOAT64 *data, FLOAT64 *r_array) {
249
613k
  WORD32 i, j;
250
613k
  FLOAT64 tmp_var;
251
59.5M
  for (i = 0; i < data_size; i += 2) {
252
58.8M
    const FLOAT64 *input1 = &data[i];
253
58.8M
    FLOAT64 temp1 = *input1;
254
58.8M
    FLOAT64 temp2 = *(input1 + 1);
255
58.8M
    FLOAT64 inp_tmp1 = *input1++;
256
462M
    for (j = 0; j <= max_order; j++) {
257
403M
      FLOAT64 inp_tmp2;
258
403M
      tmp_var = temp1 * inp_tmp1;
259
403M
      inp_tmp2 = *input1++;
260
403M
      tmp_var += temp2 * inp_tmp2;
261
403M
      r_array[j] += tmp_var;
262
403M
      j++;
263
403M
      tmp_var = temp1 * inp_tmp2;
264
403M
      inp_tmp1 = *input1++;
265
403M
      tmp_var += temp2 * inp_tmp1;
266
403M
      r_array[j] += tmp_var;
267
403M
    }
268
58.8M
  }
269
613k
  return;
270
613k
}
271
272
static FLOAT64 iusace_levinson_durbin(WORD32 order, WORD32 data_size, FLOAT64 *ptr_data,
273
613k
                                      FLOAT64 *ptr_k, FLOAT64 *ptr_win, FLOAT64 *ptr_scratch) {
274
613k
  WORD32 i, j;
275
613k
  FLOAT64 *ptr_work_buffer_temp;
276
613k
  FLOAT64 *ptr_work_buffer = ptr_scratch;
277
613k
  FLOAT64 *ptr_input = ptr_scratch + TNS_MAX_ORDER + 1;
278
613k
  memset(ptr_input, 0, (TNS_MAX_ORDER + 1) * sizeof(ptr_input[0]));
279
613k
  iusace_tns_auto_corr(order, data_size, ptr_data, ptr_input);
280
281
613k
  WORD32 num_of_coeff = order;
282
613k
  FLOAT64 *ptr_refl_coeff = ptr_k;
283
613k
  ptr_k[0] = 1.0;
284
285
613k
  if (ptr_input[0] == 0) {
286
111k
    return 0;
287
111k
  }
288
289
5.44M
  for (i = 0; i < num_of_coeff + 1; i++) {
290
4.94M
    ptr_input[i] = ptr_input[i] * ptr_win[i];
291
4.94M
  }
292
293
501k
  FLOAT64 tmp_var;
294
501k
  ptr_work_buffer[0] = ptr_input[0];
295
296
4.44M
  for (i = 1; i < num_of_coeff; i++) {
297
3.94M
    tmp_var = ptr_input[i];
298
3.94M
    ptr_work_buffer[i] = tmp_var;
299
3.94M
    ptr_work_buffer[i + num_of_coeff - 1] = tmp_var;
300
3.94M
  }
301
501k
  ptr_work_buffer[i + num_of_coeff - 1] = ptr_input[i];
302
303
4.94M
  for (i = 0; i < num_of_coeff; i++) {
304
4.44M
    FLOAT64 refc, tmp;
305
4.44M
    tmp = ptr_work_buffer[num_of_coeff + i];
306
4.44M
    if (tmp < 0) {
307
2.43M
      tmp = -tmp;
308
2.43M
    } else {
309
2.01M
      if (ptr_work_buffer[0] < tmp) {
310
0
        break;
311
0
      }
312
2.01M
    }
313
4.44M
    if (ptr_work_buffer[0] == 0) {
314
0
      refc = 0;
315
4.44M
    } else {
316
4.44M
      refc = tmp / ptr_work_buffer[0];
317
4.44M
    }
318
319
4.44M
    if (ptr_work_buffer[num_of_coeff + i] > 0) {
320
1.80M
      refc = -refc;
321
1.80M
    }
322
4.44M
    ptr_refl_coeff[i + 1] = refc;
323
4.44M
    ptr_work_buffer_temp = &(ptr_work_buffer[num_of_coeff]);
324
325
29.2M
    for (j = i; j < num_of_coeff; j++) {
326
24.8M
      FLOAT64 accu1, accu2;
327
24.8M
      accu1 = refc * ptr_work_buffer[j - i];
328
24.8M
      accu1 += ptr_work_buffer_temp[j];
329
24.8M
      accu2 = refc * ptr_work_buffer_temp[j];
330
24.8M
      accu2 += ptr_work_buffer[j - i];
331
24.8M
      ptr_work_buffer_temp[j] = accu1;
332
24.8M
      ptr_work_buffer[j - i] = accu2;
333
24.8M
    }
334
4.44M
  }
335
501k
  return (ptr_input[0] / ptr_work_buffer[0]);
336
613k
}
337
338
245k
static VOID iusace_step_up(WORD32 f_order, FLOAT64 *ptr_k, FLOAT64 *ptr_a, FLOAT64 *ptr_scratch) {
339
245k
  FLOAT64 *ptr_a_temp = ptr_scratch;
340
245k
  WORD32 i, order;
341
342
245k
  ptr_a[0] = 1.0;
343
245k
  ptr_a_temp[0] = 1.0;
344
1.43M
  for (order = 1; order <= f_order; order++) {
345
1.19M
    ptr_a[order] = 0.0;
346
6.51M
    for (i = 1; i <= order; i++) {
347
5.32M
      ptr_a_temp[i] = ptr_a[i] + ptr_k[order] * ptr_a[order - i];
348
5.32M
    }
349
6.51M
    for (i = 1; i <= order; i++) {
350
5.32M
      ptr_a[i] = ptr_a_temp[i];
351
5.32M
    }
352
1.19M
  }
353
245k
  return;
354
245k
}
355
356
static VOID iusace_calc_weighted_spec(FLOAT64 *ptr_spec, FLOAT64 *ptr_wgt_spec,
357
                                      FLOAT32 *ptr_sfb_en, WORD32 *ptr_sfb_offset,
358
                                      WORD32 lpc_start_band, WORD32 lpc_stop_band,
359
613k
                                      FLOAT64 *ptr_scratch) {
360
613k
  WORD32 i, sfb;
361
613k
  FLOAT32 temp;
362
613k
  FLOAT32 *ptr_tns_sfb_mean = (FLOAT32 *)ptr_scratch;
363
613k
  memset(ptr_scratch, 0, MAX_NUM_GROUPED_SFB * sizeof(ptr_tns_sfb_mean[0]));
364
613k
  WORD32 lpc_stop_line = ptr_sfb_offset[lpc_stop_band];
365
613k
  WORD32 lpc_start_line = ptr_sfb_offset[lpc_start_band];
366
367
5.79M
  for (sfb = lpc_start_band; sfb < lpc_stop_band; sfb++) {
368
5.18M
    ptr_tns_sfb_mean[sfb] = (FLOAT32)(1.0 / sqrt(ptr_sfb_en[sfb] + 1e-30f));
369
5.18M
  }
370
371
613k
  sfb = lpc_start_band;
372
613k
  temp = ptr_tns_sfb_mean[sfb];
373
374
118M
  for (i = lpc_start_line; i < lpc_stop_line; i++) {
375
117M
    if (ptr_sfb_offset[sfb + 1] == i) {
376
4.57M
      sfb++;
377
378
4.57M
      if (sfb + 1 < lpc_stop_band) {
379
3.97M
        temp = ptr_tns_sfb_mean[sfb];
380
3.97M
      }
381
4.57M
    }
382
117M
    ptr_wgt_spec[i] = temp;
383
117M
  }
384
385
117M
  for (i = lpc_stop_line - 2; i >= lpc_start_line; i--) {
386
117M
    ptr_wgt_spec[i] = (ptr_wgt_spec[i] + ptr_wgt_spec[i + 1]) * 0.5f;
387
117M
  }
388
389
117M
  for (i = lpc_start_line + 1; i < lpc_stop_line; i++) {
390
117M
    ptr_wgt_spec[i] = (ptr_wgt_spec[i] + ptr_wgt_spec[i - 1]) * 0.5f;
391
117M
  }
392
393
118M
  for (i = lpc_start_line; i < lpc_stop_line; i++) {
394
117M
    ptr_wgt_spec[i] = ptr_wgt_spec[i] * ptr_spec[i];
395
117M
  }
396
613k
  return;
397
613k
}
398
399
VOID iusace_tns_data_sync(ia_tns_info *ptr_tns_dest, ia_tns_info *ptr_tns_src, const WORD32 w,
400
289k
                          WORD32 order) {
401
289k
  ia_tns_window_data *win_data_src = &ptr_tns_src->window_data[w];
402
289k
  ia_tns_window_data *win_data_dest = &ptr_tns_dest->window_data[w];
403
289k
  WORD32 i;
404
289k
  if (fabs(win_data_dest->tns_pred_gain - win_data_src->tns_pred_gain) <
405
289k
      ((FLOAT32)0.03f * win_data_dest->tns_pred_gain)) {
406
133k
    win_data_dest->tns_active = win_data_src->tns_active;
407
408
1.28M
    for (i = 0; i < order; i++) {
409
1.14M
      win_data_dest->tns_filter->k_coeffs[i] = win_data_src->tns_filter->k_coeffs[i];
410
1.14M
    }
411
133k
  }
412
289k
  return;
413
289k
}
414
415
VOID iusace_tns_encode(ia_tns_info *pstr_tns_info_ch2, ia_tns_info *pstr_tns_info,
416
                       FLOAT32 *ptr_sfb_energy, WORD32 w, WORD32 i_ch, WORD32 low_pass_line,
417
                       FLOAT64 *ptr_scratch_tns_filter, WORD32 core_mode,
418
613k
                       FLOAT64 *ptr_tns_scratch) {
419
613k
  WORD32 number_of_bands = pstr_tns_info->number_of_bands;
420
613k
  WORD32 block_type = pstr_tns_info->block_type;
421
613k
  FLOAT64 *ptr_spec = pstr_tns_info->spec;
422
613k
  WORD32 start_band, stop_band, order; /**< bands over which to apply TNS */
423
613k
  WORD32 length_in_bands;              /**< Length to filter, in bands */
424
613k
  WORD32 start_index, length;
425
613k
  WORD32 nbands;
426
613k
  WORD32 coeff_res;
427
613k
  FLOAT64 *ptr_weighted_spec = ptr_tns_scratch;
428
613k
  memset(ptr_weighted_spec, 0, 4096 * sizeof(ptr_weighted_spec[0]));
429
613k
  FLOAT64 *ptr_scratch = ptr_tns_scratch + 4096;
430
613k
  FLOAT64 *ptr_window = NULL;
431
613k
  WORD32 lpc_start_band, lpc_stop_band;
432
613k
  WORD32 *ptr_sfb_offset_table;
433
434
613k
  switch (block_type) {
435
484k
    case EIGHT_SHORT_SEQUENCE:
436
484k
      start_band = pstr_tns_info->tns_min_band_number_short;
437
484k
      stop_band = number_of_bands;
438
484k
      length_in_bands = stop_band - start_band;
439
484k
      order = pstr_tns_info->tns_max_order_short;
440
484k
      start_band = MIN(start_band, pstr_tns_info->tns_max_bands_short);
441
484k
      stop_band = MIN(stop_band, pstr_tns_info->tns_max_bands_short);
442
484k
      coeff_res = 3;
443
484k
      ptr_window = pstr_tns_info->win_short;
444
484k
      nbands = pstr_tns_info->max_sfb_short;
445
484k
      lpc_start_band = pstr_tns_info->lpc_start_band_short;
446
484k
      lpc_stop_band = pstr_tns_info->lpc_stop_band_short;
447
484k
      if (core_mode == CORE_MODE_FD) {
448
484k
        ptr_sfb_offset_table = pstr_tns_info->sfb_offset_table_short;
449
484k
      } else {
450
0
        ptr_sfb_offset_table = pstr_tns_info->sfb_offset_table_short_tcx;
451
0
      }
452
484k
      break;
453
454
128k
    default:
455
128k
      start_band = pstr_tns_info->tns_min_band_number_long;
456
128k
      stop_band = number_of_bands;
457
128k
      length_in_bands = stop_band - start_band;
458
128k
      order = pstr_tns_info->tns_max_order_long;
459
128k
      start_band = MIN(start_band, pstr_tns_info->tns_max_bands_long);
460
128k
      stop_band = MIN(stop_band, pstr_tns_info->tns_max_bands_long);
461
128k
      coeff_res = 4;
462
128k
      ptr_window = pstr_tns_info->win_long;
463
128k
      nbands = pstr_tns_info->max_sfb_long;
464
128k
      lpc_start_band = pstr_tns_info->lpc_start_band_long;
465
128k
      lpc_stop_band = pstr_tns_info->lpc_stop_band_long;
466
128k
      ptr_sfb_offset_table = pstr_tns_info->sfb_offset_table_long;
467
128k
      break;
468
613k
  }
469
470
  /** Make sure that start and stop bands < max_sfb
471
   * Make sure that start and stop bands >= 0
472
   */
473
613k
  start_band = MIN(start_band, nbands);
474
613k
  stop_band = MIN(stop_band, nbands);
475
613k
  start_band = MAX(start_band, 0);
476
613k
  stop_band = MAX(stop_band, 0);
477
478
613k
  pstr_tns_info->tns_data_present = 0; /**< default TNS not used */
479
480
  /** Perform analysis and filtering for each window
481
   */
482
613k
  {
483
613k
    ia_tns_window_data *window_data = &pstr_tns_info->window_data[w];
484
613k
    ia_tns_filter_data *tns_filter = window_data->tns_filter;
485
613k
    FLOAT64 *k = tns_filter->k_coeffs; /**< reflection coeffs */
486
613k
    FLOAT64 *a = tns_filter->a_coeffs; /**< prediction coeffs */
487
488
613k
    iusace_calc_weighted_spec(ptr_spec, ptr_weighted_spec, ptr_sfb_energy, ptr_sfb_offset_table,
489
613k
                              lpc_start_band, lpc_stop_band, ptr_scratch);
490
491
613k
    window_data->n_filt = 0;
492
613k
    window_data->coef_res = coeff_res;
493
494
613k
    start_index = ptr_sfb_offset_table[lpc_start_band];
495
613k
    length =
496
613k
        ptr_sfb_offset_table[lpc_stop_band] -
497
613k
        ptr_sfb_offset_table[lpc_start_band]; /**< The length of the spectral data to be
498
                                                                                         processed
499
                                               */
500
501
613k
    window_data->tns_pred_gain = iusace_levinson_durbin(
502
613k
        order, length, &ptr_weighted_spec[start_index], k, ptr_window, ptr_scratch);
503
504
613k
    window_data->tns_active = 0;
505
613k
    if (window_data->tns_pred_gain > DEF_TNS_GAIN_THRESH) {
506
245k
      window_data->tns_active = 1;
507
245k
    }
508
509
613k
    if (i_ch == 1) {
510
289k
      iusace_tns_data_sync(pstr_tns_info, pstr_tns_info_ch2, w, order);
511
289k
    }
512
513
613k
    if (window_data->tns_pred_gain > DEF_TNS_GAIN_THRESH) {
514
      /** Use TNS
515
       */
516
245k
      WORD32 truncated_order;
517
245k
      window_data->n_filt++;
518
245k
      pstr_tns_info->tns_data_present = 1;
519
245k
      tns_filter->direction = 0;
520
245k
      tns_filter->coef_compress = 0;
521
245k
      tns_filter->length = length_in_bands;
522
245k
      iusace_quantize_reflection_coeffs(order, coeff_res, k, tns_filter->index);
523
245k
      truncated_order = iusace_truncate_coeffs(order, DEF_TNS_COEFF_THRESH, k);
524
245k
      tns_filter->order = truncated_order;
525
245k
      iusace_step_up(truncated_order, k, a, ptr_scratch); /**< Compute prediction coefficients */
526
245k
      start_index = ptr_sfb_offset_table[start_band];
527
245k
      length = MIN(ptr_sfb_offset_table[stop_band], low_pass_line) - start_index;
528
245k
      if (block_type == EIGHT_SHORT_SEQUENCE) {
529
160k
        length = ptr_sfb_offset_table[stop_band] - start_index;
530
160k
      }
531
245k
      iusace_tns_filter(length, &ptr_spec[start_index], tns_filter,
532
245k
                        ptr_scratch_tns_filter); /**< filter */
533
245k
    }
534
613k
  }
535
613k
  return;
536
613k
}