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 WORD16 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   WORD16 error_status = AAC_DEC_OK;
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 
183   cc_domain = ixheaacd_read_bits_buf(bs, 1);
184   gain_element_sign = ixheaacd_read_bits_buf(bs, 1);
185   gain_element_scale = ixheaacd_read_bits_buf(bs, 2);
186 
187   aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.num_swb_window = 0;
188   aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.sampling_rate_index =
189       samp_rate_idx;
190 
191   aac_handle->pstr_aac_dec_ch_info[0]->common_window = 0;
192 
193   error_status = ixheaacd_individual_ch_stream(
194       bs, aac_handle, 1, frame_size, total_channels, audio_object_type,
195       eld_specific_config, ele_type);
196 
197   if (error_status) return error_status;
198 
199   ind_channel_info->cc_gain[0] = 1 << 29;
200   for (c = 1; c < num_gain_element_lists; c++) {
201     WORD cge;
202     WORD common_gain_element_present[MAX_BS_ELEMENT];
203     WORD16 norm_value;
204 
205     if (ind_sw_cce_flag)
206       cge = 1;
207     else {
208       common_gain_element_present[c] = ixheaacd_read_bits_buf(bs, 1);
209       cge = common_gain_element_present[c];
210       error_status =
211           (WORD)((WORD32)IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE);
212     }
213     if (cge) {
214       UWORD8 *ptr_read_next = bs->ptr_read_next;
215       WORD32 bit_pos = 7 - bs->bit_pos;
216       WORD32 read_word = ixheaacd_aac_showbits_32(ptr_read_next);
217       UWORD32 read_word1;
218 
219       read_word1 = read_word << bit_pos;
220       ixheaacd_huffman_decode(read_word1, &index, &length, hcod_sf, table_idx);
221 
222       bit_pos += length;
223 
224       ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word);
225       while (bit_pos > 8)
226         ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word);
227 
228       bs->ptr_read_next = ptr_read_next;
229       bs->bit_pos = 7 - bit_pos;
230       bs->cnt_bits -= length;
231 
232       norm_value = index - 60;
233       if (norm_value == -1)
234         ind_channel_info->cc_gain[c] =
235             common_tables_ptr->cc_gain_scale[gain_element_scale];
236       else {
237         int i;
238         ind_channel_info->cc_gain[c] =
239             common_tables_ptr->cc_gain_scale[gain_element_scale];
240         for (i = 0; i < (-norm_value) - 1; i++) {
241           ind_channel_info->cc_gain[c] *=
242               common_tables_ptr->cc_gain_scale[gain_element_scale];
243         }
244       }
245     } else {
246       error_status =
247           (WORD)((WORD32)IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE);
248     }
249   }
250   if (bs->cnt_bits < 0) {
251     error_status = (WORD16)(
252         (WORD32)IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES);
253   }
254   return error_status;
255 }
256 
ixheaacd_dec_couple_channel(WORD16 * p_time_data,WORD16 * out_samp_cc,WORD16 frame_size,WORD total_channels,WORD32 gain_cc)257 void ixheaacd_dec_couple_channel(WORD16 *p_time_data, WORD16 *out_samp_cc,
258                                  WORD16 frame_size, WORD total_channels,
259                                  WORD32 gain_cc)
260 
261 {
262   WORD i;
263   WORD16 out_cc;
264   WORD16 *ptr_out_samp = &out_samp_cc[0];
265   for (i = frame_size - 1; i >= 0; i--) {
266     out_cc = ixheaacd_round16(ixheaacd_shl32_sat(
267         ixheaacd_mult32x16in32(gain_cc, *ptr_out_samp++), 3));
268     *p_time_data = ixheaacd_add16_sat(out_cc, *p_time_data);
269     p_time_data += total_channels;
270   }
271 }
272 
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)273 void ixheaacd_dec_ind_coupling(
274     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 *coup_ch_output,
275     WORD16 frame_size, WORD total_channels, WORD16 *ptr_time_data)
276 
277 {
278   WORD c, j, k;
279   WORD l;
280   WORD coupling_channel;
281 
282   WORD16 *out_samp_cc;
283 
284   ia_enhaacplus_dec_ind_cc *ind_channel_info;
285 
286   {
287     coupling_channel = p_obj_exhaacplus_dec->aac_config.ui_coupling_channel;
288 
289     ind_channel_info = &p_obj_exhaacplus_dec->p_state_aac->ind_cc_info;
290 
291     out_samp_cc = coup_ch_output;
292 
293     j = 0;
294     for (c = 0; c < ind_channel_info->num_coupled_elements + 1; c++) {
295       for (l = 0; l < MAX_BS_ELEMENT; l++) {
296         if (p_obj_exhaacplus_dec->aac_config.element_type[l] ==
297                 ind_channel_info->elements_coupled[c] &&
298             p_obj_exhaacplus_dec->aac_config.element_instance_order[l] ==
299                 ind_channel_info->cc_target_tag_select[c]) {
300           break;
301         }
302       }
303       if (l == MAX_BS_ELEMENT) {
304         continue;
305       }
306 
307       k = p_obj_exhaacplus_dec->aac_config.slot_element[l];
308 
309       if (ind_channel_info->cc_target_is_cpe[c] == 0) {
310         WORD16 *p_time_data = &ptr_time_data[k];
311 
312         WORD32 gain_cc = ind_channel_info->cc_gain[j];
313 
314         ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
315                                     total_channels, gain_cc);
316       }
317       if (ind_channel_info->cc_target_is_cpe[c] == 1) {
318         if (ind_channel_info->cc_l[c] == 1) {
319           WORD16 *p_time_data = &ptr_time_data[k];
320 
321           WORD32 gain_cc = ind_channel_info->cc_gain[j];
322 
323           ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
324                                       total_channels, gain_cc);
325         }
326 
327         k = p_obj_exhaacplus_dec->aac_config.slot_element[l];
328 
329         if (ind_channel_info->cc_r[c] == 1) {
330           WORD16 *p_time_data = &ptr_time_data[k + 1];
331           WORD32 gain_cc = ind_channel_info->cc_gain[j + 1];
332 
333           ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
334                                       total_channels, gain_cc);
335         }
336       }
337       if (ind_channel_info->cc_target_is_cpe[c] == 1) {
338         j += 2;
339       } else {
340         j += 1;
341       }
342     }
343   }
344 }
345 
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)346 void ixheaacd_dec_downmix_to_stereo(
347     ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 frame_size,
348     WORD total_elements, WORD16 *ptr_time_data, WORD total_channels) {
349   LOOPIDX i, j;
350   WORD k = 0;
351   if (5 == total_channels) k = 0;
352   if (6 == total_channels) k = 1;
353   if (7 == total_channels) k = 2;
354   if (8 == total_channels) k = 3;
355 
356   for (j = 0; j < frame_size; j++) {
357     WORD16 temp_l = 0, temp_r = 0;
358     for (i = 0; i < total_elements; i++) {
359       if (0 == p_obj_exhaacplus_dec->aac_config.element_type[i] ||
360           3 == p_obj_exhaacplus_dec->aac_config.element_type[i]) {
361         temp_l += (WORD16)(
362             ixheaacd_mult32x16in32(
363                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
364                     [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
365                 ptr_time_data[j * total_channels +
366                               p_obj_exhaacplus_dec->aac_config
367                                   .slot_element[i]]) >>
368             14);
369 
370         temp_r += (WORD16)(
371             ixheaacd_mult32x16in32(
372                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
373                     [k][1][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
374                 ptr_time_data[j * total_channels +
375                               p_obj_exhaacplus_dec->aac_config
376                                   .slot_element[i]]) >>
377             14);
378       }
379       if (1 == p_obj_exhaacplus_dec->aac_config.element_type[i]) {
380         temp_l += (WORD16)(
381             ixheaacd_mult32x16in32(
382                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
383                     [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
384                 ptr_time_data[j * total_channels +
385                               p_obj_exhaacplus_dec->aac_config
386                                   .slot_element[i]]) >>
387             14);
388 
389         temp_r += (WORD16)(
390             ixheaacd_mult32x16in32(
391                 p_obj_exhaacplus_dec->common_tables->down_mix_martix
392                     [k][1]
393                     [p_obj_exhaacplus_dec->aac_config.slot_element[i] + 1],
394                 ptr_time_data[j * total_channels +
395                               p_obj_exhaacplus_dec->aac_config.slot_element[i] +
396                               1]) >>
397             14);
398       }
399     }
400 
401     ptr_time_data[2 * j] = temp_l;
402     ptr_time_data[2 * j + 1] = temp_r;
403   }
404 }
405