Coverage Report

Created: 2026-09-01 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/iusace_esbr_inter_tes.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 <string.h>
22
#include <math.h>
23
24
#include "ixheaac_type_def.h"
25
#include "ixheaac_constants.h"
26
#include "ixheaace_aac_constants.h"
27
#include "ixheaac_basic_ops32.h"
28
#include "ixheaac_basic_ops16.h"
29
#include "ixheaac_basic_ops40.h"
30
#include "ixheaac_error_standards.h"
31
#include "ixheaace_error_codes.h"
32
33
#include "ixheaace_bitbuffer.h"
34
#include "ixheaace_sbr_def.h"
35
#include "iusace_esbr_inter_tes.h"
36
#include "iusace_esbr_rom.h"
37
38
VOID ixheaace_init_esbr_inter_tes(ixheaace_str_inter_tes_params *pstr_tes_enc,
39
8.64k
                                  WORD32 sbr_ratio_index) {
40
8.64k
  WORD32 ts;
41
8.64k
  WORD32 memset_sz = IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0]);
42
43
8.64k
  switch (sbr_ratio_index) {
44
2.62k
    case USAC_SBR_RATIO_INDEX_2_1:
45
2.62k
      pstr_tes_enc->op_delay = 6;
46
2.62k
      pstr_tes_enc->codec_delay = 32;
47
2.62k
      pstr_tes_enc->sbr_ratio_index = sbr_ratio_index;
48
2.62k
      break;
49
826
    case USAC_SBR_RATIO_INDEX_4_1:
50
826
      pstr_tes_enc->op_delay = 6 * 2;
51
826
      pstr_tes_enc->codec_delay = 64;
52
826
      pstr_tes_enc->sbr_ratio_index = sbr_ratio_index;
53
826
      break;
54
8.64k
  }
55
56
8.64k
  memset(&pstr_tes_enc->bw_array_prev[0], 0,
57
8.64k
         IXHEAACE_MAX_NUM_PATCHES * sizeof(pstr_tes_enc->bw_array_prev[0]));
58
8.64k
  memset(&pstr_tes_enc->inv_filt_mode_prev[0], 0,
59
8.64k
         IXHEAACE_MAX_NUM_NOISE_VALUES * sizeof(pstr_tes_enc->inv_filt_mode_prev[0]));
60
61
8.64k
  for (ts = 0;
62
188k
       ts < pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET;
63
179k
       ts++) {
64
179k
    memset(pstr_tes_enc->qmf_buf_real[ts], 0, memset_sz);
65
179k
    memset(pstr_tes_enc->qmf_buf_imag[ts], 0, memset_sz);
66
179k
  }
67
8.64k
  return;
