/src/libxaac/decoder/ixheaacd_mps_res_channel.c
Line | Count | Source |
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 | | #include <string.h> |
21 | | #include "ixheaac_type_def.h" |
22 | | #include "ixheaac_constants.h" |
23 | | #include "ixheaacd_cnst.h" |
24 | | #include "ixheaac_basic_ops32.h" |
25 | | #include "ixheaac_basic_ops16.h" |
26 | | #include "ixheaac_basic_ops40.h" |
27 | | #include "ixheaac_basic_ops.h" |
28 | | #include "ixheaacd_bitbuffer.h" |
29 | | #include "ixheaacd_mps_aac_struct.h" |
30 | | #include "ixheaacd_mps_res_rom.h" |
31 | | #include "ixheaacd_mps_res_pulsedata.h" |
32 | | #include "ixheaacd_mps_res_channelinfo.h" |
33 | | #include "ixheaacd_mps_res_block.h" |
34 | | #include "ixheaacd_defines.h" |
35 | | #include "ixheaacd_mps_res_channel.h" |
36 | | #include "ixheaac_basic_op.h" |
37 | | #include "ixheaacd_mps_res_tns.h" |
38 | | #include "ixheaacd_mps_res.h" |
39 | | #include "ixheaacd_mps_res_huffman.h" |
40 | | |
41 | 2.11k | UWORD32 ixheaacd_res_aac_showbits_32(UWORD8 *p_read_next) { |
42 | 2.11k | UWORD8 *v = p_read_next; |
43 | 2.11k | UWORD32 b = 0; |
44 | | |
45 | 2.11k | _SWAP(v, b); |
46 | 2.11k | return b; |
47 | 2.11k | } |
48 | | |
49 | | static WORD16 ixheaacd_res_c_block_read( |
50 | | ia_bit_buf_struct *it_bit_buf, |
51 | | ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info, WORD16 global_gain, |
52 | | ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) |
53 | | |
54 | 1.08k | { |
55 | 1.08k | FLAG gain_control_data_present; |
56 | 1.08k | WORD16 error_status = AAC_DEC_OK; |
57 | | |
58 | 1.08k | if (p_aac_decoder_channel_info->ics_info.window_sequence == EIGHT_SHORT_SEQUENCE) { |
59 | 321 | memset(p_aac_decoder_channel_info->p_scale_factor, 0, MAX_WINDOWS * MAX_SFB_SHORT * 3); |
60 | 321 | } |
61 | | |
62 | 1.08k | error_status = ixheaacd_c_block_read_section_data(it_bit_buf, p_aac_decoder_channel_info); |
63 | | |
64 | 1.08k | if (error_status) return error_status; |
65 | | |
66 | 1.05k | ixheaacd_res_c_block_read_scf_data(it_bit_buf, p_aac_decoder_channel_info, global_gain, |
67 | 1.05k | aac_tables_ptr); |
68 | | |
69 | 1.05k | error_status = ixheaacd_res_c_pulse_data_read( |
70 | 1.05k | it_bit_buf, &p_aac_decoder_channel_info->pulse_data, aac_tables_ptr); |
71 | 1.05k | if (error_status) return error_status; |
72 | | |
73 | 1.05k | p_aac_decoder_channel_info->tns_data.tns_data_present = |
74 | 1.05k | (FLAG)ixheaacd_read_bits_buf(it_bit_buf, 1); |
75 | | |
76 | 1.05k | error_status = ixheaacd_res_c_tns_read(it_bit_buf, p_aac_decoder_channel_info); |
77 | 1.05k | if (error_status) { |
78 | 5 | return error_status; |
79 | 5 | } |
80 | | |
81 | 1.04k | gain_control_data_present = ixheaacd_read_bits_buf(it_bit_buf, 1); |
82 | | |
83 | 1.04k | if (gain_control_data_present) { |
84 | 5 | return (WORD16)((WORD32)AAC_DEC_UNIMPLEMENTED_GAIN_CONTROL_DATA); |
85 | 5 | } |
86 | | |
87 | 1.04k | { |
88 | 1.04k | it_bit_buf->bit_pos = (7 - it_bit_buf->bit_pos); |
89 | | |
90 | 1.04k | error_status = ixheaacd_res_c_block_read_spec_data(it_bit_buf, p_aac_decoder_channel_info, |
91 | 1.04k | aac_tables_ptr); |
92 | | |
93 | 1.04k | it_bit_buf->bit_pos = (7 - it_bit_buf->bit_pos); |
94 | 1.04k | } |
95 | | |
96 | 1.04k | return error_status; |
97 | 1.04k | } |
98 | | |
99 | | WORD16 ixheaacd_res_read_ics( |
100 | | ia_bit_buf_struct *it_bit_buf, |
101 | | ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info[CHANNELS], WORD32 num_ch, |
102 | 1.15k | ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD8 tot_sf_bands_ls[2]) { |
103 | 1.15k | WORD16 error_status = AAC_DEC_OK; |
104 | 1.15k | WORD32 ch; |
105 | | |
106 | 2.20k | for (ch = 0; ch < num_ch; ch++) { |
107 | 1.15k | ia_mps_dec_residual_channel_info_struct *p_aac_dec_ch_info = p_aac_decoder_channel_info[ch]; |
108 | 1.15k | ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_dec_ch_info->ics_info; |
109 | | |
110 | 1.15k | p_aac_dec_ch_info->global_gain = (WORD16)ixheaacd_read_bits_buf(it_bit_buf, 8); |
111 | | |
112 | 1.15k | if (!p_aac_decoder_channel_info[LEFT]->common_window) { |
113 | 1.12k | error_status = ixheaacd_res_ics_read(it_bit_buf, p_ics_info, tot_sf_bands_ls); |
114 | 1.12k | if (error_status) { |
115 | 18 | if (it_bit_buf->cnt_bits < 0) |
116 | 0 | error_status = (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES); |
117 | 18 | return error_status; |
118 | 18 | } |
119 | 1.12k | } |
120 | | |
121 | 1.13k | error_status = ixheaacd_res_c_block_read(it_bit_buf, p_aac_dec_ch_info, |
122 | 1.13k | p_aac_dec_ch_info->global_gain, aac_tables_ptr); |
123 | 1.13k | if (error_status) { |
124 | 77 | if (it_bit_buf->cnt_bits < 0) |
125 | 1 | error_status = (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES); |
126 | | |
127 | 77 | return error_status; |
128 | 77 | } |
129 | 1.13k | } |
130 | | |
131 | 1.05k | return error_status; |
132 | 1.15k | } |
133 | | |
134 | | VOID ixheaacd_res_c_pulse_data_apply(ia_mps_dec_residual_pulse_data_struct *pulse_data, |
135 | | WORD8 *p_pulse_arr, |
136 | 741 | const WORD16 *p_scale_factor_band_offsets) { |
137 | 741 | WORD i, number_pulse; |
138 | 741 | WORD32 k; |
139 | | |
140 | 741 | memset(p_pulse_arr, 0, sizeof(WORD32) * 256); |
141 | | |
142 | 741 | if (pulse_data->pulse_data_present) { |
143 | 65 | k = p_scale_factor_band_offsets[pulse_data->pulse_start_band]; |
144 | 65 | number_pulse = pulse_data->number_pulse; |
145 | | |
146 | 176 | for (i = 0; i <= number_pulse; i++) { |
147 | 111 | k = add_d(k, pulse_data->pulse_offset[i]); |
148 | 111 | p_pulse_arr[k] = pulse_data->pulse_amp[i]; |
149 | 111 | } |
150 | 65 | } |
151 | 741 | } |
152 | | |
153 | | WORD16 ixheaacd_res_c_block_read_spec_data( |
154 | | ia_bit_buf_struct *it_bit_buf, |
155 | | ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info, |
156 | 1.03k | ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) { |
157 | 1.03k | WORD band, tot_bands, tot_groups = 0; |
158 | 1.03k | WORD group, groupwin, groupoffset; |
159 | | |
160 | 1.03k | WORD index; |
161 | 1.03k | WORD8 *p_code_book, *p_codebook_tmp; |
162 | 1.03k | WORD16 *p_scale_factor; |
163 | 1.03k | WORD32 *p_spectral_coefficient; |
164 | 1.03k | ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_decoder_channel_info->ics_info; |
165 | 1.03k | WORD16 *band_offsets; |
166 | 1.03k | WORD32 maximum_bins_short = ixheaac_shr16_dir_sat(p_ics_info->frame_length, 3); |
167 | | |
168 | 1.03k | WORD32 *p_spec_coeff_out; |
169 | | |
170 | 1.03k | p_code_book = p_aac_decoder_channel_info->p_code_book; |
171 | 1.03k | p_scale_factor = p_aac_decoder_channel_info->p_scale_factor; |
172 | 1.03k | p_spectral_coefficient = p_aac_decoder_channel_info->p_spectral_coefficient; |
173 | 1.03k | tot_groups = p_ics_info->window_groups; |
174 | 1.03k | tot_bands = p_ics_info->max_sf_bands; |
175 | 1.03k | band_offsets = (WORD16 *)ixheaacd_res_get_sfb_offsets(p_ics_info, aac_tables_ptr); |
176 | | |
177 | 1.03k | if (p_aac_decoder_channel_info->ics_info.window_sequence != EIGHT_SHORT_SEQUENCE) { |
178 | 741 | WORD8 *p_pul_arr = (WORD8 *)p_aac_decoder_channel_info->p_tns_scratch; |
179 | 741 | ixheaacd_res_c_pulse_data_apply(&p_aac_decoder_channel_info->pulse_data, p_pul_arr, |
180 | 741 | band_offsets); |
181 | | |
182 | 741 | p_spec_coeff_out = &p_spectral_coefficient[0]; |
183 | 1.47k | for (band = 0; band < tot_bands;) { |
184 | 757 | WORD ret_val; |
185 | 757 | WORD32 len; |
186 | 757 | WORD32 code_no = p_code_book[band]; |
187 | 757 | WORD start = band; |
188 | | |
189 | 6.78k | for (; band < tot_bands && (p_code_book[band] == code_no); band++) |
190 | 6.02k | ; |
191 | | |
192 | 757 | len = band_offsets[band] - band_offsets[start]; |
193 | | |
194 | 757 | if (code_no > ZERO_HCB && (code_no < NOISE_HCB)) { |
195 | 584 | ret_val = ixheaacd_res_c_block_decode_huff_word_all_lb( |
196 | 584 | it_bit_buf, code_no, len, aac_tables_ptr, p_spec_coeff_out, p_pul_arr); |
197 | | |
198 | 584 | if (ret_val != 0) |
199 | 19 | return (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_EXCEEDS_MAX_HUFFDEC_VAL); |
200 | 584 | } else { |
201 | 173 | if (p_aac_decoder_channel_info->pulse_data.pulse_data_present) |
202 | 55 | ixheaacd_res_inverse_quant_lb( |
203 | 55 | p_spec_coeff_out, len, |
204 | 55 | (WORD32 *)aac_tables_ptr->res_block_tables_ptr->pow_table_q17, p_pul_arr); |
205 | 118 | else |
206 | 118 | memset(p_spec_coeff_out, 0, sizeof(WORD32) * len); |
207 | 173 | } |
208 | 738 | p_pul_arr += len; |
209 | 738 | p_spec_coeff_out += len; |
210 | 738 | } |
211 | | |
212 | 722 | index = 1024 - band_offsets[tot_bands]; |
213 | 722 | memset(p_spec_coeff_out, 0, sizeof(WORD32) * index); |
214 | 722 | } else { |
215 | 296 | memset(p_spectral_coefficient, 0, sizeof(WORD32) * 1024); |
216 | | |
217 | 296 | groupoffset = 0; |
218 | | |
219 | 991 | for (group = 0; group < tot_groups; group++) { |
220 | 712 | WORD grp_win = p_ics_info->window_group_length[group]; |
221 | 712 | p_codebook_tmp = &p_code_book[group * MAX_SFB_SHORT]; |
222 | 712 | p_spec_coeff_out = &p_spectral_coefficient[groupoffset * maximum_bins_short]; |
223 | | |
224 | 1.55k | for (band = 0; band < tot_bands;) { |
225 | 856 | WORD code_no = *p_codebook_tmp; |
226 | 856 | WORD start = band; |
227 | 856 | WORD ret_val; |
228 | | |
229 | 4.06k | for (; band < tot_bands && (*p_codebook_tmp == code_no); band++, p_codebook_tmp++) |
230 | 3.21k | ; |
231 | | |
232 | 856 | if (code_no > ZERO_HCB && (code_no < NOISE_HCB)) { |
233 | 569 | ret_val = ixheaacd_res_c_block_decode_huff_word_all( |
234 | 569 | it_bit_buf, code_no, p_spec_coeff_out, (WORD16 *)band_offsets, start, band, grp_win, |
235 | 569 | aac_tables_ptr, maximum_bins_short); |
236 | | |
237 | 569 | if (ret_val != 0) |
238 | 17 | return (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_EXCEEDS_MAX_HUFFDEC_VAL); |
239 | 569 | } |
240 | 856 | } |
241 | 695 | groupoffset = (groupoffset + grp_win); |
242 | 695 | } |
243 | 296 | } |
244 | | |
245 | 1.00k | { |
246 | 1.00k | WORD8 *p_win_grp_len = &p_ics_info->window_group_length[0]; |
247 | 1.00k | WORD8 *psfb_width = (WORD8 *)ixheaacd_res_get_sfb_width(p_ics_info, aac_tables_ptr); |
248 | 1.00k | WORD32 *scale_table_ptr; |
249 | 1.00k | if (120 == maximum_bins_short) { |
250 | 0 | scale_table_ptr = aac_tables_ptr->res_block_tables_ptr->scale_table_960; |
251 | 1.00k | } else { |
252 | 1.00k | scale_table_ptr = aac_tables_ptr->res_block_tables_ptr->scale_table; |
253 | 1.00k | } |
254 | 1.41k | do { |
255 | 1.41k | groupwin = *p_win_grp_len++; |
256 | 2.95k | do { |
257 | 2.95k | ixheaacd_res_apply_scfs(&p_spectral_coefficient[0], &p_scale_factor[0], tot_bands, |
258 | 2.95k | (WORD8 *)psfb_width, scale_table_ptr); |
259 | | |
260 | 2.95k | p_spectral_coefficient += maximum_bins_short; |
261 | 2.95k | groupwin--; |
262 | 2.95k | } while (groupwin != 0); |
263 | | |
264 | 1.41k | p_scale_factor += MAX_SFB_SHORT; |
265 | 1.41k | tot_groups--; |
266 | 1.41k | } while (tot_groups != 0); |
267 | 1.00k | } |
268 | | |
269 | 1.00k | return AAC_DEC_OK; |
270 | 1.03k | } |
271 | | |
272 | | WORD16 |
273 | | ixheaacd_res_c_tns_read(ia_bit_buf_struct *it_bit_buf, |
274 | 1.04k | ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info) { |
275 | 1.04k | WORD window, window_per_frame; |
276 | 1.04k | WORD n_filt_bits, len_bits, order_bits; |
277 | 1.04k | WORD32 next_stop_band_tmp; |
278 | | |
279 | 1.04k | ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_decoder_channel_info->ics_info; |
280 | 1.04k | ia_mps_dec_residual_tns_data *p_tns_data = &p_aac_decoder_channel_info->tns_data; |
281 | | |
282 | 1.04k | if (!p_tns_data->tns_data_present) return AAC_DEC_OK; |
283 | | |
284 | 204 | if (p_ics_info->window_sequence != EIGHT_SHORT_SEQUENCE) { |
285 | 93 | n_filt_bits = 2; |
286 | 93 | len_bits = 6; |
287 | 93 | order_bits = 5; |
288 | 93 | window_per_frame = 1; |
289 | 111 | } else { |
290 | 111 | n_filt_bits = 1; |
291 | 111 | len_bits = 4; |
292 | 111 | order_bits = 3; |
293 | 111 | window_per_frame = 8; |
294 | 111 | } |
295 | | |
296 | 204 | next_stop_band_tmp = p_ics_info->total_sf_bands; |
297 | | |
298 | 1.16k | for (window = 0; window < window_per_frame; window++) { |
299 | 963 | WORD n_filt; |
300 | 963 | WORD length, coef_res; |
301 | 963 | p_tns_data->number_of_filters[window] = n_filt = |
302 | 963 | (WORD16)ixheaacd_read_bits_buf(it_bit_buf, n_filt_bits); |
303 | | |
304 | 963 | if (n_filt) { |
305 | 463 | WORD32 accu; |
306 | 463 | WORD index; |
307 | 463 | WORD nextstopband; |
308 | | |
309 | 463 | coef_res = ixheaacd_read_bits_buf(it_bit_buf, 1); |
310 | | |
311 | 463 | nextstopband = next_stop_band_tmp; |
312 | 944 | for (index = 0; index < n_filt; index++) { |
313 | 486 | WORD order; |
314 | 486 | ia_mps_dec_residual_filter_struct *filter = &p_tns_data->filter[window][index]; |
315 | 486 | length = ixheaacd_read_bits_buf(it_bit_buf, len_bits); |
316 | | |
317 | 486 | filter->start_band = nextstopband - length; |
318 | 486 | filter->stop_band = nextstopband; |
319 | | |
320 | 486 | nextstopband = filter->start_band; |
321 | | |
322 | 486 | if (filter->start_band < 0) { |
323 | 3 | filter->order = -1; |
324 | 3 | return (WORD16)((WORD32)AAC_DEC_TNS_RANGE_ERROR); |
325 | 3 | } |
326 | | |
327 | 483 | filter->order = order = ixheaacd_read_bits_buf(it_bit_buf, order_bits); |
328 | 483 | accu = order - MAX_ORDER_LONG; |
329 | | |
330 | 483 | if (accu > 0) return (WORD16)((WORD32)AAC_DEC_TNS_ORDER_ERROR); |
331 | | |
332 | 481 | if (order) { |
333 | 405 | WORD i; |
334 | 405 | WORD32 coef, coef_compress; |
335 | 405 | WORD resolution, shift; |
336 | | |
337 | 405 | filter->direction = (WORD8)(ixheaacd_read_bits_buf(it_bit_buf, 1) ? -1 : 1); |
338 | | |
339 | 405 | coef_compress = ixheaacd_read_bits_buf(it_bit_buf, 1); |
340 | | |
341 | 405 | filter->resolution = coef_res; |
342 | 405 | resolution = coef_res + 3 - coef_compress; |
343 | 405 | shift = 32 - resolution; |
344 | | |
345 | 2.21k | for (i = 0; i < order; i++) { |
346 | 1.80k | coef = ixheaacd_read_bits_buf(it_bit_buf, resolution); |
347 | 1.80k | coef = coef << shift; |
348 | 1.80k | filter->coeff[i] = (WORD8)(coef >> shift); |
349 | 1.80k | } |
350 | 405 | } |
351 | 481 | } |
352 | 463 | } |
353 | 963 | } |
354 | 199 | return AAC_DEC_OK; |
355 | 204 | } |
356 | | |
357 | | WORD32 ixheaacd_res_inv_quant(WORD32 *px_quant, WORD32 *pow_table_q17) |
358 | | |
359 | 215 | { |
360 | 215 | WORD32 q1; |
361 | 215 | WORD32 temp; |
362 | 215 | WORD32 q_abs; |
363 | 215 | WORD16 interp; |
364 | 215 | WORD32 shift; |
365 | | |
366 | 215 | q_abs = *px_quant; |
367 | | |
368 | 215 | if (q_abs > (8191 + 32)) return IA_XHEAAC_DEC_EXE_NONFATAL_EXCEEDS_MAX_HUFFDEC_VAL; |
369 | | |
370 | 140 | if (q_abs < 1024) |
371 | 109 | shift = 3; |
372 | 31 | else |
373 | 31 | shift = 6; |
374 | | |
375 | 140 | q1 = (q_abs) >> shift; |
376 | | |
377 | 140 | interp = q_abs - (q1 << shift); |
378 | | |
379 | 140 | temp = pow_table_q17[q1 + 1] - pow_table_q17[q1]; |
380 | | |
381 | 140 | temp = (WORD32)(temp * (WORD32)interp); |
382 | | |
383 | 140 | temp = temp + (pow_table_q17[q1] << shift); |
384 | | |
385 | 140 | if (shift == 3) |
386 | 109 | temp = temp << 1; |
387 | 31 | else |
388 | 31 | temp = temp << 2; |
389 | | |
390 | 140 | *px_quant = temp; |
391 | | |
392 | 140 | return 0; |
393 | 215 | } |