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