• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <string.h>
21 
22 #include <ixheaacd_type_def.h>
23 #include "ixheaacd_sbr_common.h"
24 
25 #include "ixheaacd_constants.h"
26 #include "ixheaacd_basic_ops32.h"
27 #include "ixheaacd_basic_ops16.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_basic_ops.h"
30 
31 #include "ixheaacd_bitbuffer.h"
32 
33 #include "ixheaacd_audioobjtypes.h"
34 #include "ixheaacd_sbrdecsettings.h"
35 #include "ixheaacd_memory_standards.h"
36 #include "ixheaacd_error_codes.h"
37 
38 #include "ixheaacd_defines.h"
39 #include "ixheaacd_aac_rom.h"
40 #include "ixheaacd_pns.h"
41 
42 #include "ixheaacd_pulsedata.h"
43 #include "ixheaacd_drc_data_struct.h"
44 
45 #include "ixheaacd_lt_predict.h"
46 #include "ixheaacd_channelinfo.h"
47 #include "ixheaacd_drc_dec.h"
48 
49 #include "ixheaacd_sbrdecoder.h"
50 #include "ixheaacd_sbr_scale.h"
51 #include "ixheaacd_lpp_tran.h"
52 #include "ixheaacd_env_extr_part.h"
53 #include "ixheaacd_sbr_rom.h"
54 
55 #include "ixheaacd_hybrid.h"
56 #include "ixheaacd_ps_dec.h"
57 #include "ixheaacd_ps_bitdec.h"
58 
59 #include "ixheaacd_pulsedata.h"
60 
61 #include "ixheaacd_pns.h"
62 
63 #include "ixheaacd_env_extr.h"
64 #include "ixheaacd_common_rom.h"
65 #include "ixheaacd_block.h"
66 #include "ixheaacd_channel.h"
67 #include "ixheaacd_audioobjtypes.h"
68 #include "ixheaacd_latmdemux.h"
69 #include "ixheaacd_aacdec.h"
70 #include "ixheaacd_config.h"
71 #include "ixheaacd_mps_polyphase.h"
72 #include "ixheaacd_mps_dec.h"
73 #include "ixheaacd_struct_def.h"
74 #include "ixheaacd_headerdecode.h"
75 
76 #include "ixheaacd_multichannel.h"
77 #include <ixheaacd_basic_op.h>
78 
cblock_decode_huff_symbol(UWORD8 * ptr_read_next,WORD32 bit_pos,const UWORD16 * huff_ori,WORD16 * input,WORD32 * readword)79 WORD cblock_decode_huff_symbol(UWORD8 *ptr_read_next, WORD32 bit_pos,
80                                const UWORD16 *huff_ori, WORD16 *input,
81                                WORD32 *readword)
82 
83 {
84   const UWORD16 *h;
85   WORD tot_bits;
86   {
87     UWORD16 first_offset;
88     WORD16 sign_ret_val;
89     UWORD32 read_word1;
90 
91     read_word1 = *readword << bit_pos;
92 
93     h = (UWORD16 *)(huff_ori);
94     first_offset = 7;
95 
96     h += (read_word1) >> (32 - first_offset);
97     sign_ret_val = *h;
98     tot_bits = 0;
99 
100     while (sign_ret_val > 0) {
101       tot_bits += first_offset;
102       bit_pos += first_offset;
103 
104       if ((bit_pos -= 8) >= 0) {
105         *readword = (*readword << 8) | *ptr_read_next;
106         ptr_read_next++;
107       } else {
108         bit_pos += 8;
109       }
110 
111       read_word1 = (read_word1) << (first_offset);
112 
113       first_offset = (sign_ret_val >> 11);
114       h += sign_ret_val & (0x07FF);
115 
116       h += (read_word1) >> (32 - first_offset);
117       sign_ret_val = *h;
118     }
119 
120     tot_bits += ((sign_ret_val & 0x7fff) >> 11);
121     bit_pos += ((sign_ret_val & 0x7fff) >> 11);
122     if ((bit_pos - 8) >= 0) {
123       *readword = (*readword << 8) | *ptr_read_next;
124     }
125 
126     *input = (sign_ret_val & (0x07FF)) - 60;
127   }
128 
129   return tot_bits;
130 }
131 
ixheaacd_dec_coupling_channel_element(ia_handle_bit_buf_struct bs,ia_aac_decoder_struct * aac_handle,WORD32 samp_rate_idx,ia_aac_dec_tables_struct * ptr_aac_tables,ixheaacd_misc_tables * common_tables_ptr,WORD * element_index_order,ia_enhaacplus_dec_ind_cc * ind_channel_info,WORD32 total_channels,WORD32 frame_size,WORD32 audio_object_type,ia_eld_specific_config_struct eld_specific_config,WORD32 ele_type)132 IA_ERRORCODE ixheaacd_dec_coupling_channel_element(
133     ia_handle_bit_buf_struct bs, ia_aac_decoder_struct *aac_handle,
134     WORD32 samp_rate_idx, ia_aac_dec_tables_struct *ptr_aac_tables,
135     ixheaacd_misc_tables *common_tables_ptr, WORD *element_index_order,
136     ia_enhaacplus_dec_ind_cc *ind_channel_info, WORD32 total_channels,
137     WORD32 frame_size, WORD32 audio_object_type,
138     ia_eld_specific_config_struct eld_specific_config, WORD32 ele_type) {
139   WORD32 element_instance_tag;
140   LOOPIDX c;
141 
142   WORD ind_sw_cce_flag, num_coupled_elements;
143 
144   WORD num_gain_element_lists = 0;
145   WORD cc_domain;
146   WORD gain_element_sign;
147   WORD gain_element_scale;
148 
149   const UWORD16 *hcod_sf =
150       ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl;
151   const UWORD32 *table_idx =
152       ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl_index;
153   WORD16 index, length;
154 
155   IA_ERRORCODE error_status = IA_NO_ERROR;
156 
157   element_instance_tag = ixheaacd_read_bits_buf(bs, 4);
158   element_index_order[0] = element_instance_tag;
159 
160   ind_sw_cce_flag = ixheaacd_read_bits_buf(bs, 1);
161   num_coupled_elements = ixheaacd_read_bits_buf(bs, 3);
162 
163   for (c = 0; c < MAX_BS_ELEMENT; c++)
164     ind_channel_info->elements_coupled[c] = -1;
165 
166   ind_channel_info->num_coupled_elements = num_coupled_elements;
167 
168   for (c = 0; c < (num_coupled_elements + 1); c++) {
169     num_gain_element_lists++;
170 
171     ind_channel_info->cc_target_is_cpe[c] = ixheaacd_read_bits_buf(bs, 1);
172     ind_channel_info->cc_target_tag_select[c] = ixheaacd_read_bits_buf(bs, 4);
173     if (ind_channel_info->cc_target_is_cpe[c]) {
174       ind_channel_info->cc_l[c] = ixheaacd_read_bits_buf(bs, 1);
175       ind_channel_info->cc_r[c] = ixheaacd_read_bits_buf(bs, 1);
176       if (ind_channel_info->cc_l[c] && ind_channel_info->cc_r[c])
177         num_gain_element_lists++;
178       ind_channel_info->elements_coupled[c] = 1;
179     } else
180       ind_channel_info->elements_coupled[c] = 0;
181   }
182   if ((ind_sw_cce_flag == 0) && (num_gain_element_lists > MAX_BS_ELEMENT)) {
183     return IA_FATAL_ERROR;
184   }
185   cc_domain = ixheaacd_read_bits_buf(bs, 1);
186   gain_element_sign = ixheaacd_read_bits_buf(bs, 1);
187   gain_element_scale = ixheaacd_read_bits_buf(bs, 2);
188 
189   aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.num_swb_window = 0;
190   aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.sampling_rate_index =
191       samp_rate_idx;
192 
193   aac_handle->pstr_aac_dec_ch_info[0]->common_window = 0;
194 
195   error_status = ixheaacd_individual_ch_stream(
196       bs, aac_handle, 1, frame_size, total_channels, audio_object_type,
197       eld_specific_config, ele_type);
198 
199   if (error_status) return error_status;
200 
201   ind_channel_info->cc_gain[0] = 1 << 29;
202   for (c = 1; c < num_gain_element_lists; c++) {
203     WORD cge;
204     WORD common_gain_element_present[MAX_BS_ELEMENT];
205     WORD16 norm_value;
206 
207     if (ind_sw_cce_flag)
208       cge = 1;
209     else {
210       common_gain_element_present[c] = ixheaacd_read_bits_buf(bs, 1);
211       cge = common_gain_element_present[c];
212       return IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE;
213     }
214     if (cge) {
215       UWORD8 *ptr_read_next = bs->ptr_read_next;
216       WORD32 bit_pos = 7 - bs->bit_pos;
217       WORD32 read_word =
218           ixheaacd_aac_showbits_32(bs->ptr_read_next, bs->cnt_bits, NULL);
219       UWORD32 read_word1;
220 
221       read_word1 = read_word << bit_pos;
222       ixheaacd_huffman_decode(read_word1, &index, &length, hcod_sf, table_idx);
223 
224       bit_pos += length;
225 
226       ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word);
227       while (bit_pos > 8)
228         ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word);
229 
230       bs->ptr_read_next = ptr_read_next;
231       bs->bit_pos = 7 - bit_pos;
232       bs->cnt_bits -= length;
233 
234       norm_value = index - 60;
235       if (norm_value == -1)
236         ind_channel_info->cc_gain[c] =
237             common_tables_ptr->cc_gain_scale[gain_element_scale];
238       else {
239         int i;
240         ind_channel_info->cc_gain[c] =
241             common_tables_ptr->cc_gain_scale[gain_element_scale];
242         for (i = 0; i < (-norm_value) - 1; i++) {
243           ind_channel_info->cc_gain[c] = ixheaacd_mul32_sh(
244               ind_channel_info->cc_gain[c],
245               common_tables_ptr->cc_gain_scale[gain_element_scale], 29);
246         }
247       }
248     } else {
249       return IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE;
250     }
251   }
252   if (bs->cnt_bits < 0) {
253     return IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
254   }
255   return error_status;
256 }
257 
ixheaacd_dec_couple_channel(WORD16 * p_time_data,WORD16 * out_samp_cc,WORD16 frame_size,WORD total_channels,WORD32 gain_cc)258 void ixheaacd_dec_couple_channel(WORD16 *p_time_data, WORD16 *out_samp_cc,
259                                  WORD16 frame_size, WORD total_channels,
260                                  WORD32 gain_cc)
261 
262 {
263   WORD i;
264   WORD16 out_cc;
265   WORD16 *ptr_out_samp = &out_samp_cc[0];
266   for (i = frame_size - 1; i >= 0; i--) {
267     out_cc = ixheaacd_round16(ixheaacd_shl32_sat(
268         ixheaacd_mult32x16in32(gain_cc, *ptr_out_samp++), 3));
269     *p_time_data = ixheaacd_add16_sat(out_cc, *p_time_data);
270     p_time_data += total_channels;
271   }
272 }
273 
ixheaacd_dec_ind_coupling(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec,WORD16 * coup_ch_output,WORD16 frame_size,WORD total_channels,WORD16 * ptr_time_data)274 void ixheaacd_dec_ind_coupling(
275     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 *coup_ch_output,
276     WORD16 frame_size, WORD total_channels, WORD16 *ptr_time_data)
277 
278 {
279   WORD c, j, k;
280   WORD l;
281   WORD coupling_channel;
282 
283   WORD16 *out_samp_cc;
284 
285   ia_enhaacplus_dec_ind_cc *ind_channel_info;
286 
287   {
288     coupling_channel = p_obj_exhaacplus_dec->aac_config.ui_coupling_channel;
289 
290     ind_channel_info = &p_obj_exhaacplus_dec->p_state_aac->ind_cc_info;
291 
292     out_samp_cc = coup_ch_output;
293 
294     j = 0;
295     for (c = 0; c < ind_channel_info->num_coupled_elements + 1; c++) {
296       for (l = 0; l < MAX_BS_ELEMENT; l++) {
297         if (p_obj_exhaacplus_dec->aac_config.element_type[l] ==
298                 ind_channel_info->elements_coupled[c] &&
299             p_obj_exhaacplus_dec->aac_config.element_instance_order[l] ==
300                 ind_channel_info->cc_target_tag_select[c]) {
301           break;
302         }
303       }
304       if (l == MAX_BS_ELEMENT) {
305         continue;
306       }
307 
308       k = p_obj_exhaacplus_dec->aac_config.slot_element[l];
309 
310       if (ind_channel_info->cc_target_is_cpe[c] == 0) {
311         WORD16 *p_time_data = &ptr_time_data[k];
312 
313         WORD32 gain_cc = ind_channel_info->cc_gain[j];
314 
315         ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
316                                     total_channels, gain_cc);
317       }
318       if (ind_channel_info->cc_target_is_cpe[c] == 1) {
319         if (ind_channel_info->cc_l[c] == 1) {
320           WORD16 *p_time_data = &ptr_time_data[k];
321 
322           WORD32 gain_cc = ind_channel_info->cc_gain[j];
323 
324           ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
325                                       total_channels, gain_cc);
326         }
327 
328         k = p_obj_exhaacplus_dec->aac_config.slot_element[l];
329 
330         if (ind_channel_info->cc_r[c] == 1) {
331           WORD16 *p_time_data = &ptr_time_data[k + 1];
332           WORD32 gain_cc = ind_channel_info->cc_gain[j + 1];
333 
334           ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
335                                       total_channels, gain_cc);
336         }
337       }
338       if (ind_channel_info->cc_target_is_cpe[c] == 1) {
339         j += 2;
340       } else {
341         j += 1;
342       }
343     }
344   }
345 }
346 
ixheaacd_dec_downmix_to_stereo(ia_exhaacplus_dec_api_struct * p_obj_exhaacplus_dec,WORD16 frame_size,WORD total_elements,WORD16 * ptr_time_data,WORD total_channels)347 void ixheaacd_dec_downmix_to_stereo(
348     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 frame_size,
349     WORD total_elements, WORD16 *ptr_time_data, WORD total_channels) {
350   LOOPIDX i, j;
351   WORD k = 0;
352   if (5 == total_channels) k = 0;
353   if (6 == total_channels) k = 1;
354   if (7 == total_channels) k = 2;
355   if (8 == total_channels) k = 3;
356 
357   for (j = 0; j < frame_size; j++) {
358     WORD16 temp_l = 0, temp_r = 0;
359     for (i = 0; i < total_elements; i++) {
360       if (0 == p_obj_exhaacplus_dec->aac_config.element_type[i] ||
361           3 == p_obj_exhaacplus_dec->aac_config.element_type[i]) {
362         temp_l += (WORD16)(
363             ixheaacd_mult32x16in32(
364                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
365                     [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
366                 ptr_time_data[j * total_channels +
367                               p_obj_exhaacplus_dec->aac_config
368                                   .slot_element[i]]) >>
369             14);
370 
371         temp_r += (WORD16)(
372             ixheaacd_mult32x16in32(
373                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
374                     [k][1][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
375                 ptr_time_data[j * total_channels +
376                               p_obj_exhaacplus_dec->aac_config
377                                   .slot_element[i]]) >>
378             14);
379       }
380       if (1 == p_obj_exhaacplus_dec->aac_config.element_type[i]) {
381         temp_l += (WORD16)(
382             ixheaacd_mult32x16in32(
383                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
384                     [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
385                 ptr_time_data[j * total_channels +
386                               p_obj_exhaacplus_dec->aac_config
387                                   .slot_element[i]]) >>
388             14);
389 
390         temp_r += (WORD16)(
391             ixheaacd_mult32x16in32(
392                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
393                     [k][1]
394                     [p_obj_exhaacplus_dec->aac_config.slot_element[i] + 1],
395                 ptr_time_data[j * total_channels +
396                               p_obj_exhaacplus_dec->aac_config.slot_element[i] +
397                               1]) >>
398             14);
399       }
400     }
401 
402     ptr_time_data[2 * j] = temp_l;
403     ptr_time_data[2 * j + 1] = temp_r;
404   }
405 }
406