68
8.64k
}
69
70
static VOID ixheaace_apply_inter_tes(FLOAT32 *qmf_real1, FLOAT32 *qmf_imag1, FLOAT32 *qmf_real,
71
                                     FLOAT32 *qmf_imag, WORD32 num_sample, WORD32 sub_band_start,
72
65.3k
                                     WORD32 num_subband, WORD32 gamma_idx) {
73
65.3k
  WORD32 sub_band_end = sub_band_start + num_subband;
74
65.3k
  FLOAT32 subsample_power_high[IXHEAACE_TIMESLOT_BUFFER_SIZE],
75
65.3k
      subsample_power_low[IXHEAACE_TIMESLOT_BUFFER_SIZE];
76
65.3k
  FLOAT32 total_power_high = 0.0f;
77
65.3k
  FLOAT32 total_power_low = 0.0f, total_power_high_after = 1.0e-6f;
78
65.3k
  FLOAT32 gain[IXHEAACE_TIMESLOT_BUFFER_SIZE];
79
65.3k
  FLOAT32 gain_adj, gain_adj_2;
80
65.3k
  FLOAT32 gamma = ixheaace_gamma_tab[gamma_idx];
81
65.3k
  WORD32 i, j;
82
65.3k
  WORD32 memcpy_sz = sub_band_start * sizeof(FLOAT32);
83
84
65.3k
  if (gamma > 0) {
85
1.03M
    for (i = 0; i < num_sample; i++) {
86
989k
      memcpy(&qmf_real[IXHEAACE_QMF_CHANNELS * i], &qmf_real1[IXHEAACE_QMF_CHANNELS * i],
87
989k
             memcpy_sz);
88
989k
      memcpy(&qmf_imag[IXHEAACE_QMF_CHANNELS * i], &qmf_imag1[IXHEAACE_QMF_CHANNELS * i],
89
989k
             memcpy_sz);
90
989k
    }
91
92
1.03M
    for (i = 0; i < num_sample; i++) {
93
989k
      j = 0;
94
989k
      subsample_power_low[i] = 0.0f;
95
24.6M
      while (j < sub_band_start) {
96
23.6M
        subsample_power_low[i] +=
97
23.6M
            qmf_real[IXHEAACE_QMF_CHANNELS * i + j] * qmf_real[IXHEAACE_QMF_CHANNELS * i + j];
98
23.6M
        subsample_power_low[i] +=
99
23.6M
            qmf_imag[IXHEAACE_QMF_CHANNELS * i + j] * qmf_imag[IXHEAACE_QMF_CHANNELS * i + j];
100
23.6M
        j++;
101
23.6M
      }
102
989k
      subsample_power_high[i] = 0.0f;
103
30.4M
      while (j < sub_band_end) {
104
29.4M
        subsample_power_high[i] +=
105
29.4M
            qmf_real[IXHEAACE_QMF_CHANNELS * i + j] * qmf_real[IXHEAACE_QMF_CHANNELS * i + j];
106
29.4M
        subsample_power_high[i] +=
107
29.4M
            qmf_imag[IXHEAACE_QMF_CHANNELS * i + j] * qmf_imag[IXHEAACE_QMF_CHANNELS * i + j];
108
29.4M
        j++;
109
29.4M
      }
110
989k
      total_power_low += subsample_power_low[i];
111
989k
      total_power_high += subsample_power_high[i];
112
989k
    }
113
114
1.03M
    for (i = 0; i < num_sample; i++) {
115
989k
      gain[i] =
116
989k
          (FLOAT32)(sqrt(subsample_power_low[i] * num_sample / (total_power_low + 1.0e-6f)));
117
989k
      gain[i] = (FLOAT32)(1.0f + gamma * (gain[i] - 1.0f));
118
119
989k
      if (gain[i] < 0.2f) {
120
786k
        gain[i] = 0.2f;
121
786k
      }
122
123
989k
      subsample_power_high[i] *= gain[i] * gain[i];
124
989k
      total_power_high_after += subsample_power_high[i];
125
989k
    }
126
127
49.0k
    gain_adj_2 = total_power_high / total_power_high_after;
128
49.0k
    gain_adj = (FLOAT32)(sqrt(gain_adj_2));
129
130
1.03M
    for (i = 0; i < num_sample; i++) {
131
989k
      gain[i] *= gain_adj;
132
133
989k
      j = sub_band_start;
134
30.4M
      while (j < sub_band_end) {
135
29.4M
        qmf_real[IXHEAACE_QMF_CHANNELS * i + j] *= gain[i];
136
29.4M
        qmf_imag[IXHEAACE_QMF_CHANNELS * i + j] *= gain[i];
137
29.4M
        j++;
138
29.4M
      }
139
989k
    }
140
49.0k
  }
141
65.3k
}
142
143
static WORD32 ixheaace_inter_tes_sound_activity(FLOAT32 qmf_real[][IXHEAACE_QMF_CHANNELS],
144
                                                FLOAT32 qmf_imag[][IXHEAACE_QMF_CHANNELS],
145
                                                FLOAT32 energy[], WORD32 len, WORD32 start,
146
109k
                                                WORD32 stop, WORD32 *is_transient) {
147
109k
  WORD32 snd_act = 0, ts, idx;
148
109k
  FLOAT32 ene_min = MAX_FLT_VAL, ene_max = 0.0f;
149
150
2.69M
  for (ts = 0; ts < len; ts++) {
151
2.58M
    idx = start;
152
78.8M
    while (idx < stop) {
153
76.2M
      energy[ts] += (qmf_real[ts][idx] * qmf_real[ts][idx]);
154
76.2M
      energy[ts] += (qmf_imag[ts][idx] * qmf_imag[ts][idx]);
155
76.2M
      idx++;
156
76.2M
    }
157
158
2.58M
    if (energy[ts] > ene_max) {
159
328k
      ene_max = energy[ts];
160
328k
    }
161
2.58M
    if (energy[ts] < ene_min) {
162
409k
      ene_min = energy[ts];
163
409k
    }
164
2.58M
  }
165
166
109k
  snd_act = (ene_max > IXHEAACE_ESBR_TES_ENERGY_MAX_THR) ? 1 : 0;
167
168
109k
  if ((ene_max / (ene_min + 1.0e-6f)) > 20) {
169
46.0k
    *is_transient = 1;
170
62.9k
  } else {
171
62.9k
    *is_transient = 0;
172
62.9k
  }
173
109k
  return snd_act;
174
109k
}
175
176
static WORD16 ixheaace_find_closest_entry(WORD32 goal_sb, WORD16 *ptr_master_tab,
177
14.9k
                                          WORD16 num_mf_bands, WORD16 direction) {
178
14.9k
  WORD32 index;
179
180
14.9k
  if (goal_sb <= ptr_master_tab[0]) return ptr_master_tab[0];
181
182
14.9k
  if (goal_sb >= ptr_master_tab[num_mf_bands]) return ptr_master_tab[num_mf_bands];
183
184
14.9k
  if (direction) {
185
0
    index = 0;
186
0
    while (ptr_master_tab[index] < goal_sb) {
187
0
      index++;
188
0
    }
189
14.9k
  } else {
190
14.9k
    index = num_mf_bands;
191
56.2k
    while (ptr_master_tab[index] > goal_sb) {
192
41.2k
      index--;
193
41.2k
    }
194
14.9k
  }
195
196
14.9k
  return ptr_master_tab[index];
197
14.9k
}
198
199
static VOID ixheaace_esbr_calc_co_variance(ixheaace_str_auto_corr_ele *pstr_auto_corr,
200
                                           FLOAT32 ptr_vec_x_real[][IXHEAACE_QMF_CHANNELS],
201
                                           FLOAT32 ptr_vec_x_imag[][IXHEAACE_QMF_CHANNELS],
202
324k
                                           WORD32 bd, WORD32 len) {
203
324k
  WORD32 j = 0;
204
205
324k
  FLOAT32 xr_j;
206
324k
  FLOAT32 xr_j_minus_1 = ptr_vec_x_real[j - 1][bd];
207
324k
  FLOAT32 xr_j_minus_2 = ptr_vec_x_real[j - 2][bd];
208
209
324k
  FLOAT32 xi_j;
210
324k
  FLOAT32 xi_j_minus_1 = ptr_vec_x_imag[j - 1][bd];
211
324k
  FLOAT32 xi_j_minus_2 = ptr_vec_x_imag[j - 2][bd];
212
213
324k
  memset(pstr_auto_corr, 0, sizeof(ixheaace_str_auto_corr_ele));
214
215
13.1M
  for (j = 0; j < len; j++) {
216
12.7M
    xr_j = ptr_vec_x_real[j][bd];
217
12.7M
    xi_j = ptr_vec_x_imag[j][bd];
218
219
12.7M
    pstr_auto_corr->phi_0_1_real += xr_j * xr_j_minus_1 + xi_j * xi_j_minus_1;
220
221
12.7M
    pstr_auto_corr->phi_0_1_imag += xi_j * xr_j_minus_1 - xr_j * xi_j_minus_1;
222
223
12.7M
    pstr_auto_corr->phi_0_2_real += xr_j * xr_j_minus_2 + xi_j * xi_j_minus_2;
224
225
12.7M
    pstr_auto_corr->phi_0_2_imag += xi_j * xr_j_minus_2 - xr_j * xi_j_minus_2;
226
227
12.7M
    pstr_auto_corr->phi_1_1 += xr_j_minus_1 * xr_j_minus_1 + xi_j_minus_1 * xi_j_minus_1;
228
229
12.7M
    pstr_auto_corr->phi_1_2_real += xr_j_minus_1 * xr_j_minus_2 + xi_j_minus_1 * xi_j_minus_2;
230
231
12.7M
    pstr_auto_corr->phi_1_2_imag += xi_j_minus_1 * xr_j_minus_2 - xr_j_minus_1 * xi_j_minus_2;
232
233
12.7M
    pstr_auto_corr->phi_2_2 += xr_j_minus_2 * xr_j_minus_2 + xi_j_minus_2 * xi_j_minus_2;
234
235
12.7M
    xr_j_minus_2 = xr_j_minus_1;
236
12.7M
    xr_j_minus_1 = xr_j;
237
238
12.7M
    xi_j_minus_2 = xi_j_minus_1;
239
12.7M
    xi_j_minus_1 = xi_j;
240
12.7M
  }
241
242
324k
  pstr_auto_corr->det = pstr_auto_corr->phi_1_1 * pstr_auto_corr->phi_2_2 -
243
324k
                        (pstr_auto_corr->phi_1_2_real * pstr_auto_corr->phi_1_2_real +
244
324k
                         pstr_auto_corr->phi_1_2_imag * pstr_auto_corr->phi_1_2_imag) *
245
324k
                            IXHEAACE_SBR_HF_RELAXATION_PARAM;
246
324k
}
247
248
static VOID ixheaace_gausssolve(WORD32 n, FLOAT32 ptr_a[][IXHEAACE_MAXDEG + 1], FLOAT32 ptr_b[],
249
0
                                FLOAT32 ptr_y[]) {
250
0
  WORD32 i, j, k, imax;
251
0
  FLOAT32 v;
252
253
0
  for (i = 0; i < n; i++) {
254
0
    imax = i;
255
0
    k = i + 1;
256
0
    while (k < n) {
257
0
      if (fabs(ptr_a[k][i]) > fabs(ptr_a[imax][i])) {
258
0
        imax = k;
259
0
      }
260
0
      k++;
261
0
    }
262
0
    if (imax != i) {
263
0
      v = ptr_b[imax];
264
0
      ptr_b[imax] = ptr_b[i];
265
0
      ptr_b[i] = v;
266
0
      j = i;
267
0
      while (j < n) {
268
0
        v = ptr_a[imax][j];
269
0
        ptr_a[imax][j] = ptr_a[i][j];
270
0
        ptr_a[i][j] = v;
271
0
        j++;
272
0
      }
273
0
    }
274
275
0
    v = ptr_a[i][i];
276
277
0
    ptr_b[i] /= v;
278
0
    for (j = i; j < n; j++) {
279
0
      ptr_a[i][j] /= v;
280
0
    }
281
282
0
    for (k = i + 1; k < n; k++) {
283
0
      v = ptr_a[k][i];
284
0
      ptr_b[k] -= v * ptr_b[i];
285
0
      for (j = i + 1; j < n; j++) {
286
0
        ptr_a[k][j] -= v * ptr_a[i][j];
287
0
      }
288
0
    }
289
0
  }
290
291
0
  for (i = n - 1; i >= 0; i--) {
292
0
    ptr_y[i] = ptr_b[i];
293
0
    for (j = i + 1; j < n; j++) {
294
0
      ptr_y[i] -= ptr_a[i][j] * ptr_y[j];
295
0
    }
296
0
  }
297
0
}
298
299
0
static VOID ixheaace_polyfit(WORD32 n, FLOAT32 ptr_y[], FLOAT32 ptr_p[]) {
300
0
  WORD32 i, j, k;
301
0
  FLOAT32 ptr_a[IXHEAACE_MAXDEG + 1][IXHEAACE_MAXDEG + 1] = {{0}};
302
0
  FLOAT32 ptr_b[IXHEAACE_MAXDEG + 1] = {0};
303
0
  FLOAT32 v[2 * IXHEAACE_MAXDEG + 1];
304
305
0
  for (k = 0; k < n; k++) {
306
0
    v[0] = 1.0;
307
0
    for (i = 1; i <= 2 * IXHEAACE_MAXDEG; i++) {
308
0
      v[i] = k * v[i - 1];
309
0
    }
310
311
0
    for (i = 0; i <= IXHEAACE_MAXDEG; i++) {
312
0
      ptr_b[i] += v[IXHEAACE_MAXDEG - i] * ptr_y[k];
313
0
      for (j = 0; j <= IXHEAACE_MAXDEG; j++) {
314
0
        ptr_a[i][j] += v[2 * IXHEAACE_MAXDEG - i - j];
315
0
      }
316
0
    }
317
0
  }
318
319
0
  ixheaace_gausssolve(IXHEAACE_MAXDEG + 1, ptr_a, ptr_b, ptr_p);
320
0
}
321
322
static VOID ixheaace_esbr_chirp_fac_calc(WORD32 *ptr_inv_filt_mode,
323
                                         WORD32 *ptr_inv_filt_mode_prev, WORD32 num_if_bands,
324
14.1k
                                         FLOAT32 *ptr_bw_array, FLOAT32 *ptr_bw_array_prev) {
325
14.1k
  WORD32 i;
326
327
53.7k
  for (i = 0; i < num_if_bands; i++) {
328
39.5k
    ptr_bw_array[i] = ixheaace_new_bw_tab[ptr_inv_filt_mode_prev[i]][ptr_inv_filt_mode[i]];
329
330
39.5k
    if (ptr_bw_array[i] < ptr_bw_array_prev[i]) {
331
0
      ptr_bw_array[i] = 0.75000f * ptr_bw_array[i] + 0.25000f * ptr_bw_array_prev[i];
332
39.5k
    } else {
333
39.5k
      ptr_bw_array[i] = 0.90625f * ptr_bw_array[i] + 0.09375f * ptr_bw_array_prev[i];
334
39.5k
    }
335
336
39.5k
    if (ptr_bw_array[i] < 0.015625) {
337
39.5k
      ptr_bw_array[i] = 0;
338
39.5k
    }
339
39.5k
  }
340
14.1k
}
341
342
static VOID ixheaace_pre_processing(FLOAT32 ptr_src_buf_real[][IXHEAACE_QMF_CHANNELS],
343
                                    FLOAT32 ptr_src_buf_imag[][IXHEAACE_QMF_CHANNELS],
344
                                    FLOAT32 ptr_gain_vector[], WORD32 num_bands,
345
0
                                    WORD32 start_sample, WORD32 end_sample) {
346
0
  WORD32 k, i;
347
0
  FLOAT32 poly_coeff[4];
348
0
  FLOAT32 mean_enrg = 0;
349
0
  FLOAT32 low_env_slope[IXHEAACE_QMF_CHANNELS];
350
0
  FLOAT32 low_env[IXHEAACE_QMF_CHANNELS];
351
0
  FLOAT32 a0;
352
0
  FLOAT32 a1;
353
0
  FLOAT32 a2;
354
0
  FLOAT32 a3;
355
356
0
  for (k = 0; k < num_bands; k++) {
357
0
    FLOAT32 temp = 0;
358
0
    for (i = start_sample; i < end_sample; i++) {
359
0
      temp += ptr_src_buf_real[i][k] * ptr_src_buf_real[i][k] +
360
0
              ptr_src_buf_imag[i][k] * ptr_src_buf_imag[i][k];
361
0
    }
362
0
    temp /= (end_sample - start_sample);
363
0
    low_env[k] = (FLOAT32)(10 * log10(temp + 1));
364
0
    mean_enrg += low_env[k];
365
0
  }
366
0
  mean_enrg /= num_bands;
367
368
0
  ixheaace_polyfit(num_bands, low_env, poly_coeff);
369
370
0
  a0 = poly_coeff[0];
371
0
  a1 = poly_coeff[1];
372
0
  a2 = poly_coeff[2];
373
0
  a3 = poly_coeff[3];
374
0
  for (k = 0; k < num_bands; k++) {
375
0
    low_env_slope[k] = a3 + a2 * k + a1 * k * k + a0 * k * k * k;
376
0
  }
377
378
0
  for (i = 0; i < num_bands; i++) {
379
0
    ptr_gain_vector[i] = (FLOAT32)pow(10, (mean_enrg - low_env_slope[i]) / 20.0f);
380
0
  }
381
0
}
382
383
static IA_ERRORCODE ixheaace_generate_hf(FLOAT32 ptr_src_buf_real[][64],
384
                                         FLOAT32 ptr_src_buf_imag[][64],
385
                                         FLOAT32 ptr_ph_vocod_buf_real[][64],
386
                                         FLOAT32 ptr_ph_vocod_buf_imag[][64],
387
                                         FLOAT32 ptr_dst_buf_real[][64],
388
                                         FLOAT32 ptr_dst_buf_imag[][64],
389
14.1k
                                         ixheaace_str_inter_tes_params *pstr_tes_enc) {
390
14.1k
  WORD32 bw_index, i, k, k2, patch = 0;
391
14.1k
  WORD32 co_var_len;
392
14.1k
  WORD32 start_sample, end_sample, goal_sb;
393
14.1k
  WORD32 sb, source_start_band, patch_stride, num_bands_in_patch;
394
14.1k
  WORD32 hbe_flag = 0;
395
14.1k
  FLOAT32 a0r, a0i, a1r, a1i;
396
14.1k
  FLOAT32 ptr_bw_array[IXHEAACE_MAX_NUM_PATCHES] = {0};
397
398
14.1k
  ixheaace_str_auto_corr_ele str_auto_corr;
399
400
14.1k
  WORD16 *ptr_invf_band_tbl = &pstr_tes_enc->invf_band_tbl[1];
401
14.1k
  WORD32 num_if_bands = pstr_tes_enc->num_if_bands;
402
14.1k
  WORD32 sub_band_start = pstr_tes_enc->sub_band_start;
403
14.1k
  WORD16 *ptr_master_tab = pstr_tes_enc->f_master_tbl;
404
14.1k
  WORD32 num_mf_bands = pstr_tes_enc->num_mf_bands;
405
14.1k
  WORD32 *ptr_inv_filt_mode = pstr_tes_enc->inv_filt_mode;
406
14.1k
  WORD32 *ptr_inv_filt_mode_prev = pstr_tes_enc->inv_filt_mode_prev;
407
14.1k
  WORD32 sbr_patching_mode = 1;
408
14.1k
  WORD32 pre_proc_flag = 0;
409
14.1k
  WORD32 fs = pstr_tes_enc->out_fs;
410
14.1k
  WORD32 cov_count;
411
14.1k
  WORD32 lsb = ptr_master_tab[0];
412
14.1k
  WORD32 usb = ptr_master_tab[num_mf_bands];
413
14.1k
  WORD32 memset_sz = (IXHEAACE_QMF_CHANNELS - usb) * sizeof(FLOAT32);
414
14.1k
  WORD32 xover_offset = sub_band_start - ptr_master_tab[0];
415
14.1k
  FLOAT32 bw = 0.0f;
416
14.1k
  FLOAT32 fac = 0.0f;
417
14.1k
  FLOAT32 gain;
418
14.1k
  FLOAT32 ptr_gain_vector[64];
419
14.1k
  WORD32 slope_length = 0;
420
14.1k
  WORD32 first_slot_offset = pstr_tes_enc->border_vec[0];
421
14.1k
  WORD32 end_slot_offs = 0;
422
14.1k
  FLOAT32 *ptr_bw_array_prev = pstr_tes_enc->bw_array_prev;
423
424
14.1k
  end_slot_offs = pstr_tes_enc->border_vec[pstr_tes_enc->num_env] - 16;
425
426
14.1k
  switch (pstr_tes_enc->sbr_ratio_index) {
427
10.1k
    case USAC_SBR_RATIO_INDEX_2_1:
428
10.1k
      start_sample = first_slot_offset * 2;
429
10.1k
      end_sample = 32 + end_slot_offs * 2;
430
10.1k
      co_var_len = 38;
431
10.1k
      break;
432
916
    case USAC_SBR_RATIO_INDEX_4_1:
433
916
      start_sample = first_slot_offset * 4;
434
916
      end_sample = 64 + end_slot_offs * 4;
435
916
      co_var_len = 76;
436
916
      break;
437
3.06k
    default:
438
3.06k
      start_sample = first_slot_offset * 2;
439
3.06k
      end_sample = 32 + end_slot_offs * 2;
440
3.06k
      co_var_len = 38;
441
3.06k
      break;
442
14.1k
  }
443
444
14.1k
  if (pre_proc_flag) {
445
0
    ixheaace_pre_processing(ptr_src_buf_real, ptr_src_buf_imag, ptr_gain_vector,
446
0
                            ptr_master_tab[0], start_sample, end_sample);
447
0
  }
448
449
14.1k
  ixheaace_esbr_chirp_fac_calc(ptr_inv_filt_mode, ptr_inv_filt_mode_prev, num_if_bands,
450
14.1k
                               ptr_bw_array, ptr_bw_array_prev);
451
452
431k
  for (i = start_sample; i < end_sample; i++) {
453
416k
    memset(ptr_dst_buf_real[i] + usb, 0, memset_sz);
454
416k
    memset(ptr_dst_buf_imag[i] + usb, 0, memset_sz);
455
416k
  }
456
457
14.1k
  if (sbr_patching_mode || !hbe_flag) {
458
14.1k
    FLOAT32 alpha_real[IXHEAACE_QMF_CHANNELS][2] = {{0}},
459
14.1k
            alpha_imag[IXHEAACE_QMF_CHANNELS][2] = {{0}};
460
14.1k
    cov_count = ptr_master_tab[0];
461
462
339k
    for (k = 1; k < cov_count; k++) {
463
324k
      ixheaace_esbr_calc_co_variance(&str_auto_corr, &ptr_src_buf_real[0], &ptr_src_buf_imag[0],
464
324k
                                     k, co_var_len);
465
324k
      if (str_auto_corr.det == 0.0f) {
466
7.63k
        alpha_real[k][1] = alpha_imag[k][1] = 0;
467
317k
      } else {
468
317k
        fac = 1.0f / str_auto_corr.det;
469
317k
        alpha_real[k][1] = (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
470
317k
                            str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
471
317k
                            str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
472
317k
                           fac;
473
317k
        alpha_imag[k][1] = (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
474
317k
                            str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
475
317k
                            str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
476
317k
                           fac;
477
317k
      }
478
479
324k
      if (str_auto_corr.phi_1_1 == 0) {
480
7.62k
        alpha_real[k][0] = alpha_imag[k][0] = 0;
481
317k
      } else {
482
317k
        fac = 1.0f / str_auto_corr.phi_1_1;
483
317k
        alpha_real[k][0] =
484
317k
            -(str_auto_corr.phi_0_1_real + alpha_real[k][1] * str_auto_corr.phi_1_2_real +
485
317k
              alpha_imag[k][1] * str_auto_corr.phi_1_2_imag) *
486
317k
            fac;
487
317k
        alpha_imag[k][0] =
488
317k
            -(str_auto_corr.phi_0_1_imag + alpha_imag[k][1] * str_auto_corr.phi_1_2_real -
489
317k
              alpha_real[k][1] * str_auto_corr.phi_1_2_imag) *
490
317k
            fac;
491
317k
      }
492
493
324k
      if ((alpha_real[k][0] * alpha_real[k][0] + alpha_imag[k][0] * alpha_imag[k][0] >= 16.0f) ||
494
324k
          (alpha_real[k][1] * alpha_real[k][1] + alpha_imag[k][1] * alpha_imag[k][1] >= 16.0f)) {
495
1.02k
        alpha_real[k][0] = 0.0f;
496
1.02k
        alpha_imag[k][0] = 0.0f;
497
1.02k
        alpha_real[k][1] = 0.0f;
498
1.02k
        alpha_imag[k][1] = 0.0f;
499
1.02k
      }
500
324k
    }
501
502
14.1k
    goal_sb = (WORD32)(2.048e6f / fs + 0.5f);
503
14.1k
    {
504
14.1k
      WORD32 index;
505
14.1k
      if (goal_sb < ptr_master_tab[num_mf_bands]) {
506
12.3k
        for (index = 0; (ptr_master_tab[index] < goal_sb); index++)
507
6.15k
          goal_sb = ptr_master_tab[index];
508
7.99k
      } else {
509
7.99k
        goal_sb = ptr_master_tab[num_mf_bands];
510
7.99k
      }
511
14.1k
    }
512
513
14.1k
    source_start_band = xover_offset + 1;
514
515
14.1k
    sb = lsb + xover_offset;
516
517
14.1k
    patch = 0;
518
49.4k
    while (sb < usb) {
519
35.2k
      if (IXHEAACE_MAX_NUM_PATCHES <= patch) {
520
0
        return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH;
521
0
      }
522
523
35.2k
      num_bands_in_patch = goal_sb - sb;
524
525
35.2k
      if (num_bands_in_patch + source_start_band >= lsb) {
526
14.9k
        patch_stride = sb - source_start_band;
527
14.9k
        patch_stride = patch_stride & ~1;
528
14.9k
        num_bands_in_patch = lsb - (sb - patch_stride);
529
14.9k
        num_bands_in_patch = ixheaace_find_closest_entry(sb + num_bands_in_patch, ptr_master_tab,
530
14.9k
                                                         (WORD16)(num_mf_bands), 0) -
531
14.9k
                             (WORD32)(sb);
532
14.9k
      }
533
534
35.2k
      patch_stride = num_bands_in_patch + sb - lsb;
535
35.2k
      patch_stride = (patch_stride + 1) & ~1;
536
537
35.2k
      source_start_band = 1;
538
539
35.2k
      if (goal_sb - (sb + num_bands_in_patch) < 3) {
540
20.3k
        goal_sb = usb;
541
20.3k
      }
542
543
35.2k
      if ((num_bands_in_patch < 3) && (patch > 0) && (sb + num_bands_in_patch == usb)) {
544
0
        for (i = start_sample + slope_length; i < end_sample + slope_length; i++) {
545
0
          for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
546
0
            if (k2 < 0 || k2 >= 64) {
547
0
              break;
548
0
            }
549
0
            ptr_dst_buf_real[i][k2] = 0.0f;
550
0
            ptr_dst_buf_imag[i][k2] = 0.0f;
551
0
          }
552
0
        }
553
0
        break;
554
0
      }
555
556
35.2k
      if (num_bands_in_patch <= 0) {
557
6.15k
        continue;
558
6.15k
      }
559
560
445k
      for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
561
416k
        k = k2 - patch_stride;
562
416k
        bw_index = 0;
563
925k
        while (k2 >= ptr_invf_band_tbl[bw_index]) {
564
508k
          bw_index++;
565
508k
          if (bw_index >= IXHEAACE_MAX_NOISE_COEFFS) {
566
0
            return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX;
567
0
          }
568
508k
        }
569
570
416k
        if (bw_index >= IXHEAACE_MAX_NUM_PATCHES) {
571
0
          return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX;
572
0
        }
573
416k
        bw = ptr_bw_array[bw_index];
574
575
416k
        a0r = bw * alpha_real[k][0];
576
416k
        a0i = bw * alpha_imag[k][0];
577
416k
        bw *= bw;
578
416k
        a1r = bw * alpha_real[k][1];
579
416k
        a1i = bw * alpha_imag[k][1];
580
581
416k
        if (pre_proc_flag) {
582
0
          gain = ptr_gain_vector[k];
583
416k
        } else {
584
416k
          gain = 1.0f;
585
416k
        }
586
587
12.9M
        for (i = start_sample + slope_length; i < end_sample + slope_length; i++) {
588
12.5M
          ptr_dst_buf_real[i][k2] = ptr_src_buf_real[i][k] * gain;
589
590
12.5M
          ptr_dst_buf_imag[i][k2] = ptr_src_buf_imag[i][k] * gain;
591
592
12.5M
          if (bw > 0.0f) {
593
0
            ptr_dst_buf_real[i][k2] +=
594
0
                (a0r * ptr_src_buf_real[i - 1][k] - a0i * ptr_src_buf_imag[i - 1][k] +
595
0
                 a1r * ptr_src_buf_real[i - 2][k] - a1i * ptr_src_buf_imag[i - 2][k]) *
596
0
                gain;
597
0
            ptr_dst_buf_imag[i][k2] +=
598
0
                (a0i * ptr_src_buf_real[i - 1][k] + a0r * ptr_src_buf_imag[i - 1][k] +
599
0
                 a1i * ptr_src_buf_real[i - 2][k] + a1r * ptr_src_buf_imag[i - 2][k]) *
600
0
                gain;
601
0
          }
602
12.5M
        }
603
416k
      }
604
29.1k
      sb += num_bands_in_patch;
605
29.1k
      patch++;
606
29.1k
    }
607
14.1k
  }
608
609
14.1k
  if (hbe_flag && !sbr_patching_mode) {
610
0
    FLOAT32 alpha_real[2], alpha_imag[2];
611
612
0
    bw_index = 0, patch = 1;
613
0
    if (NULL == ptr_ph_vocod_buf_real || NULL == ptr_ph_vocod_buf_imag) {
614
0
      return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VOCOD_BUF;
615
0
    }
616
617
0
    for (k2 = sub_band_start; k2 < ptr_master_tab[num_mf_bands]; k2++) {
618
0
      ixheaace_esbr_calc_co_variance(&str_auto_corr, &ptr_ph_vocod_buf_real[0],
619
0
                                     &ptr_ph_vocod_buf_imag[0], k2, co_var_len);
620
621
0
      if (str_auto_corr.det == 0.0f) {
622
0
        alpha_real[1] = alpha_imag[1] = 0;
623
0
      } else {
624
0
        fac = 1.0f / str_auto_corr.det;
625
0
        alpha_real[1] = (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
626
0
                         str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
627
0
                         str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
628
0
                        fac;
629
0
        alpha_imag[1] = (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
630
0
                         str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
631
0
                         str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
632
0
                        fac;
633
0
      }
634
635
0
      if (str_auto_corr.phi_1_1 == 0) {
636
0
        alpha_real[0] = alpha_imag[0] = 0;
637
0
      } else {
638
0
        fac = 1.0f / str_auto_corr.phi_1_1;
639
0
        alpha_real[0] =
640
0
            -(str_auto_corr.phi_0_1_real + alpha_real[1] * str_auto_corr.phi_1_2_real +
641
0
              alpha_imag[1] * str_auto_corr.phi_1_2_imag) *
642
0
            fac;
643
0
        alpha_imag[0] =
644
0
            -(str_auto_corr.phi_0_1_imag + alpha_imag[1] * str_auto_corr.phi_1_2_real -
645
0
              alpha_real[1] * str_auto_corr.phi_1_2_imag) *
646
0
            fac;
647
0
      }
648
649
0
      if (alpha_real[0] * alpha_real[0] + alpha_imag[0] * alpha_imag[0] >= 16.0f ||
650
0
          alpha_real[1] * alpha_real[1] + alpha_imag[1] * alpha_imag[1] >= 16.0f) {
651
0
        alpha_real[0] = 0.0f;
652
0
        alpha_imag[0] = 0.0f;
653
0
        alpha_real[1] = 0.0f;
654
0
        alpha_imag[1] = 0.0f;
655
0
      }
656
657
0
      while (k2 >= ptr_invf_band_tbl[bw_index]) {
658
0
        bw_index++;
659
0
        if (bw_index >= IXHEAACE_MAX_NOISE_COEFFS) {
660
0
          return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX;
661
0
        }
662
0
      }
663
664
0
      if (bw_index >= IXHEAACE_MAX_NUM_PATCHES) {
665
0
        return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX;
666
0
      }
667
0
      bw = ptr_bw_array[bw_index];
668
669
0
      a0r = bw * alpha_real[0];
670
0
      a0i = bw * alpha_imag[0];
671
0
      bw *= bw;
672
0
      a1r = bw * alpha_real[1];
673
0
      a1i = bw * alpha_imag[1];
674
675
0
      if (bw > 0.0f) {
676
0
        for (i = start_sample; i < end_sample; i++) {
677
0
          FLOAT32 real1, imag1, real2, imag2;
678
679
0
          real1 = ptr_ph_vocod_buf_real[i - 1][k2];
680
0
          imag1 = ptr_ph_vocod_buf_imag[i - 1][k2];
681
0
          real2 = ptr_ph_vocod_buf_real[i - 2][k2];
682
0
          imag2 = ptr_ph_vocod_buf_imag[i - 2][k2];
683
0
          ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2] +
684
0
                                    ((a0r * real1 - a0i * imag1) + (a1r * real2 - a1i * imag2));
685
0
          ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2] +
686
0
                                    ((a0i * real1 + a0r * imag1) + (a1i * real2 + a1r * imag2));
687
0
        }
688
0
      } else {
689
0
        for (i = start_sample; i < end_sample; i++) {
690
0
          ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2];
691
0
          ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2];
692
0
        }
693
0
      }
694
0
    }
