205 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C
		
	
	
	
| /******************************************************************************
 | |
|  *                                                                            *
 | |
|  * Copyright (C) 2018 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at:
 | |
|  *
 | |
|  * http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  *
 | |
|  *****************************************************************************
 | |
|  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
 | |
| */
 | |
| #include "ixheaacd_sbr_common.h"
 | |
| #include "ixheaacd_type_def.h"
 | |
| 
 | |
| #include "ixheaacd_constants.h"
 | |
| #include "ixheaacd_basic_ops32.h"
 | |
| #include "ixheaacd_basic_ops16.h"
 | |
| #include "ixheaacd_basic_ops40.h"
 | |
| #include "ixheaacd_basic_ops.h"
 | |
| 
 | |
| #include "ixheaacd_defines.h"
 | |
| #include "ixheaacd_aac_rom.h"
 | |
| #include "ixheaacd_bitbuffer.h"
 | |
| #include "ixheaacd_common_rom.h"
 | |
| #include "ixheaacd_basic_funcs.h"
 | |
| 
 | |
| #include "ixheaacd_basic_op.h"
 | |
| #include "ixheaacd_intrinsics.h"
 | |
| 
 | |
| #include "ixheaacd_pulsedata.h"
 | |
| 
 | |
| #include "ixheaacd_pns.h"
 | |
| #include "ixheaacd_drc_data_struct.h"
 | |
| 
 | |
| #include "ixheaacd_lt_predict.h"
 | |
| #include "ixheaacd_channelinfo.h"
 | |
| #include "ixheaacd_channel.h"
 | |
| #include "ixheaacd_drc_dec.h"
 | |
| #include "ixheaacd_audioobjtypes.h"
 | |
| 
 | |
| #include "ixheaacd_stereo.h"
 | |
| 
 | |
| VOID ixheaacd_ms_stereo_process(
 | |
|     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2],
 | |
|     ia_aac_dec_tables_struct *ptr_aac_tables)
 | |
| 
 | |
| {
 | |
|   WORD32 win_grp, grp_len, k;
 | |
|   WORD32 *l_spec = ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff;
 | |
|   WORD32 *r_spec = ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff;
 | |
|   WORD8 *ptr_group_len =
 | |
|       ptr_aac_dec_channel_info[LEFT]->str_ics_info.window_group_length;
 | |
|   const WORD8 *ptr_sfb_width =
 | |
|       ptr_aac_tables
 | |
|           ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT]
 | |
|                                  ->str_ics_info.window_sequence]
 | |
|           .sfb_width;
 | |
| 
 | |
|   UWORD8 *ptr_ms_used =
 | |
|       &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0];
 | |
| 
 | |
|   for (win_grp = 0;
 | |
|        win_grp < ptr_aac_dec_channel_info[LEFT]->str_ics_info.num_window_groups;
 | |
|        win_grp++) {
 | |
|     for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) {
 | |
|       WORD32 sfb;
 | |
|       WORD32 ixheaacd_drc_offset = 0;
 | |
| 
 | |
|       for (sfb = 0; sfb < ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb;
 | |
|            sfb++) {
 | |
|         ixheaacd_drc_offset += ptr_sfb_width[sfb];
 | |
| 
 | |
|         if (*ptr_ms_used++) {
 | |
|           for (k = 0; k < ptr_sfb_width[sfb]; k = k + 2) {
 | |
|             WORD32 left_coef = *l_spec;
 | |
|             WORD32 right_coef = *r_spec;
 | |
|             WORD32 left_coef2 = *(l_spec + 1);
 | |
|             WORD32 right_coef2 = *(r_spec + 1);
 | |
| 
 | |
|             *l_spec++ = ixheaacd_add32_sat(left_coef, right_coef);
 | |
|             *r_spec++ = ixheaacd_sub32_sat(left_coef, right_coef);
 | |
|             *l_spec++ = ixheaacd_add32_sat(left_coef2, right_coef2);
 | |
|             *r_spec++ = ixheaacd_sub32_sat(left_coef2, right_coef2);
 | |
|           }
 | |
|         } else {
 | |
|           l_spec += ptr_sfb_width[sfb];
 | |
|           r_spec += ptr_sfb_width[sfb];
 | |
|         }
 | |
|       }
 | |
|       ptr_ms_used -= ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb;
 | |
|       l_spec = l_spec + 128 - ixheaacd_drc_offset;
 | |
|       r_spec = r_spec + 128 - ixheaacd_drc_offset;
 | |
|     }
 | |
| 
 | |
