1358 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1358 lines
		
	
	
		
			39 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_common_rom.h"
 | |
| #include "ixheaacd_basic_funcs.h"
 | |
| #include "ixheaacd_defines.h"
 | |
| #include "ixheaacd_aac_rom.h"
 | |
| #include "ixheaacd_bitbuffer.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_drc_dec.h"
 | |
| 
 | |
| #include "ixheaacd_block.h"
 | |
| #include "ixheaacd_channel.h"
 | |
| 
 | |
| #include "ixheaacd_basic_op.h"
 | |
| 
 | |
| #include "ixheaacd_tns.h"
 | |
| #include "ixheaacd_sbrdecoder.h"
 | |
| #include "ixheaacd_error_codes.h"
 | |
| 
 | |
| #include "ixheaacd_audioobjtypes.h"
 | |
| #include "ixheaacd_latmdemux.h"
 | |
| 
 | |
| #include "ixheaacd_aacdec.h"
 | |
| 
 | |
| static PLATFORM_INLINE WORD32 ixheaacd_shr32_drc(WORD32 a, WORD32 b) {
 | |
|   WORD32 out_val;
 | |
| 
 | |
|   b = ((UWORD32)(b << 24) >> 24);
 | |
|   if (b == 0) {
 | |
|     out_val = a;
 | |
|   } else if (b >= 31) {
 | |
|     if (a < 0)
 | |
|       out_val = -1;
 | |
|     else
 | |
|       out_val = 0;
 | |
|   } else {
 | |
|     a += (1 << (b - 1));
 | |
|     out_val = (WORD32)a >> b;
 | |
|   }
 | |
| 
 | |
|   return out_val;
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_drc(WORD32 a, WORD16 b) {
 | |
|   WORD32 result;
 | |
|   WORD64 temp_result;
 | |
| 
 | |
|   temp_result = (WORD64)a * (WORD64)b;
 | |
| 
 | |
|   if (temp_result < (WORD64)MIN_32)
 | |
|     result = MIN_32;
 | |
| 
 | |
|   else if (temp_result > (WORD64)MAX_32)
 | |
|     result = MAX_32;
 | |
| 
 | |
|   else
 | |
|     result = (WORD32)(temp_result);
 | |
| 
 | |
|   return (result);
 | |
| }
 | |
| static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32_drc(WORD32 a, WORD32 b,
 | |
|                                                         WORD16 c) {
 | |
|   WORD32 acc;
 | |
| 
 | |
|   acc = ixheaacd_mult32x16in32_drc(b, c);
 | |
| 
 | |
|   acc = ixheaacd_add32_sat(a, acc);
 | |
| 
 | |
|   return acc;
 | |
| }
 | |
| 
 | |
| WORD32 ixheaacd_cnt_leading_ones(WORD32 a);
 | |
| 
 | |
| VOID ixheaacd_huff_sfb_table(WORD32 it_bit_buff, WORD16 *huff_index,
 | |
|                              WORD32 *len, const UWORD16 *code_book_tbl,
 | |
|                              const UWORD32 *idx_table) {
 | |
|   UWORD32 temp = 0;
 | |
|   UWORD32 temp1 = 0;
 | |
|   WORD32 found = 0;
 | |
|   UWORD32 mask = 0x80000000;
 | |
| 
 | |
|   WORD32 leading_ones;
 | |
|   WORD32 max_len;
 | |
|   WORD32 ixheaacd_drc_offset = 0;
 | |
|   WORD32 length;
 | |
|   UWORD32 code_word;
 | |
|   WORD32 len_end;
 | |
| 
 | |
|   max_len = code_book_tbl[0];
 | |
|   mask = mask - (1 << (31 - max_len));
 | |
|   mask = mask << 1;
 | |
| 
 | |
|   temp = (UWORD32)((it_bit_buff & mask));
 | |
| 
 | |
|   len_end = code_book_tbl[0];
 | |
|   leading_ones = ixheaacd_cnt_leading_ones(temp);
 | |
|   do {
 | |
|     ixheaacd_drc_offset = (idx_table[leading_ones] >> 20) & 0x1ff;
 | |
|     length = code_book_tbl[ixheaacd_drc_offset + 1] & 0x1f;
 | |
|     code_word = idx_table[leading_ones] & 0xfffff;
 | |
|     temp1 = temp >> (32 - length);
 | |
|     if (temp1 <= code_word) {
 | |
|       ixheaacd_drc_offset = ixheaacd_drc_offset - (code_word - temp1);
 | |
|       found = 1;
 | |
|     } else {
 | |
|       len_end = len_end + ((idx_table[leading_ones] >> 29) & 0x7);
 | |
|       leading_ones = len_end;
 | |
|     }
 | |
|   } while (!found);
 | |
|   *huff_index = code_book_tbl[ixheaacd_drc_offset + 1] >> 5;
 | |
|   *len = length;
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_inverse_quantize(WORD32 *x_invquant, WORD no_band,
 | |
|                                WORD32 *ixheaacd_pow_table_Q13,
 | |
|                                WORD8 *scratch_in) {
 | |
|   WORD32 j;
 | |
|   WORD32 temp;
 | |
|   WORD32 q_abs;
 | |
| 
 | |
|   for (j = no_band - 1; j >= 0; j--) {
 | |
|     q_abs = *scratch_in++;
 | |
|     temp = (ixheaacd_pow_table_Q13[q_abs]);
 | |
|     *x_invquant++ = -temp;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD ixheaacd_huffman_dec_word1(
 | |
|     ia_bit_buf_struct *it_bit_buff, WORD32 *spec_coef, WORD16 *offsets,
 | |
|     WORD no_bands, WORD group_len, const UWORD16 *code_book_tbl,
 | |
|     WORD32 *ixheaacd_pow_table_Q13, const UWORD32 *idx_table) {
 | |
|   WORD32 sp1, sp2;
 | |
|   WORD32 flush_cw;
 | |
|   WORD32 i, value, norm_val, off;
 | |
|   WORD idx, grp_idx;
 | |
|   WORD32 out1, out2;
 | |
|   WORD32 err_code = 0;
 | |
|   WORD len_idx = 0;
 | |
|   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
 | |
|   WORD32 bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD16 index;
 | |
|   WORD32 length;
 | |
|   WORD32 read_word;
 | |
|   WORD32 increment;
 | |
| 
 | |
|   read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
 | |
|                                        &increment);
 | |
|   ptr_read_next += increment;
 | |
| 
 | |
|   do {
 | |
|     len_idx = offsets[1] - offsets[0];
 | |
|     grp_idx = group_len;
 | |
| 
 | |
|     do {
 | |
|       spec_coef = spec_coef + offsets[0];
 | |
|       idx = len_idx;
 | |
|       do {
 | |
|         {
 | |
|           UWORD32 read_word1;
 | |
| 
 | |
|           read_word1 = read_word << bit_pos;
 | |
|           ixheaacd_huff_sfb_table(read_word1, &index, &length, code_book_tbl,
 | |
|                                   idx_table);
 | |
|           bit_pos += length;
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
|         }
 | |
| 
 | |
|         out1 = index / 17;
 | |
|         out2 = index - out1 * 17;
 | |
|         flush_cw = read_word << bit_pos;
 | |
| 
 | |
|         sp1 = out1;
 | |
|         sp2 = out2;
 | |
| 
 | |
|         if (out1) {
 | |
|           if (flush_cw & 0x80000000) {
 | |
|             out1 = -out1;
 | |
|           }
 | |
|           bit_pos++;
 | |
|           flush_cw = (WORD32)flush_cw << 1;
 | |
|         }
 | |
| 
 | |
|         if (out2) {
 | |
|           bit_pos++;
 | |
|           if (flush_cw & 0x80000000) {
 | |
|             out2 = -out2;
 | |
|           }
 | |
|         }
 | |
|         ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                     it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|         if (sp1 == 16) {
 | |
|           i = 4;
 | |
|           value = ixheaacd_extu(read_word, bit_pos, 23);
 | |
|           value = value | 0xfffffe00;
 | |
|           norm_val = ixheaacd_norm32(value);
 | |
| 
 | |
|           i += (norm_val - 22);
 | |
|           bit_pos += (norm_val - 21);
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|           off = ixheaacd_extu(read_word, bit_pos, 32 - i);
 | |
| 
 | |
|           bit_pos += i;
 | |
| 
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|           i = off + ((WORD32)1 << i);
 | |
| 
 | |
|           if (i <= IQ_TABLE_SIZE_HALF)
 | |
|             i = ixheaacd_pow_table_Q13[i];
 | |
|           else {
 | |
|             err_code |= ixheaacd_inv_quant(&i, ixheaacd_pow_table_Q13);
 | |
|           }
 | |
| 
 | |
|           if (out1 < 0) {
 | |
|             out1 = -i;
 | |
|           } else {
 | |
|             out1 = i;
 | |
|           }
 | |
|           *spec_coef++ = out1;
 | |
|         } else {
 | |
|           if (out1 <= 0) {
 | |
|             out1 = -out1;
 | |
|             out1 = ixheaacd_pow_table_Q13[out1];
 | |
|             *spec_coef++ = -out1;
 | |
|           } else {
 | |
|             out1 = ixheaacd_pow_table_Q13[out1];
 | |
|             *spec_coef++ = out1;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         if (sp2 == 16) {
 | |
|           i = 4;
 | |
|           value = ixheaacd_extu(read_word, bit_pos, 23);
 | |
|           value = value | 0xfffffe00;
 | |
|           norm_val = ixheaacd_norm32(value);
 | |
| 
 | |
|           i += (norm_val - 22);
 | |
| 
 | |
|           bit_pos += (norm_val - 21);
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|           off = ixheaacd_extu(read_word, bit_pos, 32 - i);
 | |
| 
 | |
|           bit_pos += i;
 | |
| 
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
|           ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                       it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|           i = off + ((WORD32)1 << i);
 | |
| 
 | |
|           if (i <= IQ_TABLE_SIZE_HALF)
 | |
|             i = ixheaacd_pow_table_Q13[i];
 | |
|           else {
 | |
|             err_code |= ixheaacd_inv_quant(&i, ixheaacd_pow_table_Q13);
 | |
|           }
 | |
| 
 | |
|           if (out2 < 0) {
 | |
|             out2 = -i;
 | |
|           } else {
 | |
|             out2 = i;
 | |
|           }
 | |
|           *spec_coef++ = out2;
 | |
|         } else {
 | |
|           if (out2 <= 0) {
 | |
|             out2 = -out2;
 | |
|             out2 = ixheaacd_pow_table_Q13[out2];
 | |
|             *spec_coef++ = -out2;
 | |
|           } else {
 | |
|             out2 = ixheaacd_pow_table_Q13[out2];
 | |
|             *spec_coef++ = out2;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         idx -= 2;
 | |
|       } while (idx != 0);
 | |
| 
 | |
|       spec_coef += (MAX_BINS_SHORT - offsets[1]);
 | |
|       grp_idx--;
 | |
|     } while (grp_idx != 0);
 | |
| 
 | |
|     offsets++;
 | |
|     spec_coef -= (MAX_BINS_SHORT * group_len);
 | |
|     no_bands--;
 | |
|   } while (no_bands >= 0);
 | |
| 
 | |
|   ptr_read_next = ptr_read_next - increment;
 | |
|   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|   it_bit_buff->bit_pos = bit_pos;
 | |
|   it_bit_buff->ptr_read_next = ptr_read_next;
 | |
| 
 | |
|   return err_code;
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD ixheaacd_huffman_dec_word2_11(
 | |
|     ia_bit_buf_struct *it_bit_buff, WORD32 width, const UWORD16 *code_book_tbl,
 | |
|     WORD32 *x_invquant, WORD32 *ixheaacd_pow_table_Q13, WORD8 *ptr_scratch,
 | |
|     const UWORD32 *idx_table) {
 | |
|   WORD32 sp1, sp2;
 | |
|   WORD32 flush_cw;
 | |
|   WORD32 i, value, norm_val, off;
 | |
|   WORD idx;
 | |
|   WORD32 out1, out2;
 | |
|   WORD32 err_code = 0;
 | |
|   WORD16 index;
 | |
|   WORD32 length;
 | |
|   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
 | |
|   WORD32 bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD32 read_word;
 | |
|   WORD32 increment;
 | |
| 
 | |
|   read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
 | |
|                                        &increment);
 | |
|   ptr_read_next += increment;
 | |
| 
 | |
|   for (idx = width; idx != 0; idx -= 2) {
 | |
|     {
 | |
|       UWORD32 read_word1;
 | |
| 
 | |
|       read_word1 = read_word << bit_pos;
 | |
|       ixheaacd_huff_sfb_table(read_word1, &index, &length, code_book_tbl,
 | |
|                               idx_table);
 | |
|       bit_pos += length;
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
|     }
 | |
| 
 | |
|     flush_cw = read_word << bit_pos;
 | |
|     out1 = index / 17;
 | |
|     out2 = index - out1 * 17;
 | |
|     sp1 = out1;
 | |
| 
 | |
|     if (out1) {
 | |
|       if (flush_cw & 0x80000000) {
 | |
|         out1 = -out1;
 | |
|       }
 | |
| 
 | |
|       bit_pos++;
 | |
|       flush_cw = (WORD32)flush_cw << 1;
 | |
|     }
 | |
| 
 | |
|     sp2 = out2;
 | |
|     if (out2) {
 | |
|       bit_pos++;
 | |
|       if (flush_cw & 0x80000000) {
 | |
|         out2 = -out2;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                 it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|     if (sp1 == 16) {
 | |
|       i = 4;
 | |
|       value = ixheaacd_extu(read_word, bit_pos, 23);
 | |
|       value = value | 0xfffffe00;
 | |
|       norm_val = ixheaacd_norm32(value);
 | |
|       i += (norm_val - 22);
 | |
|       bit_pos += (norm_val - 21);
 | |
| 
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|       off = ixheaacd_extu(read_word, bit_pos, 32 - i);
 | |
| 
 | |
|       bit_pos += i;
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|       value = *ptr_scratch++;
 | |
| 
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
|       i = off + ((WORD32)1 << i);
 | |
|       i += value;
 | |
| 
 | |
|       if (i <= IQ_TABLE_SIZE_HALF)
 | |
|         i = ixheaacd_pow_table_Q13[i];
 | |
|       else {
 | |
|         err_code |= ixheaacd_inv_quant(&i, ixheaacd_pow_table_Q13);
 | |
|       }
 | |
|       if (out1 < 0) {
 | |
|         i = -i;
 | |
|       }
 | |
|       *x_invquant++ = i;
 | |
|     } else {
 | |
|       WORD8 temp = *ptr_scratch++;
 | |
|       if (out1 <= 0) {
 | |
|         out1 = temp - out1;
 | |
|         out1 = ixheaacd_pow_table_Q13[out1];
 | |
|         *x_invquant++ = -out1;
 | |
|       } else {
 | |
|         out1 += temp;
 | |
|         out1 = ixheaacd_pow_table_Q13[out1];
 | |
|         *x_invquant++ = out1;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (sp2 == 16) {
 | |
|       i = 4;
 | |
|       value = ixheaacd_extu(read_word, bit_pos, 23);
 | |
|       value = value | 0xfffffe00;
 | |
|       norm_val = ixheaacd_norm32(value);
 | |
| 
 | |
|       i += (norm_val - 22);
 | |
| 
 | |
|       bit_pos += (norm_val - 21);
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|       off = ixheaacd_extu(read_word, bit_pos, 32 - i);
 | |
| 
 | |
|       bit_pos += i;
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
|       value = *ptr_scratch++;
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|       i = off + ((WORD32)1 << i);
 | |
|       i += value;
 | |
|       if (i <= IQ_TABLE_SIZE_HALF)
 | |
|         i = ixheaacd_pow_table_Q13[i];
 | |
|       else {
 | |
|         err_code |= ixheaacd_inv_quant(&i, ixheaacd_pow_table_Q13);
 | |
|       }
 | |
| 
 | |
|       if (out2 < 0) {
 | |
|         i = -i;
 | |
|       }
 | |
|       *x_invquant++ = i;
 | |
| 
 | |
|     } else {
 | |
|       WORD8 temp = *ptr_scratch++;
 | |
|       if (out2 <= 0) {
 | |
|         out2 = temp - out2;
 | |
|         out2 = ixheaacd_pow_table_Q13[out2];
 | |
|         *x_invquant++ = -out2;
 | |
|       } else {
 | |
|         out2 += temp;
 | |
|         out2 = ixheaacd_pow_table_Q13[out2];
 | |
|         *x_invquant++ = out2;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   ptr_read_next = ptr_read_next - increment;
 | |
|   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                it_bit_buff->ptr_bit_buf_end);
 | |
| 
 | |
|   it_bit_buff->ptr_read_next = ptr_read_next;
 | |
|   it_bit_buff->bit_pos = bit_pos;
 | |
| 
 | |
|   return err_code;
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD ixheaacd_huffman_dec_quad(
 | |
|     ia_bit_buf_struct *it_bit_buff, WORD32 *spec_coef, WORD16 *offsets,
 | |
|     WORD no_bands, WORD group_len, const UWORD16 *code_book_tbl,
 | |
|     WORD32 *ixheaacd_pow_table_Q13, WORD32 tbl_sign, const UWORD32 *idx_table) {
 | |
|   WORD idx, grp_idx;
 | |
|   WORD idx_len;
 | |
|   WORD32 *spec_orig;
 | |
|   WORD16 index, length;
 | |
|   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
 | |
|   WORD32 bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD32 read_word;
 | |
|   WORD32 increment;
 | |
| 
 | |
|   read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
 | |
|                                        &increment);
 | |
|   ptr_read_next += increment;
 | |
|   spec_orig = spec_coef;
 | |
|   do {
 | |
|     idx_len = offsets[1] - offsets[0];
 | |
|     grp_idx = group_len;
 | |
| 
 | |
|     do {
 | |
|       spec_coef = spec_coef + offsets[0];
 | |
|       idx = idx_len;
 | |
|       do {
 | |
|         UWORD32 read_word1;
 | |
| 
 | |
|         read_word1 = read_word << bit_pos;
 | |
|         ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
 | |
|                                 idx_table);
 | |
|         bit_pos += length;
 | |
|         ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                     it_bit_buff->ptr_bit_buf_end);
 | |
|         if (tbl_sign) {
 | |
|           WORD32 temp_word;
 | |
|           WORD32 w, x, y, z;
 | |
|           temp_word = read_word << bit_pos;
 | |
|           w = index / 27;
 | |
|           index = index - w * 27;
 | |
|           x = index / 9;
 | |
|           index = index - x * 9;
 | |
|           y = index / 3;
 | |
|           z = index - y * 3;
 | |
|           if (w) {
 | |
|             w = ixheaacd_pow_table_Q13[w];
 | |
|             if (temp_word & 0x80000000) w = -w;
 | |
|             temp_word <<= 1;
 | |
|             bit_pos++;
 | |
|           }
 | |
|           *spec_coef++ = w;
 | |
| 
 | |
|           if (x) {
 | |
|             x = ixheaacd_pow_table_Q13[x];
 | |
|             if (temp_word & 0x80000000) x = -x;
 | |
|             temp_word <<= 1;
 | |
|             bit_pos++;
 | |
|           }
 | |
|           *spec_coef++ = x;
 | |
|           if (y) {
 | |
|             y = ixheaacd_pow_table_Q13[y];
 | |
|             if (temp_word & 0x80000000) y = -y;
 | |
|             temp_word <<= 1;
 | |
|             bit_pos++;
 | |
|           }
 | |
|           *spec_coef++ = y;
 | |
|           if (z) {
 | |
|             z = ixheaacd_pow_table_Q13[z];
 | |
|             if (temp_word & 0x80000000) z = -z;
 | |
|             temp_word <<= 1;
 | |
|             bit_pos++;
 | |
|           }
 | |
|           *spec_coef++ = z;
 | |
| 
 | |
|         }
 | |
| 
 | |
|         else {
 | |
|           WORD32 w, x, y, z;
 | |
| 
 | |
|           w = index / 27 - 1;
 | |
|           index = index - (w + 1) * 27;
 | |
|           x = index / 9 - 1;
 | |
|           index = index - (x + 1) * 9;
 | |
|           y = index / 3 - 1;
 | |
|           z = index - ((y + 1) * 3) - 1;
 | |
|           if (w < 0) {
 | |
|             w = -w;
 | |
|             w = ixheaacd_pow_table_Q13[w];
 | |
|             w = -w;
 | |
|           } else
 | |
|             w = ixheaacd_pow_table_Q13[w];
 | |
| 
 | |
|           *spec_coef++ = w;
 | |
| 
 | |
|           if (x < 0) {
 | |
|             x = -x;
 | |
|             x = ixheaacd_pow_table_Q13[x];
 | |
|             x = -x;
 | |
|           } else
 | |
|             x = ixheaacd_pow_table_Q13[x];
 | |
| 
 | |
|           *spec_coef++ = x;
 | |
| 
 | |
|           if (y < 0) {
 | |
|             y = -y;
 | |
|             y = ixheaacd_pow_table_Q13[y];
 | |
|             y = -y;
 | |
|           } else
 | |
|             y = ixheaacd_pow_table_Q13[y];
 | |
| 
 | |
|           *spec_coef++ = y;
 | |
| 
 | |
|           if (z < 0) {
 | |
|             z = -z;
 | |
|             z = ixheaacd_pow_table_Q13[z];
 | |
|             z = -z;
 | |
|           } else
 | |
|             z = ixheaacd_pow_table_Q13[z];
 | |
| 
 | |
|           *spec_coef++ = z;
 | |
|         }
 | |
| 
 | |
|         ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                     it_bit_buff->ptr_bit_buf_end);
 | |
|         idx -= 4;
 | |
|       } while (idx != 0);
 | |
| 
 | |
|       spec_coef += (MAX_BINS_SHORT - offsets[1]);
 | |
|       grp_idx--;
 | |
|     } while (grp_idx != 0);
 | |
|     offsets++;
 | |
|     spec_coef = spec_orig;
 | |
|     no_bands--;
 | |
|   } while (no_bands >= 0);
 | |
| 
 | |
|   ptr_read_next = ptr_read_next - increment;
 | |
|   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                it_bit_buff->ptr_bit_buf_end);
 | |
|   it_bit_buff->ptr_read_next = ptr_read_next;
 | |
|   it_bit_buff->bit_pos = bit_pos;
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD ixheaacd_huffman_dec_word2_quad(
 | |
|     ia_bit_buf_struct *it_bit_buff, WORD32 width, const UWORD16 *code_book_tbl,
 | |
|     WORD32 *x_invquant, WORD32 *ixheaacd_pow_table_Q13, WORD8 *ptr_scratch,
 | |
|     WORD32 tbl_sign, const UWORD32 *idx_table) {
 | |
|   WORD idx;
 | |
|   WORD16 index, length;
 | |
|   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
 | |
|   WORD32 bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD32 read_word;
 | |
|   WORD32 increment;
 | |
| 
 | |
|   read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
 | |
|                                        &increment);
 | |
|   ptr_read_next += increment;
 | |
| 
 | |
|   for (idx = width; idx != 0; idx -= 4) {
 | |
|     WORD32 ampres, ampres1;
 | |
|     WORD32 ampres2, ampres3;
 | |
|     UWORD32 read_word1;
 | |
| 
 | |
|     read_word1 = read_word << bit_pos;
 | |
|     ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
 | |
|                             idx_table);
 | |
|     bit_pos += length;
 | |
|     ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                 it_bit_buff->ptr_bit_buf_end);
 | |
|     if (tbl_sign) {
 | |
|       WORD32 w, x, y, z;
 | |
|       WORD32 ampout0, ampout1, ampout2, ampout3;
 | |
|       WORD32 temp_word;
 | |
|       temp_word = read_word << bit_pos;
 | |
| 
 | |
|       w = index / 27;
 | |
|       index = index - w * 27;
 | |
|       x = index / 9;
 | |
|       index = index - x * 9;
 | |
|       y = index / 3;
 | |
|       z = index - y * 3;
 | |
| 
 | |
|       ampout0 = w + *ptr_scratch++;
 | |
|       ampout0 = ixheaacd_pow_table_Q13[ampout0];
 | |
| 
 | |
|       if (w) {
 | |
|         if (temp_word & 0x80000000) {
 | |
|           ampout0 = -ampout0;
 | |
|         }
 | |
|         temp_word = temp_word << 1;
 | |
|         bit_pos++;
 | |
|       } else {
 | |
|         ampout0 = -ampout0;
 | |
|       }
 | |
| 
 | |
|       ampout1 = x + *ptr_scratch++;
 | |
|       ampout1 = ixheaacd_pow_table_Q13[ampout1];
 | |
| 
 | |
|       if (x) {
 | |
|         if (temp_word & 0x80000000) {
 | |
|           ampout1 = -ampout1;
 | |
|         }
 | |
|         temp_word = temp_word << 1;
 | |
|         bit_pos++;
 | |
|       } else {
 | |
|         ampout1 = -ampout1;
 | |
|       }
 | |
| 
 | |
|       ampout2 = y + *ptr_scratch++;
 | |
|       ampout2 = ixheaacd_pow_table_Q13[ampout2];
 | |
| 
 | |
|       if (y) {
 | |
|         if (temp_word & 0x80000000) {
 | |
|           ampout2 = -ampout2;
 | |
|         }
 | |
|         temp_word = temp_word << 1;
 | |
|         bit_pos++;
 | |
|       } else {
 | |
|         ampout2 = -ampout2;
 | |
|       }
 | |
| 
 | |
|       ampout3 = z + *ptr_scratch++;
 | |
|       ampout3 = ixheaacd_pow_table_Q13[ampout3];
 | |
| 
 | |
|       if (z) {
 | |
|         if (temp_word & 0x80000000) {
 | |
|           ampout3 = -ampout3;
 | |
|         }
 | |
|         temp_word = temp_word << 1;
 | |
|         bit_pos++;
 | |
|       } else {
 | |
|         ampout3 = -ampout3;
 | |
|       }
 | |
|       *x_invquant++ = ampout0;
 | |
|       *x_invquant++ = ampout1;
 | |
|       *x_invquant++ = ampout2;
 | |
|       *x_invquant++ = ampout3;
 | |
|     } else {
 | |
|       WORD32 w, x, y, z;
 | |
|       ampres = *ptr_scratch++;
 | |
|       ampres1 = *ptr_scratch++;
 | |
|       ampres2 = *ptr_scratch++;
 | |
|       ampres3 = *ptr_scratch++;
 | |
| 
 | |
|       w = index / 27 - 1;
 | |
|       index = index - (w + 1) * 27;
 | |
|       x = index / 9 - 1;
 | |
|       index = index - (x + 1) * 9;
 | |
|       y = index / 3 - 1;
 | |
|       z = index - ((y + 1) * 3) - 1;
 | |
|       if (w <= 0) {
 | |
|         ampres = ampres - w;
 | |
|         ampres = ixheaacd_pow_table_Q13[ampres];
 | |
|         ampres = -ampres;
 | |
|       } else {
 | |
|         ampres += w;
 | |
|         ampres = ixheaacd_pow_table_Q13[ampres];
 | |
|       }
 | |
| 
 | |
|       if (x <= 0) {
 | |
|         ampres1 = ampres1 - x;
 | |
|         ampres1 = ixheaacd_pow_table_Q13[ampres1];
 | |
|         ampres1 = -ampres1;
 | |
|       } else {
 | |
|         ampres1 += x;
 | |
|         ampres1 = ixheaacd_pow_table_Q13[ampres1];
 | |
|       }
 | |
| 
 | |
|       if (y <= 0) {
 | |
|         ampres2 = ampres2 - y;
 | |
|         ampres2 = ixheaacd_pow_table_Q13[ampres2];
 | |
|         ampres2 = -ampres2;
 | |
|       } else {
 | |
|         ampres2 += y;
 | |
|         ampres2 = ixheaacd_pow_table_Q13[ampres2];
 | |
|       }
 | |
| 
 | |
|       if (z <= 0) {
 | |
|         ampres3 = ampres3 - z;
 | |
|         ampres3 = ixheaacd_pow_table_Q13[ampres3];
 | |
|         ampres3 = -ampres3;
 | |
|       } else {
 | |
|         ampres3 += z;
 | |
|         ampres3 = ixheaacd_pow_table_Q13[ampres3];
 | |
|       }
 | |
| 
 | |
|       *x_invquant++ = ampres;
 | |
|       *x_invquant++ = ampres1;
 | |
|       *x_invquant++ = ampres2;
 | |
|       *x_invquant++ = ampres3;
 | |
|     }
 | |
| 
 | |
|     ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                 it_bit_buff->ptr_bit_buf_end);
 | |
|   }
 | |
| 
 | |
|   ptr_read_next = ptr_read_next - increment;
 | |
|   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                it_bit_buff->ptr_bit_buf_end);
 | |
|   it_bit_buff->ptr_read_next = ptr_read_next;
 | |
|   it_bit_buff->bit_pos = bit_pos;
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD ixheaacd_huffman_dec_pair(
 | |
|     ia_bit_buf_struct *it_bit_buff, WORD32 *spec_coef, WORD16 *offsets,
 | |
|     WORD no_bands, WORD group_len, const UWORD16 *code_book_tbl,
 | |
|     WORD32 *ixheaacd_pow_table_Q13, WORD32 tbl_sign, const UWORD32 *idx_table,
 | |
|     WORD32 huff_mode)
 | |
| 
 | |
| {
 | |
|   WORD idx, grp_idx;
 | |
|   WORD len_idx;
 | |
|   WORD16 index, length;
 | |
|   WORD32 y, z;
 | |
|   WORD32 *spec_orig = spec_coef;
 | |
| 
 | |
|   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
 | |
|   WORD32 bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD32 read_word;
 | |
|   WORD32 increment;
 | |
| 
 | |
|   read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
 | |
|                                        &increment);
 | |
|   ptr_read_next += increment;
 | |
| 
 | |
|   do {
 | |
|     len_idx = offsets[1] - offsets[0];
 | |
|     grp_idx = group_len;
 | |
|     do {
 | |
|       spec_coef += offsets[0];
 | |
|       idx = len_idx;
 | |
|       do {
 | |
|         UWORD32 read_word1;
 | |
|         read_word1 = read_word << bit_pos;
 | |
|         ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
 | |
|                                 idx_table);
 | |
|         bit_pos += length;
 | |
|         ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                     it_bit_buff->ptr_bit_buf_end);
 | |
|         if (tbl_sign) {
 | |
|           WORD32 temp_word;
 | |
|           temp_word = read_word << bit_pos;
 | |
|           y = index / huff_mode;
 | |
|           z = index - huff_mode * y;
 | |
|           if (y) {
 | |
|             y = ixheaacd_pow_table_Q13[y];
 | |
|             if (temp_word & 0x80000000) y = -y;
 | |
| 
 | |
|             temp_word = temp_word << 1;
 | |
|             bit_pos++;
 | |
|           }
 | |
|           *spec_coef++ = y;
 | |
| 
 | |
|           if (z) {
 | |
|             z = ixheaacd_pow_table_Q13[z];
 | |
|             if (temp_word & 0x80000000) {
 | |
|               z = -z;
 | |
|             }
 | |
|             temp_word <<= 1;
 | |
|             bit_pos++;
 | |
|           }
 | |
|           *spec_coef++ = z;
 | |
|         } else {
 | |
|           y = (index / huff_mode) - 4;
 | |
|           z = index - ((y + 4) * huff_mode) - 4;
 | |
|           if (y < 0) {
 | |
|             y = -y;
 | |
|             y = ixheaacd_pow_table_Q13[y];
 | |
|             y = -y;
 | |
|           } else
 | |
|             y = ixheaacd_pow_table_Q13[y];
 | |
| 
 | |
|           if (z < 0) {
 | |
|             z = -z;
 | |
|             z = ixheaacd_pow_table_Q13[z];
 | |
|             z = -z;
 | |
|           } else
 | |
|             z = ixheaacd_pow_table_Q13[z];
 | |
| 
 | |
|           *spec_coef++ = y;
 | |
|           *spec_coef++ = z;
 | |
|         }
 | |
|         ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                     it_bit_buff->ptr_bit_buf_end);
 | |
|         idx -= 2;
 | |
|       } while (idx != 0);
 | |
| 
 | |
|       spec_coef += (MAX_BINS_SHORT - offsets[1]);
 | |
|       grp_idx--;
 | |
|     } while (grp_idx != 0);
 | |
| 
 | |
|     offsets++;
 | |
|     spec_coef = spec_orig;
 | |
|     no_bands--;
 | |
|   } while (no_bands >= 0);
 | |
| 
 | |
|   ptr_read_next = ptr_read_next - increment;
 | |
|   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                it_bit_buff->ptr_bit_buf_end);
 | |
|   it_bit_buff->ptr_read_next = ptr_read_next;
 | |
|   it_bit_buff->bit_pos = bit_pos;
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE WORD ixheaacd_huffman_dec_word2_pair(
 | |
|     ia_bit_buf_struct *it_bit_buff, WORD32 width, const UWORD16 *code_book_tbl,
 | |
|     WORD32 *x_invquant, WORD32 *ixheaacd_pow_table_Q13, WORD8 *ptr_scratch,
 | |
|     WORD32 tbl_sign, const UWORD32 *idx_table, WORD32 huff_mode)
 | |
| 
 | |
| {
 | |
|   WORD32 ampres;
 | |
|   WORD idx;
 | |
|   WORD16 index, length;
 | |
|   UWORD8 *ptr_read_next = it_bit_buff->ptr_read_next;
 | |
|   WORD32 bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD32 read_word;
 | |
|   WORD32 increment;
 | |
| 
 | |
|   read_word = ixheaacd_aac_showbits_32(ptr_read_next, it_bit_buff->cnt_bits,
 | |
|                                        &increment);
 | |
|   ptr_read_next += increment;
 | |
| 
 | |
|   for (idx = width; idx != 0; idx -= 2) {
 | |
|     {
 | |
|       UWORD32 read_word1;
 | |
|       read_word1 = read_word << bit_pos;
 | |
|       ixheaacd_huffman_decode(read_word1, &index, &length, code_book_tbl,
 | |
|                               idx_table);
 | |
|       bit_pos += length;
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
|     }
 | |
| 
 | |
|     if (tbl_sign) {
 | |
|       WORD32 out0, out1, temp_word;
 | |
|       WORD32 ampout0, ampout1;
 | |
| 
 | |
|       ampout0 = *ptr_scratch++;
 | |
|       ampout1 = *ptr_scratch++;
 | |
|       out0 = index / huff_mode;
 | |
|       out1 = index - huff_mode * out0;
 | |
|       ampout0 += out0;
 | |
|       ampout0 = ixheaacd_pow_table_Q13[ampout0];
 | |
| 
 | |
|       ampout1 += out1;
 | |
|       ampout1 = ixheaacd_pow_table_Q13[ampout1];
 | |
|       temp_word = read_word << bit_pos;
 | |
|       if (out0) {
 | |
|         if (temp_word & 0x80000000) {
 | |
|           ampout0 = -(ampout0);
 | |
|         }
 | |
| 
 | |
|         bit_pos++;
 | |
|         temp_word = temp_word << 1;
 | |
|       } else {
 | |
|         ampout0 = -(ampout0);
 | |
|       }
 | |
| 
 | |
|       if (out1) {
 | |
|         if (temp_word & 0x80000000) {
 | |
|           ampout1 = -(ampout1);
 | |
|         }
 | |
|         bit_pos++;
 | |
|       } else {
 | |
|         ampout1 = -(ampout1);
 | |
|       }
 | |
| 
 | |
|       ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                   it_bit_buff->ptr_bit_buf_end);
 | |
|       *x_invquant++ = ampout0;
 | |
|       *x_invquant++ = ampout1;
 | |
|     } else {
 | |
|       WORD32 y, z;
 | |
|       y = (index / huff_mode) - 4;
 | |
|       z = index - ((y + 4) * huff_mode) - 4;
 | |
| 
 | |
|       ampres = *ptr_scratch++;
 | |
|       if (y <= 0) {
 | |
|         ampres = ampres - y;
 | |
|         ampres = ixheaacd_pow_table_Q13[ampres];
 | |
|         *x_invquant++ = -ampres;
 | |
|       } else {
 | |
|         ampres += y;
 | |
|         *x_invquant++ = ixheaacd_pow_table_Q13[ampres];
 | |
|       }
 | |
|       ampres = *ptr_scratch++;
 | |
|       if (z <= 0) {
 | |
|         ampres = ampres - z;
 | |
|         ampres = ixheaacd_pow_table_Q13[ampres];
 | |
|         *x_invquant++ = -ampres;
 | |
|       } else {
 | |
|         ampres += z;
 | |
|         *x_invquant++ = ixheaacd_pow_table_Q13[ampres];
 | |
|       }
 | |
|     }
 | |
|     ixheaacd_aac_read_byte_corr(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                 it_bit_buff->ptr_bit_buf_end);
 | |
|   }
 | |
| 
 | |
|   ptr_read_next = ptr_read_next - increment;
 | |
|   ixheaacd_aac_read_byte_corr1(&ptr_read_next, &bit_pos, &read_word,
 | |
|                                it_bit_buff->ptr_bit_buf_end);
 | |
|   it_bit_buff->ptr_read_next = ptr_read_next;
 | |
|   it_bit_buff->bit_pos = bit_pos;
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| WORD ixheaacd_decode_huffman(ia_bit_buf_struct *it_bit_buff, WORD32 cb_no,
 | |
|                              WORD32 *spec_coef, WORD16 *sfb_offset, WORD start,
 | |
|                              WORD sfb, WORD group_len,
 | |
|                              ia_aac_dec_tables_struct *ptr_aac_tables) {
 | |
|   WORD ret_val = 0;
 | |
|   WORD start_bit_pos = it_bit_buff->bit_pos;
 | |
|   UWORD8 *start_read_pos = it_bit_buff->ptr_read_next;
 | |
|   const UWORD16 *cb_table = (UWORD16 *)(ptr_aac_tables->code_book[cb_no]);
 | |
|   WORD32 huff_mode;
 | |
|   const UWORD32 *idx_table = (UWORD32 *)(ptr_aac_tables->index_table[cb_no]);
 | |
|   WORD32 *pow_table =
 | |
|       (WORD32 *)ptr_aac_tables->pstr_block_tables->ixheaacd_pow_table_Q13;
 | |
|   WORD32 no_bands = sfb - start - 1;
 | |
|   WORD16 *band_offset = sfb_offset + start;
 | |
| 
 | |
|   if (cb_no == 11) {
 | |
|     const UWORD32 *idx_table =
 | |
|         ptr_aac_tables->pstr_huffmann_tables->idx_table_hf11;
 | |
|     const UWORD16 *cb_table =
 | |
|         ptr_aac_tables->pstr_huffmann_tables->input_table_cb11;
 | |
| 
 | |
|     ret_val = ixheaacd_huffman_dec_word1(it_bit_buff, spec_coef, band_offset,
 | |
|                                          no_bands, group_len, cb_table,
 | |
|                                          pow_table, idx_table);
 | |
| 
 | |
|   } else if (cb_no <= 4) {
 | |
|     WORD32 tbl_sign = 0;
 | |
| 
 | |
|     if (cb_no > 2) {
 | |
|       tbl_sign = 1;
 | |
|     }
 | |
|     ret_val = ixheaacd_huffman_dec_quad(it_bit_buff, spec_coef, band_offset,
 | |
|                                         no_bands, group_len, cb_table,
 | |
|                                         pow_table, tbl_sign, idx_table);
 | |
|   }
 | |
| 
 | |
|   else if (cb_no <= 10) {
 | |
|     WORD32 tbl_sign = 0;
 | |
|     huff_mode = 9;
 | |
|     if (cb_no > 6) {
 | |
|       if (cb_no > 8)
 | |
|         huff_mode = 13;
 | |
|       else
 | |
|         huff_mode = 8;
 | |
|       tbl_sign = 1;
 | |
|     }
 | |
|     ret_val = ixheaacd_huffman_dec_pair(
 | |
|         it_bit_buff, spec_coef, band_offset, no_bands, group_len, cb_table,
 | |
|         pow_table, tbl_sign, idx_table, huff_mode);
 | |
|   }
 | |
| 
 | |
|   {
 | |
|     WORD bits_cons;
 | |
|     bits_cons = ((it_bit_buff->ptr_read_next - start_read_pos) << 3) +
 | |
|                 (it_bit_buff->bit_pos - start_bit_pos);
 | |
|     it_bit_buff->cnt_bits -= bits_cons;
 | |
|   }
 | |
|   return ret_val;
 | |
| }
 | |
| 
 | |
| WORD ixheaacd_huffman_dec_word2(ia_bit_buf_struct *it_bit_buff, WORD32 cb_no,
 | |
|                                 WORD32 width,
 | |
|                                 ia_aac_dec_tables_struct *ptr_aac_tables,
 | |
|                                 WORD32 *x_invquant, WORD8 *scratch_ptr) {
 | |
|   WORD ret_val = 0;
 | |
|   WORD32 huff_mode;
 | |
|   WORD start_bit_pos = it_bit_buff->bit_pos;
 | |
|   WORD32 cnt_bits = it_bit_buff->cnt_bits;
 | |
|   WORD32 *pow_table =
 | |
|       (WORD32 *)ptr_aac_tables->pstr_block_tables->ixheaacd_pow_table_Q13;
 | |
|   UWORD8 *start_read_pos = it_bit_buff->ptr_read_next;
 | |
| 
 | |
|   const UWORD16 *cb_table = (UWORD16 *)(ptr_aac_tables->code_book[cb_no]);
 | |
|   const UWORD32 *idx_table = (UWORD32 *)(ptr_aac_tables->index_table[cb_no]);
 | |
| 
 | |
|   if (cb_no == 11) {
 | |
|     const UWORD16 *cb_table =
 | |
|         ptr_aac_tables->pstr_huffmann_tables->input_table_cb11;
 | |
| 
 | |
|     ret_val = ixheaacd_huffman_dec_word2_11(
 | |
|         it_bit_buff, width, cb_table, x_invquant, pow_table, scratch_ptr,
 | |
|         ptr_aac_tables->pstr_huffmann_tables->idx_table_hf11);
 | |
|   } else if (cb_no <= 4) {
 | |
|     WORD32 tbl_sign = 0;
 | |
|     if (cb_no > 2) tbl_sign = 1;
 | |
|     ret_val = ixheaacd_huffman_dec_word2_quad(it_bit_buff, width, cb_table,
 | |
|                                               x_invquant, pow_table,
 | |
|                                               scratch_ptr, tbl_sign, idx_table);
 | |
|   } else if (cb_no <= 10) {
 | |
|     WORD32 tbl_sign = 0;
 | |
|     huff_mode = 9;
 | |
|     if (cb_no > 6) {
 | |
|       if (cb_no > 8) {
 | |
|         huff_mode = 13;
 | |
|       } else {
 | |
|         huff_mode = 8;
 | |
|       }
 | |
| 
 | |
|       tbl_sign = 1;
 | |
|     }
 | |
|     ret_val = ixheaacd_huffman_dec_word2_pair(
 | |
|         it_bit_buff, width, cb_table, x_invquant, pow_table, scratch_ptr,
 | |
|         tbl_sign, idx_table, huff_mode);
 | |
|   }
 | |
| 
 | |
|   {
 | |
|     WORD bits_cons;
 | |
|     if (it_bit_buff->bit_pos <= 7) {
 | |
|       bits_cons = ((it_bit_buff->ptr_read_next - start_read_pos) << 3) +
 | |
|                   (it_bit_buff->bit_pos - start_bit_pos);
 | |
|       it_bit_buff->cnt_bits = cnt_bits - bits_cons;
 | |
|     } else {
 | |
|       it_bit_buff->ptr_read_next += (it_bit_buff->bit_pos) >> 3;
 | |
|       it_bit_buff->bit_pos = it_bit_buff->bit_pos & 0x7;
 | |
| 
 | |
|       bits_cons = ((it_bit_buff->ptr_read_next - start_read_pos) << 3) +
 | |
|                   ((it_bit_buff->bit_pos - start_bit_pos));
 | |
|       it_bit_buff->cnt_bits = cnt_bits - bits_cons;
 | |
|     }
 | |
|   }
 | |
|   return ret_val;
 | |
| }
 | |
| 
 | |
| void ixheaacd_lap1_512_480(WORD32 *coef, WORD32 *prev, WORD16 *out,
 | |
|                            const WORD16 *window, WORD16 q_shift, WORD16 size,
 | |
|                            WORD16 stride) {
 | |
|   WORD32 accu;
 | |
|   WORD32 i;
 | |
|   WORD16 rounding_fac = -0x2000;
 | |
| 
 | |
|   WORD32 *window_i = (WORD32 *)window;
 | |
| 
 | |
|   WORD16 *ptr_out1, *ptr_out2;
 | |
| 
 | |
|   WORD32 *pwin1, *pwin2;
 | |
|   WORD32 *pCoef = &coef[size * 2 - 1 - 0];
 | |
| 
 | |
|   pwin1 = &window_i[size - 1 - 0];
 | |
|   pwin2 = &window_i[size + 0];
 | |
| 
 | |
|   ptr_out1 = &out[stride * (size - 1 - 0)];
 | |
|   ptr_out2 = &out[stride * (size + 0)];
 | |
| 
 | |
|   for (i = 0; i < size; i++) {
 | |
|     WORD32 win1, win2, coeff;
 | |
|     WORD32 prev_data = *prev++;
 | |
| 
 | |
|     win1 = *pwin1--;
 | |
|     coeff = *pCoef--;
 | |
|     win2 = *pwin2++;
 | |
| 
 | |
|     accu = ixheaacd_sub32_sat(
 | |
|         ixheaacd_shl32_dir_sat_limit(ixheaacd_mult32_shl(coeff, win1), q_shift),
 | |
|         ixheaacd_mac32x16in32_shl(rounding_fac, win2, (WORD16)(prev_data)));
 | |
| 
 | |
|     accu = ixheaacd_add32_sat(accu, accu);
 | |
|     accu = ixheaacd_add32_sat(accu, accu);
 | |
| 
 | |
|     *ptr_out1 = ixheaacd_shr32(accu, 16);
 | |
|     ptr_out1 -= stride;
 | |
| 
 | |
|     accu = ixheaacd_sub32_sat(
 | |
|         ixheaacd_shl32_dir_sat_limit(
 | |
|             ixheaacd_mult32_shl(ixheaacd_negate32(coeff), win2), q_shift),
 | |
|         ixheaacd_mac32x16in32_shl(rounding_fac, win1, (WORD16)(prev_data)));
 | |
| 
 | |
|     accu = ixheaacd_add32_sat(accu, accu);
 | |
|     accu = ixheaacd_add32_sat(accu, accu);
 | |
| 
 | |
|     *ptr_out2 = ixheaacd_shr32(accu, 16);
 | |
|     ptr_out2 += stride;
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_over_lap_add1_dec(WORD32 *coef, WORD32 *prev, WORD16 *out,
 | |
|                                 const WORD16 *window, WORD16 q_shift,
 | |
|                                 WORD16 size, WORD16 ch_fac) {
 | |
|   WORD32 accu;
 | |
|   WORD32 i;
 | |
|   WORD16 rounding_fac = -0x2000;
 | |
| 
 | |
|   for (i = 0; i < size; i++) {
 | |
|     WORD16 window1, window2;
 | |
| 
 | |
|     window1 = window[2 * size - 2 * i - 1];
 | |
|     window2 = window[2 * size - 2 * i - 2];
 | |
|     accu = ixheaacd_sub32_sat(
 | |
|         ixheaacd_shl32_dir_sat_limit(
 | |
|             ixheaacd_mult32x16in32(coef[size * 2 - 1 - i], window2), q_shift),
 | |
|         ixheaacd_mac32x16in32_drc(rounding_fac, prev[i], window1));
 | |
|     out[ch_fac * (size - i - 1)] =
 | |
|         ixheaacd_shr32(ixheaacd_shl32_dir_sat_limit(accu, 2), 16);
 | |
|     accu = ixheaacd_sub32_sat(
 | |
|         ixheaacd_shl32_dir_sat_limit(
 | |
|             ixheaacd_mult32x16in32(ixheaacd_negate32(coef[size * 2 - 1 - i]),
 | |
|                                    window1),
 | |
|             q_shift),
 | |
|         ixheaacd_mac32x16in32_drc(rounding_fac, prev[i], window2));
 | |
|     out[ch_fac * (size + i)] =
 | |
|         ixheaacd_shr32(ixheaacd_shl32_dir_sat_limit(accu, 2), 16);
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_over_lap_add2_dec(WORD32 *coef, WORD32 *prev, WORD32 *out,
 | |
|                                 const WORD16 *window, WORD16 q_shift,
 | |
|                                 WORD16 size, WORD16 ch_fac) {
 | |
|   WORD32 accu;
 | |
|   WORD32 i;
 | |
| 
 | |
|   for (i = 0; i < size; i++) {
 | |
|     accu = ixheaacd_sub32_sat(
 | |
|         ixheaacd_mult32x16in32(coef[size + i], window[2 * i]),
 | |
|         ixheaacd_mult32x16in32(prev[size - 1 - i], window[2 * i + 1]));
 | |
|     out[ch_fac * i] = ixheaacd_shr32_drc(accu, 16 - (q_shift + 1));
 | |
|   }
 | |
| 
 | |
|   for (i = 0; i < size; i++) {
 | |
|     accu = ixheaacd_sub32_sat(
 | |
|         ixheaacd_mult32x16in32(ixheaacd_negate32_sat(coef[size * 2 - 1 - i]),
 | |
|                                window[2 * size - 2 * i - 1]),
 | |
|         ixheaacd_mult32x16in32(prev[i], window[2 * size - 2 * i - 2]));
 | |
|     out[ch_fac * (i + size)] = ixheaacd_shr32_drc(accu, 16 - (q_shift + 1));
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_process_single_scf(WORD32 scale_factor, WORD32 *x_invquant,
 | |
|                                  WORD32 width, WORD32 *ptr_scale_table,
 | |
|                                  WORD32 total_channels, WORD32 object_type,
 | |
|                                  WORD32 aac_sf_data_resil_flag) {
 | |
|   WORD32 j;
 | |
| 
 | |
|   WORD32 temp1;
 | |
|   WORD32 q_factor;
 | |
|   WORD32 buffer1;
 | |
|   WORD16 scale_short;
 | |
| 
 | |
|   object_type = 0;
 | |
|   aac_sf_data_resil_flag = 0;
 | |
| 
 | |
|   if (scale_factor < 24) {
 | |
|     for (j = width; j > 0; j--) {
 | |
|       *x_invquant++ = 0;
 | |
|     }
 | |
|   } else {
 | |
|     WORD32 shift;
 | |
| 
 | |
|     if (total_channels > 2)
 | |
|       q_factor = 34 - (scale_factor >> 2);
 | |
|     else
 | |
|       q_factor = 37 - (scale_factor >> 2);
 | |
| 
 | |
|     scale_short = ptr_scale_table[(scale_factor & 0x0003)];
 | |
|     shift = q_factor;
 | |
|     if (shift > 0) {
 | |
|       if (scale_short == (WORD16)0x8000) {
 | |
|         for (j = width; j > 0; j--) {
 | |
|           temp1 = *x_invquant;
 | |
|           buffer1 = ixheaacd_mult32x16in32_shl_sat(temp1, scale_short);
 | |
|           buffer1 = ixheaacd_shr32(buffer1, shift);
 | |
|           *x_invquant++ = buffer1;
 | |
|         }
 | |
|       } else {
 | |
|         for (j = width; j > 0; j--) {
 | |
|           temp1 = *x_invquant;
 | |
|           buffer1 = ixheaacd_mult32x16in32_shl(temp1, scale_short);
 | |
|           buffer1 = ixheaacd_shr32(buffer1, shift);
 | |
|           *x_invquant++ = buffer1;
 | |
|         }
 | |
|       }
 | |
|     } else {
 | |
|       shift = -shift;
 | |
|       if (shift > 0) {
 | |
|         if (scale_short == (WORD16)0x8000) {
 | |
|           for (j = width; j > 0; j--) {
 | |
|             temp1 = *x_invquant;
 | |
|             temp1 = ixheaacd_shl32(temp1, shift - 1);
 | |
|             buffer1 = ixheaacd_mult32x16in32_shl_sat(temp1, scale_short);
 | |
|             buffer1 = ixheaacd_shl32(buffer1, 1);
 | |
|             *x_invquant++ = buffer1;
 | |
|           }
 | |
|         } else {
 | |
|           for (j = width; j > 0; j--) {
 | |
|             temp1 = *x_invquant;
 | |
|             temp1 = ixheaacd_shl32(temp1, shift - 1);
 | |
|             buffer1 = ixheaacd_mult32x16in32_shl(temp1, scale_short);
 | |
|             buffer1 = ixheaacd_shl32(buffer1, 1);
 | |
|             *x_invquant++ = buffer1;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|       } else {
 | |
|         if (scale_short == (WORD16)0x8000) {
 | |
|           for (j = width; j > 0; j--) {
 | |
|             temp1 = *x_invquant;
 | |
|             buffer1 = ixheaacd_mult32x16in32_shl_sat(temp1, scale_short);
 | |
|             *x_invquant++ = buffer1;
 | |
|           }
 | |
|         } else {
 | |
|           for (j = width; j > 0; j--) {
 | |
|             temp1 = *x_invquant;
 | |
|             buffer1 = ixheaacd_mult32x16in32_shl(temp1, scale_short);
 | |
|             *x_invquant++ = buffer1;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_scale_factor_process_dec(WORD32 *x_invquant, WORD16 *scale_fact,
 | |
|                                        WORD no_band, WORD8 *width,
 | |
|                                        WORD32 *ptr_scale_table,
 | |
|                                        WORD32 total_channels,
 | |
|                                        WORD32 object_type,
 | |
|                                        WORD32 aac_sf_data_resil_flag) {
 | |
|   WORD32 i;
 | |
|   WORD16 scale_factor;
 | |
| 
 | |
|   for (i = no_band - 1; i >= 0; i--) {
 | |
|     scale_factor = *scale_fact++;
 | |
|     ixheaacd_process_single_scf(scale_factor, x_invquant, *width,
 | |
|                                 ptr_scale_table, total_channels, object_type,
 | |
|                                 aac_sf_data_resil_flag);
 | |
| 
 | |
|     x_invquant += *width;
 | |
|     width++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void ixheaacd_right_shift_block(WORD32 *p_spectrum, WORD32 length,
 | |
|                                 WORD32 shift_val) {
 | |
|   WORD32 i;
 | |
|   WORD32 temp1, temp2;
 | |
|   WORD32 *temp_ptr = &p_spectrum[0];
 | |
|   length = length >> 2;
 | |
| 
 | |
|   for (i = length - 1; i >= 0; i--) {
 | |
|     temp1 = *temp_ptr;
 | |
|     temp2 = *(temp_ptr + 1);
 | |
|     *temp_ptr++ = temp1 >> shift_val;
 | |
|     temp1 = *(temp_ptr + 1);
 | |
|     *temp_ptr++ = temp2 >> shift_val;
 | |
|     temp2 = *(temp_ptr + 1);
 | |
|     *temp_ptr++ = temp1 >> shift_val;
 | |
|     *temp_ptr++ = temp2 >> shift_val;
 | |
|   }
 | |
| }
 |