695
0
  }
696
14.1k
  if (patch >= (IXHEAACE_MAX_NUM_PATCHES + 1)) {
697
0
    return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH;
698
0
  }
699
53.7k
  for (i = 0; i < num_if_bands; i++) {
700
39.5k
    ptr_bw_array_prev[i] = ptr_bw_array[i];
701
39.5k
  }
702
14.1k
  return IA_NO_ERROR;
703
14.1k
}
704
705
IA_ERRORCODE ixheaace_process_inter_tes(ixheaace_str_inter_tes_params *pstr_tes_enc,
706
91.0k
                                        WORD8 *ptr_scr) {
707
91.0k
  WORD32 gi = 0, env, tes_enable = 0, ts, bd, start_ts, stop_ts;
708
91.0k
  WORD32 is_sound_activity[IXHEAACE_MAX_ENVELOPES] = {0},
709
91.0k
         is_transient[IXHEAACE_MAX_ENVELOPES] = {0};
710
91.0k
  WORD32 tes_shape_mode = 0;
711
91.0k
  WORD32 num_samples, num_bands;
712
91.0k
  WORD32 len;
713
91.0k
  IA_ERRORCODE status = IA_NO_ERROR;
714
91.0k
  FLOAT32 energy_high[64] = {0};
715
91.0k
  FLOAT32 energy[64] = {0};
716
91.0k
  FLOAT32 gamma[IXHEAACE_ESBR_NUM_GAMMA_IDXS] = {0};
717
91.0k
  FLOAT32 gamma_min = MAX_FLT_VAL;
718
91.0k
  ixheaace_str_inter_tes_scr *tes_scr = (ixheaace_str_inter_tes_scr *)ptr_scr;
719
91.0k
  num_bands = pstr_tes_enc->sub_band_end - pstr_tes_enc->sub_band_start;
720
721
200k
  for (env = 0; env < pstr_tes_enc->num_env; env++) {
722
109k
    tes_shape_mode = 0;
723
109k
    len = 2 * (pstr_tes_enc->border_vec[env + 1] - pstr_tes_enc->border_vec[env]);
724
109k
    is_sound_activity[env] = ixheaace_inter_tes_sound_activity(
725
109k
        &pstr_tes_enc
726
109k
             ->qmf_buf_real[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]],
727
109k
        &pstr_tes_enc
728
109k
             ->qmf_buf_imag[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]],
729
109k
        &energy_high[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]], len,
