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 if ((goal_sb < sb) && (lsb > src_start_band)) {
353 return -1;
354 }
355
356 while (((sb - usb) < 0) && (patch < MAX_NUM_PATCHES)) {
357 ia_patch_param_struct *ptr_loc_patch_param = &p_str_patch_param[patch];
358
359 ptr_loc_patch_param->guard_start_band = sb;
360 sb = (sb + GUARDBANDS);
361 ptr_loc_patch_param->dst_start_band = sb;
362
363 num_bands_in_patch = (goal_sb - sb);
364
365 if ((num_bands_in_patch - (lsb - src_start_band)) >= 0) {
366 patch_stride = sb - src_start_band;
367 patch_stride = (WORD16)(patch_stride & ~1);
368 num_bands_in_patch = (lsb - (sb - patch_stride));
369 num_bands_in_patch = ixheaacd_find_closest_entry(
370 sb + num_bands_in_patch, f_master_tbl, num_mf_bands, 0);
371 num_bands_in_patch -= sb;
372 }
373
374 patch_stride = ((num_bands_in_patch + sb) - lsb);
375 patch_stride = (WORD16)((patch_stride + 1) & ~1);
376
377 if (num_bands_in_patch > 0) {
378 ptr_loc_patch_param->src_start_band = (sb - patch_stride);
379 ptr_loc_patch_param->dst_end_band = patch_stride;
380 ptr_loc_patch_param->num_bands_in_patch = num_bands_in_patch;
381 ptr_loc_patch_param->src_end_band =
382 (ptr_loc_patch_param->src_start_band + num_bands_in_patch);
383
384 sb = (sb + ptr_loc_patch_param->num_bands_in_patch);
385 patch++;
386 }
387
388 src_start_band = SHIFT_START_SB;
389
390 if ((ixheaacd_abs16_sat((WORD16)((sb - goal_sb))) - 3) < 0) {
391 goal_sb = usb;
392 }
393 }
394
395 patch--;
396
397 if ((patch > 0) && (p_str_patch_param[patch].num_bands_in_patch < 3)) {
398 patch--;
399 sb = p_str_patch_param[patch].dst_start_band +
400 p_str_patch_param[patch].num_bands_in_patch;
401 }
402
403 if (patch >= MAX_NUM_PATCHES) {
404 return -1;
405 }
406
407 pstr_transposer_settings->num_patches = patch + 1;
408
409 temp = 0;
410
411 for (patch = 0; patch < pstr_transposer_settings->num_patches; patch++) {
412 sb = ixheaacd_min32(sb, p_str_patch_param[patch].src_start_band);
413 temp = ixheaacd_max32(temp, p_str_patch_param[patch].src_end_band);
414 }
415
416 pstr_transposer_settings->start_patch = sb;
417 pstr_transposer_settings->stop_patch = temp;
418
419 ptr_noise_freq_tbl =
420 ptr_header_data->pstr_freq_band_data->freq_band_tbl_noise;
421 num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
422
423 memcpy(&pstr_transposer_settings->bw_borders[0], &ptr_noise_freq_tbl[1],
424 sizeof(WORD16) * num_nf_bands);
425
426 memset(ptr_hf_gen_str->bw_array_prev, 0, sizeof(WORD32) * MAX_NUM_PATCHES);
427
428 return 0;
429 }
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)430 VOID ixheaacd_rescale_x_overlap(
431 ia_sbr_dec_struct *ptr_sbr_dec, ia_sbr_header_data_struct *ptr_header_data,
432 ia_sbr_frame_info_data_struct *ptr_frame_data,
433 ia_sbr_prev_frame_data_struct *ptr_frame_data_prev,
434 WORD32 **pp_overlap_buffer_real, WORD32 **pp_overlap_buffer_imag,
435 FLAG low_pow_flag) {
436 WORD32 k, l;
437 WORD32 start_band, end_band;
438 WORD32 target_lsb, target_usb;
439 WORD32 source_scale, target_scale, delta_scale, reserve;
440
441 WORD32 old_lsb = ptr_frame_data_prev->max_qmf_subband_aac;
442 WORD32 start_slot =
443 (ptr_header_data->time_step *
444 (ptr_frame_data_prev->end_position - ptr_header_data->num_time_slots));
445 WORD32 new_lsb = ptr_frame_data->max_qmf_subband_aac;
446
447 ptr_sbr_dec->str_codec_qmf_bank.usb = new_lsb;
448 ptr_sbr_dec->str_synthesis_qmf_bank.lsb = new_lsb;
449
450 start_band = ixheaacd_min32(old_lsb, new_lsb);
451 end_band = ixheaacd_max32(old_lsb, new_lsb);
452
453 if (new_lsb != old_lsb && old_lsb > 0) {
454 for (l = start_slot; l < 6; l++) {
455 for (k = old_lsb; k < new_lsb; k++) {
456 pp_overlap_buffer_real[l][k] = 0L;
457
458 if (!low_pow_flag) {
459 pp_overlap_buffer_imag[l][k] = 0L;
460 }
461 }
462 }
463
464 if (new_lsb > old_lsb) {
465 source_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale;
466 target_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale;
467 target_lsb = 0;
468 target_usb = old_lsb;
469 } else {
470 source_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale;
471 target_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale;
472 target_lsb = old_lsb;
473 target_usb = ptr_sbr_dec->str_synthesis_qmf_bank.usb;
474 }
475
476 reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
477 pp_overlap_buffer_real, pp_overlap_buffer_imag, start_band, end_band, 0,
478 start_slot, low_pow_flag);
479
480 (*ixheaacd_adjust_scale)(pp_overlap_buffer_real, pp_overlap_buffer_imag,
481 start_band, end_band, 0, start_slot, reserve,
482 low_pow_flag);
483
484 source_scale += reserve;
485
486 delta_scale = (target_scale - source_scale);
487
488 if (delta_scale > 0) {
489 delta_scale = -(delta_scale);
490 start_band = target_lsb;
491 end_band = target_usb;
492
493 if (new_lsb > old_lsb) {
494 ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale = source_scale;
495 } else {
496 ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale = source_scale;
497 }
498 }
499
500 (*ixheaacd_adjust_scale)(pp_overlap_buffer_real, pp_overlap_buffer_imag,
501 start_band, end_band, 0, start_slot, delta_scale,
502 low_pow_flag);
503 }
504 }
505
ixheaacd_map_sineflags(WORD16 * freq_band_table,WORD16 num_sf_bands,FLAG * add_harmonics,WORD8 * harm_flags_prev,WORD16 transient_env,WORD8 * sine_mapped)506 VOID ixheaacd_map_sineflags(WORD16 *freq_band_table, WORD16 num_sf_bands,
507 FLAG *add_harmonics, WORD8 *harm_flags_prev,
508 WORD16 transient_env, WORD8 *sine_mapped)
509
510 {
511 WORD32 qmfband2, li, ui, i;
512 WORD32 low_subband_sec;
513 WORD32 oldflags;
514
515 low_subband_sec = (freq_band_table[0] << 1);
516
517 memset(sine_mapped, MAX_ENVELOPES, sizeof(WORD8) * MAX_FREQ_COEFFS);
518
519 for (i = (num_sf_bands - 1); i >= 0; i--) {
520 oldflags = *harm_flags_prev;
521 *harm_flags_prev++ = add_harmonics[i];
522
523 if (add_harmonics[i]) {
524 li = freq_band_table[i];
525
526 ui = freq_band_table[i + 1];
527
528 qmfband2 = ((ui + li) - low_subband_sec) >> 1;
529
530 if (oldflags)
531 sine_mapped[qmfband2] = 0;
532 else
533 sine_mapped[qmfband2] = (WORD8)transient_env;
534 }
535 }
536 }
537
ixheaacd_map_34_params_to_20(WORD16 * params)538 VOID ixheaacd_map_34_params_to_20(WORD16 *params) {
539 params[0] = ixheaacd_divideby3(params[0] + params[0] + params[1]);
540 params[1] = ixheaacd_divideby3(params[1] + params[2] + params[2]);
541 params[2] = ixheaacd_divideby3(params[3] + params[3] + params[4]);
542 params[3] = ixheaacd_divideby3(params[4] + params[5] + params[5]);
543 params[4] = ixheaacd_divideby2(params[6] + params[7]);
544 params[5] = ixheaacd_divideby2(params[8] + params[9]);
545 params[6] = params[10];
546 params[7] = params[11];
547 params[8] = ixheaacd_divideby2(params[12] + params[13]);
548 params[9] = ixheaacd_divideby2(params[14] + params[15]);
549 params[10] = params[16];
550 params[11] = params[17];
551 params[12] = params[18];
552 params[13] = params[19];
553 params[14] = ixheaacd_divideby2(params[20] + params[21]);
554 params[15] = ixheaacd_divideby2(params[22] + params[23]);
555 params[16] = ixheaacd_divideby2(params[24] + params[25]);
556 params[17] = ixheaacd_divideby2(params[26] + params[27]);
557 params[18] = ixheaacd_divideby2(
558 ixheaacd_divideby2(params[28] + params[29] + params[30] + params[31]));
559 params[19] = ixheaacd_divideby2(params[32] + params[33]);
560 }
561
562 extern const WORD16 ixheaacd_num_bands[3];
563
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)564 WORD16 ixheaacd_read_ps_data(ia_ps_dec_struct *ptr_ps_dec,
565 ia_bit_buf_struct *it_bit_buff,
566 WORD16 num_bits_left,
567 ia_ps_tables_struct *ps_tables_ptr) {
568 WORD b, e, temp;
569 const WORD16 num_env_tab[4] = {0, 1, 2, 4};
570 WORD cnt_bits;
571 ia_huffman_data_type huffman_table, huffman_df_table, huffman_dt_table;
572 FLAG enable_ps_header;
573
574 if (!ptr_ps_dec) {
575 return 0;
576 }
577
578 cnt_bits = it_bit_buff->cnt_bits;
579
580 enable_ps_header = ixheaacd_read_bits_buf(it_bit_buff, 1);
581
582 if (enable_ps_header) {
583 ptr_ps_dec->enable_iid = ixheaacd_read_bits_buf(it_bit_buff, 1);
584 if (ptr_ps_dec->enable_iid) {
585 ptr_ps_dec->iid_mode = ixheaacd_read_bits_buf(it_bit_buff, 3);
586 }
587
588 if (ptr_ps_dec->iid_mode > 2) {
589 ptr_ps_dec->iid_quant = 1;
590 ptr_ps_dec->iid_mode -= 3;
591 } else {
592 ptr_ps_dec->iid_quant = 0;
593 }
594
595 ptr_ps_dec->enable_icc = ixheaacd_read_bits_buf(it_bit_buff, 1);
596 if (ptr_ps_dec->enable_icc) {
597 ptr_ps_dec->icc_mode = ixheaacd_read_bits_buf(it_bit_buff, 3);
598 }
599
600 ptr_ps_dec->enable_ext = ixheaacd_read_bits_buf(it_bit_buff, 1);
601
602 if (ptr_ps_dec->icc_mode > 2) {
603 ptr_ps_dec->icc_mode -= 3;
604 }
605 }
606
607 if ((ptr_ps_dec->enable_iid && ptr_ps_dec->iid_mode > 2) ||
608 (ptr_ps_dec->enable_icc && ptr_ps_dec->icc_mode > 2)) {
609 ptr_ps_dec->ps_data_present = 0;
610
611 num_bits_left -= (cnt_bits - it_bit_buff->cnt_bits);
612
613 while (num_bits_left > 8) {
614 ixheaacd_read_bits_buf(it_bit_buff, 8);
615 num_bits_left -= 8;
616 }
617 ixheaacd_read_bits_buf(it_bit_buff, num_bits_left);
618
619 return (cnt_bits - it_bit_buff->cnt_bits);
620 }
621
622 ptr_ps_dec->frame_class = (FLAG)ixheaacd_read_bits_buf(it_bit_buff, 1);
623
624 temp = ixheaacd_read_bits_buf(it_bit_buff, 2);
625
626 if (ptr_ps_dec->frame_class == 0) {
627 ptr_ps_dec->num_env = num_env_tab[temp];
628 } else {
629 ptr_ps_dec->num_env = (((1 + temp) << 8) >> 8);
630
631 for (e = 1; e < ptr_ps_dec->num_env + 1; e++) {
632 ptr_ps_dec->border_position[e] =
633 (((ixheaacd_read_bits_buf(it_bit_buff, 5) + 1) << 8) >> 8);
634 }
635 }
636
637 if (ptr_ps_dec->enable_iid) {
638 if (ptr_ps_dec->iid_quant) {
639 huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_df_fine;
640 huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_dt_fine;
641 } else {
642 huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_df;
643 huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_dt;
644 }
645
646 for (e = 0; e < ptr_ps_dec->num_env; e++) {
647 ptr_ps_dec->iid_dt[e] = (FLAG)ixheaacd_read_bits_buf(it_bit_buff, 1);
648
649 if (ptr_ps_dec->iid_dt[e]) {
650 huffman_table = huffman_dt_table;
651 } else {
652 huffman_table = huffman_df_table;
653 }
654
655 for (b = 0; b < ixheaacd_num_bands[ptr_ps_dec->iid_mode]; b++) {
656 ptr_ps_dec->iid_par_table[e][b] =
657 ixheaacd_ssc_huff_dec(huffman_table, it_bit_buff);
658 }
659 }
660 }
661
662 if (ptr_ps_dec->enable_icc) {
663 huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_icc_df;
664 huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_icc_dt;
665
666 for (e = 0; e < ptr_ps_dec->num_env; e++) {
667 ptr_ps_dec->icc_dt[e] = ixheaacd_read_bits_buf(it_bit_buff, 1);
668
669 if (ptr_ps_dec->icc_dt[e]) {
670 huffman_table = huffman_dt_table;
671 } else {
672 huffman_table = huffman_df_table;
673 }
674
675 for (b = 0; b < ixheaacd_num_bands[ptr_ps_dec->icc_mode]; b++) {
676 ptr_ps_dec->icc_par_table[e][b] =
677 ixheaacd_ssc_huff_dec(huffman_table, it_bit_buff);
678 }
679 }
680 }
681
682 if (ptr_ps_dec->enable_ext) {
683 WORD32 cnt = ixheaacd_read_bits_buf(it_bit_buff, 4);
684
685 if (cnt == 15) {
686 cnt += ixheaacd_read_bits_buf(it_bit_buff, 8);
687 }
688 while (cnt--) {
689 ixheaacd_read_bits_buf(it_bit_buff, 8);
690 }
691 }
692
693 ptr_ps_dec->ps_data_present = 1;
694
695 return (cnt_bits - it_bit_buff->cnt_bits);
696 }
697
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)698 VOID ixheaacd_invfilt_level_emphasis(ia_sbr_hf_generator_struct *ptr_hf_gen_str,
699 WORD32 num_if_bands, WORD32 *inv_filt_mode,
700 WORD32 *inv_filt_mode_prev,
701 WORD32 *bw_array) {
702 WORD32 i;
703 WORD32 accu;
704 WORD16 w1, w2;
705
706 for (i = 0; i < num_if_bands; i++) {
707 bw_array[i] =
708 ixheaacd_inew_bw_table[inv_filt_mode_prev[i]][inv_filt_mode[i]];
709
710 if (bw_array[i] < ptr_hf_gen_str->bw_array_prev[i]) {
711 w1 = 0x6000;
712 w2 = 0x2000;
713 } else {
714 w1 = 0x7400;
715 w2 = 0x0c00;
716 }
717 accu = ixheaacd_add32(
718 ixheaacd_mult32x16in32_shl(bw_array[i], w1),
719 ixheaacd_mult32x16in32_shl(ptr_hf_gen_str->bw_array_prev[i], w2));
720
721 if (accu < 0x02000000) {
722 accu = 0;
723 }
724
725 if (accu >= 0x7f800000) {
726 accu = 0x7f800000;
727 }
728 bw_array[i] = accu;
729 }
730 }
731
732 typedef struct {
733 FLOAT32 phi_0_1_real;
734 FLOAT32 phi_0_1_imag;
735 FLOAT32 phi_0_2_real;
736 FLOAT32 phi_0_2_imag;
737 FLOAT32 phi_1_1;
738 FLOAT32 phi_1_2_real;
739 FLOAT32 phi_1_2_imag;
740 FLOAT32 phi_2_2;
741 FLOAT32 det;
742 } ia_auto_corr_ele_struct;
743
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)744 static VOID ixheaacd_esbr_calc_co_variance(
745 ia_auto_corr_ele_struct *pstr_auto_corr, FLOAT32 vec_x_real[][64],
746 FLOAT32 vec_x_imag[][64], WORD32 bd, WORD32 len) {
747 WORD32 j, jminus1, jminus2;
748
749 memset(pstr_auto_corr, 0, sizeof(ia_auto_corr_ele_struct));
750
751 for (j = 0; j < len; j++) {
752 jminus1 = j - 1;
753 jminus2 = jminus1 - 1;
754
755 pstr_auto_corr->phi_0_1_real +=
756 vec_x_real[j][bd] * vec_x_real[jminus1][bd] +
757 vec_x_imag[j][bd] * vec_x_imag[jminus1][bd];
758
759 pstr_auto_corr->phi_0_1_imag +=
760 vec_x_imag[j][bd] * vec_x_real[jminus1][bd] -
761 vec_x_real[j][bd] * vec_x_imag[jminus1][bd];
762
763 pstr_auto_corr->phi_0_2_real +=
764 vec_x_real[j][bd] * vec_x_real[jminus2][bd] +
765 vec_x_imag[j][bd] * vec_x_imag[jminus2][bd];
766
767 pstr_auto_corr->phi_0_2_imag +=
768 vec_x_imag[j][bd] * vec_x_real[jminus2][bd] -
769 vec_x_real[j][bd] * vec_x_imag[jminus2][bd];
770
771 pstr_auto_corr->phi_1_1 +=
772 vec_x_real[jminus1][bd] * vec_x_real[jminus1][bd] +
773 vec_x_imag[jminus1][bd] * vec_x_imag[jminus1][bd];
774
775 pstr_auto_corr->phi_1_2_real +=
776 vec_x_real[jminus1][bd] * vec_x_real[jminus2][bd] +
777 vec_x_imag[jminus1][bd] * vec_x_imag[jminus2][bd];
778
779 pstr_auto_corr->phi_1_2_imag +=
780 vec_x_imag[jminus1][bd] * vec_x_real[jminus2][bd] -
781 vec_x_real[jminus1][bd] * vec_x_imag[jminus2][bd];
782
783 pstr_auto_corr->phi_2_2 +=
784 vec_x_real[jminus2][bd] * vec_x_real[jminus2][bd] +
785 vec_x_imag[jminus2][bd] * vec_x_imag[jminus2][bd];
786 }
787
788 pstr_auto_corr->det =
789 pstr_auto_corr->phi_1_1 * pstr_auto_corr->phi_2_2 -
790 (pstr_auto_corr->phi_1_2_real * pstr_auto_corr->phi_1_2_real +
791 pstr_auto_corr->phi_1_2_imag * pstr_auto_corr->phi_1_2_imag) *
792 SBR_HF_RELAXATION_PARAM;
793 }
794
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)795 static void ixheaacd_esbr_chirp_fac_calc(WORD32 *inv_filt_mode,
796 WORD32 *inv_filt_mode_prev,
797 WORD32 num_if_bands, FLOAT32 *bw_array,
798 FLOAT32 *bw_array_prev) {
799 WORD32 i;
800
801 for (i = 0; i < num_if_bands; i++) {
802 bw_array[i] =
803 ixheaacd_new_bw_table[inv_filt_mode_prev[i]][inv_filt_mode[i]];
804
805 if (bw_array[i] < bw_array_prev[i])
806 bw_array[i] = 0.75000f * bw_array[i] + 0.25000f * bw_array_prev[i];
807 else
808 bw_array[i] = 0.90625f * bw_array[i] + 0.09375f * bw_array_prev[i];
809
810 if (bw_array[i] < 0.015625) bw_array[i] = 0;
811 }
812 }
813
ixheaacd_gausssolve(WORD32 n,FLOAT32 a[][MAXDEG+1],FLOAT32 b[],FLOAT32 y[])814 static void ixheaacd_gausssolve(WORD32 n, FLOAT32 a[][MAXDEG + 1], FLOAT32 b[],
815 FLOAT32 y[]) {
816 WORD32 i, j, k, imax;
817 FLOAT32 v;
818
819 for (i = 0; i < n; i++) {
820 imax = i;
821 for (k = i + 1; k < n; k++) {
822 if (fabs(a[k][i]) > fabs(a[imax][i])) {
823 imax = k;
824 }
825 }
826 if (imax != i) {
827 v = b[imax];
828 b[imax] = b[i];
829 b[i] = v;
830 for (j = i; j < n; j++) {
831 v = a[imax][j];
832 a[imax][j] = a[i][j];
833 a[i][j] = v;
834 }
835 }
836
837 v = a[i][i];
838
839 b[i] /= v;
840 for (j = i; j < n; j++) {
841 a[i][j] /= v;
842 }
843
844 for (k = i + 1; k < n; k++) {
845 v = a[k][i];
846 b[k] -= v * b[i];
847 for (j = i + 1; j < n; j++) {
848 a[k][j] -= v * a[i][j];
849 }
850 }
851 }
852
853 for (i = n - 1; i >= 0; i--) {
854 y[i] = b[i];
855 for (j = i + 1; j < n; j++) {
856 y[i] -= a[i][j] * y[j];
857 }
858 }
859 }
860
ixheaacd_polyfit(WORD32 n,FLOAT32 y[],FLOAT32 p[])861 void ixheaacd_polyfit(WORD32 n, FLOAT32 y[], FLOAT32 p[]) {
862 WORD32 i, j, k;
863 FLOAT32 a[MAXDEG + 1][MAXDEG + 1];
864 FLOAT32 b[MAXDEG + 1];
865 FLOAT32 v[2 * MAXDEG + 1];
866
867 for (i = 0; i <= MAXDEG; i++) {
868 b[i] = 0.0f;
869 for (j = 0; j <= MAXDEG; j++) {
870 a[i][j] = 0.0f;
871 }
872 }
873
874 for (k = 0; k < n; k++) {
875 v[0] = 1.0;
876 for (i = 1; i <= 2 * MAXDEG; i++) {
877 v[i] = k * v[i - 1];
878 }
879
880 for (i = 0; i <= MAXDEG; i++) {
881 b[i] += v[MAXDEG - i] * y[k];
882 for (j = 0; j <= MAXDEG; j++) {
883 a[i][j] += v[2 * MAXDEG - i - j];
884 }
885 }
886 }
887
888 ixheaacd_gausssolve(MAXDEG + 1, a, b, p);
889 }
890
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)891 VOID ixheaacd_pre_processing(FLOAT32 ptr_src_buf_real[][64],
892 FLOAT32 ptr_src_buf_imag[][64],
893 FLOAT32 gain_vector[], WORD32 num_bands,
894 WORD32 start_sample, WORD32 end_sample) {
895 WORD32 k, i;
896 FLOAT32 poly_coeff[4];
897 FLOAT32 mean_enrg = 0;
898 FLOAT32 low_env_slope[64];
899 FLOAT32 low_env[64];
900 FLOAT32 a0;
901 FLOAT32 a1;
902 FLOAT32 a2;
903 FLOAT32 a3;
904
905 for (k = 0; k < num_bands; k++) {
906 FLOAT32 temp = 0;
907 for (i = start_sample; i < end_sample; i++) {
908 temp += ptr_src_buf_real[i][k] * ptr_src_buf_real[i][k] +
909 ptr_src_buf_imag[i][k] * ptr_src_buf_imag[i][k];
910 }
911 temp /= (end_sample - start_sample);
912 low_env[k] = (FLOAT32)(10 * log10(temp + 1));
913 mean_enrg = mean_enrg + low_env[k];
914 }
915 mean_enrg /= num_bands;
916
917 ixheaacd_polyfit(num_bands, low_env, poly_coeff);
918
919 a0 = poly_coeff[0];
920 a1 = poly_coeff[1];
921 a2 = poly_coeff[2];
922 a3 = poly_coeff[3];
923 for (k = 0; k < num_bands; k++) {
924 FLOAT32 x_low_l = (FLOAT32)k;
925 FLOAT32 low_env_slope_l = a3;
926 low_env_slope_l = low_env_slope_l + a2 * x_low_l;
927
928 x_low_l = x_low_l * x_low_l;
929 low_env_slope_l = low_env_slope_l + a1 * x_low_l;
930
931 x_low_l = x_low_l * (FLOAT32)k;
932 low_env_slope_l = low_env_slope_l + a0 * x_low_l;
933
934 low_env_slope[k] = low_env_slope_l;
935 }
936
937 for (i = 0; i < num_bands; i++) {
938 gain_vector[i] = (FLOAT32)pow(10, (mean_enrg - low_env_slope[i]) / 20.0f);
939 }
940 }
941
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)942 WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64],
943 FLOAT32 ptr_src_buf_imag[][64],
944 FLOAT32 ptr_ph_vocod_buf_real[][64],
945 FLOAT32 ptr_ph_vocod_buf_imag[][64],
946 FLOAT32 ptr_dst_buf_real[][64],
947 FLOAT32 ptr_dst_buf_imag[][64],
948 ia_sbr_frame_info_data_struct *ptr_frame_data,
949 ia_sbr_header_data_struct *ptr_header_data) {
950 WORD32 bw_index, i, k, k2, patch = 0;
951 WORD32 co_var_len;
952 WORD32 start_sample, end_sample, goal_sb;
953 WORD32 sb, source_start_band, patch_stride, num_bands_in_patch;
954 WORD32 hbe_flag = ptr_header_data->hbe_flag;
955 FLOAT32 a0r, a0i, a1r, a1i;
956 FLOAT32 bw_array[MAX_NUM_PATCHES] = {0};
957
958 ia_auto_corr_ele_struct str_auto_corr;
959
960 WORD16 *ptr_invf_band_tbl =
961 &ptr_header_data->pstr_freq_band_data
962 ->freq_band_tbl_noise[1]; // offest 1 used as base address of
963 // ptr_invf_band_tbl
964 WORD32 num_if_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
965 WORD32 sub_band_start = ptr_header_data->pstr_freq_band_data->sub_band_start;
966 WORD16 *f_master_tbl = ptr_header_data->pstr_freq_band_data->f_master_tbl;
967 WORD32 num_mf_bands = ptr_header_data->pstr_freq_band_data->num_mf_bands;
968 WORD32 *inv_filt_mode = ptr_frame_data->sbr_invf_mode;
969 WORD32 *inv_filt_mode_prev = ptr_frame_data->sbr_invf_mode_prev;
970 WORD32 sbr_patching_mode = ptr_frame_data->sbr_patching_mode;
971 ia_frame_info_struct *p_frame_info = &ptr_frame_data->str_frame_info_details;
972 WORD32 pre_proc_flag = ptr_header_data->pre_proc_flag;
973 WORD32 is_usf_4 = ptr_header_data->is_usf_4;
974 WORD32 fs = ptr_header_data->out_sampling_freq;
975
976 WORD32 lsb = f_master_tbl[0];
977 WORD32 usb = f_master_tbl[num_mf_bands];
978 WORD32 xover_offset = sub_band_start - f_master_tbl[0];
979
980 FLOAT32 bw = 0.0f;
981 FLOAT32 fac = 0.0f;
982
983 FLOAT32 gain;
984 FLOAT32 gain_vector[64];
985
986 WORD32 slope_length = 0;
987 WORD32 first_slot_offset = p_frame_info->border_vec[0];
988 WORD32 end_slot_offs = 0;
989
990 FLOAT32 *bw_array_prev = ptr_frame_data->bw_array_prev;
991
992 end_slot_offs = p_frame_info->border_vec[p_frame_info->num_env] - 16;
993 if (is_usf_4) {
994 start_sample = first_slot_offset * 4;
995 end_sample = 64 + end_slot_offs * 4;
996 co_var_len = 76;
997 } else {
998 start_sample = first_slot_offset * 2;
999 end_sample = 32 + end_slot_offs * 2;
1000 co_var_len = 38;
1001 }
1002
1003 if (pre_proc_flag) {
1004 ixheaacd_pre_processing(ptr_src_buf_real, ptr_src_buf_imag, gain_vector,
1005 f_master_tbl[0], start_sample, end_sample);
1006 }
1007
1008 ixheaacd_esbr_chirp_fac_calc(inv_filt_mode, inv_filt_mode_prev, num_if_bands,
1009 bw_array, bw_array_prev);
1010
1011 for (i = start_sample; i < end_sample; i++) {
1012 memset(ptr_dst_buf_real[i] + usb, 0, (64 - usb) * sizeof(FLOAT32));
1013 memset(ptr_dst_buf_imag[i] + usb, 0, (64 - usb) * sizeof(FLOAT32));
1014 }
1015
1016 if (sbr_patching_mode || !hbe_flag) {
1017 FLOAT32 alpha_real[64][2], alpha_imag[64][2];
1018
1019 for (k = 1; k < f_master_tbl[0]; k++) {
1020 ixheaacd_esbr_calc_co_variance(&str_auto_corr, &ptr_src_buf_real[0],
1021 &ptr_src_buf_imag[0], k, co_var_len);
1022 if (str_auto_corr.det == 0.0f) {
1023 alpha_real[k][1] = alpha_imag[k][1] = 0;
1024 } else {
1025 fac = 1.0f / str_auto_corr.det;
1026 alpha_real[k][1] =
1027 (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
1028 str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
1029 str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
1030 fac;
1031 alpha_imag[k][1] =
1032 (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
1033 str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
1034 str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
1035 fac;
1036 }
1037
1038 if (str_auto_corr.phi_1_1 == 0) {
1039 alpha_real[k][0] = alpha_imag[k][0] = 0;
1040 } else {
1041 fac = 1.0f / str_auto_corr.phi_1_1;
1042 alpha_real[k][0] = -(str_auto_corr.phi_0_1_real +
1043 alpha_real[k][1] * str_auto_corr.phi_1_2_real +
1044 alpha_imag[k][1] * str_auto_corr.phi_1_2_imag) *
1045 fac;
1046 alpha_imag[k][0] = -(str_auto_corr.phi_0_1_imag +
1047 alpha_imag[k][1] * str_auto_corr.phi_1_2_real -
1048 alpha_real[k][1] * str_auto_corr.phi_1_2_imag) *
1049 fac;
1050 }
1051
1052 if ((alpha_real[k][0] * alpha_real[k][0] +
1053 alpha_imag[k][0] * alpha_imag[k][0] >=
1054 16.0f) ||
1055 (alpha_real[k][1] * alpha_real[k][1] +
1056 alpha_imag[k][1] * alpha_imag[k][1] >=
1057 16.0f)) {
1058 alpha_real[k][0] = 0.0f;
1059 alpha_imag[k][0] = 0.0f;
1060 alpha_real[k][1] = 0.0f;
1061 alpha_imag[k][1] = 0.0f;
1062 }
1063 }
1064
1065 goal_sb = (WORD32)(2.048e6f / fs + 0.5f);
1066 {
1067 WORD32 index;
1068 if (goal_sb < f_master_tbl[num_mf_bands]) {
1069 for (index = 0; (f_master_tbl[index] < goal_sb); index++)
1070 ;
1071 goal_sb = f_master_tbl[index];
1072 } else {
1073 goal_sb = f_master_tbl[num_mf_bands];
1074 }
1075 }
1076
1077 source_start_band = xover_offset + 1;
1078 sb = lsb + xover_offset;
1079
1080 patch = 0;
1081 while (sb < usb) {
1082 if (MAX_NUM_PATCHES <= patch) return -1;
1083 ptr_frame_data->patch_param.start_subband[patch] = sb;
1084 num_bands_in_patch = goal_sb - sb;
1085
1086 if (num_bands_in_patch >= lsb - source_start_band) {
1087 patch_stride = sb - source_start_band;
1088 patch_stride = patch_stride & ~1;
1089 num_bands_in_patch = lsb - (sb - patch_stride);
1090 num_bands_in_patch =
1091 ixheaacd_find_closest_entry(sb + num_bands_in_patch, f_master_tbl,
1092 (WORD16)(num_mf_bands), 0) -
1093 (WORD32)(sb);
1094 }
1095
1096 patch_stride = num_bands_in_patch + sb - lsb;
1097 patch_stride = (patch_stride + 1) & ~1;
1098
1099 source_start_band = 1;
1100
1101 if (goal_sb - (sb + num_bands_in_patch) < 3) {
1102 goal_sb = usb;
1103 }
1104
1105 if ((num_bands_in_patch < 3) && (patch > 0) &&
1106 (sb + num_bands_in_patch == usb)) {
1107 for (i = start_sample + slope_length; i < end_sample + slope_length;
1108 i++) {
1109 for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
1110 ptr_dst_buf_real[i][k2] = 0.0f;
1111 ptr_dst_buf_imag[i][k2] = 0.0f;
1112 }
1113 }
1114
1115 break;
1116 }
1117
1118 if (num_bands_in_patch <= 0) {
1119 return -1;
1120 }
1121
1122 for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
1123 k = k2 - patch_stride;
1124 bw_index = 0;
1125 while (k2 >= ptr_invf_band_tbl[bw_index]) {
1126 bw_index++;
1127 if (bw_index >= MAX_NOISE_COEFFS) return -1;
1128 }
1129
1130 if (bw_index >= MAX_NUM_PATCHES) return -1;
1131 bw = bw_array[bw_index];
1132
1133 a0r = bw * alpha_real[k][0];
1134 a0i = bw * alpha_imag[k][0];
1135 bw *= bw;
1136 a1r = bw * alpha_real[k][1];
1137 a1i = bw * alpha_imag[k][1];
1138
1139 if (pre_proc_flag) {
1140 gain = gain_vector[k];
1141 } else {
1142 gain = 1.0f;
1143 }
1144
1145 for (i = start_sample + slope_length; i < end_sample + slope_length;
1146 i++) {
1147 ptr_dst_buf_real[i][k2] = ptr_src_buf_real[i][k] * gain;
1148
1149 ptr_dst_buf_imag[i][k2] = ptr_src_buf_imag[i][k] * gain;
1150
1151 if (bw > 0.0f) {
1152 ptr_dst_buf_real[i][k2] += (a0r * ptr_src_buf_real[i - 1][k] -
1153 a0i * ptr_src_buf_imag[i - 1][k] +
1154 a1r * ptr_src_buf_real[i - 2][k] -
1155 a1i * ptr_src_buf_imag[i - 2][k]) *
1156 gain;
1157 ptr_dst_buf_imag[i][k2] += (a0i * ptr_src_buf_real[i - 1][k] +
1158 a0r * ptr_src_buf_imag[i - 1][k] +
1159 a1i * ptr_src_buf_real[i - 2][k] +
1160 a1r * ptr_src_buf_imag[i - 2][k]) *
1161 gain;
1162 }
1163 }
1164 }
1165 sb += num_bands_in_patch;
1166 patch++;
1167 }
1168 }
1169
1170 if (hbe_flag && !sbr_patching_mode) {
1171 FLOAT32 alpha_real[2], alpha_imag[2];
1172
1173 bw_index = 0, patch = 1;
1174 if (NULL == ptr_ph_vocod_buf_real || NULL == ptr_ph_vocod_buf_imag)
1175 return -1;
1176
1177 for (k2 = sub_band_start; k2 < f_master_tbl[num_mf_bands]; k2++) {
1178 ixheaacd_esbr_calc_co_variance(&str_auto_corr, &ptr_ph_vocod_buf_real[0],
1179 &ptr_ph_vocod_buf_imag[0], k2, co_var_len);
1180
1181 if (str_auto_corr.det == 0.0f) {
1182 alpha_real[1] = alpha_imag[1] = 0;
1183 } else {
1184 fac = 1.0f / str_auto_corr.det;
1185 alpha_real[1] =
1186 (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
1187 str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
1188 str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
1189 fac;
1190 alpha_imag[1] =
1191 (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
1192 str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
1193 str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
1194 fac;
1195 }
1196
1197 if (str_auto_corr.phi_1_1 == 0) {
1198 alpha_real[0] = alpha_imag[0] = 0;
1199 } else {
1200 fac = 1.0f / str_auto_corr.phi_1_1;
1201 alpha_real[0] = -(str_auto_corr.phi_0_1_real +
1202 alpha_real[1] * str_auto_corr.phi_1_2_real +
1203 alpha_imag[1] * str_auto_corr.phi_1_2_imag) *
1204 fac;
1205 alpha_imag[0] = -(str_auto_corr.phi_0_1_imag +
1206 alpha_imag[1] * str_auto_corr.phi_1_2_real -
1207 alpha_real[1] * str_auto_corr.phi_1_2_imag) *
1208 fac;
1209 }
1210
1211 if (alpha_real[0] * alpha_real[0] + alpha_imag[0] * alpha_imag[0] >=
1212 16.0f ||
1213 alpha_real[1] * alpha_real[1] + alpha_imag[1] * alpha_imag[1] >=
1214 16.0f) {
1215 alpha_real[0] = 0.0f;
1216 alpha_imag[0] = 0.0f;
1217 alpha_real[1] = 0.0f;
1218 alpha_imag[1] = 0.0f;
1219 }
1220
1221 while (k2 >= ptr_invf_band_tbl[bw_index]) {
1222 bw_index++;
1223 if (bw_index >= MAX_NOISE_COEFFS) return -1;
1224 }
1225
1226 if (bw_index >= MAX_NUM_PATCHES) return -1;
1227 bw = bw_array[bw_index];
1228
1229 a0r = bw * alpha_real[0];
1230 a0i = bw * alpha_imag[0];
1231 bw *= bw;
1232 a1r = bw * alpha_real[1];
1233 a1i = bw * alpha_imag[1];
1234
1235 if (bw > 0.0f) {
1236 for (i = start_sample; i < end_sample; i++) {
1237 FLOAT32 real1, imag1, real2, imag2, realTarget, imag_target;
1238
1239 realTarget = ptr_ph_vocod_buf_real[i][k2];
1240 imag_target = ptr_ph_vocod_buf_imag[i][k2];
1241 real1 = ptr_ph_vocod_buf_real[i - 1][k2];
1242 imag1 = ptr_ph_vocod_buf_imag[i - 1][k2];
1243 real2 = ptr_ph_vocod_buf_real[i - 2][k2];
1244 imag2 = ptr_ph_vocod_buf_imag[i - 2][k2];
1245 realTarget +=
1246 ((a0r * real1 - a0i * imag1) + (a1r * real2 - a1i * imag2));
1247 imag_target +=
1248 ((a0i * real1 + a0r * imag1) + (a1i * real2 + a1r * imag2));
1249
1250 ptr_dst_buf_real[i][k2] = realTarget;
1251 ptr_dst_buf_imag[i][k2] = imag_target;
1252 }
1253 } else {
1254 for (i = start_sample; i < end_sample; i++) {
1255 ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2];
1256 ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2];
1257 }
1258 }
1259 }
1260 }
1261 ptr_frame_data->patch_param.num_patches = patch;
1262 if (patch >= (MAX_NUM_PATCHES + 1)) return -1;
1263 for (i = 0; i < num_if_bands; i++) {
1264 bw_array_prev[i] = bw_array[i];
1265 }
1266 return 0;
1267 }
1268