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