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