|     ptr_ms_used += JOINT_STEREO_MAX_BANDS;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32l(WORD32 a, WORD32 b) {
 | |
|   WORD32 result;
 | |
|   WORD64 temp_result;
 | |
| 
 | |
|   temp_result = (WORD64)a * (WORD64)b;
 | |
| 
 | |
|   result = (WORD32)(temp_result >> 16);
 | |
| 
 | |
|   return (result);
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_intensity_stereo_process(
 | |
|     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2],
 | |
|     ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type,
 | |
|     WORD32 aac_sf_data_resil_flag) {
 | |
|   UWORD8 *ptr_ms_used =
 | |
|       &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0];
 | |
|   WORD8 *ptr_code_book = &ptr_aac_dec_channel_info[RIGHT]->ptr_code_book[0];
 | |
|   WORD16 *ptr_scale_factor =
 | |
|       &ptr_aac_dec_channel_info[RIGHT]->ptr_scale_factor[0];
 | |
|   WORD32 *r_spec = &ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff[0];
 | |
|   WORD32 *l_spec = &ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff[0];
 | |
|   WORD8 *ptr_group_len =
 | |
|       ptr_aac_dec_channel_info[RIGHT]->str_ics_info.window_group_length;
 | |
|   const WORD8 *ptr_sfb_width =
 | |
|       ptr_aac_tables
 | |
|           ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT]
 | |
|                                  ->str_ics_info.window_sequence]
 | |
|           .sfb_width;
 | |
|   WORD32 *ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table;
 | |
|   WORD32 win_grp, grp_len, k;
 | |
| 
 | |
|   for (win_grp = 0;
 | |
|        win_grp <
 | |
|        ptr_aac_dec_channel_info[RIGHT]->str_ics_info.num_window_groups;
 | |
|        win_grp++) {
 | |
|     for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) {
 | |
|       WORD32 sfb;
 | |
|       WORD32 ixheaacd_drc_offset = 0;
 | |
| 
 | |
|       for (sfb = 0; sfb < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.max_sfb;
 | |
|            sfb++) {
 | |
|         WORD8 code_book = ptr_code_book[sfb];
 | |
|         ixheaacd_drc_offset += ptr_sfb_width[sfb];
 | |
| 
 | |
|         if (((code_book >= INTENSITY_HCB2) &&
 | |
|              ((object_type != AOT_ER_AAC_ELD) &&
 | |
|               (object_type != AOT_ER_AAC_LD))) ||
 | |
|             (((code_book == INTENSITY_HCB2) || (code_book == INTENSITY_HCB)) &&
 | |
|              ((object_type == AOT_ER_AAC_ELD) ||
 | |
|               (object_type == AOT_ER_AAC_LD))))
 | |
| 
 | |
|         {
 | |
|           WORD32 sfb_factor, scale;
 | |
|           WORD32 scf_exp;
 | |
| 
 | |
|           sfb_factor = (ptr_scale_factor[sfb]);
 | |
|           if (aac_sf_data_resil_flag) sfb_factor = -sfb_factor;
 | |
| 
 | |
|           scf_exp = (sfb_factor >> 2);
 | |
|           scale = *(ptr_scale_table + (sfb_factor & 3));
 | |
|           if (!((ptr_ms_used[sfb]) ^ (code_book & 0x1))) {
 | |
|             scale = ixheaacd_negate32(scale);
 | |
|           }
 | |
| 
 | |
|           scf_exp = -(scf_exp + 2);
 | |
| 
 | |
|           for (k = 0; k < ptr_sfb_width[sfb]; k++) {
 | |
|             WORD32 temp, shift_val;
 | |
|             temp = *l_spec++;
 | |
| 
 | |
|             shift_val = ixheaacd_norm32(temp);
 | |
|             temp = ixheaacd_shl32(temp, shift_val);
 | |
| 
 | |
|             temp = ixheaacd_mult32x16in32l(temp, scale);
 | |
|             shift_val = shift_val + scf_exp;
 | |
| 
 | |
|             if (shift_val < 0) {
 | |
|               temp = ixheaacd_shl32_sat(temp, -shift_val);
 | |
|             } else {
 | |
|               temp = ixheaacd_shr32(temp, shift_val);
 | |
|             }
 | |
|             *r_spec++ = temp;
 | |
|           }
 | |
| 
 | |
|         } else {
 | |
|           l_spec += ptr_sfb_width[sfb];
 | |
|           r_spec += ptr_sfb_width[sfb];
 | |
|         }
 | |
|       }
 | |
|       l_spec += 128 - ixheaacd_drc_offset;
 | |
|       r_spec += 128 - ixheaacd_drc_offset;
 | |
|     }
 | |
|     ptr_ms_used += 64;
 | |
|     ptr_code_book += 16;
 | |
|     ptr_scale_factor += 16;
 | |
|   }
 | |
| }
 |