Coverage Report

Created: 2025-12-10 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_sbrdec_lpfuncs.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 <string.h>
21
#include <math.h>
22
#include "ixheaacd_sbr_common.h"
23
#include "ixheaac_type_def.h"
24
25
#include "ixheaac_constants.h"
26
#include "ixheaac_basic_ops32.h"
27
#include "ixheaac_basic_ops16.h"
28
#include "ixheaac_basic_ops40.h"
29
#include "ixheaac_basic_ops.h"
30
#include "ixheaacd_defines.h"
31
32
#include "ixheaacd_intrinsics.h"
33
#include "ixheaac_sbr_const.h"
34
#include "ixheaac_basic_op.h"
35
#include "ixheaacd_defines.h"
36
#include "ixheaacd_bitbuffer.h"
37
#include "ixheaacd_pns.h"
38
39
#include "ixheaacd_aac_rom.h"
40
#include "ixheaacd_pulsedata.h"
41
42
#include "ixheaacd_drc_data_struct.h"
43
#include "ixheaacd_lt_predict.h"
44
#include "ixheaacd_cnst.h"
45
#include "ixheaacd_ec_defines.h"
46
#include "ixheaacd_ec_struct_def.h"
47
#include "ixheaacd_channelinfo.h"
48
#include "ixheaacd_drc_dec.h"
49
50
#include "ixheaacd_sbrdecoder.h"
51
52
#include "ixheaacd_sbrdecsettings.h"
53
#include "ixheaacd_sbr_scale.h"
54
#include "ixheaacd_lpp_tran.h"
55
#include "ixheaacd_env_extr_part.h"
56
#include "ixheaacd_sbr_rom.h"
57
#include "ixheaacd_hybrid.h"
58
#include "ixheaacd_ps_dec.h"
59
#include "ixheaacd_ps_bitdec.h"
60
#include "ixheaacd_env_extr.h"
61
#include "ixheaacd_common_rom.h"
62
#include "ixheaacd_freq_sca.h"
63
64
#include "ixheaacd_qmf_dec.h"
65
66
#include "ixheaacd_env_calc.h"
67
68
#include "ixheaacd_pvc_dec.h"
69
#include "ixheaacd_sbr_dec.h"
70
#include "ixheaacd_env_dec.h"
71
#include "ixheaacd_basic_funcs.h"
72
#include "ixheaacd_sbr_crc.h"
73
#include "ixheaacd_function_selector.h"
74
75
#include "ixheaacd_audioobjtypes.h"
76
#include "ixheaacd_error_codes.h"
77
78
#define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
79
80
static const FLOAT32 ixheaacd_new_bw_table[4][4] = {
81
    {0.00f, 0.60f, 0.90f, 0.98f},
82
    {0.60f, 0.75f, 0.90f, 0.98f},
83
    {0.00f, 0.75f, 0.90f, 0.98f},
84
    {0.00f, 0.75f, 0.90f, 0.98f}};
