/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.78k | UWORD32 ixheaacd_res_aac_showbits_32(UWORD8 *p_read_next) { |
42 | 2.78k | UWORD8 *v = p_read_next; |
43 | 2.78k | UWORD32 b = 0; |
44 | | |
45 | 2.78k | _SWAP(v, b); |
46 | 2.78k | return b; |
47 | 2.78k | } |
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.37k | { |
55 | 1.37k | FLAG gain_control_data_present; |
56 | 1.37k | WORD16 error_status = AAC_DEC_OK; |
57 | | |
58 | 1.37k | if (p_aac_decoder_channel_info->ics_info.window_sequence == EIGHT_SHORT_SEQUENCE) { |
59 | 475 | memset(p_aac_decoder_channel_info->p_scale_factor, 0, MAX_WINDOWS * MAX_SFB_SHORT * 3); |
60 | 475 | } |
61 | | |
62 | 1.37k | error_status = ixheaacd_c_block_read_section_data(it_bit_buf, p_aac_decoder_channel_info); |
63 | | |
64 | 1.37k | if (error_status) return error_status; |
65 | | |
66 | 1.34k | ixheaacd_res_c_block_read_scf_data(it_bit_buf, p_aac_decoder_channel_info, global_gain, |
67 | 1.34k | aac_tables_ptr); |
68 | | |
69 | 1.34k | error_status = ixheaacd_res_c_pulse_data_read( |
70 | 1.34k | it_bit_buf, &p_aac_decoder_channel_info->pulse_data, aac_tables_ptr); |
71 | 1.34k | if (error_status) return error_status; |
72 | | |
73 | 1.33k | p_aac_decoder_channel_info->tns_data.tns_data_present = |
74 | 1.33k | (FLAG)ixheaacd_read_bits_buf(it_bit_buf, 1); |
75 | | |
76 | 1.33k | error_status = ixheaacd_res_c_tns_read(it_bit_buf, p_aac_decoder_channel_info); |
77 | 1.33k | if (error_status) { |
78 | 6 | return error_status; |
79 | 6 | } |
80 | | |
81 | 1.33k | gain_control_data_present = ixheaacd_read_bits_buf(it_bit_buf, 1); |
82 | | |
83 | 1.33k | if (gain_control_data_present) { |
84 | 6 | return (WORD16)((WORD32)AAC_DEC_UNIMPLEMENTED_GAIN_CONTROL_DATA); |
85 | 6 | } |
86 | | |
87 | 1.32k | { |
88 | 1.32k | it_bit_buf->bit_pos = (7 - it_bit_buf->bit_pos); |
89 | | |
90 | 1.32k | error_status = ixheaacd_res_c_block_read_spec_data(it_bit_buf, p_aac_decoder_channel_info, |
91 | 1.32k | aac_tables_ptr); |
92 | | |
93 | 1.32k | it_bit_buf->bit_pos = (7 - it_bit_buf->bit_pos); |
94 | 1.32k | } |
95 | | |
96 | 1.32k | return error_status; |
97 | 1.33k | } |
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.42k | ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD8 tot_sf_bands_ls[2]) { |
103 | 1.42k | WORD16 error_status = AAC_DEC_OK; |
104 | 1.42k | WORD32 ch; |
105 | | |
106 | 2.73k | for (ch = 0; ch < num_ch; ch++) { |
107 | 1.42k | ia_mps_dec_residual_channel_info_struct *p_aac_dec_ch_info = p_aac_decoder_channel_info[ch]; |
108 | 1.42k | ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_dec_ch_info->ics_info; |
109 | | |
110 | 1.42k | p_aac_dec_ch_info->global_gain = (WORD16)ixheaacd_read_bits_buf(it_bit_buf, 8); |
111 | | |
112 | 1.42k | if (!p_aac_decoder_channel_info[LEFT]->common_window) { |
113 | 1.39k | error_status = ixheaacd_res_ics_read(it_bit_buf, p_ics_info, tot_sf_bands_ls); |
114 | 1.39k | 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.39k | } |
120 | | |
121 | 1.40k | error_status = ixheaacd_res_c_block_read(it_bit_buf, p_aac_dec_ch_info, |
122 | 1.40k | p_aac_dec_ch_info->global_gain, aac_tables_ptr); |
123 | 1.40k | if (error_status) { |
124 | 93 | if (it_bit_buf->cnt_bits < 0) |
125 | 1 | error_status = (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES); |
126 | | |
127 | 93 | return error_status; |
128 | 93 | } |
129 | 1.40k | } |
130 | | |
131 | 1.31k | return error_status; |
132 | 1.42k | } |
133 | | |
134 | | VOID ixheaacd_res_c_pulse_data_apply(ia_mps_dec_residual_pulse_data_struct *pulse_data, |
135 | | WORD8 *p_pulse_arr, |
136 | 880 | const WORD16 *p_scale_factor_band_offsets) { |
137 | 880 | WORD i, number_pulse; |
138 | 880 | WORD32 k; |
139 | | |
140 | 880 | memset(p_pulse_arr, 0, sizeof(WORD32) * 256); |
141 | | |
142 | 880 | if (pulse_data->pulse_data_present) { |
143 | 87 | k = p_scale_factor_band_offsets[pulse_data->pulse_start_band]; |
144 | 87 | number_pulse = pulse_data->number_pulse; |
145 | | |
146 | 246 | for (i = 0; i <= number_pulse; i++) { |
147 | 159 | k = add_d(k, pulse_data->pulse_offset[i]); |
148 | 159 | p_pulse_arr[k] = pulse_data->pulse_amp[i]; |
149 | 159 | } |
150 | 87 | } |
151 | 880 | } |
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.32k | ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) { |
157 | 1.32k | WORD band, tot_bands, tot_groups = 0; |
158 | 1.32k | WORD group, groupwin, groupoffset; |
159 | | |
160 | 1.32k | WORD index; |
161 | 1.32k | WORD8 *p_code_book, *p_codebook_tmp; |
162 | 1.32k | WORD16 *p_scale_factor; |
163 | 1.32k | WORD32 *p_spectral_coefficient; |
164 | 1.32k | ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_decoder_channel_info->ics_info; |
165 | 1.32k | WORD16 *band_offsets; |
166 | 1.32k | WORD32 maximum_bins_short = ixheaac_shr16_dir_sat(p_ics_info->frame_length, 3); |
167 | | |
168 | 1.32k | WORD32 *p_spec_coeff_out; |
169 | | |
170 | 1.32k | p_code_book = p_aac_decoder_channel_info->p_code_book; |
171 | 1.32k | p_scale_factor = p_aac_decoder_channel_info->p_scale_factor; |
172 | 1.32k | p_spectral_coefficient = p_aac_decoder_channel_info->p_spectral_coefficient; |
173 | 1.32k | tot_groups = p_ics_info->window_groups; |
174 | 1.32k | tot_bands = p_ics_info->max_sf_bands; |
175 | 1.32k | band_offsets = (WORD16 *)ixheaacd_res_get_sfb_offsets(p_ics_info, aac_tables_ptr); |
176 | | |
177 | 1.32k | if (p_aac_decoder_channel_info->ics_info.window_sequence != EIGHT_SHORT_SEQUENCE) { |
178 | 880 | WORD8 *p_pul_arr = (WORD8 *)p_aac_decoder_channel_info->p_tns_scratch; |
179 | 880 | ixheaacd_res_c_pulse_data_apply(&p_aac_decoder_channel_info->pulse_data, p_pul_arr, |
180 | 880 | band_offsets); |
181 | | |
182 | 880 | p_spec_coeff_out = &p_spectral_coefficient[0]; |
183 | 1.99k | for (band = 0; band < tot_bands;) { |
184 | 1.13k | WORD ret_val; |
185 | 1.13k | WORD32 len; |
186 | 1.13k | WORD32 code_no = p_code_book[band]; |
187 | 1.13k | WORD start = band; |
188 | | |
189 | 9.53k | for (; band < tot_bands && (p_code_book[band] == code_no); band++) |
190 | 8.40k | ; |
191 | | |
192 | 1.13k | len = band_offsets[band] - band_offsets[start]; |
193 | | |
194 | 1.13k | if (code_no > ZERO_HCB && (code_no < NOISE_HCB)) { |
195 | 860 | ret_val = ixheaacd_res_c_block_decode_huff_word_all_lb( |
196 | 860 | it_bit_buf, code_no, len, aac_tables_ptr, p_spec_coeff_out, p_pul_arr); |
197 | | |
198 | 860 | if (ret_val != 0) |
199 | 21 | return (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_EXCEEDS_MAX_HUFFDEC_VAL); |
200 | 860 | } else { |
201 | 276 | if (p_aac_decoder_channel_info->pulse_data.pulse_data_present) |
202 | 87 | ixheaacd_res_inverse_quant_lb( |
203 | 87 | p_spec_coeff_out, len, |
204 | 87 | (WORD32 *)aac_tables_ptr->res_block_tables_ptr->pow_table_q17, p_pul_arr); |
205 | 189 | else |
206 | 189 | memset(p_spec_coeff_out, 0, sizeof(WORD32) * len); |
207 | 276 | } |
208 | 1.11k | p_pul_arr += len; |
209 | 1.11k | p_spec_coeff_out += len; |
210 | 1.11k | } |
211 | | |
212 | 859 | index = 1024 - band_offsets[tot_bands]; |
213 | 859 | memset(p_spec_coeff_out, 0, sizeof(WORD32) * index); |
214 | 859 | } else { |
215 | 440 | memset(p_spectral_coefficient, 0, sizeof(WORD32) * 1024); |
216 | | |
217 | 440 | groupoffset = 0; |
218 | | |
219 | 1.46k | for (group = 0; group < tot_groups; group++) { |
220 | 1.04k | WORD grp_win = p_ics_info->window_group_length[group]; |
221 | 1.04k | p_codebook_tmp = &p_code_book[group * MAX_SFB_SHORT]; |
222 | 1.04k | p_spec_coeff_out = &p_spectral_coefficient[groupoffset * maximum_bins_short]; |
223 | | |
224 | 1.92k | for (band = 0; band < tot_bands;) { |
225 | 897 | WORD code_no = *p_codebook_tmp; |
226 | 897 | WORD start = band; |
227 | 897 | WORD ret_val; |
228 | | |
229 | 5.00k | for (; band < tot_bands && (*p_codebook_tmp == code_no); band++, p_codebook_tmp++) |
230 | 4.10k | ; |
231 | | |
232 | 897 | if (code_no > ZERO_HCB && (code_no < NOISE_HCB)) { |
233 | 666 | ret_val = ixheaacd_res_c_block_decode_huff_word_all( |
234 | 666 | it_bit_buf, code_no, p_spec_coeff_out, (WORD16 *)band_offsets, start, band, grp_win, |
235 | 666 | aac_tables_ptr, maximum_bins_short); |
236 | | |
237 | 666 | if (ret_val != 0) |
238 | 23 | return (WORD16)((WORD32)IA_XHEAAC_DEC_EXE_NONFATAL_EXCEEDS_MAX_HUFFDEC_VAL); |
239 | 666 | } |
240 | 897 | } |
241 | 1.02k | groupoffset = (groupoffset + grp_win); |
242 | 1.02k | } |
243 | 440 | } |
244 | | |
245 | 1.27k | { |
246 | 1.27k | WORD8 *p_win_grp_len = &p_ics_info->window_group_length[0]; |
247 | 1.27k | WORD8 *psfb_width = (WORD8 *)ixheaacd_res_get_sfb_width(p_ics_info, aac_tables_ptr); |
248 | 1.27k | WORD32 *scale_table_ptr; |
249 | 1.27k | if (120 == maximum_bins_short) { |
250 | 0 | scale_table_ptr = aac_tables_ptr->res_block_tables_ptr->scale_table_960; |
251 | 1.27k | } else { |
252 | 1.27k | scale_table_ptr = aac_tables_ptr->res_block_tables_ptr->scale_table; |
253 | 1.27k | } |
254 | 1.88k | do { |
255 | 1.88k | groupwin = *p_win_grp_len++; |
256 | 4.19k | do { |
257 | 4.19k | ixheaacd_res_apply_scfs(&p_spectral_coefficient[0], &p_scale_factor[0], tot_bands, |
258 | 4.19k | (WORD8 *)psfb_width, scale_table_ptr); |
259 | | |
260 | 4.19k | p_spectral_coefficient += maximum_bins_short; |
261 | 4.19k | groupwin--; |
262 | 4.19k | } while (groupwin != 0); |
263 | | |
264 | 1.88k | p_scale_factor += MAX_SFB_SHORT; |
265 | 1.88k | tot_groups--; |
266 | 1.88k | } while (tot_groups != 0); |
267 | 1.27k | } |
268 | | |
269 | 1.27k | return AAC_DEC_OK; |
270 | 1.32k | } |
271 | | |
272 | | WORD16 |
273 | | ixheaacd_res_c_tns_read(ia_bit_buf_struct *it_bit_buf, |
274 | 1.33k | ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info) { |
275 | 1.33k | WORD window, window_per_frame; |
276 | 1.33k | WORD n_filt_bits, len_bits, order_bits; |
277 | 1.33k | WORD32 next_stop_band_tmp; |
278 | | |
279 | 1.33k | ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_decoder_channel_info->ics_info; |
280 | 1.33k | ia_mps_dec_residual_tns_data *p_tns_data = &p_aac_decoder_channel_info->tns_data; |
281 | | |
282 | 1.33k | if (!p_tns_data->tns_data_present) return AAC_DEC_OK; |
283 | | |
284 | 345 | if (p_ics_info->window_sequence != EIGHT_SHORT_SEQUENCE) { |
285 | 124 | n_filt_bits = 2; |
286 | 124 | len_bits = 6; |
287 | 124 | order_bits = 5; |
288 | 124 | window_per_frame = 1; |
289 | 221 | } else { |
290 | 221 | n_filt_bits = 1; |
291 | 221 | len_bits = 4; |
292 | 221 | order_bits = 3; |
293 | 221 | window_per_frame = 8; |
294 | 221 | } |
295 | | |
296 | 345 | next_stop_band_tmp = p_ics_info->total_sf_bands; |
297 | | |
298 | 2.21k | for (window = 0; window < window_per_frame; window++) { |
299 | 1.87k | WORD n_filt; |
300 | 1.87k | WORD length, coef_res; |
301 | 1.87k | p_tns_data->number_of_filters[window] = n_filt = |
302 | 1.87k | (WORD16)ixheaacd_read_bits_buf(it_bit_buf, n_filt_bits); |
303 | | |
304 | 1.87k | if (n_filt) { |
305 | 764 | WORD32 accu; |
306 | 764 | WORD index; |
307 | 764 | WORD nextstopband; |
308 | | |
309 | 764 | coef_res = ixheaacd_read_bits_buf(it_bit_buf, 1); |
310 | | |
311 | 764 | nextstopband = next_stop_band_tmp; |
312 | 1.56k | for (index = 0; index < n_filt; index++) { |
313 | 806 | WORD order; |
314 | 806 | ia_mps_dec_residual_filter_struct *filter = &p_tns_data->filter[window][index]; |
315 | 806 | length = ixheaacd_read_bits_buf(it_bit_buf, len_bits); |
316 | | |
317 | 806 | filter->start_band = nextstopband - length; |
318 | 806 | filter->stop_band = nextstopband; |
319 | | |
320 | 806 | nextstopband = filter->start_band; |
321 | | |
322 | 806 | if (filter->start_band < 0) { |
323 | 5 | filter->order = -1; |
324 | 5 | return (WORD16)((WORD32)AAC_DEC_TNS_RANGE_ERROR); |
325 | 5 | } |
326 | | |
327 | 801 | filter->order = order = ixheaacd_read_bits_buf(it_bit_buf, order_bits); |
328 | 801 | accu = order - MAX_ORDER_LONG; |
329 | | |
330 | 801 | if (accu > 0) return (WORD16)((WORD32)AAC_DEC_TNS_ORDER_ERROR); |
331 | | |
332 | 800 | if (order) { |
333 | 638 | WORD i; |
334 | 638 | WORD32 coef, coef_compress; |
335 | 638 | WORD resolution, shift; |
336 | | |
337 | 638 | filter->direction = (WORD8)(ixheaacd_read_bits_buf(it_bit_buf, 1) ? -1 : 1); |
338 | | |
339 | 638 | coef_compress = ixheaacd_read_bits_buf(it_bit_buf, 1); |
340 | | |
341 | 638 | filter->resolution = coef_res; |
342 | 638 | resolution = coef_res + 3 - coef_compress; |
343 | 638 | shift = 32 - resolution; |
344 | | |
345 | 3.33k | for (i = 0; i < order; i++) { |
346 | 2.69k | coef = ixheaacd_read_bits_buf(it_bit_buf, resolution); |
347 | 2.69k | coef = coef << shift; |
348 | 2.69k | filter->coeff[i] = (WORD8)(coef >> shift); |
349 | 2.69k | } |
350 | 638 | } |
351 | 800 | } |
352 | 764 | } |
353 | 1.87k | } |
354 | 339 | return AAC_DEC_OK; |
355 | 345 | } |
356 | | |
357 | | WORD32 ixheaacd_res_inv_quant(WORD32 *px_quant, WORD32 *pow_table_q17) |
358 | | |
359 | 323 | { |
360 | 323 | WORD32 q1; |
361 | 323 | WORD32 temp; |
362 | 323 | WORD32 q_abs; |
363 | 323 | WORD16 interp; |
364 | 323 | WORD32 shift; |
365 | | |
366 | 323 | q_abs = *px_quant; |
367 | | |
368 | 323 | if (q_abs > (8191 + 32)) return IA_XHEAAC_DEC_EXE_NONFATAL_EXCEEDS_MAX_HUFFDEC_VAL; |
369 | | |
370 | 213 | if (q_abs < 1024) |
371 | 147 | shift = 3; |
372 | 66 | else |
373 | 66 | shift = 6; |
374 | | |
375 | 213 | q1 = (q_abs) >> shift; |
376 | | |
377 | 213 | interp = q_abs - (q1 << shift); |
378 | | |
379 | 213 | temp = pow_table_q17[q1 + 1] - pow_table_q17[q1]; |
380 | | |
381 | 213 | temp = (WORD32)(temp * (WORD32)interp); |
382 | | |
383 | 213 | temp = temp + (pow_table_q17[q1] << shift); |
384 | | |
385 | 213 | if (shift == 3) |
386 | 147 | temp = temp << 1; |
387 | 66 | else |
388 | 66 | temp = temp << 2; |
389 | | |
390 | 213 | *px_quant = temp; |
391 | | |
392 | 213 | return 0; |
393 | 323 | } |