1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker * *
3*15dc779aSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker *
5*15dc779aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker *
9*15dc779aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker *
11*15dc779aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker *
17*15dc779aSAndroid Build Coastguard Worker *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker */
20*15dc779aSAndroid Build Coastguard Worker
21*15dc779aSAndroid Build Coastguard Worker #include <string.h>
22*15dc779aSAndroid Build Coastguard Worker #include <math.h>
23*15dc779aSAndroid Build Coastguard Worker #include "iusace_type_def.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_error_standards.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_error_codes.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_common_define.h"
27*15dc779aSAndroid Build Coastguard Worker #include "iusace_cnst.h"
28*15dc779aSAndroid Build Coastguard Worker #include "iusace_block_switch_const.h"
29*15dc779aSAndroid Build Coastguard Worker #include "iusace_bitbuffer.h"
30*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_common_enc.h"
31*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc.h"
32*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_api.h"
33*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc_eq.h"
34*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc_filter_bank.h"
35*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_gain_enc.h"
36*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_struct_def.h"
37*15dc779aSAndroid Build Coastguard Worker
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_memory_standards.h"
39*15dc779aSAndroid Build Coastguard Worker #include "iusace_tns_usac.h"
40*15dc779aSAndroid Build Coastguard Worker #include "iusace_psy_mod.h"
41*15dc779aSAndroid Build Coastguard Worker #include "iusace_config.h"
42*15dc779aSAndroid Build Coastguard Worker #include "iusace_ms.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold_data.h"
44*15dc779aSAndroid Build Coastguard Worker #include "iusace_fd_qc_util.h"
45*15dc779aSAndroid Build Coastguard Worker #include "iusace_arith_enc.h"
46*15dc779aSAndroid Build Coastguard Worker #include "iusace_fd_quant.h"
47*15dc779aSAndroid Build Coastguard Worker #include "iusace_signal_classifier.h"
48*15dc779aSAndroid Build Coastguard Worker #include "iusace_block_switch_struct_def.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_sbr_header.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_config.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_asc_write.h"
52*15dc779aSAndroid Build Coastguard Worker #include "iusace_main.h"
53*15dc779aSAndroid Build Coastguard Worker #include "iusace_write_bitstream.h"
54*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_nf.h"
55*15dc779aSAndroid Build Coastguard Worker #include "iusace_fd_qc_adjthr.h"
56*15dc779aSAndroid Build Coastguard Worker #include "iusace_block_switch_const.h"
57*15dc779aSAndroid Build Coastguard Worker #include "iusace_rom.h"
58*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_cplx_pred.h"
59*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_aac_constants.h"
60*15dc779aSAndroid Build Coastguard Worker
61*15dc779aSAndroid Build Coastguard Worker static WORD32 iusace_window_shape[5] = {WIN_SEL_1, WIN_SEL_0, WIN_SEL_0, WIN_SEL_1, WIN_SEL_0};
62*15dc779aSAndroid Build Coastguard Worker
iusace_count_ms_bits(WORD32 sfb_count,WORD32 sfb_per_grp,WORD32 max_sfb_per_grp)63*15dc779aSAndroid Build Coastguard Worker static WORD32 iusace_count_ms_bits(WORD32 sfb_count, WORD32 sfb_per_grp, WORD32 max_sfb_per_grp) {
64*15dc779aSAndroid Build Coastguard Worker WORD32 ms_bits = 0, sfb_offs, sfb;
65*15dc779aSAndroid Build Coastguard Worker for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += sfb_per_grp) {
66*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < max_sfb_per_grp; sfb++) {
67*15dc779aSAndroid Build Coastguard Worker ms_bits++;
68*15dc779aSAndroid Build Coastguard Worker }
69*15dc779aSAndroid Build Coastguard Worker }
70*15dc779aSAndroid Build Coastguard Worker return (ms_bits);
71*15dc779aSAndroid Build Coastguard Worker }
72*15dc779aSAndroid Build Coastguard Worker
iusace_count_static_bits(ia_usac_data_struct * ptr_usac_data,ia_usac_encoder_config_struct * ptr_usac_config,ia_sfb_params_struct * pstr_sfb_params,ia_psy_mod_out_data_struct * pstr_psy_out,WORD32 channels,WORD32 chn,WORD32 usac_independency_flag,WORD32 ele_id)73*15dc779aSAndroid Build Coastguard Worker static WORD32 iusace_count_static_bits(ia_usac_data_struct *ptr_usac_data,
74*15dc779aSAndroid Build Coastguard Worker ia_usac_encoder_config_struct *ptr_usac_config,
75*15dc779aSAndroid Build Coastguard Worker ia_sfb_params_struct *pstr_sfb_params,
76*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_out_data_struct *pstr_psy_out, WORD32 channels,
77*15dc779aSAndroid Build Coastguard Worker WORD32 chn, WORD32 usac_independency_flag, WORD32 ele_id) {
78*15dc779aSAndroid Build Coastguard Worker WORD32 ms_mask = ptr_usac_data->str_ms_info[chn].ms_mask;
79*15dc779aSAndroid Build Coastguard Worker WORD32 noise_filling = ptr_usac_data->noise_filling[ele_id];
80*15dc779aSAndroid Build Coastguard Worker WORD32 stat_bits = 0, i;
81*15dc779aSAndroid Build Coastguard Worker WORD32 tns_active = 0, tns_present_both = 0;
82*15dc779aSAndroid Build Coastguard Worker WORD32 max_sfb = pstr_psy_out[chn].max_sfb_per_grp;
83*15dc779aSAndroid Build Coastguard Worker (VOID) ptr_usac_config;
84*15dc779aSAndroid Build Coastguard Worker
85*15dc779aSAndroid Build Coastguard Worker if (channels == 1) {
86*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // core mode
87*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // tns active
88*15dc779aSAndroid Build Coastguard Worker
89*15dc779aSAndroid Build Coastguard Worker switch (pstr_psy_out[chn].window_sequence) {
90*15dc779aSAndroid Build Coastguard Worker case ONLY_LONG_SEQUENCE:
91*15dc779aSAndroid Build Coastguard Worker case LONG_START_SEQUENCE:
92*15dc779aSAndroid Build Coastguard Worker case LONG_STOP_SEQUENCE:
93*15dc779aSAndroid Build Coastguard Worker stat_bits += SI_ICS_INFO_BITS_LONG;
94*15dc779aSAndroid Build Coastguard Worker break;
95*15dc779aSAndroid Build Coastguard Worker case EIGHT_SHORT_SEQUENCE:
96*15dc779aSAndroid Build Coastguard Worker stat_bits += SI_ICS_INFO_BITS_SHORT;
97*15dc779aSAndroid Build Coastguard Worker break;
98*15dc779aSAndroid Build Coastguard Worker }
99*15dc779aSAndroid Build Coastguard Worker } else {
100*15dc779aSAndroid Build Coastguard Worker stat_bits += 2; // core mode
101*15dc779aSAndroid Build Coastguard Worker stat_bits += 2; // tns and common window
102*15dc779aSAndroid Build Coastguard Worker
103*15dc779aSAndroid Build Coastguard Worker switch (pstr_psy_out[chn].window_sequence) {
104*15dc779aSAndroid Build Coastguard Worker case ONLY_LONG_SEQUENCE:
105*15dc779aSAndroid Build Coastguard Worker case LONG_START_SEQUENCE:
106*15dc779aSAndroid Build Coastguard Worker case LONG_STOP_SEQUENCE:
107*15dc779aSAndroid Build Coastguard Worker stat_bits += SI_ICS_INFO_BITS_LONG;
108*15dc779aSAndroid Build Coastguard Worker break;
109*15dc779aSAndroid Build Coastguard Worker case EIGHT_SHORT_SEQUENCE:
110*15dc779aSAndroid Build Coastguard Worker stat_bits += SI_ICS_INFO_BITS_SHORT;
111*15dc779aSAndroid Build Coastguard Worker break;
112*15dc779aSAndroid Build Coastguard Worker }
113*15dc779aSAndroid Build Coastguard Worker
114*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // common_max_sfb
115*15dc779aSAndroid Build Coastguard Worker stat_bits += SI_CPE_MS_MASK_BITS;
116*15dc779aSAndroid Build Coastguard Worker
117*15dc779aSAndroid Build Coastguard Worker if (ms_mask != 3) {
118*15dc779aSAndroid Build Coastguard Worker if (ms_mask == 1) {
119*15dc779aSAndroid Build Coastguard Worker stat_bits += iusace_count_ms_bits(pstr_psy_out[chn].sfb_count,
120*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[chn].sfb_per_group, max_sfb);
121*15dc779aSAndroid Build Coastguard Worker }
122*15dc779aSAndroid Build Coastguard Worker } else {
123*15dc779aSAndroid Build Coastguard Worker stat_bits += iusace_write_cplx_pred_data(
124*15dc779aSAndroid Build Coastguard Worker NULL, pstr_sfb_params->num_window_groups[chn], max_sfb,
125*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->complex_coef[chn], ptr_usac_data->pred_coef_re[chn],
126*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pred_coef_im[chn], iusace_huffman_code_table, usac_independency_flag,
127*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pred_dir_idx[chn], ptr_usac_data->cplx_pred_used[chn],
128*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->cplx_pred_all[chn], ptr_usac_data->temp_pred_coef_re_prev[chn],
129*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->temp_pred_coef_im_prev[chn], &ptr_usac_data->delta_code_time[chn]);
130*15dc779aSAndroid Build Coastguard Worker }
131*15dc779aSAndroid Build Coastguard Worker
132*15dc779aSAndroid Build Coastguard Worker if (ptr_usac_data->pstr_tns_info[chn] != NULL &&
133*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pstr_tns_info[chn + 1] != NULL) {
134*15dc779aSAndroid Build Coastguard Worker tns_active = ptr_usac_data->pstr_tns_info[chn]->tns_data_present ||
135*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pstr_tns_info[chn + 1]->tns_data_present;
136*15dc779aSAndroid Build Coastguard Worker tns_present_both = ptr_usac_data->pstr_tns_info[chn]->tns_data_present &&
137*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pstr_tns_info[chn + 1]->tns_data_present;
138*15dc779aSAndroid Build Coastguard Worker }
139*15dc779aSAndroid Build Coastguard Worker if (tns_active) {
140*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // common_tns
141*15dc779aSAndroid Build Coastguard Worker
142*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // tns_present_both
143*15dc779aSAndroid Build Coastguard Worker
144*15dc779aSAndroid Build Coastguard Worker if (!tns_present_both) {
145*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // tns_data_present1
146*15dc779aSAndroid Build Coastguard Worker }
147*15dc779aSAndroid Build Coastguard Worker }
148*15dc779aSAndroid Build Coastguard Worker }
149*15dc779aSAndroid Build Coastguard Worker
150*15dc779aSAndroid Build Coastguard Worker for (i = chn; i < chn + channels; i++) {
151*15dc779aSAndroid Build Coastguard Worker stat_bits += 8; // global_gain
152*15dc779aSAndroid Build Coastguard Worker
153*15dc779aSAndroid Build Coastguard Worker if (noise_filling) {
154*15dc779aSAndroid Build Coastguard Worker stat_bits += 8;
155*15dc779aSAndroid Build Coastguard Worker }
156*15dc779aSAndroid Build Coastguard Worker }
157*15dc779aSAndroid Build Coastguard Worker
158*15dc779aSAndroid Build Coastguard Worker for (i = chn; i < chn + channels; i++) {
159*15dc779aSAndroid Build Coastguard Worker if (ptr_usac_data->pstr_tns_info[i] != NULL &&
160*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pstr_tns_info[i]->tns_data_present == 1) {
161*15dc779aSAndroid Build Coastguard Worker stat_bits += iusace_write_tns_data(NULL, ptr_usac_data->pstr_tns_info[i],
162*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[i].window_sequence, 0);
163*15dc779aSAndroid Build Coastguard Worker }
164*15dc779aSAndroid Build Coastguard Worker
165*15dc779aSAndroid Build Coastguard Worker if (!usac_independency_flag) {
166*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // arith_reset_flag
167*15dc779aSAndroid Build Coastguard Worker }
168*15dc779aSAndroid Build Coastguard Worker
169*15dc779aSAndroid Build Coastguard Worker stat_bits += 1; // fac_data_present
170*15dc779aSAndroid Build Coastguard Worker stat_bits += ptr_usac_data->str_scratch.ptr_num_fac_bits[i];
171*15dc779aSAndroid Build Coastguard Worker }
172*15dc779aSAndroid Build Coastguard Worker
173*15dc779aSAndroid Build Coastguard Worker stat_bits += (ptr_usac_data->num_sbr_bits + ptr_usac_data->num_drc_bits);
174*15dc779aSAndroid Build Coastguard Worker
175*15dc779aSAndroid Build Coastguard Worker return stat_bits;
176*15dc779aSAndroid Build Coastguard Worker }
177*15dc779aSAndroid Build Coastguard Worker
iusace_sort_for_grouping(WORD32 * sfb_offset,const WORD32 * sfb_width_table,FLOAT64 * ptr_scratch,FLOAT64 * ptr_spec,WORD32 num_window_groups,const WORD32 * window_group_length,WORD32 nr_of_sfb,WORD32 ccfl)178*15dc779aSAndroid Build Coastguard Worker static VOID iusace_sort_for_grouping(WORD32 *sfb_offset, const WORD32 *sfb_width_table,
179*15dc779aSAndroid Build Coastguard Worker FLOAT64 *ptr_scratch, FLOAT64 *ptr_spec,
180*15dc779aSAndroid Build Coastguard Worker WORD32 num_window_groups, const WORD32 *window_group_length,
181*15dc779aSAndroid Build Coastguard Worker WORD32 nr_of_sfb, WORD32 ccfl) {
182*15dc779aSAndroid Build Coastguard Worker WORD32 i, j, ii;
183*15dc779aSAndroid Build Coastguard Worker WORD32 index = 0;
184*15dc779aSAndroid Build Coastguard Worker WORD32 group_offset = 0;
185*15dc779aSAndroid Build Coastguard Worker WORD32 k = 0;
186*15dc779aSAndroid Build Coastguard Worker WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG;
187*15dc779aSAndroid Build Coastguard Worker
188*15dc779aSAndroid Build Coastguard Worker sfb_offset[k] = 0;
189*15dc779aSAndroid Build Coastguard Worker for (k = 1; k < nr_of_sfb + 1; k++) {
190*15dc779aSAndroid Build Coastguard Worker sfb_offset[k] = sfb_offset[k - 1] + sfb_width_table[k - 1];
191*15dc779aSAndroid Build Coastguard Worker }
192*15dc779aSAndroid Build Coastguard Worker
193*15dc779aSAndroid Build Coastguard Worker index = 0;
194*15dc779aSAndroid Build Coastguard Worker group_offset = 0;
195*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_window_groups; i++) {
196*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < nr_of_sfb; k++) {
197*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < window_group_length[i]; j++) {
198*15dc779aSAndroid Build Coastguard Worker for (ii = 0; ii < sfb_width_table[k]; ii++) {
199*15dc779aSAndroid Build Coastguard Worker ptr_scratch[index++] =
200*15dc779aSAndroid Build Coastguard Worker ptr_spec[ii + sfb_offset[k] + frame_len_short * j + group_offset];
201*15dc779aSAndroid Build Coastguard Worker }
202*15dc779aSAndroid Build Coastguard Worker }
203*15dc779aSAndroid Build Coastguard Worker }
204*15dc779aSAndroid Build Coastguard Worker group_offset += frame_len_short * window_group_length[i];
205*15dc779aSAndroid Build Coastguard Worker }
206*15dc779aSAndroid Build Coastguard Worker
207*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec, ptr_scratch, ccfl * sizeof(ptr_spec[0]));
208*15dc779aSAndroid Build Coastguard Worker
209*15dc779aSAndroid Build Coastguard Worker index = 0;
210*15dc779aSAndroid Build Coastguard Worker sfb_offset[index++] = 0;
211*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_window_groups; i++) {
212*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < nr_of_sfb; k++) {
213*15dc779aSAndroid Build Coastguard Worker sfb_offset[index] = sfb_offset[index - 1] + sfb_width_table[k] * window_group_length[i];
214*15dc779aSAndroid Build Coastguard Worker index++;
215*15dc779aSAndroid Build Coastguard Worker }
216*15dc779aSAndroid Build Coastguard Worker }
217*15dc779aSAndroid Build Coastguard Worker
218*15dc779aSAndroid Build Coastguard Worker return;
219*15dc779aSAndroid Build Coastguard Worker }
220*15dc779aSAndroid Build Coastguard Worker
iusace_degroup_int(const WORD32 * ptr_grouped_sfb_offsets,WORD32 sfb_per_group,WORD32 * ptr_scratch,WORD32 * ptr_spec,WORD32 num_window_groups,const WORD32 * window_group_length,WORD32 ccfl)221*15dc779aSAndroid Build Coastguard Worker static VOID iusace_degroup_int(const WORD32 *ptr_grouped_sfb_offsets, WORD32 sfb_per_group,
222*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_scratch, WORD32 *ptr_spec, WORD32 num_window_groups,
223*15dc779aSAndroid Build Coastguard Worker const WORD32 *window_group_length, WORD32 ccfl)
224*15dc779aSAndroid Build Coastguard Worker
225*15dc779aSAndroid Build Coastguard Worker {
226*15dc779aSAndroid Build Coastguard Worker WORD32 i, j, k, n;
227*15dc779aSAndroid Build Coastguard Worker WORD32 index, group_offset;
228*15dc779aSAndroid Build Coastguard Worker WORD32 loop1, loop2;
229*15dc779aSAndroid Build Coastguard Worker WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG;
230*15dc779aSAndroid Build Coastguard Worker index = 0;
231*15dc779aSAndroid Build Coastguard Worker group_offset = 0;
232*15dc779aSAndroid Build Coastguard Worker
233*15dc779aSAndroid Build Coastguard Worker memset(ptr_scratch, 0, ccfl * sizeof(WORD32));
234*15dc779aSAndroid Build Coastguard Worker
235*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_window_groups; i++) {
236*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < sfb_per_group; j++) {
237*15dc779aSAndroid Build Coastguard Worker WORD32 idx = i * sfb_per_group + j;
238*15dc779aSAndroid Build Coastguard Worker loop1 = ((ptr_grouped_sfb_offsets[idx + 1] - ptr_grouped_sfb_offsets[idx]) /
239*15dc779aSAndroid Build Coastguard Worker window_group_length[i]);
240*15dc779aSAndroid Build Coastguard Worker
241*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < window_group_length[i]; k++) {
242*15dc779aSAndroid Build Coastguard Worker loop2 = ((ptr_grouped_sfb_offsets[idx] - group_offset) / window_group_length[i]) +
243*15dc779aSAndroid Build Coastguard Worker frame_len_short * k + group_offset;
244*15dc779aSAndroid Build Coastguard Worker
245*15dc779aSAndroid Build Coastguard Worker for (n = 0; n < loop1; n++) {
246*15dc779aSAndroid Build Coastguard Worker ptr_scratch[n + loop2] = ptr_spec[index++];
247*15dc779aSAndroid Build Coastguard Worker }
248*15dc779aSAndroid Build Coastguard Worker }
249*15dc779aSAndroid Build Coastguard Worker }
250*15dc779aSAndroid Build Coastguard Worker group_offset += frame_len_short * window_group_length[i];
251*15dc779aSAndroid Build Coastguard Worker }
252*15dc779aSAndroid Build Coastguard Worker
253*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec, ptr_scratch, ccfl * sizeof(WORD32));
254*15dc779aSAndroid Build Coastguard Worker
255*15dc779aSAndroid Build Coastguard Worker return;
256*15dc779aSAndroid Build Coastguard Worker }
257*15dc779aSAndroid Build Coastguard Worker
iusace_stereo_proc(ia_sfb_params_struct * pstr_sfb_prms,WORD32 usac_independancy_flag,ia_usac_data_struct * ptr_usac_data,ia_usac_encoder_config_struct * ptr_usac_config,WORD32 chn)258*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE iusace_stereo_proc(ia_sfb_params_struct *pstr_sfb_prms,
259*15dc779aSAndroid Build Coastguard Worker WORD32 usac_independancy_flag, ia_usac_data_struct *ptr_usac_data,
260*15dc779aSAndroid Build Coastguard Worker ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn) {
261*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE err_code;
262*15dc779aSAndroid Build Coastguard Worker WORD32 i = 0;
263*15dc779aSAndroid Build Coastguard Worker WORD32 j = 0;
264*15dc779aSAndroid Build Coastguard Worker iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch;
265*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data;
266*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data;
267*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb;
268*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups;
269*15dc779aSAndroid Build Coastguard Worker WORD32 ccfl = ptr_usac_config->ccfl;
270*15dc779aSAndroid Build Coastguard Worker ia_ms_info_struct *pstr_ms_info = &ptr_usac_data->str_ms_info[chn];
271*15dc779aSAndroid Build Coastguard Worker
272*15dc779aSAndroid Build Coastguard Worker FLOAT64 tmp = 0.0f;
273*15dc779aSAndroid Build Coastguard Worker FLOAT32 nrg_mid = 0.0f, nrg_side = 0.0f, nrg_left = 0.0f, nrg_right = 0.0f;
274*15dc779aSAndroid Build Coastguard Worker FLOAT64 *ptr_scratch_spec = pstr_scratch->p_quant_spectrum_spec_scratch;
275*15dc779aSAndroid Build Coastguard Worker FLOAT32 ratio_mid = 0.0f, ratio_side = 0.0f;
276*15dc779aSAndroid Build Coastguard Worker FLOAT32 eps = 1.0e-6f;
277*15dc779aSAndroid Build Coastguard Worker /* Save a copy of left and right channel MDCT spectra before they are modified */
278*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_usac_data->left_chan_save[chn], ptr_usac_data->spectral_line_vector[chn],
279*15dc779aSAndroid Build Coastguard Worker ccfl * sizeof(FLOAT64));
280*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_usac_data->right_chan_save[chn], ptr_usac_data->spectral_line_vector[chn + 1],
281*15dc779aSAndroid Build Coastguard Worker ccfl * sizeof(FLOAT64));
282*15dc779aSAndroid Build Coastguard Worker
283*15dc779aSAndroid Build Coastguard Worker if (ptr_usac_config->cmplx_pred_flag == 1) {
284*15dc779aSAndroid Build Coastguard Worker /* Refinement - decision on whether to use complex prediction or MS */
285*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ccfl; i++) {
286*15dc779aSAndroid Build Coastguard Worker tmp = ptr_usac_data->spectral_line_vector[chn][i];
287*15dc779aSAndroid Build Coastguard Worker ptr_scratch_spec[i] = 0.5f * (ptr_usac_data->spectral_line_vector[chn][i] +
288*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[chn + 1][i]);
289*15dc779aSAndroid Build Coastguard Worker ptr_scratch_spec[ccfl + i] = 0.5f * (tmp - ptr_usac_data->spectral_line_vector[chn + 1][i]);
290*15dc779aSAndroid Build Coastguard Worker }
291*15dc779aSAndroid Build Coastguard Worker
292*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ccfl; i++) {
293*15dc779aSAndroid Build Coastguard Worker nrg_mid += (FLOAT32)(ptr_scratch_spec[i] * ptr_scratch_spec[i]);
294*15dc779aSAndroid Build Coastguard Worker nrg_side += (FLOAT32)(ptr_scratch_spec[ccfl + i] * ptr_scratch_spec[ccfl + i]);
295*15dc779aSAndroid Build Coastguard Worker nrg_left += (FLOAT32)(ptr_usac_data->spectral_line_vector[chn][i] *
296*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[chn][i]);
297*15dc779aSAndroid Build Coastguard Worker nrg_right += (FLOAT32)(ptr_usac_data->spectral_line_vector[chn + 1][i] *
298*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[chn + 1][i]);
299*15dc779aSAndroid Build Coastguard Worker }
300*15dc779aSAndroid Build Coastguard Worker
301*15dc779aSAndroid Build Coastguard Worker ratio_mid = nrg_mid / (MAX(nrg_left, nrg_right) + eps);
302*15dc779aSAndroid Build Coastguard Worker ratio_side = nrg_side / (MAX(nrg_left, nrg_right) + eps);
303*15dc779aSAndroid Build Coastguard Worker
304*15dc779aSAndroid Build Coastguard Worker if (ratio_mid >= 0.8f || ratio_side >= 0.8f || nrg_mid == 0.f || nrg_side == 0.f) {
305*15dc779aSAndroid Build Coastguard Worker pstr_ms_info->ms_mask = 0;
306*15dc779aSAndroid Build Coastguard Worker } else {
307*15dc779aSAndroid Build Coastguard Worker pstr_ms_info->ms_mask = 3;
308*15dc779aSAndroid Build Coastguard Worker }
309*15dc779aSAndroid Build Coastguard Worker }
310*15dc779aSAndroid Build Coastguard Worker
311*15dc779aSAndroid Build Coastguard Worker if (pstr_ms_info->ms_mask != 3) {
312*15dc779aSAndroid Build Coastguard Worker WORD32 idx = 0;
313*15dc779aSAndroid Build Coastguard Worker WORD32 sfb;
314*15dc779aSAndroid Build Coastguard Worker
315*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < ptr_num_sfb[chn]; sfb++) {
316*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pred_coef_re_prev[chn][sfb] = 0;
317*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->pred_coef_im_prev[chn][sfb] = 0;
318*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->temp_pred_coef_re_prev[chn][sfb] = 0;
319*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->temp_pred_coef_im_prev[chn][sfb] = 0;
320*15dc779aSAndroid Build Coastguard Worker }
321*15dc779aSAndroid Build Coastguard Worker
322*15dc779aSAndroid Build Coastguard Worker memset(ptr_usac_data->str_ms_info[chn].ms_used, 0,
323*15dc779aSAndroid Build Coastguard Worker MAX_SFB_LONG * MAX_SHORT_WINDOWS * sizeof(WORD32));
324*15dc779aSAndroid Build Coastguard Worker
325*15dc779aSAndroid Build Coastguard Worker iusace_ms_apply(pstr_psy_data, ptr_usac_data->spectral_line_vector[chn],
326*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[chn + 1],
327*15dc779aSAndroid Build Coastguard Worker &ptr_usac_data->str_ms_info[chn].ms_mask,
328*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_ms_info[chn].ms_used,
329*15dc779aSAndroid Build Coastguard Worker ptr_num_window_groups[chn] * ptr_num_sfb[chn], ptr_num_sfb[chn],
330*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[chn].max_sfb_per_grp, pstr_sfb_prms->grouped_sfb_offset[chn],
331*15dc779aSAndroid Build Coastguard Worker chn, ptr_usac_config->cmplx_pred_flag == 1 ? ptr_scratch_spec : NULL);
332*15dc779aSAndroid Build Coastguard Worker
333*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ptr_num_window_groups[chn]; i++) {
334*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < ptr_num_sfb[chn]; j++) {
335*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[chn].ms_used[idx++] = ptr_usac_data->str_ms_info[chn].ms_used[i][j];
336*15dc779aSAndroid Build Coastguard Worker }
337*15dc779aSAndroid Build Coastguard Worker }
338*15dc779aSAndroid Build Coastguard Worker } else {
339*15dc779aSAndroid Build Coastguard Worker /* Reset buffer to zero */
340*15dc779aSAndroid Build Coastguard Worker for (WORD32 group = 0; group < MAX_SHORT_WINDOWS; group++) {
341*15dc779aSAndroid Build Coastguard Worker memset(ptr_usac_data->cplx_pred_used[chn][group], 0, MAX_SFB_LONG * sizeof(WORD32));
342*15dc779aSAndroid Build Coastguard Worker }
343*15dc779aSAndroid Build Coastguard Worker
344*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->cplx_pred_all[chn] = 1; /* Disable bandwise switching to L/R */
345*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ptr_num_window_groups[chn]; i++) {
346*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < ptr_num_sfb[chn]; j += 2) {
347*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->cplx_pred_used[chn][i][j] = 1;
348*15dc779aSAndroid Build Coastguard Worker if ((j + 1) < ptr_num_sfb[chn]) {
349*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->cplx_pred_used[chn][i][j + 1] = ptr_usac_data->cplx_pred_used[chn][i][j];
350*15dc779aSAndroid Build Coastguard Worker }
351*15dc779aSAndroid Build Coastguard Worker }
352*15dc779aSAndroid Build Coastguard Worker }
353*15dc779aSAndroid Build Coastguard Worker
354*15dc779aSAndroid Build Coastguard Worker err_code = iusace_cplx_pred_proc(
355*15dc779aSAndroid Build Coastguard Worker ptr_usac_data, ptr_usac_config, usac_independancy_flag, pstr_sfb_prms, chn, pstr_psy_data,
356*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[chn], pstr_scratch->p_cmpx_mdct_temp_buf,
357*15dc779aSAndroid Build Coastguard Worker ptr_scratch_spec, nrg_mid, nrg_side);
358*15dc779aSAndroid Build Coastguard Worker if (err_code != IA_NO_ERROR) {
359*15dc779aSAndroid Build Coastguard Worker return err_code;
360*15dc779aSAndroid Build Coastguard Worker }
361*15dc779aSAndroid Build Coastguard Worker }
362*15dc779aSAndroid Build Coastguard Worker return IA_NO_ERROR;
363*15dc779aSAndroid Build Coastguard Worker }
364*15dc779aSAndroid Build Coastguard Worker
iusace_grouping(ia_sfb_params_struct * pstr_sfb_prms,WORD32 num_chans,ia_usac_data_struct * ptr_usac_data,ia_usac_encoder_config_struct * ptr_usac_config,WORD32 chn,WORD32 ele_id)365*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE iusace_grouping(ia_sfb_params_struct *pstr_sfb_prms, WORD32 num_chans,
366*15dc779aSAndroid Build Coastguard Worker ia_usac_data_struct *ptr_usac_data,
367*15dc779aSAndroid Build Coastguard Worker ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn,
368*15dc779aSAndroid Build Coastguard Worker WORD32 ele_id) {
369*15dc779aSAndroid Build Coastguard Worker WORD32 i = 0, grp, sfb, wnd;
370*15dc779aSAndroid Build Coastguard Worker WORD32 j = 0;
371*15dc779aSAndroid Build Coastguard Worker WORD32 k;
372*15dc779aSAndroid Build Coastguard Worker WORD32 ch;
373*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_struct *pstr_psy_config = &ptr_usac_data->str_psy_mod;
374*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data;
375*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_window_sequence = pstr_sfb_prms->window_sequence;
376*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb;
377*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups;
378*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data;
379*15dc779aSAndroid Build Coastguard Worker
380*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
381*15dc779aSAndroid Build Coastguard Worker if (ptr_window_sequence[ch] == EIGHT_SHORT_SEQUENCE) {
382*15dc779aSAndroid Build Coastguard Worker iusace_sort_for_grouping(
383*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch], pstr_sfb_prms->sfb_width_table[ch],
384*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_scratch.p_sort_grouping_scratch,
385*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[ch], ptr_num_window_groups[ch],
386*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->window_group_length[ch], ptr_num_sfb[ch], ptr_usac_config->ccfl);
387*15dc779aSAndroid Build Coastguard Worker } else if ((ptr_window_sequence[ch] == ONLY_LONG_SEQUENCE) ||
388*15dc779aSAndroid Build Coastguard Worker (ptr_window_sequence[ch] == LONG_START_SEQUENCE) ||
389*15dc779aSAndroid Build Coastguard Worker (ptr_window_sequence[ch] == LONG_STOP_SEQUENCE) ||
390*15dc779aSAndroid Build Coastguard Worker (ptr_window_sequence[ch] == STOP_START_SEQUENCE)) {
391*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch][0] = 0;
392*15dc779aSAndroid Build Coastguard Worker k = 0;
393*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ptr_num_sfb[ch]; i++) {
394*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch][i] = k;
395*15dc779aSAndroid Build Coastguard Worker k += pstr_sfb_prms->sfb_width_table[ch][i];
396*15dc779aSAndroid Build Coastguard Worker }
397*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch][i] = k;
398*15dc779aSAndroid Build Coastguard Worker } else {
399*15dc779aSAndroid Build Coastguard Worker return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_WINDOW_TYPE;
400*15dc779aSAndroid Build Coastguard Worker }
401*15dc779aSAndroid Build Coastguard Worker }
402*15dc779aSAndroid Build Coastguard Worker
403*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
404*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_data[ch].window_sequence == 2) {
405*15dc779aSAndroid Build Coastguard Worker i = 0;
406*15dc779aSAndroid Build Coastguard Worker for (grp = 0; grp < ptr_num_window_groups[ch]; grp++) {
407*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) {
408*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_min_snr[i++] =
409*15dc779aSAndroid Build Coastguard Worker pstr_psy_config->str_psy_short_config[ele_id].sfb_min_snr[sfb];
410*15dc779aSAndroid Build Coastguard Worker }
411*15dc779aSAndroid Build Coastguard Worker }
412*15dc779aSAndroid Build Coastguard Worker wnd = 0;
413*15dc779aSAndroid Build Coastguard Worker i = 0;
414*15dc779aSAndroid Build Coastguard Worker for (grp = 0; grp < ptr_num_window_groups[ch]; grp++) {
415*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) {
416*15dc779aSAndroid Build Coastguard Worker FLOAT32 threshold = pstr_psy_data[ch].sfb_thr_short[wnd][sfb];
417*15dc779aSAndroid Build Coastguard Worker FLOAT32 energy = pstr_psy_data[ch].sfb_energy_short[wnd][sfb];
418*15dc779aSAndroid Build Coastguard Worker FLOAT32 energy_ms = pstr_psy_data[ch].ptr_sfb_energy_short_ms[wnd][sfb];
419*15dc779aSAndroid Build Coastguard Worker FLOAT32 spread_energy = pstr_psy_data[ch].sfb_spreaded_energy_short[wnd][sfb];
420*15dc779aSAndroid Build Coastguard Worker for (j = 1; j < pstr_sfb_prms->window_group_length[ch][grp]; j++) {
421*15dc779aSAndroid Build Coastguard Worker threshold = threshold + pstr_psy_data[ch].sfb_thr_short[wnd + j][sfb];
422*15dc779aSAndroid Build Coastguard Worker energy = energy + pstr_psy_data[ch].sfb_energy_short[wnd + j][sfb];
423*15dc779aSAndroid Build Coastguard Worker spread_energy =
424*15dc779aSAndroid Build Coastguard Worker spread_energy + pstr_psy_data[ch].sfb_spreaded_energy_short[wnd + j][sfb];
425*15dc779aSAndroid Build Coastguard Worker energy_ms = energy_ms + pstr_psy_data[ch].ptr_sfb_energy_short_ms[wnd + j][sfb];
426*15dc779aSAndroid Build Coastguard Worker }
427*15dc779aSAndroid Build Coastguard Worker pstr_psy_data[ch].ptr_sfb_thr_long[i] = threshold;
428*15dc779aSAndroid Build Coastguard Worker pstr_psy_data[ch].ptr_sfb_energy_long[i] = energy;
429*15dc779aSAndroid Build Coastguard Worker pstr_psy_data[ch].ptr_sfb_energy_long_ms[i] = energy_ms;
430*15dc779aSAndroid Build Coastguard Worker pstr_psy_data[ch].ptr_sfb_spreaded_energy_long[i++] = spread_energy;
431*15dc779aSAndroid Build Coastguard Worker }
432*15dc779aSAndroid Build Coastguard Worker wnd += pstr_sfb_prms->window_group_length[ch][grp];
433*15dc779aSAndroid Build Coastguard Worker }
434*15dc779aSAndroid Build Coastguard Worker } else {
435*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) {
436*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_min_snr[sfb] =
437*15dc779aSAndroid Build Coastguard Worker pstr_psy_config->str_psy_long_config[ele_id].sfb_min_snr[sfb];
438*15dc779aSAndroid Build Coastguard Worker }
439*15dc779aSAndroid Build Coastguard Worker }
440*15dc779aSAndroid Build Coastguard Worker }
441*15dc779aSAndroid Build Coastguard Worker return IA_NO_ERROR;
442*15dc779aSAndroid Build Coastguard Worker }
443*15dc779aSAndroid Build Coastguard Worker
iusace_quantize_spec(ia_sfb_params_struct * pstr_sfb_prms,WORD32 usac_independancy_flag,WORD32 num_chans,ia_usac_data_struct * ptr_usac_data,ia_usac_encoder_config_struct * ptr_usac_config,WORD32 chn,WORD32 ele_id,WORD32 * is_quant_spec_zero,WORD32 * is_gain_limited)444*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE iusace_quantize_spec(ia_sfb_params_struct *pstr_sfb_prms,
445*15dc779aSAndroid Build Coastguard Worker WORD32 usac_independancy_flag, WORD32 num_chans,
446*15dc779aSAndroid Build Coastguard Worker ia_usac_data_struct *ptr_usac_data,
447*15dc779aSAndroid Build Coastguard Worker ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn,
448*15dc779aSAndroid Build Coastguard Worker WORD32 ele_id, WORD32 *is_quant_spec_zero,
449*15dc779aSAndroid Build Coastguard Worker WORD32 *is_gain_limited) {
450*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE err_code;
451*15dc779aSAndroid Build Coastguard Worker WORD32 i = 0, sfb;
452*15dc779aSAndroid Build Coastguard Worker WORD32 j = 0;
453*15dc779aSAndroid Build Coastguard Worker WORD32 k;
454*15dc779aSAndroid Build Coastguard Worker WORD32 max_bits;
455*15dc779aSAndroid Build Coastguard Worker WORD32 ch;
456*15dc779aSAndroid Build Coastguard Worker iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch;
457*15dc779aSAndroid Build Coastguard Worker WORD32 num_scfs[2];
458*15dc779aSAndroid Build Coastguard Worker FLOAT32 **sfb_form_fac = &pstr_scratch->ptr_sfb_form_fac[0];
459*15dc779aSAndroid Build Coastguard Worker WORD32 max_ch_dyn_bits[2] = {0};
460*15dc779aSAndroid Build Coastguard Worker FLOAT32 ch_bit_dist[2];
461*15dc779aSAndroid Build Coastguard Worker WORD32 constraints_fulfilled;
462*15dc779aSAndroid Build Coastguard Worker WORD32 iterations = 0;
463*15dc779aSAndroid Build Coastguard Worker WORD32 max_val;
464*15dc779aSAndroid Build Coastguard Worker WORD32 kk, idx = 0;
465*15dc779aSAndroid Build Coastguard Worker
466*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_exp_spec = pstr_scratch->p_exp_spec;
467*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_mdct_spec_float = pstr_scratch->p_mdct_spec_float;
468*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data;
469*15dc779aSAndroid Build Coastguard Worker ia_qc_out_data_struct *pstr_qc_out = &ptr_usac_data->str_qc_main.str_qc_out;
470*15dc779aSAndroid Build Coastguard Worker ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data;
471*15dc779aSAndroid Build Coastguard Worker ia_qc_data_struct *pstr_qc_data = &ptr_usac_data->str_qc_main.str_qc_data[ele_id];
472*15dc779aSAndroid Build Coastguard Worker ia_adj_thr_elem_struct *pstr_adj_thr_elem = &pstr_qc_data->str_adj_thr_ele;
473*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_window_sequence = pstr_sfb_prms->window_sequence;
474*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_max_sfb = pstr_sfb_prms->max_sfb;
475*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb;
476*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups;
477*15dc779aSAndroid Build Coastguard Worker WORD32 bitres_bits, bitres_diff;
478*15dc779aSAndroid Build Coastguard Worker WORD32 gain;
479*15dc779aSAndroid Build Coastguard Worker
480*15dc779aSAndroid Build Coastguard Worker memset(num_scfs, 0, 2 * sizeof(num_scfs[0]));
481*15dc779aSAndroid Build Coastguard Worker
482*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
483*15dc779aSAndroid Build Coastguard Worker num_scfs[idx] = ptr_num_sfb[ch] * ptr_num_window_groups[ch];
484*15dc779aSAndroid Build Coastguard Worker
485*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_count = num_scfs[idx];
486*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_per_group = num_scfs[idx] / ptr_num_window_groups[ch];
487*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].window_sequence = pstr_psy_data[ch].window_sequence;
488*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].window_shape = iusace_window_shape[pstr_psy_data[ch].window_sequence];
489*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].ptr_spec_coeffs = ptr_usac_data->spectral_line_vector[ch];
490*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].ptr_sfb_energy = pstr_psy_data[ch].ptr_sfb_energy_long;
491*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].ptr_sfb_thr = pstr_psy_data[ch].ptr_sfb_thr_long;
492*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].ptr_sfb_spread_energy = pstr_psy_data[ch].ptr_sfb_spreaded_energy_long;
493*15dc779aSAndroid Build Coastguard Worker
494*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < num_scfs[idx]; j++) {
495*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_offsets[j] = pstr_sfb_prms->grouped_sfb_offset[ch][j];
496*15dc779aSAndroid Build Coastguard Worker }
497*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_offsets[num_scfs[idx]] =
498*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch][num_scfs[idx]];
499*15dc779aSAndroid Build Coastguard Worker
500*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < MAX_NUM_GROUPED_SFB; j++) {
501*15dc779aSAndroid Build Coastguard Worker sfb_form_fac[idx][j] = MIN_FLT_VAL;
502*15dc779aSAndroid Build Coastguard Worker }
503*15dc779aSAndroid Build Coastguard Worker
504*15dc779aSAndroid Build Coastguard Worker iusace_calc_form_fac_per_chan(&pstr_psy_out[ch], pstr_scratch, idx);
505*15dc779aSAndroid Build Coastguard Worker idx++;
506*15dc779aSAndroid Build Coastguard Worker }
507*15dc779aSAndroid Build Coastguard Worker
508*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->static_bits =
509*15dc779aSAndroid Build Coastguard Worker iusace_count_static_bits(ptr_usac_data, ptr_usac_config, pstr_sfb_prms, pstr_psy_out,
510*15dc779aSAndroid Build Coastguard Worker num_chans, chn, usac_independancy_flag, ele_id);
511*15dc779aSAndroid Build Coastguard Worker
512*15dc779aSAndroid Build Coastguard Worker iusace_adj_bitrate(pstr_qc_data, pstr_qc_data->ch_bitrate, ptr_usac_config->core_sample_rate,
513*15dc779aSAndroid Build Coastguard Worker ptr_usac_config->ccfl);
514*15dc779aSAndroid Build Coastguard Worker err_code =
515*15dc779aSAndroid Build Coastguard Worker iusace_adj_thr(pstr_adj_thr_elem, pstr_psy_out, ch_bit_dist, pstr_qc_out,
516*15dc779aSAndroid Build Coastguard Worker pstr_qc_data->avg_bits - pstr_qc_out->static_bits, pstr_qc_data->bit_res_lvl,
517*15dc779aSAndroid Build Coastguard Worker pstr_qc_data->max_bitres_bits, pstr_qc_out->static_bits,
518*15dc779aSAndroid Build Coastguard Worker &pstr_qc_data->max_bit_fac, num_chans, chn, pstr_scratch);
519*15dc779aSAndroid Build Coastguard Worker if (err_code != IA_NO_ERROR) {
520*15dc779aSAndroid Build Coastguard Worker return err_code;
521*15dc779aSAndroid Build Coastguard Worker }
522*15dc779aSAndroid Build Coastguard Worker
523*15dc779aSAndroid Build Coastguard Worker iusace_estimate_scfs_chan(pstr_psy_out, pstr_qc_out->str_qc_out_chan, num_chans, chn,
524*15dc779aSAndroid Build Coastguard Worker pstr_scratch);
525*15dc779aSAndroid Build Coastguard Worker idx = 0;
526*15dc779aSAndroid Build Coastguard Worker for (ch = 0; ch < num_chans; ch++) {
527*15dc779aSAndroid Build Coastguard Worker max_ch_dyn_bits[ch] = (WORD32)floor(
528*15dc779aSAndroid Build Coastguard Worker ch_bit_dist[ch] * (FLOAT32)(pstr_qc_data->avg_bits + pstr_qc_data->bit_res_lvl - 7 -
529*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->static_bits));
530*15dc779aSAndroid Build Coastguard Worker idx++;
531*15dc779aSAndroid Build Coastguard Worker }
532*15dc779aSAndroid Build Coastguard Worker
533*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->dyn_bits = 0;
534*15dc779aSAndroid Build Coastguard Worker idx = 0;
535*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
536*15dc779aSAndroid Build Coastguard Worker iterations = 0;
537*15dc779aSAndroid Build Coastguard Worker gain = 0;
538*15dc779aSAndroid Build Coastguard Worker for (kk = 0; kk < ptr_usac_config->ccfl; kk++) {
539*15dc779aSAndroid Build Coastguard Worker ptr_exp_spec[kk] = (FLOAT32)pstr_psy_out[ch].ptr_spec_coeffs[kk];
540*15dc779aSAndroid Build Coastguard Worker ptr_mdct_spec_float[kk] = (FLOAT32)pstr_psy_out[ch].ptr_spec_coeffs[kk];
541*15dc779aSAndroid Build Coastguard Worker }
542*15dc779aSAndroid Build Coastguard Worker do {
543*15dc779aSAndroid Build Coastguard Worker constraints_fulfilled = 1;
544*15dc779aSAndroid Build Coastguard Worker WORD32 quant_spec_is_zero = 1;
545*15dc779aSAndroid Build Coastguard Worker if (iterations > 0) {
546*15dc779aSAndroid Build Coastguard Worker for (WORD32 sfb_offs = 0; sfb_offs < pstr_psy_out[ch].sfb_count;
547*15dc779aSAndroid Build Coastguard Worker sfb_offs += pstr_psy_out[ch].sfb_per_group) {
548*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_out[ch].max_sfb_per_grp; sfb++) {
549*15dc779aSAndroid Build Coastguard Worker WORD32 scalefactor = pstr_qc_out->str_qc_out_chan[idx].scalefactor[sfb + sfb_offs];
550*15dc779aSAndroid Build Coastguard Worker gain = MAX(gain, pstr_qc_out->str_qc_out_chan[idx].global_gain - scalefactor);
551*15dc779aSAndroid Build Coastguard Worker iusace_quantize_lines(
552*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->str_qc_out_chan[idx].global_gain - scalefactor,
553*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb + 1] -
554*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb],
555*15dc779aSAndroid Build Coastguard Worker ptr_exp_spec + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb],
556*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->str_qc_out_chan[idx].quant_spec +
557*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb],
558*15dc779aSAndroid Build Coastguard Worker ptr_mdct_spec_float + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb]);
559*15dc779aSAndroid Build Coastguard Worker }
560*15dc779aSAndroid Build Coastguard Worker }
561*15dc779aSAndroid Build Coastguard Worker }
562*15dc779aSAndroid Build Coastguard Worker max_val =
563*15dc779aSAndroid Build Coastguard Worker iusace_calc_max_val_in_sfb(pstr_psy_out[ch].sfb_count, pstr_psy_out[ch].max_sfb_per_grp,
564*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch].sfb_per_group, pstr_psy_out[ch].sfb_offsets,
565*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->str_qc_out_chan[idx].quant_spec);
566*15dc779aSAndroid Build Coastguard Worker if (max_val > MAX_QUANT) {
567*15dc779aSAndroid Build Coastguard Worker constraints_fulfilled = 0;
568*15dc779aSAndroid Build Coastguard Worker }
569*15dc779aSAndroid Build Coastguard Worker
570*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < num_scfs[idx]; k++) {
571*15dc779aSAndroid Build Coastguard Worker for (i = pstr_sfb_prms->grouped_sfb_offset[ch][k];
572*15dc779aSAndroid Build Coastguard Worker i < pstr_sfb_prms->grouped_sfb_offset[ch][k + 1]; i++) {
573*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_quant_info[idx].quant_degroup[i] =
574*15dc779aSAndroid Build Coastguard Worker (WORD32)pstr_qc_out->str_qc_out_chan[idx].quant_spec[i];
575*15dc779aSAndroid Build Coastguard Worker if (ptr_usac_data->str_quant_info[idx].quant_degroup[i] != 0) {
576*15dc779aSAndroid Build Coastguard Worker quant_spec_is_zero = 0;
577*15dc779aSAndroid Build Coastguard Worker }
578*15dc779aSAndroid Build Coastguard Worker }
579*15dc779aSAndroid Build Coastguard Worker }
580*15dc779aSAndroid Build Coastguard Worker
581*15dc779aSAndroid Build Coastguard Worker if (ptr_window_sequence[ch] == EIGHT_SHORT_SEQUENCE) {
582*15dc779aSAndroid Build Coastguard Worker iusace_degroup_int(pstr_sfb_prms->grouped_sfb_offset[ch], ptr_num_sfb[ch],
583*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_scratch.p_degroup_scratch,
584*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_quant_info[idx].quant_degroup,
585*15dc779aSAndroid Build Coastguard Worker ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch],
586*15dc779aSAndroid Build Coastguard Worker ptr_usac_config->ccfl);
587*15dc779aSAndroid Build Coastguard Worker }
588*15dc779aSAndroid Build Coastguard Worker
589*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_quant_info[idx].max_spec_coeffs = 0;
590*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < ptr_max_sfb[ch]; k++) {
591*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_quant_info[idx].max_spec_coeffs +=
592*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->sfb_width_table[ch][k];
593*15dc779aSAndroid Build Coastguard Worker }
594*15dc779aSAndroid Build Coastguard Worker
595*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_scfs[idx]; i++) {
596*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_quant_info[idx].scale_factor[i] =
597*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->str_qc_out_chan[idx].global_gain -
598*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->str_qc_out_chan[idx].scalefactor[i] + SF_OFFSET;
599*15dc779aSAndroid Build Coastguard Worker }
600*15dc779aSAndroid Build Coastguard Worker
601*15dc779aSAndroid Build Coastguard Worker max_bits = iusace_count_fd_bits(pstr_sfb_prms, ptr_usac_data, usac_independancy_flag,
602*15dc779aSAndroid Build Coastguard Worker ptr_usac_config, ch, idx);
603*15dc779aSAndroid Build Coastguard Worker
604*15dc779aSAndroid Build Coastguard Worker if (max_bits > max_ch_dyn_bits[idx]) {
605*15dc779aSAndroid Build Coastguard Worker constraints_fulfilled = 0;
606*15dc779aSAndroid Build Coastguard Worker }
607*15dc779aSAndroid Build Coastguard Worker if (quant_spec_is_zero == 1) {
608*15dc779aSAndroid Build Coastguard Worker constraints_fulfilled = 1;
609*15dc779aSAndroid Build Coastguard Worker /*Bit consuption is exceding bit reservoir, there is no scope left for bit consumption
610*15dc779aSAndroid Build Coastguard Worker reduction, as spectrum is zero. Hence breaking the quantization loop. */
611*15dc779aSAndroid Build Coastguard Worker if (iterations > 0) {
612*15dc779aSAndroid Build Coastguard Worker *is_quant_spec_zero = 1;
613*15dc779aSAndroid Build Coastguard Worker max_bits = max_ch_dyn_bits[idx];
614*15dc779aSAndroid Build Coastguard Worker }
615*15dc779aSAndroid Build Coastguard Worker }
616*15dc779aSAndroid Build Coastguard Worker if ((gain == MAX_GAIN_INDEX) && (constraints_fulfilled == 0)) {
617*15dc779aSAndroid Build Coastguard Worker /* Bit consuption is exceding bit reservoir, there is no scope left for bit consumption
618*15dc779aSAndroid Build Coastguard Worker reduction, as gain has reached the maximum value. Hence breaking the quantization
619*15dc779aSAndroid Build Coastguard Worker loop. */
620*15dc779aSAndroid Build Coastguard Worker constraints_fulfilled = 1;
621*15dc779aSAndroid Build Coastguard Worker *is_gain_limited = 1;
622*15dc779aSAndroid Build Coastguard Worker max_bits = max_ch_dyn_bits[idx];
623*15dc779aSAndroid Build Coastguard Worker }
624*15dc779aSAndroid Build Coastguard Worker if (!constraints_fulfilled) {
625*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->str_qc_out_chan[idx].global_gain++;
626*15dc779aSAndroid Build Coastguard Worker }
627*15dc779aSAndroid Build Coastguard Worker iterations++;
628*15dc779aSAndroid Build Coastguard Worker } while (!constraints_fulfilled);
629*15dc779aSAndroid Build Coastguard Worker
630*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->dyn_bits += max_bits;
631*15dc779aSAndroid Build Coastguard Worker
632*15dc779aSAndroid Build Coastguard Worker if (ptr_usac_data->noise_filling[ele_id]) {
633*15dc779aSAndroid Build Coastguard Worker WORD32 max_nf_sfb = ptr_max_sfb[ch];
634*15dc779aSAndroid Build Coastguard Worker
635*15dc779aSAndroid Build Coastguard Worker if (ptr_window_sequence[ch] != EIGHT_SHORT_SEQUENCE) {
636*15dc779aSAndroid Build Coastguard Worker iusace_noise_filling(
637*15dc779aSAndroid Build Coastguard Worker &ptr_usac_data->noise_level[idx], &ptr_usac_data->noise_offset[idx],
638*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[ch], &ptr_usac_data->str_quant_info[idx],
639*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch], max_nf_sfb, ptr_usac_config->ccfl,
640*15dc779aSAndroid Build Coastguard Worker ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], 160,
641*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->str_scratch.p_noise_filling_highest_tone);
642*15dc779aSAndroid Build Coastguard Worker } else {
643*15dc779aSAndroid Build Coastguard Worker iusace_noise_filling(
644*15dc779aSAndroid Build Coastguard Worker &ptr_usac_data->noise_level[idx], &ptr_usac_data->noise_offset[idx],
645*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->spectral_line_vector[ch], &ptr_usac_data->str_quant_info[idx],
646*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->grouped_sfb_offset[ch], max_nf_sfb, ptr_usac_config->ccfl >> 3,
647*15dc779aSAndroid Build Coastguard Worker ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], 20,
648*15dc779aSAndroid Build Coastguard Worker (FLOAT64 *)ptr_usac_data->str_scratch.p_noise_filling_highest_tone);
649*15dc779aSAndroid Build Coastguard Worker }
650*15dc779aSAndroid Build Coastguard Worker
651*15dc779aSAndroid Build Coastguard Worker if (ptr_usac_data->noise_level[idx] == 0 && ptr_usac_data->noise_offset[idx] != 0 &&
652*15dc779aSAndroid Build Coastguard Worker pstr_sfb_prms->common_win[ch]) {
653*15dc779aSAndroid Build Coastguard Worker ptr_usac_data->complex_coef[ch] = 0;
654*15dc779aSAndroid Build Coastguard Worker }
655*15dc779aSAndroid Build Coastguard Worker }
656*15dc779aSAndroid Build Coastguard Worker idx++;
657*15dc779aSAndroid Build Coastguard Worker }
658*15dc779aSAndroid Build Coastguard Worker
659*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_elem->dyn_bits_last = pstr_qc_out->dyn_bits;
660*15dc779aSAndroid Build Coastguard Worker
661*15dc779aSAndroid Build Coastguard Worker bitres_bits = pstr_qc_data->max_bitres_bits - pstr_qc_data->bit_res_lvl;
662*15dc779aSAndroid Build Coastguard Worker bitres_diff = pstr_qc_data->avg_bits - (pstr_qc_out->static_bits + pstr_qc_out->dyn_bits);
663*15dc779aSAndroid Build Coastguard Worker pstr_qc_out->fill_bits = MAX(0, (bitres_diff - bitres_bits));
664*15dc779aSAndroid Build Coastguard Worker
665*15dc779aSAndroid Build Coastguard Worker if (pstr_qc_data->avg_bits > 0) {
666*15dc779aSAndroid Build Coastguard Worker pstr_qc_data->bit_res_lvl +=
667*15dc779aSAndroid Build Coastguard Worker pstr_qc_data->avg_bits -
668*15dc779aSAndroid Build Coastguard Worker (pstr_qc_out->static_bits + pstr_qc_out->dyn_bits + pstr_qc_out->fill_bits);
669*15dc779aSAndroid Build Coastguard Worker } else {
670*15dc779aSAndroid Build Coastguard Worker pstr_qc_data->bit_res_lvl = pstr_qc_data->max_bits;
671*15dc779aSAndroid Build Coastguard Worker }
672*15dc779aSAndroid Build Coastguard Worker
673*15dc779aSAndroid Build Coastguard Worker if (pstr_qc_data->bit_res_lvl < 0 ||
674*15dc779aSAndroid Build Coastguard Worker pstr_qc_data->bit_res_lvl > pstr_qc_data->max_bitres_bits) {
675*15dc779aSAndroid Build Coastguard Worker return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_BIT_RSVR_LVL;
676*15dc779aSAndroid Build Coastguard Worker }
677*15dc779aSAndroid Build Coastguard Worker
678*15dc779aSAndroid Build Coastguard Worker return IA_NO_ERROR;
679*15dc779aSAndroid Build Coastguard Worker }
680