730
109k
        pstr_tes_enc->sub_band_start, pstr_tes_enc->sub_band_end, &is_transient[env]);
731
109k
    if (1 == is_transient[env] && 1 == is_sound_activity[env]) {
732
16.3k
      tes_enable = 1;
733
16.3k
    }
734
109k
  }
735
736
91.0k
  if (1 == tes_enable) {
737
14.1k
    status = ixheaace_generate_hf(&pstr_tes_enc->qmf_buf_real[IXHEAACE_SBR_HF_ADJ_OFFSET],
738
14.1k
                                  &pstr_tes_enc->qmf_buf_imag[IXHEAACE_SBR_HF_ADJ_OFFSET], NULL,
739
14.1k
                                  NULL, &tes_scr->dst_qmf_r[IXHEAACE_SBR_HF_ADJ_OFFSET],
740
14.1k
                                  &tes_scr->dst_qmf_i[IXHEAACE_SBR_HF_ADJ_OFFSET], pstr_tes_enc);
741
742
14.1k
    if (status) {
743
0
      return status;
744
0
    }
745
35.0k
    for (env = 0; env < pstr_tes_enc->num_env; env++) {
746
20.8k
      if ((1 == is_sound_activity[env]) && (1 == is_transient[env])) {
747
16.3k
        num_samples = (pstr_tes_enc->border_vec[env + 1] - pstr_tes_enc->border_vec[env]) * 2;
748
16.3k
        start_ts = IXHEAACE_SBR_HF_ADJ_OFFSET + pstr_tes_enc->border_vec[env] * 2;
749
16.3k
        stop_ts = start_ts + num_samples;
750
751
81.7k
        for (gi = 0; gi < IXHEAACE_ESBR_NUM_GAMMA_IDXS; gi++) {
752
65.3k
          ixheaace_apply_inter_tes(
753
65.3k
              &tes_scr
754
65.3k
                   ->dst_qmf_r[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]][0],
755
65.3k
              &tes_scr
756
65.3k
                   ->dst_qmf_i[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]][0],
757
65.3k
              &pstr_tes_enc->qmf_buf_real[IXHEAACE_SBR_HF_ADJ_OFFSET +
758
65.3k
                                          2 * pstr_tes_enc->border_vec[env]][0],
759
65.3k
              &pstr_tes_enc->qmf_buf_imag[IXHEAACE_SBR_HF_ADJ_OFFSET +
760
65.3k
                                          2 * pstr_tes_enc->border_vec[env]][0],
761
65.3k
              num_samples, pstr_tes_enc->sub_band_start, num_bands, gi);
762
1.38M
          for (ts = start_ts; ts < stop_ts; ts++) {
763
1.31M
            energy[ts] = 0.0f;
764
40.6M
            for (bd = pstr_tes_enc->sub_band_start; bd < pstr_tes_enc->sub_band_end; bd++) {
765
39.2M
              energy[ts] += tes_scr->dst_qmf_r[ts][bd] * tes_scr->dst_qmf_r[ts][bd];
766
39.2M
              energy[ts] += tes_scr->dst_qmf_i[ts][bd] * tes_scr->dst_qmf_i[ts][bd];
767
39.2M
            }
768
1.31M
            gamma[gi] += (FLOAT32)fabs(energy[ts] - energy_high[ts]) /
769
1.31M
                         (FLOAT32)(pow((energy_high[ts] + 1e-6f), 0.9f));
770
1.31M
          }
771
65.3k
          if (gamma[gi] < gamma_min) {
772
14.1k
            gamma_min = gamma[gi];
773
14.1k
            tes_shape_mode = gi;
774
14.1k
          }
775
65.3k
        }
776
16.3k
      }
777
778
20.8k
      if (tes_shape_mode > 0) {
779
0
        pstr_tes_enc->bs_tes_shape[env] = 1;
780
0
        pstr_tes_enc->bs_tes_shape_mode[env] = tes_shape_mode;
781
20.8k
      } else {
782
20.8k
        pstr_tes_enc->bs_tes_shape[env] = 0;
783
20.8k
        pstr_tes_enc->bs_tes_shape_mode[env] = 0;
784
20.8k
      }
785
20.8k
    }
786
76.8k
  } else {
787
165k
    for (env = 0; env < pstr_tes_enc->num_env; env++) {
788
88.1k
      pstr_tes_enc->bs_tes_shape[env] = 0;
789
88.1k
      pstr_tes_enc->bs_tes_shape_mode[env] = 0;
790
88.1k
    }
791
76.8k
  }
792
91.0k
  return status;
793
91.0k
}