85
static const WORD32 ixheaacd_inew_bw_table[4][4] = {
86
    {0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7},
87
    {0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7},
88
    {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
89
    {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7}};
90
91
134k
VOID ixheaacd_reset_sbrenvelope_calc(ia_sbr_calc_env_struct *h_cal_env) {
92
134k
  h_cal_env->ph_index = 0;
93
134k
  h_cal_env->filt_buf_noise_e = 0;
94
134k
  h_cal_env->start_up = 1;
95
134k
}
96
97
VOID ixheaacd_derive_lim_band_tbl(
98
    ia_sbr_header_data_struct *ptr_header_data,
99
    const ia_patch_param_struct *p_str_patch_param, WORD16 num_patches,
100
25.7k
    ixheaacd_misc_tables *pstr_common_tables) {
101
25.7k
  WORD32 i, k, k_1;
102
25.7k
  WORD32 nr_lim, patch_border_k, patch_border_k_1, temp_nr_lim;
103
104
25.7k
  WORD16 lim_table[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
105
25.7k
  WORD16 patch_borders[MAX_NUM_PATCHES + 1];
106
25.7k
  WORD16 kx, k2;
107
25.7k
  WORD16 temp, lim_bands, num_octaves;
108
109
25.7k
  WORD16 *f_lim_tbl = ptr_header_data->pstr_freq_band_data->freq_band_tbl_lim;
110
25.7k
  WORD16 *num_lf_bands = &ptr_header_data->pstr_freq_band_data->num_lf_bands;
111
25.7k
  WORD16 *f_low_tbl =
112
25.7k
      ptr_header_data->pstr_freq_band_data->freq_band_table[LOW];
113
25.7k
  WORD16 num_low_bnd = ptr_header_data->pstr_freq_band_data->num_sf_bands[LOW];
114
25.7k
  WORD16 limiter_bands = ptr_header_data->limiter_bands;
115
116
25.7k
  WORD16 sub_band_start = f_low_tbl[0];
117
25.7k
  WORD16 sub_band_end = f_low_tbl[num_low_bnd];
118
25.7k
  const WORD16 limbnd_per_oct[4] = {(WORD16)0x2000, (WORD16)0x2666, (WORD16)0x4000,
119
25.7k
                                    (WORD16)0x6000};
120
121
25.7k
  if (limiter_bands == 0) {
122
3.08k
    f_lim_tbl[0] = 0;
123
3.08k
    f_lim_tbl[1] = sub_band_end - sub_band_start;
124
3.08k
    nr_lim = 1;
125
22.6k
  } else {
126
77.8k
    for (k = 0; k < num_patches; k++) {
127
55.2k
      patch_borders[k] = p_str_patch_param[k].guard_start_band - sub_band_start;
128
55.2k
    }
129
22.6k
    patch_borders[k] = sub_band_end - sub_band_start;
130
131
181k
    for (k = 0; k <= num_low_bnd; k++) {
132
158k
      lim_table[k] = f_low_tbl[k] - sub_band_start;
133
158k
    }
134
55.9k
    for (k = 1; k < num_patches; k++) {
135
33.3k
      lim_table[num_low_bnd + k] = patch_borders[k];
136
33.3k
    }
137
138
22.6k
    temp_nr_lim = nr_lim = (num_low_bnd + num_patches) - 1;
139
22.6k
    ixheaacd_aac_shellsort(lim_table, (temp_nr_lim + 1));
140
141
22.6k
    k = 1;
142
22.6k
    k_1 = 0;
143
144
22.6k
    lim_bands = limbnd_per_oct[limiter_bands];
145
146
190k
    while ((k - temp_nr_lim) <= 0) {
147
168k
      k2 = lim_table[k] + sub_band_start;
148
168k
      kx = lim_table[k_1] + sub_band_start;
149
150
168k
      num_octaves = pstr_common_tables->log_dual_is_table[k2];
151
168k
      num_octaves -= pstr_common_tables->log_dual_is_table[kx];
152
153
168k
      temp = (WORD16)(((WORD32)lim_bands * (WORD32)num_octaves) >> 15);
154
155
168k
      if (temp < 0x01f6) {
156
102k
        if (lim_table[k_1] == lim_table[k]) {
157
14.2k
          lim_table[k] = sub_band_end;
158
14.2k
          nr_lim = nr_lim - 1;
159
14.2k
          k = (k + 1);
160
14.2k
          continue;
161
14.2k
        }
162
88.5k
        patch_border_k_1 = patch_border_k = 0;
163
164
432k
        for (i = 0; i <= num_patches; i++) {
165
343k
          if (lim_table[k] == patch_borders[i]) {
166
30.1k
            patch_border_k = 1;
167
30.1k
          }
168
343k
          if (lim_table[k_1] == patch_borders[i]) {
169
51.2k
            patch_border_k_1 = 1;
170
51.2k
          }
171
343k
        }
172
88.5k
        if (!patch_border_k) {
173
58.3k
          lim_table[k] = sub_band_end;
174
58.3k
          nr_lim = nr_lim - 1;
175
58.3k
          k = (k + 1);
176
58.3k
          continue;
177
58.3k
        }
178
179
30.1k
        if (!patch_border_k_1) {
180
19.9k
          lim_table[k_1] = sub_band_end;
181
19.9k
          nr_lim = nr_lim - 1;
182
19.9k
        }
183
30.1k
      }
184
95.6k
      k_1 = k;
185
95.6k
      k = (k + 1);
186
95.6k
    }
187
22.6k
    ixheaacd_aac_shellsort(lim_table, (temp_nr_lim + 1));
188
189
22.6k
    memcpy(f_lim_tbl, lim_table, sizeof(WORD16) * (nr_lim + 1));
190
22.6k
  }
191
25.7k
  *num_lf_bands = nr_lim;
192
193
25.7k
  return;
194
25.7k
}
195
196
VOID ixheaacd_lean_sbrconcealment(
197
    ia_sbr_header_data_struct *ptr_header_data,
198
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
199
47.5k
    ia_sbr_prev_frame_data_struct *ptr_prev_data) {
200
47.5k
  WORD32 target;
201
47.5k
  WORD32 step;
202
47.5k
  WORD32 i;
203
204
47.5k
  WORD16 cur_start_pos;
205
47.5k
  WORD16 cur_stop_pos;
206
207
47.5k
  ptr_sbr_data->amp_res = ptr_prev_data->amp_res;
208
47.5k
  ptr_sbr_data->coupling_mode = ptr_prev_data->coupling_mode;
209
47.5k
  ptr_sbr_data->max_qmf_subband_aac = ptr_prev_data->max_qmf_subband_aac;
210
211
47.5k
  memcpy(ptr_sbr_data->sbr_invf_mode, ptr_prev_data->sbr_invf_mode,
212
47.5k
         sizeof(WORD32) * MAX_INVF_BANDS);
213
214
47.5k
  ptr_sbr_data->str_frame_info_details.num_env = 1;
215
216
47.5k
  cur_start_pos = ptr_prev_data->end_position - ptr_header_data->num_time_slots;
217
47.5k
  cur_stop_pos = ptr_header_data->num_time_slots;
218
219
47.5k
  ptr_sbr_data->str_frame_info_details.border_vec[0] = cur_start_pos;
220
47.5k
  ptr_sbr_data->str_frame_info_details.border_vec[1] = cur_stop_pos;
221
222
47.5k
  ptr_sbr_data->str_frame_info_details.noise_border_vec[0] = cur_start_pos;
223
47.5k
  ptr_sbr_data->str_frame_info_details.noise_border_vec[1] = cur_stop_pos;
224
47.5k
  ;
225
226
47.5k
  ptr_sbr_data->str_frame_info_details.freq_res[0] = 1;
227
47.5k
  ptr_sbr_data->str_frame_info_details.transient_env = -1;
228
47.5k
  ptr_sbr_data->str_frame_info_details.num_noise_env = 1;
229
230
47.5k
  ptr_sbr_data->num_env_sfac =
231
47.5k
      ptr_header_data->pstr_freq_band_data->num_sf_bands[1];
232
233
47.5k
  ptr_sbr_data->del_cod_dir_arr[0] = DTDF_DIR_TIME;
234
235
47.5k
  if (ptr_sbr_data->coupling_mode == COUPLING_BAL) {
236
5.64k
    target = SBR_ENERGY_PAN_OFFSET;
237
41.9k
  } else {
238
41.9k
    target = 0;
239
41.9k
  }
240
241
47.5k
  step = 1;
242
243
47.5k
  if (ptr_header_data->amp_res - SBR_AMPLITUDE_RESOLUTION_1_5 == 0) {
244
30.7k
    target = (target << 1);
245
30.7k
    step = (step << 1);
246
30.7k
  }
247
248
558k
  for (i = 0; i < ptr_sbr_data->num_env_sfac; i++) {
249
510k
    if (ptr_prev_data->sfb_nrg_prev[i] > target)
250
288k
      ptr_sbr_data->int_env_sf_arr[i] = -(step);
251
222k
    else
252
222k
      ptr_sbr_data->int_env_sf_arr[i] = step;
253
510k
  }
254
255
47.5k
  ptr_sbr_data->del_cod_dir_noise_arr[0] = DTDF_DIR_TIME;
256
257
47.5k
  memset(ptr_sbr_data->int_noise_floor, 0,
258
47.5k
         sizeof(ptr_sbr_data->int_noise_floor));
259
260
47.5k
  memset(ptr_sbr_data->add_harmonics, 0, sizeof(FLAG) * MAX_FREQ_COEFFS);
261
47.5k
}
262
263
static WORD16 ixheaacd_find_closest_entry(WORD32 goal_sb, WORD16 *f_master_tbl,
264
                                          WORD16 num_mf_bands,
265
483k
                                          WORD16 direction) {
266
483k
  WORD32 index;
267
268
483k
  if (goal_sb <= f_master_tbl[0]) return f_master_tbl[0];
269
270
483k
  if (goal_sb >= f_master_tbl[num_mf_bands]) return f_master_tbl[num_mf_bands];
271
272
437k
  if (direction) {
273
1.38k
    index = 0;
274
9.15k
    while (f_master_tbl[index] < goal_sb) {
275
7.77k
      index++;
276
7.77k
    }
277
436k
  } else {
278
436k
    index = num_mf_bands;
279
2.88M
    while (f_master_tbl[index] > goal_sb) {
280
2.44M
      index--;
281
2.44M
    }
282
436k
  }
283
284
437k
  return f_master_tbl[index];
285
483k
}
286
287
WORD32 ixheaacd_reset_hf_generator(ia_sbr_hf_generator_struct *ptr_hf_gen_str,
288
                                   ia_sbr_header_data_struct *ptr_header_data,
289
25.7k
                                   WORD audio_object_type) {
290
25.7k
  WORD32 patch, sb;
291
25.7k
  WORD32 temp;
292
25.7k
  WORD16 *ptr_noise_freq_tbl;
293
25.7k
  WORD32 num_nf_bands;
294
295
25.7k
  ia_transposer_settings_struct *pstr_transposer_settings =
296
25.7k
      ptr_hf_gen_str->pstr_settings;
297
25.7k
  ia_patch_param_struct *p_str_patch_param =
298
25.7k
      pstr_transposer_settings->str_patch_param;
299
300
25.7k
  WORD32 sub_band_start = ptr_header_data->pstr_freq_band_data->sub_band_start;
301
25.7k
  WORD16 *f_master_tbl = ptr_header_data->pstr_freq_band_data->f_master_tbl;
302
25.7k
  WORD16 num_mf_bands = ptr_header_data->pstr_freq_band_data->num_mf_bands;
303
25.7k
  WORD16 usb = ptr_header_data->pstr_freq_band_data->sub_band_end;
304
305
25.7k
  WORD32 src_start_band;
306
25.7k
  WORD32 patch_stride;
307
25.7k
  WORD32 num_bands_in_patch;
308
309
25.7k
  WORD32 lsb = f_master_tbl[0];
310
25.7k
  WORD16 xover_offset = sub_band_start - lsb;
311
312
25.7k
  WORD16 goal_sb, flag_break_1 = 0;
313
25.7k
  WORD32 fs = ptr_header_data->out_sampling_freq;
314
315
25.7k
  if (lsb < (SHIFT_START_SB + 4)) {
316
0
    return (1);
317
0
  }
318
25.7k
  switch (fs) {
319
2.04k
    case 16000:
320
2.22k
    case 22050:
321
2.48k
    case 24000:
322
21.4k
    case 32000:
323
21.4k
      goal_sb = 64;
324
21.4k
      break;
325
59
    case 44100:
326
59
      goal_sb = 46;
327
59
      break;
328
95
    case 48000:
329
95
      goal_sb = 43;
330
95
      break;
331
198
    case 64000:
332
198
      goal_sb = 32;
333
198
      break;
334
1.67k
    case 88200:
335
1.67k
      goal_sb = 23;
336
1.67k
      break;
337
1.30k
    case 96000:
338
1.30k
      goal_sb = 21;
339
1.30k
      break;
340
991
    default:
341
991
      return (0);
342
25.7k
  }
343
344
24.7k
  goal_sb = ixheaacd_find_closest_entry(goal_sb, f_master_tbl, num_mf_bands, 1);
345
24.7k
  if (audio_object_type != AOT_ER_AAC_ELD &&
346
729
      audio_object_type != AOT_ER_AAC_LD) {
347
729
    if (ixheaac_abs16_sat((WORD16)(goal_sb - usb)) < 4) {
348
615
      goal_sb = usb;
349
615
    }
350
729
  }
351
352
24.7k
  src_start_band = SHIFT_START_SB + xover_offset;
353
24.7k
  sb = (lsb + xover_offset);
354
355
24.7k
  patch = 0;
356
357
24.7k
  if ((goal_sb < sb) && (lsb > src_start_band)) {
358
14
    return -1;
359
14
  }
360
361
90.5k
  while (((sb - usb) < 0) && (patch < MAX_NUM_PATCHES)) {
362
65.7k
    ia_patch_param_struct *ptr_loc_patch_param = &p_str_patch_param[patch];
363
65.7k
    WORD16 abs_sb, flag_break = 0;
364
65.7k
    ptr_loc_patch_param->guard_start_band = sb;
365
65.7k
    sb = (sb + GUARDBANDS);
366
65.7k
    ptr_loc_patch_param->dst_start_band = sb;
367
368
65.7k
    num_bands_in_patch = (goal_sb - sb);
369
65.7k
    if ((num_bands_in_patch <= 0) &&
370
119
        ((num_bands_in_patch - (lsb - src_start_band)) < 0)) {
371
115
      flag_break = 1;
372
115
    }
373
65.7k
    if ((num_bands_in_patch - (lsb - src_start_band)) >= 0) {
374
42.2k
      patch_stride = sb - src_start_band;
375
42.2k
      patch_stride = (WORD16)(patch_stride & ~1);
376
42.2k
      num_bands_in_patch = (lsb - (sb - patch_stride));
377
42.2k
      num_bands_in_patch = ixheaacd_find_closest_entry(
378
42.2k
          sb + num_bands_in_patch, f_master_tbl, num_mf_bands, 0);
379
42.2k
      num_bands_in_patch -= sb;
380
42.2k
    }
381
382
65.7k
    patch_stride = ((num_bands_in_patch + sb) - lsb);
383
65.7k
    patch_stride = (WORD16)((patch_stride + 1) & ~1);
384
385
65.7k
    if (num_bands_in_patch > 0) {
386
64.2k
      ptr_loc_patch_param->src_start_band = (sb - patch_stride);
387
64.2k
      ptr_loc_patch_param->dst_end_band = patch_stride;
388
64.2k
      ptr_loc_patch_param->num_bands_in_patch = num_bands_in_patch;
389
64.2k
      ptr_loc_patch_param->src_end_band =
390
64.2k
          (ptr_loc_patch_param->src_start_band + num_bands_in_patch);
391
392
64.2k
      sb = (sb + ptr_loc_patch_param->num_bands_in_patch);
393
64.2k
      patch++;
394
64.2k
    }
395
396
65.7k
    src_start_band = SHIFT_START_SB;
397
65.7k
    abs_sb = ixheaac_abs16_sat((WORD16)((sb - goal_sb))) - 3;
398
399
65.7k
    if (num_bands_in_patch <= 0 && flag_break_1 == 1) {
400
0
      break;
401
0
    }
402
403
65.7k
    if (abs_sb < 0) {
404
26.4k
      goal_sb = usb;
405
39.3k
    } else {
406
39.3k
      if (flag_break == 1) break;
407
39.3k
    }
408
409
65.7k
    if (num_bands_in_patch <= 0) {
410
1.54k
      flag_break_1 = 1;
411
64.2k
    } else {
412
64.2k
      flag_break_1 = 0;
413
64.2k
    }
414
65.7k
  }
415
416
24.7k
  patch--;
417
418
24.7k
  if ((patch > 0) && (p_str_patch_param[patch].num_bands_in_patch < 3)) {
419
1.26k
    patch--;
420
1.26k
    sb = p_str_patch_param[patch].dst_start_band +
421
1.26k
         p_str_patch_param[patch].num_bands_in_patch;
422
1.26k
  }
423
424
24.7k
  if (patch >= MAX_NUM_PATCHES) {
425
0
    return -1;
426
0
  }
427
428
24.7k
  pstr_transposer_settings->num_patches = patch + 1;
429
430
24.7k
  temp = 0;
431
432
87.7k
  for (patch = 0; patch < pstr_transposer_settings->num_patches; patch++) {
433
62.9k
    sb = ixheaac_min32(sb, p_str_patch_param[patch].src_start_band);
434
62.9k
    temp = ixheaac_max32(temp, p_str_patch_param[patch].src_end_band);
435
62.9k
  }
436
437
24.7k
  if (sb > temp) return IA_FATAL_ERROR;
438
439
24.7k
  pstr_transposer_settings->start_patch = sb;
440
24.7k
  pstr_transposer_settings->stop_patch = temp;
441
442
24.7k
  ptr_noise_freq_tbl =
443
24.7k
      ptr_header_data->pstr_freq_band_data->freq_band_tbl_noise;
444
24.7k
  num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
445
446
24.7k
  memcpy(&pstr_transposer_settings->bw_borders[0], &ptr_noise_freq_tbl[1],
447
24.7k
         sizeof(WORD16) * num_nf_bands);
448
449
24.7k
  memset(ptr_hf_gen_str->bw_array_prev, 0, sizeof(WORD32) * MAX_NUM_PATCHES);
450
451
24.7k
  return 0;
452
24.7k
}
453
VOID ixheaacd_rescale_x_overlap(
454
    ia_sbr_dec_struct *ptr_sbr_dec, ia_sbr_header_data_struct *ptr_header_data,
455
    ia_sbr_frame_info_data_struct *ptr_frame_data,
456
    ia_sbr_prev_frame_data_struct *ptr_frame_data_prev,
457
    WORD32 **pp_overlap_buffer_real, WORD32 **pp_overlap_buffer_imag,
458
70.7k
    FLAG low_pow_flag) {
459
70.7k
  WORD32 k, l;
460
70.7k
  WORD32 start_band, end_band;
461
70.7k
  WORD32 target_lsb, target_usb;
462
70.7k
  WORD32 source_scale, target_scale, delta_scale, reserve;
463
464
70.7k
  WORD32 old_lsb = ptr_frame_data_prev->max_qmf_subband_aac;
465
70.7k
  WORD32 start_slot =
466
70.7k
      (ptr_header_data->time_step *
467
70.7k
       (ptr_frame_data_prev->end_position - ptr_header_data->num_time_slots));
468
70.7k
  WORD32 new_lsb = ptr_frame_data->max_qmf_subband_aac;
469
470
70.7k
  ptr_sbr_dec->str_codec_qmf_bank.usb = new_lsb;
471
70.7k
  ptr_sbr_dec->str_synthesis_qmf_bank.lsb = new_lsb;
472
473
70.7k
  start_band = ixheaac_min32(old_lsb, new_lsb);
474
70.7k
  end_band = ixheaac_max32(old_lsb, new_lsb);
475
476
70.7k
  if (new_lsb != old_lsb && old_lsb > 0) {
477
74.1k
    for (l = start_slot; l < 6; l++) {
478
283k
      for (k = old_lsb; k < new_lsb; k++) {
479
220k
        pp_overlap_buffer_real[l][k] = 0L;
480
481
220k
        if (!low_pow_flag) {
482
220k
          pp_overlap_buffer_imag[l][k] = 0L;
483
220k
        }
484
220k
      }
485
63.5k
    }
486
487
10.5k
    if (new_lsb > old_lsb) {
488
4.92k
      source_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale;
489
4.92k
      target_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale;
490
4.92k
      target_lsb = 0;
491
4.92k
      target_usb = old_lsb;
492
5.66k
    } else {
493
5.66k
      source_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale;
494
5.66k
      target_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale;
495
5.66k
      target_lsb = old_lsb;
496
5.66k
      target_usb = ptr_sbr_dec->str_synthesis_qmf_bank.usb;
497
5.66k
    }
498
499
10.5k
    reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
500
10.5k
        pp_overlap_buffer_real, pp_overlap_buffer_imag, start_band, end_band, 0,
501
10.5k
        start_slot, low_pow_flag);
502
503
10.5k
    (*ixheaacd_adjust_scale)(pp_overlap_buffer_real, pp_overlap_buffer_imag,
504
10.5k
                             start_band, end_band, 0, start_slot, reserve,
505
10.5k
                             low_pow_flag);
506
507
10.5k
    source_scale += reserve;
508
509
10.5k
    delta_scale = (target_scale - source_scale);
510
511
10.5k
    if (delta_scale > 0) {
512
76
      delta_scale = -(delta_scale);
513
76
      start_band = target_lsb;
514
76
      end_band = target_usb;
515
516
76
      if (new_lsb > old_lsb) {
517
0
        ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale = source_scale;
518
76
      } else {
519
76
        ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale = source_scale;
520
76
      }
521
76
    }
522
523
10.5k
    (*ixheaacd_adjust_scale)(pp_overlap_buffer_real, pp_overlap_buffer_imag,
524
10.5k
                             start_band, end_band, 0, start_slot, delta_scale,
525
10.5k
                             low_pow_flag);
526
10.5k
  }
527
70.7k
}
528
529
VOID ixheaacd_map_sineflags(WORD16 *freq_band_table, WORD16 num_sf_bands,
530
                            FLAG *add_harmonics, WORD8 *harm_flags_prev,
531
                            WORD16 transient_env, WORD8 *sine_mapped)
532
533
65.3k
{
534
65.3k
  WORD32 qmfband2, li, ui, i;
535
65.3k
  WORD32 low_subband_sec;
536
65.3k
  WORD32 oldflags;
537
538
65.3k
  low_subband_sec = (freq_band_table[0] << 1);
539
540
65.3k
  memset(sine_mapped, MAX_ENVELOPES, sizeof(WORD8) * MAX_FREQ_COEFFS);
541
542
778k
  for (i = (num_sf_bands - 1); i >= 0; i--) {
543
712k
    oldflags = *harm_flags_prev;
544
712k
    *harm_flags_prev++ = add_harmonics[i];
545
546
712k
    if (add_harmonics[i]) {
547
33.3k
      li = freq_band_table[i];
548
549
33.3k
      ui = freq_band_table[i + 1];
550
551
33.3k
      qmfband2 = ((ui + li) - low_subband_sec) >> 1;
552
553
33.3k
      if (oldflags)
554
5.25k
        sine_mapped[qmfband2] = 0;
555
28.0k
      else
556
28.0k
        sine_mapped[qmfband2] = (WORD8)transient_env;
557
33.3k
    }
558
712k
  }
559
65.3k
}
560
561
3.81k
VOID ixheaacd_map_34_params_to_20(WORD16 *params) {
562
3.81k
  params[0] = ixheaacd_divideby3(params[0] + params[0] + params[1]);
563
3.81k
  params[1] = ixheaacd_divideby3(params[1] + params[2] + params[2]);
564
3.81k
  params[2] = ixheaacd_divideby3(params[3] + params[3] + params[4]);
565
3.81k
  params[3] = ixheaacd_divideby3(params[4] + params[5] + params[5]);
566
3.81k
  params[4] = ixheaacd_divideby2(params[6] + params[7]);
567
3.81k
  params[5] = ixheaacd_divideby2(params[8] + params[9]);
568
3.81k
  params[6] = params[10];
569
3.81k
  params[7] = params[11];
570
3.81k
  params[8] = ixheaacd_divideby2(params[12] + params[13]);
571
3.81k
  params[9] = ixheaacd_divideby2(params[14] + params[15]);
572
3.81k
  params[10] = params[16];
573
3.81k
  params[11] = params[17];
574
3.81k
  params[12] = params[18];
575
3.81k
  params[13] = params[19];
576
3.81k
  params[14] = ixheaacd_divideby2(params[20] + params[21]);
577
3.81k
  params[15] = ixheaacd_divideby2(params[22] + params[23]);
578
3.81k
  params[16] = ixheaacd_divideby2(params[24] + params[25]);
579
3.81k
  params[17] = ixheaacd_divideby2(params[26] + params[27]);
580
3.81k
  params[18] = ixheaacd_divideby2(
581
3.81k
      ixheaacd_divideby2(params[28] + params[29] + params[30] + params[31]));
582
3.81k
  params[19] = ixheaacd_divideby2(params[32] + params[33]);
583
3.81k
}
584
585
extern const WORD16 ixheaacd_num_bands[3];
586
587
IA_ERRORCODE ixheaacd_read_ps_data(ia_ps_dec_struct *ptr_ps_dec, ia_bit_buf_struct *it_bit_buff,
588
                                   WORD16 num_bits_left, ia_ps_tables_struct *ps_tables_ptr)
589
4.83k
{
590
4.83k
  WORD b, e, temp;
591
4.83k
  const WORD16 num_env_tab[4] = {0, 1, 2, 4};
592
4.83k
  WORD cnt_bits;
593
4.83k
  ia_huffman_data_type huffman_table, huffman_df_table, huffman_dt_table;
594
4.83k
  FLAG enable_ps_header;
595
596
4.83k
  if (!ptr_ps_dec) {
597
0
    return 0;
598
0
  }
599
600
4.83k
  cnt_bits = it_bit_buff->cnt_bits;
601
602
4.83k
  enable_ps_header = ixheaacd_read_bits_buf(it_bit_buff, 1);
603
604
4.83k
  if (enable_ps_header) {
605
1.29k
    ptr_ps_dec->enable_iid = ixheaacd_read_bits_buf(it_bit_buff, 1);
606
1.29k
    if (ptr_ps_dec->enable_iid) {
607
1.01k
      ptr_ps_dec->iid_mode = ixheaacd_read_bits_buf(it_bit_buff, 3);
608
1.01k
    }
609
610
1.29k
    if (ptr_ps_dec->iid_mode > 2) {
611
757
      ptr_ps_dec->iid_quant = 1;
612
757
      ptr_ps_dec->iid_mode -= 3;
613
757
    } else {
614
536
      ptr_ps_dec->iid_quant = 0;
615
536
    }
616
617
1.29k
    ptr_ps_dec->enable_icc = ixheaacd_read_bits_buf(it_bit_buff, 1);
618
1.29k
    if (ptr_ps_dec->enable_icc) {
619
766
      ptr_ps_dec->icc_mode = ixheaacd_read_bits_buf(it_bit_buff, 3);
620
766
    }
621
622
1.29k
    ptr_ps_dec->enable_ext = ixheaacd_read_bits_buf(it_bit_buff, 1);
623
624
1.29k
    if (ptr_ps_dec->icc_mode > 2) {
625
748
      ptr_ps_dec->icc_mode -= 3;
626
748
      ptr_ps_dec->use_pca_rot_flg = 1;
627
748
    } else {
628
545
      ptr_ps_dec->use_pca_rot_flg = 0;
629
545
    }
630
1.29k
    ptr_ps_dec->freq_res_ipd = ptr_ps_dec->iid_mode;
631
1.29k
    if (ptr_ps_dec->freq_res_ipd > 2) {
632
2
      return IA_FATAL_ERROR;
633
2
    }
634
1.29k
  }
635
636
4.83k
  ptr_ps_dec->use_34_st_bands = 0;
637
4.83k
  ptr_ps_dec->use_pca_rot_flg = 0;
638
639
4.83k
  if ((ptr_ps_dec->enable_iid && ptr_ps_dec->iid_mode > 2) ||
640
4.83k
      (ptr_ps_dec->enable_icc && ptr_ps_dec->icc_mode > 2)) {
641
888
    ptr_ps_dec->ps_data_present = 0;
642
643
888
    num_bits_left -= (cnt_bits - it_bit_buff->cnt_bits);
644
645
4.89k
    while (num_bits_left > 8) {
646
4.00k
      ixheaacd_read_bits_buf(it_bit_buff, 8);
647
4.00k
      num_bits_left -= 8;
648
4.00k
    }
649
888
    if (num_bits_left >= 0) {
650
809
      ixheaacd_read_bits_buf(it_bit_buff, num_bits_left);
651
809
    }
652
653
888
    return (cnt_bits - it_bit_buff->cnt_bits);
654
888
  }
655
656
3.94k
  ptr_ps_dec->frame_class = (FLAG)ixheaacd_read_bits_buf(it_bit_buff, 1);
657
658
3.94k
  temp = ixheaacd_read_bits_buf(it_bit_buff, 2);
659
660
3.94k
  if (ptr_ps_dec->frame_class == 0) {
661
2.94k
    ptr_ps_dec->num_env = num_env_tab[temp];
662
2.94k
  } else {
663
996
    ptr_ps_dec->num_env = (((1 + temp) << 8) >> 8);
664
665
4.29k
    for (e = 1; e < ptr_ps_dec->num_env + 1; e++) {
666
3.29k
      ptr_ps_dec->border_position[e] =
667
3.29k
          (((ixheaacd_read_bits_buf(it_bit_buff, 5) + 1) << 8) >> 8);
668
3.29k
    }
669
996
  }
670
671
3.94k
  if (ptr_ps_dec->enable_iid) {
672
1.36k
    if (ptr_ps_dec->iid_quant) {
673
1.05k
      huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_df_fine;
674
1.05k
      huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_dt_fine;
675
1.05k
    } else {
676
310
      huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_df;
677
310
      huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_dt;
678
310
    }
679
680
4.29k
    for (e = 0; e < ptr_ps_dec->num_env; e++) {
681
2.92k
      ptr_ps_dec->iid_dt[e] = (FLAG)ixheaacd_read_bits_buf(it_bit_buff, 1);
682
683
2.92k
      if (ptr_ps_dec->iid_dt[e]) {
684
1.41k
        huffman_table = huffman_dt_table;
685
1.51k
      } else {
686
1.51k
        huffman_table = huffman_df_table;
687
1.51k
      }
688
689
77.7k
      for (b = 0; b < ixheaacd_num_bands[ptr_ps_dec->iid_mode]; b++) {
690
74.8k
        ptr_ps_dec->iid_par_table[e][b] =
691
74.8k
            ixheaacd_ssc_huff_dec(huffman_table, it_bit_buff);
692
74.8k
      }
693
2.92k
    }
694
1.36k
  }
695
696
3.94k
  if (ptr_ps_dec->enable_icc) {
697
945
    huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_icc_df;
698
945
    huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_icc_dt;
699
700
3.85k
    for (e = 0; e < ptr_ps_dec->num_env; e++) {
701
2.90k
      ptr_ps_dec->icc_dt[e] = ixheaacd_read_bits_buf(it_bit_buff, 1);
702
703
2.90k
      if (ptr_ps_dec->icc_dt[e]) {
704
1.07k
        huffman_table = huffman_dt_table;
705
1.83k
      } else {
706
1.83k
        huffman_table = huffman_df_table;
707
1.83k
      }
708
709
39.2k
      for (b = 0; b < ixheaacd_num_bands[ptr_ps_dec->icc_mode]; b++) {
710
36.3k
        ptr_ps_dec->icc_par_table[e][b] = ixheaacd_ssc_huff_dec(huffman_table, it_bit_buff);
711
36.3k
      }
712
2.90k
    }
713
945
  }
714
715
3.94k
  if (ptr_ps_dec->enable_ext) {
716
617
    WORD32 cnt;
717
617
    if (it_bit_buff->cnt_bits < 4)
718
15
      cnt = ixheaacd_read_bits_buf(it_bit_buff, it_bit_buff->cnt_bits);
719
602
    else
720
602
      cnt = ixheaacd_read_bits_buf(it_bit_buff, 4);
721
722
617
    if (cnt == 15) {
723
57
      cnt += ixheaacd_read_bits_buf(it_bit_buff, 8);
724
57
    }
725
12.4k
    while (cnt--) {
726
11.8k
      ixheaacd_read_bits_buf(it_bit_buff, 8);
727
11.8k
    }
728
617
  }
729
730
3.94k
  ptr_ps_dec->ps_data_present = 1;
731
732
3.94k
  return (cnt_bits - it_bit_buff->cnt_bits);
733
4.83k
}
734
735
VOID ixheaacd_invfilt_level_emphasis(ia_sbr_hf_generator_struct *ptr_hf_gen_str,
736
                                     WORD32 num_if_bands, WORD32 *inv_filt_mode,
737
                                     WORD32 *inv_filt_mode_prev,
738
65.3k
                                     WORD32 *bw_array) {
739
65.3k
  WORD32 i;
740
65.3k
  WORD32 accu;
741
65.3k
  WORD16 w1, w2;
742
743
221k
  for (i = 0; i < num_if_bands; i++) {
744
156k
    bw_array[i] =
745
156k
        ixheaacd_inew_bw_table[inv_filt_mode_prev[i]][inv_filt_mode[i]];
746
747
156k
    if (bw_array[i] < ptr_hf_gen_str->bw_array_prev[i]) {
748
15.9k
      w1 = 0x6000;
749
15.9k
      w2 = 0x2000;
750
140k
    } else {
751
140k
      w1 = 0x7400;
752
140k
      w2 = 0x0c00;
753
140k
    }
754
156k
    accu = ixheaac_add32(
755
156k
        ixheaac_mult32x16in32_shl(bw_array[i], w1),
756
156k
        ixheaac_mult32x16in32_shl(ptr_hf_gen_str->bw_array_prev[i], w2));
757
758
156k
    if (accu < 0x02000000) {
759
103k
      accu = 0;
760
103k
    }
761
762
156k
    if (accu >= 0x7f800000) {
763
0
      accu = 0x7f800000;
764
0
    }
765
156k
    bw_array[i] = accu;
766
156k
  }
767
65.3k
}
768
769
typedef struct {
770
  FLOAT32 phi_0_1_real;
771
  FLOAT32 phi_0_1_imag;
772
  FLOAT32 phi_0_2_real;
773
  FLOAT32 phi_0_2_imag;
774
  FLOAT32 phi_1_1;
775
  FLOAT32 phi_1_2_real;
776
  FLOAT32 phi_1_2_imag;
777
  FLOAT32 phi_2_2;
778
  FLOAT32 det;
779
} ia_auto_corr_ele_struct;
780
781
static VOID ixheaacd_esbr_calc_co_variance(
782
    ia_auto_corr_ele_struct *pstr_auto_corr, FLOAT32 vec_x_real[][64],
783
5.51M
    FLOAT32 vec_x_imag[][64], WORD32 bd, WORD32 len) {
784
5.51M
  WORD32 j, jminus1, jminus2;
785
786
5.51M
  memset(pstr_auto_corr, 0, sizeof(ia_auto_corr_ele_struct));
787
788
216M
  for (j = 0; j < len; j++) {
789
210M
    jminus1 = j - 1;
790
210M
    jminus2 = jminus1 - 1;
791
792
210M
    pstr_auto_corr->phi_0_1_real +=
793
210M
        vec_x_real[j][bd] * vec_x_real[jminus1][bd] +
794
210M
        vec_x_imag[j][bd] * vec_x_imag[jminus1][bd];
795
796
210M
    pstr_auto_corr->phi_0_1_imag +=
797
210M
        vec_x_imag[j][bd] * vec_x_real[jminus1][bd] -
798
210M
        vec_x_real[j][bd] * vec_x_imag[jminus1][bd];
799
800
210M
    pstr_auto_corr->phi_0_2_real +=
801
210M
        vec_x_real[j][bd] * vec_x_real[jminus2][bd] +
802
210M
        vec_x_imag[j][bd] * vec_x_imag[jminus2][bd];
803
804
210M
    pstr_auto_corr->phi_0_2_imag +=
805
210M
        vec_x_imag[j][bd] * vec_x_real[jminus2][bd] -
806
210M
        vec_x_real[j][bd] * vec_x_imag[jminus2][bd];
807
808
210M
    pstr_auto_corr->phi_1_1 +=
809
210M
        vec_x_real[jminus1][bd] * vec_x_real[jminus1][bd] +
810
210M
        vec_x_imag[jminus1][bd] * vec_x_imag[jminus1][bd];
811
812
210M
    pstr_auto_corr->phi_1_2_real +=
813
210M
        vec_x_real[jminus1][bd] * vec_x_real[jminus2][bd] +
814
210M
        vec_x_imag[jminus1][bd] * vec_x_imag[jminus2][bd];
815
816
210M
    pstr_auto_corr->phi_1_2_imag +=
817
210M
        vec_x_imag[jminus1][bd] * vec_x_real[jminus2][bd] -
818
210M
        vec_x_real[jminus1][bd] * vec_x_imag[jminus2][bd];
819
820
210M
    pstr_auto_corr->phi_2_2 +=
821
210M
        vec_x_real[jminus2][bd] * vec_x_real[jminus2][bd] +
822
210M
        vec_x_imag[jminus2][bd] * vec_x_imag[jminus2][bd];
823
210M
  }
824
825
5.51M
  pstr_auto_corr->det =
826
5.51M
      pstr_auto_corr->phi_1_1 * pstr_auto_corr->phi_2_2 -
827
5.51M
      (pstr_auto_corr->phi_1_2_real * pstr_auto_corr->phi_1_2_real +
828
5.51M
       pstr_auto_corr->phi_1_2_imag * pstr_auto_corr->phi_1_2_imag) *
829
5.51M
          SBR_HF_RELAXATION_PARAM;
830
5.51M
}
831
832
static void ixheaacd_esbr_chirp_fac_calc(WORD32 *inv_filt_mode,
833
                                         WORD32 *inv_filt_mode_prev,
834
                                         WORD32 num_if_bands, FLOAT32 *bw_array,
835
326k
                                         FLOAT32 *bw_array_prev) {
836
326k
  WORD32 i;
837
838
1.16M
  for (i = 0; i < num_if_bands; i++) {
839
834k
    bw_array[i] =
840
834k
        ixheaacd_new_bw_table[inv_filt_mode_prev[i]][inv_filt_mode[i]];
841
842
834k
    if (bw_array[i] < bw_array_prev[i])
843
227k
      bw_array[i] = 0.75000f * bw_array[i] + 0.25000f * bw_array_prev[i];
844
607k
    else
845
607k
      bw_array[i] = 0.90625f * bw_array[i] + 0.09375f * bw_array_prev[i];
846
847
834k
    if (bw_array[i] < 0.015625) bw_array[i] = 0;
848
834k
  }
849
326k
}
850
851
static void ixheaacd_gausssolve(WORD32 n, FLOAT32 a[][MAXDEG + 1], FLOAT32 b[],
852
30.5k
                                FLOAT32 y[]) {
853
30.5k
  WORD32 i, j, k, imax;
854
30.5k
  FLOAT32 v;
855
856
152k
  for (i = 0; i < n; i++) {
857
122k
    imax = i;
858
305k
    for (k = i + 1; k < n; k++) {
859
183k
      if (fabs(a[k][i]) > fabs(a[imax][i])) {
860
5.54k
        imax = k;
861
5.54k
      }
862
183k
    }
863
122k
    if (imax != i) {
864
5.51k
      v = b[imax];
865
5.51k
      b[imax] = b[i];
866
5.51k
      b[i] = v;
867
16.5k
      for (j = i; j < n; j++) {
868
11.0k
        v = a[imax][j];
869
11.0k
        a[imax][j] = a[i][j];
870
11.0k
        a[i][j] = v;
871
11.0k
      }
872
5.51k
    }
873
874
122k
    v = a[i][i];
875
876
122k
    b[i] /= v;
877
428k
    for (j = i; j < n; j++) {
878
305k
      a[i][j] /= v;
879
305k
    }
880
881
305k
    for (k = i + 1; k < n; k++) {
882
183k
      v = a[k][i];
883
183k
      b[k] -= v * b[i];
884
611k
      for (j = i + 1; j < n; j++) {
885
428k
        a[k][j] -= v * a[i][j];
886
428k
      }
887
183k
    }
888
122k
  }
889
890
152k
  for (i = n - 1; i >= 0; i--) {
891
122k
    y[i] = b[i];
892
305k
    for (j = i + 1; j < n; j++) {
893
183k
      y[i] -= a[i][j] * y[j];
894
183k
    }
895
122k
  }
896
30.5k
}
897
898
30.5k
void ixheaacd_polyfit(WORD32 n, FLOAT32 y[], FLOAT32 p[]) {
899
30.5k
  WORD32 i, j, k;
900
30.5k
  FLOAT32 a[MAXDEG + 1][MAXDEG + 1];
901
30.5k
  FLOAT32 b[MAXDEG + 1];
902
30.5k
  FLOAT32 v[2 * MAXDEG + 1];
903
904
152k
  for (i = 0; i <= MAXDEG; i++) {
905
122k
    b[i] = 0.0f;
906
611k
    for (j = 0; j <= MAXDEG; j++) {
907
489k
      a[i][j] = 0.0f;
908
489k
    }
909
122k
  }
910
911
551k
  for (k = 0; k < n; k++) {
912
520k
    v[0] = 1.0;
913
3.64M
    for (i = 1; i <= 2 * MAXDEG; i++) {
914
3.12M
      v[i] = k * v[i - 1];
915
3.12M
    }
916
917
2.60M
    for (i = 0; i <= MAXDEG; i++) {
918
2.08M
      b[i] += v[MAXDEG - i] * y[k];
919
10.4M
      for (j = 0; j <= MAXDEG; j++) {
920
8.32M
        a[i][j] += v[2 * MAXDEG - i - j];
921
8.32M
      }
922
2.08M
    }
923
520k
  }
924
925
30.5k
  ixheaacd_gausssolve(MAXDEG + 1, a, b, p);
926
30.5k
}
927
928
VOID ixheaacd_pre_processing(FLOAT32 ptr_src_buf_real[][64],
929
                             FLOAT32 ptr_src_buf_imag[][64],
930
                             FLOAT32 gain_vector[], WORD32 num_bands,
931
30.5k
                             WORD32 start_sample, WORD32 end_sample) {
932
30.5k
  WORD32 k, i;
933
30.5k
  FLOAT32 poly_coeff[4];
934
30.5k
  FLOAT32 mean_enrg = 0;
935
30.5k
  FLOAT32 low_env_slope[64];
936
30.5k
  FLOAT32 low_env[64] = {0};
937
30.5k
  FLOAT32 a0;
938
30.5k
  FLOAT32 a1;
939
30.5k
  FLOAT32 a2;
940
30.5k
  FLOAT32 a3;
941
942
30.5k
  if (num_bands != 0 && end_sample != start_sample) {
943
544k
    for (k = 0; k < num_bands; k++) {
944
513k
      FLOAT32 temp = 0;
945
17.1M
      for (i = start_sample; i < end_sample; i++) {
946
16.5M
        temp += ptr_src_buf_real[i][k] * ptr_src_buf_real[i][k] +
947
16.5M
                ptr_src_buf_imag[i][k] * ptr_src_buf_imag[i][k];
948
16.5M
      }
949
513k
      temp /= (end_sample - start_sample);
950
513k
      low_env[k] = (FLOAT32)(10 * log10(temp + 1));
951
513k
      mean_enrg = mean_enrg + low_env[k];
952
513k
    }
953
30.2k
    mean_enrg /= num_bands;
954
30.2k
  }
955
956
30.5k
  ixheaacd_polyfit(num_bands, low_env, poly_coeff);
957
958
30.5k
  a0 = poly_coeff[0];
959
30.5k
  a1 = poly_coeff[1];
960
30.5k
  a2 = poly_coeff[2];
961
30.5k
  a3 = poly_coeff[3];
962
551k
  for (k = 0; k < num_bands; k++) {
963
520k
    FLOAT32 x_low_l = (FLOAT32)k;
964
520k
    FLOAT32 low_env_slope_l = a3;
965
520k
    low_env_slope_l = low_env_slope_l + a2 * x_low_l;
966
967
520k
    x_low_l = x_low_l * x_low_l;
968
520k
    low_env_slope_l = low_env_slope_l + a1 * x_low_l;
969
970
520k
    x_low_l = x_low_l * (FLOAT32)k;
971
520k
    low_env_slope_l = low_env_slope_l + a0 * x_low_l;
972
973
520k
    low_env_slope[k] = low_env_slope_l;
974
520k
  }
975
976
551k
  for (i = 0; i < num_bands; i++) {
977
520k
    gain_vector[i] = (FLOAT32)pow(10, (mean_enrg - low_env_slope[i]) / 20.0f);
978
520k
  }
979
30.5k
}
980
981
WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64], FLOAT32 ptr_src_buf_imag[][64],
982
                            FLOAT32 ptr_ph_vocod_buf_real[][64],
