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