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