Home | History | Annotate | Download | only in decoder
      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 
     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 
    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 
    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 
    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 
    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