983
                            FLOAT32 ptr_ph_vocod_buf_imag[][64], FLOAT32 ptr_dst_buf_real[][64],
984
                            FLOAT32 ptr_dst_buf_imag[][64],
985
                            ia_sbr_frame_info_data_struct *ptr_frame_data,
986
                            ia_sbr_header_data_struct *ptr_header_data, WORD32 ldmps_present,
987
326k
                            WORD32 time_slots, WORD32 ec_flag) {
988
326k
  WORD32 bw_index, i, k, k2, patch = 0;
989
326k
  WORD32 co_var_len;
990
326k
  WORD32 start_sample, end_sample, goal_sb;
991
326k
  WORD32 sb, source_start_band, patch_stride, num_bands_in_patch;
992
326k
  WORD32 hbe_flag = ptr_header_data->hbe_flag;
993
326k
  FLOAT32 a0r, a0i, a1r, a1i;
994
326k
  FLOAT32 bw_array[MAX_NUM_PATCHES] = {0};
995
996
326k
  ia_auto_corr_ele_struct str_auto_corr;
997
998
326k
  WORD16 *ptr_invf_band_tbl =
999
326k
      &ptr_header_data->pstr_freq_band_data
1000
326k
           ->freq_band_tbl_noise[1];  // offest 1 used as base address of
1001
                                      // ptr_invf_band_tbl
1002
326k
  WORD32 num_if_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
1003
326k
  WORD32 sub_band_start = ptr_header_data->pstr_freq_band_data->sub_band_start;
1004
326k
  WORD16 *f_master_tbl = ptr_header_data->pstr_freq_band_data->f_master_tbl;
1005
326k
  WORD32 num_mf_bands = ptr_header_data->pstr_freq_band_data->num_mf_bands;
1006
326k
  WORD32 *inv_filt_mode = ptr_frame_data->sbr_invf_mode;
1007
326k
  WORD32 *inv_filt_mode_prev = ptr_frame_data->sbr_invf_mode_prev;
1008
326k
  WORD32 sbr_patching_mode = ptr_frame_data->sbr_patching_mode;
1009
326k
  ia_frame_info_struct *p_frame_info = &ptr_frame_data->str_frame_info_details;
1010
326k
  WORD32 pre_proc_flag = ptr_header_data->pre_proc_flag;
1011
326k
  WORD32 is_usf_4 = ptr_header_data->is_usf_4;
1012
326k
  WORD32 fs = ptr_header_data->out_sampling_freq;
1013
326k
  WORD32 cov_count;
1014
326k
  WORD32 lsb = f_master_tbl[0];
1015
326k
  WORD32 usb = f_master_tbl[num_mf_bands];
1016
326k
  WORD32 xover_offset = sub_band_start - f_master_tbl[0];
1017
1018
326k
  FLOAT32 bw = 0.0f;
1019
326k
  FLOAT32 fac = 0.0f;
1020
1021
326k
  FLOAT32 gain;
1022
326k
  FLOAT32 gain_vector[64];
1023
1024
326k
  WORD32 slope_length = 0;
1025
326k
  WORD32 first_slot_offset = p_frame_info->border_vec[0];
1026
326k
  WORD32 end_slot_offs = 0;
1027
1028
326k
  FLOAT32 *bw_array_prev = ptr_frame_data->bw_array_prev;
1029
1030
326k
  end_slot_offs = p_frame_info->border_vec[p_frame_info->num_env] - 16;
1031
1032
326k
  if (ldmps_present == 1)
1033
5.40k
    end_slot_offs =
1034
5.40k
        p_frame_info->border_vec[p_frame_info->num_env] - time_slots;
1035
1036
326k
  if (is_usf_4) {
1037
15.9k
    start_sample = first_slot_offset * 4;
1038
15.9k
    end_sample = 64 + end_slot_offs * 4;
1039
15.9k
    co_var_len = 76;
1040
310k
  } else {
1041
310k
    start_sample = first_slot_offset * 2;
1042
310k
    end_sample = 32 + end_slot_offs * 2;
1043
310k
    co_var_len = 38;
1044
310k
  }
1045
1046
326k
  if (ldmps_present == 1) {
1047
5.40k
    start_sample = 0;
1048
5.40k
    end_sample = time_slots;
1049
5.40k
    co_var_len = time_slots;
1050
5.40k
  }
1051
1052
326k
  if (pre_proc_flag) {
1053
30.5k
    ixheaacd_pre_processing(ptr_src_buf_real, ptr_src_buf_imag, gain_vector,
1054
30.5k
                            f_master_tbl[0], start_sample, end_sample);
1055
30.5k
  }
1056
1057
326k
  ixheaacd_esbr_chirp_fac_calc(inv_filt_mode, inv_filt_mode_prev, num_if_bands,
1058
326k
                               bw_array, bw_array_prev);
1059
1060
11.1M
  for (i = start_sample; i < end_sample; i++) {
1061
10.8M
    memset(ptr_dst_buf_real[i] + usb, 0, (64 - usb) * sizeof(FLOAT32));
1062
10.8M
    memset(ptr_dst_buf_imag[i] + usb, 0, (64 - usb) * sizeof(FLOAT32));
1063
10.8M
  }
1064
1065
326k
  if (sbr_patching_mode || !hbe_flag) {
1066
198k
    WORD32 flag_break = 0;
1067
198k
    FLOAT32 alpha_real[64][2] = {{0}}, alpha_imag[64][2] = {{0}};
1068
198k
    if (ptr_frame_data->mps_sbr_flag) {
1069
79.9k
      cov_count = (f_master_tbl[0] < ptr_frame_data->cov_count)
1070
79.9k
                      ? f_master_tbl[0]
1071
79.9k
                      : ptr_frame_data->cov_count;
1072
118k
    } else {
1073
118k
      cov_count = f_master_tbl[0];
1074
118k
    }
1075
1076
3.25M
    for (k = 1; k < cov_count; k++) {
1077
3.05M
      ixheaacd_esbr_calc_co_variance(&str_auto_corr, &ptr_src_buf_real[0],
1078
3.05M
                                     &ptr_src_buf_imag[0], k, co_var_len);
1079
3.05M
      if (str_auto_corr.det == 0.0f) {
1080
1.43M
        alpha_real[k][1] = alpha_imag[k][1] = 0;
1081
1.62M
      } else {
1082
1.62M
        fac = 1.0f / str_auto_corr.det;
1083
1.62M
        alpha_real[k][1] =
1084
1.62M
            (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
1085
1.62M
             str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
1086
1.62M
             str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
1087
1.62M
            fac;
1088
1.62M
        alpha_imag[k][1] =
1089
1.62M
            (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
1090
1.62M
             str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
1091
1.62M
             str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
1092
1.62M
            fac;
1093
1.62M
      }
1094
1095
3.05M
      if (str_auto_corr.phi_1_1 == 0) {
1096
1.42M
        alpha_real[k][0] = alpha_imag[k][0] = 0;
1097
1.62M
      } else {
1098
1.62M
        fac = 1.0f / str_auto_corr.phi_1_1;
1099
1.62M
        alpha_real[k][0] = -(str_auto_corr.phi_0_1_real +
1100
1.62M
                             alpha_real[k][1] * str_auto_corr.phi_1_2_real +
1101
1.62M
                             alpha_imag[k][1] * str_auto_corr.phi_1_2_imag) *
1102
1.62M
                           fac;
1103
1.62M
        alpha_imag[k][0] = -(str_auto_corr.phi_0_1_imag +
1104
1.62M
                             alpha_imag[k][1] * str_auto_corr.phi_1_2_real -
1105
1.62M
                             alpha_real[k][1] * str_auto_corr.phi_1_2_imag) *
1106
1.62M
                           fac;
1107
1.62M
      }
1108
1109
3.05M
      if ((alpha_real[k][0] * alpha_real[k][0] +
1110
3.05M
               alpha_imag[k][0] * alpha_imag[k][0] >=
1111
3.05M
           16.0f) ||
1112
3.05M
          (alpha_real[k][1] * alpha_real[k][1] +
1113
3.05M
               alpha_imag[k][1] * alpha_imag[k][1] >=
1114
3.05M
           16.0f)) {
1115
4.87k
        alpha_real[k][0] = 0.0f;
1116
4.87k
        alpha_imag[k][0] = 0.0f;
1117
4.87k
        alpha_real[k][1] = 0.0f;
1118
4.87k
        alpha_imag[k][1] = 0.0f;
1119
4.87k
      }
1120
3.05M
    }
1121
1122
198k
    goal_sb = (WORD32)(2.048e6f / fs + 0.5f);
1123
198k
    {
1124
198k
      WORD32 index;
1125
198k
      if (goal_sb < f_master_tbl[num_mf_bands]) {
1126
117k
        for (index = 0; (f_master_tbl[index] < goal_sb); index++)
1127
104k
          ;
1128
13.2k
        goal_sb = f_master_tbl[index];
1129
185k
      } else {
1130
185k
        goal_sb = f_master_tbl[num_mf_bands];
1131
185k
      }
1132
198k
    }
1133
1134
198k
    source_start_band = xover_offset + 1;
1135
198k
    sb = lsb + xover_offset;
1136
1137
198k
    patch = 0;
1138
743k
    while (sb < usb) {
1139
602k
      if (MAX_NUM_PATCHES <= patch) {
1140
36
        if (ec_flag) {
1141
0
          break;
1142
36
        } else {
1143
36
          return -1;
1144
36
        }
1145
36
      }
1146
602k
      ptr_frame_data->patch_param.start_subband[patch] = sb;
1147
602k
      num_bands_in_patch = goal_sb - sb;
1148
1149
602k
      if (num_bands_in_patch >= lsb - source_start_band) {
1150
416k
        patch_stride = sb - source_start_band;
1151
416k
        patch_stride = patch_stride & ~1;
1152
416k
        num_bands_in_patch = lsb - (sb - patch_stride);
1153
416k
        num_bands_in_patch =
1154
416k
            ixheaacd_find_closest_entry(sb + num_bands_in_patch, f_master_tbl,
1155
416k
                                        (WORD16)(num_mf_bands), 0) -
1156
416k
            (WORD32)(sb);
1157
416k
      }
1158
1159
602k
      patch_stride = num_bands_in_patch + sb - lsb;
1160
602k
      patch_stride = (patch_stride + 1) & ~1;
1161
1162
602k
      source_start_band = 1;
1163
1164
602k
      if (goal_sb - (sb + num_bands_in_patch) < 3) {
1165
254k
        goal_sb = usb;
1166
254k
      }
1167
1168
602k
      if ((num_bands_in_patch < 3) && (patch > 0) &&
1169
55.2k
          (sb + num_bands_in_patch == usb)) {
1170
1.77M
        for (i = start_sample + slope_length; i < end_sample + slope_length;
1171
1.72M
             i++) {
1172
5.16M
          for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
1173
3.44M
            ptr_dst_buf_real[i][k2] = 0.0f;
1174
3.44M
            ptr_dst_buf_imag[i][k2] = 0.0f;
1175
3.44M
          }
1176
1.72M
        }
1177
1178
53.5k
        break;
1179
53.5k
      }
1180
1181
548k
      if (num_bands_in_patch < 0 && flag_break == 1) {
1182
3.17k
        break;
1183
3.17k
      }
1184
1185
545k
      if (num_bands_in_patch < 0) {
1186
13.8k
        flag_break = 1;
1187
13.8k
        continue;
1188
531k
      } else {
1189
531k
        flag_break = 0;
1190
531k
      }
1191
1192
5.55M
      for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
1193
5.01M
        k = k2 - patch_stride;
1194
5.01M
        bw_index = 0;
1195
11.2M
        while (k2 >= ptr_invf_band_tbl[bw_index]) {
1196
6.25M
          bw_index++;
1197
6.25M
          if (bw_index >= MAX_NOISE_COEFFS) {
1198
0
            if (ec_flag) {
1199
0
              bw_index = MAX_NOISE_COEFFS - 1;
1200
0
              break;
1201
0
            } else
1202
0
              return -1;
1203
0
          }
1204
6.25M
        }
1205
1206
5.01M
        if (bw_index >= MAX_NUM_PATCHES) {
1207
0
          if (ec_flag)
1208
0
            bw_index = MAX_NUM_PATCHES - 1;
1209
0
          else
1210
0
            return -1;
1211
0
        }
1212
5.01M
        bw = bw_array[bw_index];
1213
1214
5.01M
        a0r = bw * alpha_real[k][0];
1215
5.01M
        a0i = bw * alpha_imag[k][0];
1216
5.01M
        bw *= bw;
1217
5.01M
        a1r = bw * alpha_real[k][1];
1218
5.01M
        a1i = bw * alpha_imag[k][1];
1219
1220
5.01M
        if (pre_proc_flag) {
1221
507k
          gain = gain_vector[k];
1222
4.51M
        } else {
1223
4.51M
          gain = 1.0f;
1224
4.51M
        }
1225
1226
164M
        for (i = start_sample + slope_length; i < end_sample + slope_length;
1227
159M
             i++) {
1228
159M
          ptr_dst_buf_real[i][k2] = ptr_src_buf_real[i][k] * gain;
1229
1230
159M
          ptr_dst_buf_imag[i][k2] = ptr_src_buf_imag[i][k] * gain;
1231
1232
159M
          if (bw > 0.0f) {
1233
92.0M
            ptr_dst_buf_real[i][k2] += (a0r * ptr_src_buf_real[i - 1][k] -
1234
92.0M
                                        a0i * ptr_src_buf_imag[i - 1][k] +
1235
92.0M
                                        a1r * ptr_src_buf_real[i - 2][k] -
1236
92.0M
                                        a1i * ptr_src_buf_imag[i - 2][k]) *
1237
92.0M
                                       gain;
1238
92.0M
            ptr_dst_buf_imag[i][k2] += (a0i * ptr_src_buf_real[i - 1][k] +
1239
92.0M
                                        a0r * ptr_src_buf_imag[i - 1][k] +
1240
92.0M
                                        a1i * ptr_src_buf_real[i - 2][k] +
1241
92.0M
                                        a1r * ptr_src_buf_imag[i - 2][k]) *
1242
92.0M
                                       gain;
1243
92.0M
          }
1244
159M
        }
1245
5.01M
      }
1246
531k
      sb += num_bands_in_patch;
1247
531k
      patch++;
1248
531k
    }
1249
198k
  }
1250
1251
326k
  if (NULL != ptr_ph_vocod_buf_real && NULL != ptr_ph_vocod_buf_imag) {
1252
220k
    if (hbe_flag && !sbr_patching_mode) {
1253
102k
      FLOAT32 alpha_real[2], alpha_imag[2];
1254
1255
102k
      bw_index = 0, patch = 1;
1256
1257
2.55M
      for (k2 = sub_band_start; k2 < f_master_tbl[num_mf_bands]; k2++) {
1258
2.45M
        ixheaacd_esbr_calc_co_variance(&str_auto_corr, &ptr_ph_vocod_buf_real[0],
1259
2.45M
                                       &ptr_ph_vocod_buf_imag[0], k2, co_var_len);
1260
1261
2.45M
        if (str_auto_corr.det == 0.0f) {
1262
1.12M
          alpha_real[1] = alpha_imag[1] = 0;
1263
1.32M
        } else {
1264
1.32M
          fac = 1.0f / str_auto_corr.det;
1265
1.32M
          alpha_real[1] = (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
1266
1.32M
                           str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
1267
1.32M
                           str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
1268
1.32M
                          fac;
1269
1.32M
          alpha_imag[1] = (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
1270
1.32M
                           str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
1271
1.32M
                           str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
1272
1.32M
                          fac;
1273
1.32M
        }
1274
1275
2.45M
        if (str_auto_corr.phi_1_1 == 0) {
1276
1.11M
          alpha_real[0] = alpha_imag[0] = 0;
1277
1.33M
        } else {
1278
1.33M
          fac = 1.0f / str_auto_corr.phi_1_1;
1279
1.33M
          alpha_real[0] =
1280
1.33M
              -(str_auto_corr.phi_0_1_real + alpha_real[1] * str_auto_corr.phi_1_2_real +
1281
1.33M
                alpha_imag[1] * str_auto_corr.phi_1_2_imag) *
1282
1.33M
              fac;
1283
1.33M
          alpha_imag[0] =
1284
1.33M
              -(str_auto_corr.phi_0_1_imag + alpha_imag[1] * str_auto_corr.phi_1_2_real -
1285
1.33M
                alpha_real[1] * str_auto_corr.phi_1_2_imag) *
1286
1.33M
              fac;
1287
1.33M
        }
1288
1289
2.45M
        if (alpha_real[0] * alpha_real[0] + alpha_imag[0] * alpha_imag[0] >= 16.0f ||
1290
2.44M
            alpha_real[1] * alpha_real[1] + alpha_imag[1] * alpha_imag[1] >= 16.0f) {
1291
39.4k
          alpha_real[0] = 0.0f;
1292
39.4k
          alpha_imag[0] = 0.0f;
1293
39.4k
          alpha_real[1] = 0.0f;
1294
39.4k
          alpha_imag[1] = 0.0f;
1295
39.4k
        }
1296
1297
2.66M
        while (k2 >= ptr_invf_band_tbl[bw_index]) {
1298
209k
          bw_index++;
1299
209k
          if (bw_index >= MAX_NOISE_COEFFS) {
1300
0
            if (ec_flag) {
1301
0
              bw_index = MAX_NOISE_COEFFS - 1;
1302
0
              break;
1303
0
            } else
1304
0
              return -1;
1305
0
          }
1306
209k
        }
1307
1308
2.45M
        if (bw_index >= MAX_NUM_PATCHES) {
1309
0
          if (ec_flag)
1310
0
            bw_index = MAX_NUM_PATCHES - 1;
1311
0
          else
1312
0
            return -1;
1313
0
        }
1314
2.45M
        bw = bw_array[bw_index];
1315
1316
2.45M
        a0r = bw * alpha_real[0];
1317
2.45M
        a0i = bw * alpha_imag[0];
1318
2.45M
        bw *= bw;
1319
2.45M
        a1r = bw * alpha_real[1];
1320
2.45M
        a1i = bw * alpha_imag[1];
1321
1322
2.45M
        if (bw > 0.0f) {
1323
43.1M
          for (i = start_sample; i < end_sample; i++) {
1324
41.8M
            FLOAT32 real1, imag1, real2, imag2, realTarget, imag_target;
1325
1326
41.8M
            realTarget = ptr_ph_vocod_buf_real[i][k2];
1327
41.8M
            imag_target = ptr_ph_vocod_buf_imag[i][k2];
1328
41.8M
            real1 = ptr_ph_vocod_buf_real[i - 1][k2];
1329
41.8M
            imag1 = ptr_ph_vocod_buf_imag[i - 1][k2];
1330
41.8M
            real2 = ptr_ph_vocod_buf_real[i - 2][k2];
1331
41.8M
            imag2 = ptr_ph_vocod_buf_imag[i - 2][k2];
1332
41.8M
            realTarget += ((a0r * real1 - a0i * imag1) + (a1r * real2 - a1i * imag2));
1333
41.8M
            imag_target += ((a0i * real1 + a0r * imag1) + (a1i * real2 + a1r * imag2));
1334
1335
41.8M
            ptr_dst_buf_real[i][k2] = realTarget;
1336
41.8M
            ptr_dst_buf_imag[i][k2] = imag_target;
1337
41.8M
          }
1338
1.27M
        } else {
1339
40.5M
          for (i = start_sample; i < end_sample; i++) {
1340
39.3M
            ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2];
1341
39.3M
            ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2];
1342
39.3M
          }
1343
1.17M
        }
1344
2.45M
      }
1345
102k
    }
1346
220k
  }
1347
326k
  if ((MAX_NUM_PATCHES + 1) <= patch) {
1348
0
    if (ec_flag) {
1349
0
      patch = MAX_NUM_PATCHES;
1350
0
    } else {
1351
0
      return -1;
1352
0
    }
1353
0
  }
1354
326k
  ptr_frame_data->patch_param.num_patches = patch;
1355
1.16M
  for (i = 0; i < num_if_bands; i++) {
1356
834k
    bw_array_prev[i] = bw_array[i];
1357
834k
  }
1358
326k
  return 0;
1359
326k
}