1099 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1099 lines
		
	
	
		
			34 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 <math.h>
 | |
| #include <assert.h>
 | |
| #include <stdio.h>
 | |
| #include "ixheaacd_type_def.h"
 | |
| #include "ixheaacd_bitbuffer.h"
 | |
| #include "ixheaacd_config.h"
 | |
| #include "ixheaacd_mps_polyphase.h"
 | |
| #include "ixheaacd_mps_dec.h"
 | |
| #include "ixheaacd_mps_interface.h"
 | |
| #include "ixheaacd_mps_nlc_dec.h"
 | |
| #include "ixheaacd_mps_hybfilter.h"
 | |
| #include "ixheaacd_error_standards.h"
 | |
| 
 | |
| #define min(a, b) ((a) < (b) ? (a) : (b))
 | |
| 
 | |
| #define max(a, b) ((a) > (b) ? (a) : (b))
 | |
| 
 | |
| static const int ixheaacd_freq_res_table[] = {0, 28, 20, 14, 10, 7, 5, 4};
 | |
| 
 | |
| static const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_4_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 | |
|         2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 | |
|         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
 | |
| 
 | |
| static const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_5_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 | |
|         3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 | |
|         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
 | |
| 
 | |
| static const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_7_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5,
 | |
|         5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 | |
|         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
 | |
| 
 | |
| static const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_10_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8,
 | |
|         8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 | |
|         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
 | |
| 
 | |
| static const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_14_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         0,  0,  0,  0,  1,  1,  2,  3,  4,  4,  5,  6,  6,  7,  7,  8,  8,  8,
 | |
|         9,  9,  9,  10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
 | |
|         12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
 | |
|         13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
 | |
| 
 | |
| const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_20_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         1,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 14,
 | |
|         15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
 | |
|         18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 | |
|         19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19};
 | |
| 
 | |
| const int
 | |
|     ixheaacd_hybrid_band_71_to_processing_band_28_map[MAX_HYBRID_BANDS_MPS] = {
 | |
|         1,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
 | |
|         16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23,
 | |
|         23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,
 | |
|         26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27};
 | |
| 
 | |
| static const float ixheaacd_mps_clip_gain_table[] = {
 | |
|     1.000000f, 1.189207f, 1.414213f, 1.681792f,
 | |
|     2.000000f, 2.378414f, 2.828427f, 4.000000f};
 | |
| 
 | |
| static const int ixheaacd_mps_stride_table[] = {1, 2, 5, 28};
 | |
| 
 | |
| static const float ixheaacd_cld_de_quant_table[] = {
 | |
|     -150.0, -45.0, -40.0, -35.0, -30.0, -25.0, -22.0, -19.0,
 | |
|     -16.0,  -13.0, -10.0, -8.0,  -6.0,  -4.0,  -2.0,  0.0,
 | |
|     2.0,    4.0,   6.0,   8.0,   10.0,  13.0,  16.0,  19.0,
 | |
|     22.0,   25.0,  30.0,  35.0,  40.0,  45.0,  150.0};
 | |
| 
 | |
| static const float ixheaacd_icc_de_quant_table[] = {
 | |
|     1.0000f, 0.9370f, 0.84118f, 0.60092f, 0.36764f, 0.0f, -0.5890f, -0.9900f};
 | |
| 
 | |
| const float ixheaacd_ipd_de_quant_table[] = {
 | |
|     0.f,          0.392699082f, 0.785398163f, 1.178097245f,
 | |
|     1.570796327f, 1.963495408f, 2.35619449f,  2.748893572f,
 | |
|     3.141592654f, 3.534291735f, 3.926990817f, 4.319689899f,
 | |
|     4.71238898f,  5.105088062f, 5.497787144f, 5.890486225f};
 | |
| const int ixheaacd_ipd_de_quant_table_q28[] = {
 | |
|     0,          105414360,  210828720,  316243072, 421657440,  527071776,
 | |
|     632486144,  737900480,  843314880,  948729216, 1054143552, 1159557888,
 | |
|     1264972288, 1370386688, 1475800960, 1581215360};
 | |
| static const int ixheaacd_smoothing_time_table[] = {64, 128, 256, 512};
 | |
| 
 | |
| static const int ixheaacd_inverse_smoothing_time_table_q30[] = {
 | |
|     16777216, 8388608, 4194304, 2097152};
 | |
| 
 | |
| static WORD32 bound_check(WORD32 var, WORD32 lower_bound, WORD32 upper_bound) {
 | |
|   var = min(var, upper_bound);
 | |
|   var = max(var, lower_bound);
 | |
|   return var;
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_longmult1(unsigned short a[], unsigned short b,
 | |
|                                unsigned short d[], int len) {
 | |
|   int k;
 | |
|   UWORD32 tmp;
 | |
|   UWORD32 b0 = (UWORD32)b;
 | |
| 
 | |
|   tmp = ((UWORD32)a[0]) * b0;
 | |
|   d[0] = (unsigned short)tmp;
 | |
| 
 | |
|   for (k = 1; k < len; k++) {
 | |
|     tmp = (tmp >> 16) + ((UWORD32)a[k]) * b0;
 | |
|     d[k] = (unsigned short)tmp;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_longdiv(unsigned short b[], unsigned short a,
 | |
|                              unsigned short d[], unsigned short *pr, int len) {
 | |
|   UWORD32 r;
 | |
|   UWORD32 tmp;
 | |
|   UWORD32 temp;
 | |
|   int k;
 | |
| 
 | |
|   assert(a != 0);
 | |
| 
 | |
|   r = 0;
 | |
| 
 | |
|   for (k = len - 1; k >= 0; k--) {
 | |
|     tmp = ((UWORD32)b[k]) + (r << 16);
 | |
| 
 | |
|     if (tmp) {
 | |
|       d[k] = (unsigned short)(tmp / a);
 | |
|       temp = d[k] * a;
 | |
|       r = tmp - temp;
 | |
|     } else {
 | |
|       d[k] = 0;
 | |
|     }
 | |
|   }
 | |
|   *pr = (unsigned short)r;
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_longsub(unsigned short a[], unsigned short b[], int lena,
 | |
|                              int lenb) {
 | |
|   int h;
 | |
|   WORD32 carry = 0;
 | |
| 
 | |
|   assert(lena >= lenb);
 | |
|   for (h = 0; h < lenb; h++) {
 | |
|     carry = carry + (WORD32)(a[h] - b[h]);
 | |
|     a[h] = (unsigned short)carry;
 | |
|     carry = carry >> 16;
 | |
|   }
 | |
| 
 | |
|   for (; h < lena; h++) {
 | |
|     carry = ((UWORD32)a[h]) + carry;
 | |
|     a[h] = (unsigned short)carry;
 | |
|     carry = carry >> 16;
 | |
|   }
 | |
| 
 | |
|   assert(carry == 0);
 | |
|   return;
 | |
| }
 | |
| 
 | |
| static int ixheaacd_longcompare(unsigned short a[], unsigned short b[],
 | |
|                                 int len) {
 | |
|   int i;
 | |
| 
 | |
|   for (i = len - 1; i > 0; i--) {
 | |
|     if (a[i] != b[i]) break;
 | |
|   }
 | |
|   return (a[i] >= b[i]) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_mps_coarse2fine(int *data, WORD32 data_type,
 | |
|                                      int band_start, int ixheaacd_num_bands) {
 | |
|   int i;
 | |
| 
 | |
|   for (i = band_start; i < band_start + ixheaacd_num_bands; i++) {
 | |
|     data[i] <<= 1;
 | |
|   }
 | |
| 
 | |
|   if (data_type == CLD) {
 | |
|     for (i = band_start; i < band_start + ixheaacd_num_bands; i++) {
 | |
|       if (data[i] == -14)
 | |
|         data[i] = -15;
 | |
|       else if (data[i] == 14)
 | |
|         data[i] = 15;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_mps_fine2coarse(int *data, int ixheaacd_num_bands) {
 | |
|   int i;
 | |
| 
 | |
|   for (i = 0; i < ixheaacd_num_bands; i++) {
 | |
|     data[i] /= 2;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static int ixheaacd_mps_getstridemap(int freq_res_stride, int band_start,
 | |
|                                      int band_stop, int *strides) {
 | |
|   int i, pb, ch_fac, data_bands, start_offset;
 | |
| 
 | |
|   ch_fac = ixheaacd_mps_stride_table[freq_res_stride];
 | |
|   data_bands = (band_stop - band_start - 1) / ch_fac + 1;
 | |
| 
 | |
|   strides[0] = band_start;
 | |
|   for (pb = 1; pb <= data_bands; pb++) {
 | |
|     strides[pb] = strides[pb - 1] + ch_fac;
 | |
|   }
 | |
|   start_offset = 0;
 | |
|   while (strides[data_bands] > band_stop) {
 | |
|     if (start_offset < data_bands)
 | |
|       start_offset++;
 | |
|     else
 | |
|       start_offset = 1;
 | |
| 
 | |
|     for (i = start_offset; i <= data_bands; i++) {
 | |
|       strides[i]--;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return data_bands;
 | |
| }
 | |
| 
 | |
| static IA_ERRORCODE ixheaacd_mps_ecdata_decoding(
 | |
|     ia_mps_dec_state_struct *self, ia_handle_bit_buf_struct bitstream,
 | |
|     int data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], int datatype) {
 | |
|   int i, j, pb, set_index, bs_data_pair, data_bands, old_quant_coarse_xxx;
 | |
|   int strides[MAX_PARAMETER_BANDS + 1] = {0};
 | |
|   int band_stop = 0;
 | |
| 
 | |
|   int *lastdata = NULL;
 | |
|   ia_mps_data_struct *frame_xxx_data = NULL;
 | |
|   int default_val = 0;
 | |
|   IA_ERRORCODE err = IA_NO_ERROR;
 | |
| 
 | |
|   ia_mps_bs_frame *frame = &(self->bs_frame);
 | |
| 
 | |
|   if (datatype == 0) {
 | |
|     frame_xxx_data = &frame->cld_data;
 | |
|     lastdata = frame->cmp_cld_idx_prev;
 | |
|     band_stop = self->bs_param_bands;
 | |
|   } else if (datatype == 1) {
 | |
|     frame_xxx_data = &frame->icc_data;
 | |
|     lastdata = frame->cmp_icc_idx_prev;
 | |
|     band_stop = self->bs_param_bands;
 | |
|   } else if (datatype == 2) {
 | |
|     frame_xxx_data = &frame->ipd_data;
 | |
|     lastdata = frame->ipd_idx_data_prev;
 | |
|     band_stop = self->num_bands_ipd;
 | |
|   } else {
 | |
|     frame_xxx_data = &frame->cld_data;
 | |
|     lastdata = frame->cmp_cld_idx_prev;
 | |
|     band_stop = self->bs_param_bands;
 | |
|   }
 | |
| 
 | |
|   for (i = 0; i < self->num_parameter_sets; i++) {
 | |
|     frame_xxx_data->bs_xxx_data_mode[i] = ixheaacd_read_bits_buf(bitstream, 2);
 | |
|   }
 | |
| 
 | |
|   set_index = 0;
 | |
|   bs_data_pair = 0;
 | |
|   old_quant_coarse_xxx = frame_xxx_data->bs_quant_coarse_xxx_prev;
 | |
| 
 | |
|   for (i = 0; i < self->num_parameter_sets; i++) {
 | |
|     if (frame_xxx_data->bs_xxx_data_mode[i] == 0) {
 | |
|       for (pb = 0; pb < band_stop; pb++) {
 | |
|         lastdata[pb] = default_val;
 | |
|       }
 | |
| 
 | |
|       old_quant_coarse_xxx = 0;
 | |
|     }
 | |
| 
 | |
|     if (frame_xxx_data->bs_xxx_data_mode[i] == 3) {
 | |
|       if (bs_data_pair) {
 | |
|         bs_data_pair = 0;
 | |
|       } else {
 | |
|         bs_data_pair = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|         frame_xxx_data->bs_quant_coarse_xxx[set_index] =
 | |
|             ixheaacd_read_bits_buf(bitstream, 1);
 | |
|         frame_xxx_data->bs_freq_res_stride_xxx[set_index] =
 | |
|             ixheaacd_read_bits_buf(bitstream, 2);
 | |
| 
 | |
|         if (frame_xxx_data->bs_quant_coarse_xxx[set_index] !=
 | |
|             old_quant_coarse_xxx) {
 | |
|           if (old_quant_coarse_xxx) {
 | |
|             ixheaacd_mps_coarse2fine(lastdata, datatype, 0, band_stop - 0);
 | |
|           } else {
 | |
|             ixheaacd_mps_fine2coarse(lastdata, band_stop);
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         data_bands = ixheaacd_mps_getstridemap(
 | |
|             frame_xxx_data->bs_freq_res_stride_xxx[set_index], 0, band_stop,
 | |
|             strides);
 | |
| 
 | |
|         for (pb = 0; pb < data_bands; pb++) {
 | |
|           lastdata[pb] = lastdata[strides[pb]];
 | |
|         }
 | |
| 
 | |
|         err = ixheaacd_mps_ecdatapairdec(
 | |
|             bitstream, data, lastdata, datatype, set_index, data_bands,
 | |
|             bs_data_pair, frame_xxx_data->bs_quant_coarse_xxx[set_index],
 | |
|             frame->independency_flag && (i == 0));
 | |
|         if (err) return err;
 | |
| 
 | |
|         for (pb = 0; pb < data_bands; pb++) {
 | |
|           for (j = strides[pb]; j < strides[pb + 1]; j++) {
 | |
|             if (datatype == IPD) {
 | |
|               if (frame_xxx_data->bs_quant_coarse_xxx[set_index]) {
 | |
|                 lastdata[j] = data[set_index + bs_data_pair][pb] & 7;
 | |
|               } else {
 | |
|                 lastdata[j] = data[set_index + bs_data_pair][pb] & 15;
 | |
|               }
 | |
|             } else {
 | |
|               lastdata[j] = data[set_index + bs_data_pair][pb];
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         old_quant_coarse_xxx = frame_xxx_data->bs_quant_coarse_xxx[set_index];
 | |
| 
 | |
|         if (bs_data_pair) {
 | |
|           frame_xxx_data->bs_quant_coarse_xxx[set_index + 1] =
 | |
|               frame_xxx_data->bs_quant_coarse_xxx[set_index];
 | |
|           frame_xxx_data->bs_freq_res_stride_xxx[set_index + 1] =
 | |
|               frame_xxx_data->bs_freq_res_stride_xxx[set_index];
 | |
|         }
 | |
|         set_index += bs_data_pair + 1;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| IA_ERRORCODE ixheaacd_mps_frame_parsing(ia_mps_dec_state_struct *self,
 | |
|                                         int usac_independency_flag,
 | |
|                                         ia_handle_bit_buf_struct bitstream) {
 | |
|   int i, bs_frame_type, data_bands, bs_temp_shape_enable, num_of_temp_shape_ch;
 | |
|   int ps, pg, ts, pb;
 | |
|   int env_shape_data[MAX_TIME_SLOTS];
 | |
| 
 | |
|   int bits_param_slot = 0;
 | |
| 
 | |
|   ia_mps_bs_frame *frame = &(self->bs_frame);
 | |
|   IA_ERRORCODE err = IA_NO_ERROR;
 | |
| 
 | |
|   if (self->parse_nxt_frame == 0) return IA_NO_ERROR;
 | |
| 
 | |
|   self->num_parameter_sets_prev = self->num_parameter_sets;
 | |
| 
 | |
|   if (self->bs_high_rate_mode) {
 | |
|     bs_frame_type = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|     self->num_parameter_sets = ixheaacd_read_bits_buf(bitstream, 3) + 1;
 | |
|   } else {
 | |
|     bs_frame_type = 0;
 | |
|     self->num_parameter_sets = 1;
 | |
|   }
 | |
| 
 | |
|   if (self->time_slots == 32)
 | |
|     bits_param_slot = 5;
 | |
|   else if (self->time_slots == 64)
 | |
|     bits_param_slot = 6;
 | |
| 
 | |
|   if (bs_frame_type) {
 | |
|     for (i = 0; i < self->num_parameter_sets; i++) {
 | |
|       self->param_slots[i] = ixheaacd_read_bits_buf(bitstream, bits_param_slot);
 | |
|     }
 | |
|   } else {
 | |
|     self->param_slots[0] = self->time_slots - 1;
 | |
|   }
 | |
| 
 | |
|   if (!usac_independency_flag) {
 | |
|     frame->independency_flag = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|   } else {
 | |
|     frame->independency_flag = 1;
 | |
|   }
 | |
| 
 | |
|   err = ixheaacd_mps_ecdata_decoding(self, bitstream, frame->cmp_cld_idx, CLD);
 | |
|   if (err) return err;
 | |
| 
 | |
|   err = ixheaacd_mps_ecdata_decoding(self, bitstream, frame->cmp_icc_idx, ICC);
 | |
|   if (err) return err;
 | |
| 
 | |
|   if (self->config->bs_phase_coding) {
 | |
|     self->bs_phase_mode = ixheaacd_read_bits_buf(bitstream, 1);
 | |
| 
 | |
|     if (!self->bs_phase_mode) {
 | |
|       for (pb = 0; pb < self->num_bands_ipd; pb++) {
 | |
|         frame->ipd_idx_data_prev[pb] = 0;
 | |
|         for (i = 0; i < self->num_parameter_sets; i++) {
 | |
|           frame->ipd_idx_data[i][pb] = 0;
 | |
|           self->bs_frame.ipd_idx[i][pb] = 0;
 | |
|         }
 | |
|         self->bs_frame.ipd_idx_prev[pb] = 0;
 | |
|       }
 | |
|       self->opd_smoothing_mode = 0;
 | |
|     } else {
 | |
|       self->opd_smoothing_mode = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|       err = ixheaacd_mps_ecdata_decoding(self, bitstream, frame->ipd_idx_data,
 | |
|                                          IPD);
 | |
|       if (err) return err;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   else {
 | |
|     self->bs_phase_mode = 0;
 | |
|     for (pb = 0; pb < self->num_bands_ipd; pb++) {
 | |
|       frame->ipd_idx_data_prev[pb] = 0;
 | |
|       for (i = 0; i < self->num_parameter_sets; i++) {
 | |
|         frame->ipd_idx_data[i][pb] = 0;
 | |
|         self->bs_frame.ipd_idx[i][pb] = 0;
 | |
|       }
 | |
|       self->bs_frame.ipd_idx_prev[pb] = 0;
 | |
|     }
 | |
|     self->opd_smoothing_mode = 0;
 | |
|   }
 | |
| 
 | |
|   if (self->bs_high_rate_mode) {
 | |
|     for (ps = 0; ps < self->num_parameter_sets; ps++) {
 | |
|       frame->bs_smooth_mode[ps] = ixheaacd_read_bits_buf(bitstream, 2);
 | |
|       if (frame->bs_smooth_mode[ps] >= 2) {
 | |
|         frame->bs_smooth_time[ps] = ixheaacd_read_bits_buf(bitstream, 2);
 | |
|       }
 | |
|       if (frame->bs_smooth_mode[ps] == 3) {
 | |
|         frame->bs_freq_res_stride_smg[ps] =
 | |
|             ixheaacd_read_bits_buf(bitstream, 2);
 | |
|         data_bands =
 | |
|             (self->bs_param_bands - 1) /
 | |
|                 ixheaacd_mps_stride_table[frame->bs_freq_res_stride_smg[ps]] +
 | |
|             1;
 | |
|         for (pg = 0; pg < data_bands; pg++) {
 | |
|           frame->bs_smg_data[ps][pg] = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     for (ps = 0; ps < self->num_parameter_sets; ps++) {
 | |
|       frame->bs_smooth_mode[ps] = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (i = 0; i < 2; i++) {
 | |
|     self->temp_shape_enable_ch_stp[i] = 0;
 | |
|     self->temp_shape_enable_ch_ges[i] = 0;
 | |
|   }
 | |
| 
 | |
|   self->bs_tsd_enable = 0;
 | |
|   if (self->config->bs_temp_shape_config == 3) {
 | |
|     self->bs_tsd_enable = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|   } else if (self->config->bs_temp_shape_config != 0) {
 | |
|     bs_temp_shape_enable = ixheaacd_read_bits_buf(bitstream, 1);
 | |
|     if (bs_temp_shape_enable) {
 | |
|       num_of_temp_shape_ch = 2;
 | |
|       switch (self->config->bs_temp_shape_config) {
 | |
|         case 1:
 | |
|           for (i = 0; i < num_of_temp_shape_ch; i++) {
 | |
|             self->temp_shape_enable_ch_stp[i] =
 | |
|                 ixheaacd_read_bits_buf(bitstream, 1);
 | |
|           }
 | |
|           break;
 | |
|         case 2:
 | |
|           for (i = 0; i < num_of_temp_shape_ch; i++) {
 | |
|             self->temp_shape_enable_ch_ges[i] =
 | |
|                 ixheaacd_read_bits_buf(bitstream, 1);
 | |
|           }
 | |
|           for (i = 0; i < num_of_temp_shape_ch; i++) {
 | |
|             if (self->temp_shape_enable_ch_ges[i]) {
 | |
|               ixheaacd_mps_huff_decode(bitstream, env_shape_data,
 | |
|                                        self->time_slots);
 | |
|               for (ts = 0; ts < self->time_slots; ts++) {
 | |
|                 self->env_shape_data[i][ts] = (float)pow(
 | |
|                     2, (float)env_shape_data[ts] /
 | |
|                                (self->config->bs_env_quant_mode + 2) -
 | |
|                            1);
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           break;
 | |
|         default:
 | |
|           assert(0);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (self->bs_tsd_enable) {
 | |
|     unsigned short s[4];
 | |
|     UWORD64 s_64;
 | |
|     unsigned short c[5];
 | |
|     UWORD64 c_64;
 | |
|     unsigned short b;
 | |
|     unsigned short r[1];
 | |
|     static const unsigned short table_64[] = {
 | |
|         6,  11, 16, 20, 23, 27, 30, 33, 35, 38, 40, 42, 44, 46, 48, 49,
 | |
|         51, 52, 53, 55, 56, 57, 58, 58, 59, 60, 60, 60, 61, 61, 61, 61};
 | |
|     static const unsigned short table_32[] = {5,  9,  13, 16, 18, 20, 22, 24,
 | |
|                                               25, 26, 27, 28, 29, 29, 30, 30};
 | |
|     unsigned const short *tab = NULL;
 | |
|     int k;
 | |
|     unsigned short h;
 | |
|     WORD32 nbits_tr_slots = 0;
 | |
| 
 | |
|     if (self->time_slots == 32) {
 | |
|       nbits_tr_slots = 4;
 | |
|       tab = table_32;
 | |
|     } else if (self->time_slots == 64) {
 | |
|       nbits_tr_slots = 5;
 | |
|       tab = table_64;
 | |
|     }
 | |
| 
 | |
|     self->tsd_num_tr_slots = ixheaacd_read_bits_buf(bitstream, nbits_tr_slots);
 | |
|     self->tsd_num_tr_slots++;
 | |
|     self->tsd_codeword_len = tab[self->tsd_num_tr_slots - 1];
 | |
| 
 | |
|     if (self->tsd_codeword_len > 48) {
 | |
|       s[3] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len - 48);
 | |
|       s_64 = s[3];
 | |
|       s[2] = ixheaacd_read_bits_buf(bitstream, 16);
 | |
|       s_64 = (s_64 << 16) | s[2];
 | |
|       s[1] = ixheaacd_read_bits_buf(bitstream, 16);
 | |
|       s_64 = (s_64 << 16) | s[1];
 | |
|       s[0] = ixheaacd_read_bits_buf(bitstream, 16);
 | |
|       s_64 = (s_64 << 16) | s[0];
 | |
|     } else if (self->tsd_codeword_len > 32) {
 | |
|       s[3] = 0;
 | |
|       s_64 = s[3];
 | |
|       s[2] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len - 32);
 | |
|       s_64 = (s_64 << 16) | s[2];
 | |
|       s[1] = ixheaacd_read_bits_buf(bitstream, 16);
 | |
|       s_64 = (s_64 << 16) | s[1];
 | |
|       s[0] = ixheaacd_read_bits_buf(bitstream, 16);
 | |
|       s_64 = (s_64 << 16) | s[0];
 | |
|     } else if (self->tsd_codeword_len > 16) {
 | |
|       s[3] = 0;
 | |
|       s_64 = s[3];
 | |
|       s[2] = 0;
 | |
|       s_64 = (s_64 << 16) | s[2];
 | |
|       s[1] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len - 16);
 | |
|       s_64 = (s_64 << 16) | s[1];
 | |
|       s[0] = ixheaacd_read_bits_buf(bitstream, 16);
 | |
|       s_64 = (s_64 << 16) | s[0];
 | |
|     } else {
 | |
|       s[3] = 0;
 | |
|       s_64 = s[3];
 | |
|       s[2] = 0;
 | |
|       s_64 = (s_64 << 16) | s[2];
 | |
|       s[1] = 0;
 | |
|       s_64 = (s_64 << 16) | s[1];
 | |
|       s[0] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len);
 | |
|       s_64 = (s_64 << 16) | s[0];
 | |
|     }
 | |
| 
 | |
|     {
 | |
|       int p = self->tsd_num_tr_slots;
 | |
| 
 | |
|       for (i = 0; i < self->time_slots; i++) self->bs_tsd_sep_data[i] = 0;
 | |
| 
 | |
|       for (k = self->time_slots - 1; k >= 0; k--) {
 | |
|         if (p > k) {
 | |
|           for (; k >= 0; k--) self->bs_tsd_sep_data[k] = 1;
 | |
|           break;
 | |
|         }
 | |
| 
 | |
|         c[0] = k - p + 1;
 | |
|         c_64 = c[0];
 | |
|         for (i = 1; i < 5; i++) c[i] = 0;
 | |
| 
 | |
|         for (h = 2; h <= p; h++) {
 | |
|           b = k - p + h;
 | |
|           c_64 = c_64 * (b / h);
 | |
|           ixheaacd_longmult1(c, b, c, 5);
 | |
|           b = h;
 | |
|           ixheaacd_longdiv(c, b, c, r, 5);
 | |
|         }
 | |
| 
 | |
|         if (ixheaacd_longcompare(s, c, 4)) {
 | |
|           ixheaacd_longsub(s, c, 4, 4);
 | |
|           self->bs_tsd_sep_data[k] = 1;
 | |
|           p--;
 | |
|           if (p == 0) break;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     for (i = 0; i < self->time_slots; i++) {
 | |
|       if (self->bs_tsd_sep_data[i])
 | |
|         self->bs_tsd_tr_phase_data[i] = ixheaacd_read_bits_buf(bitstream, 3);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   self->parse_nxt_frame = 0;
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_mps_createmapping(int map[MAX_PARAMETER_BANDS + 1],
 | |
|                                        int band_start, int band_stop,
 | |
|                                        int ch_fac) {
 | |
|   int input_bands, out_bands, bands_achived, bands_diff, incr, k, i;
 | |
|   int vdk[MAX_PARAMETER_BANDS + 1];
 | |
|   input_bands = band_stop - band_start;
 | |
|   out_bands = (input_bands - 1) / ch_fac + 1;
 | |
|   if (out_bands < 1) {
 | |
|     out_bands = 1;
 | |
|   }
 | |
| 
 | |
|   bands_achived = out_bands * ch_fac;
 | |
|   bands_diff = input_bands - bands_achived;
 | |
|   for (i = 0; i < out_bands; i++) {
 | |
|     vdk[i] = ch_fac;
 | |
|   }
 | |
| 
 | |
|   if (bands_diff > 0) {
 | |
|     incr = -1;
 | |
|     k = out_bands - 1;
 | |
|   } else {
 | |
|     incr = 1;
 | |
|     k = 0;
 | |
|   }
 | |
| 
 | |
|   while (bands_diff != 0) {
 | |
|     vdk[k] = vdk[k] - incr;
 | |
|     k = k + incr;
 | |
|     bands_diff = bands_diff + incr;
 | |
|     if (k >= out_bands) {
 | |
|       if (bands_diff > 0) {
 | |
|         k = out_bands - 1;
 | |
|       } else if (bands_diff < 0) {
 | |
|         k = 0;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   map[0] = band_start;
 | |
|   for (i = 0; i < out_bands; i++) {
 | |
|     map[i + 1] = map[i] + vdk[i];
 | |
|   }
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_mps_mapfrequency(int *in, int *out, int *map,
 | |
|                                       int data_bands) {
 | |
|   int i, j, band_start, band_stop, value;
 | |
|   int start_band_0 = map[0];
 | |
| 
 | |
|   for (i = 0; i < data_bands; i++) {
 | |
|     value = in[i + start_band_0];
 | |
| 
 | |
|     band_start = map[i];
 | |
|     band_stop = map[i + 1];
 | |
|     for (j = band_start; j < band_stop; j++) {
 | |
|       out[j] = value;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static float ixheaacd_mps_de_quantize(int value, int param_type) {
 | |
|   switch (param_type) {
 | |
|     case CLD:
 | |
|       return ixheaacd_cld_de_quant_table[value + 15];
 | |
| 
 | |
|     case ICC:
 | |
|       return ixheaacd_icc_de_quant_table[value];
 | |
| 
 | |
|     case IPD:
 | |
|       return ixheaacd_ipd_de_quant_table[(value & 15)];
 | |
| 
 | |
|     default:
 | |
|       assert(0);
 | |
|       return 0.0;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static WORD32 ixheaacd_mps_mapindexdata(
 | |
|     ia_mps_dec_state_struct *self, ia_mps_data_struct *frame_xxx_data,
 | |
|     float out_data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
 | |
|     int out_idx_data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
 | |
|     int cmp_idx_data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
 | |
|     int idx_prev[MAX_PARAMETER_BANDS], int param_type) {
 | |
|   int interpolate_local[MAX_PARAMETER_SETS_MPS] = {0};
 | |
|   int map[MAX_PARAMETER_BANDS + 1];
 | |
| 
 | |
|   int set_index, i, band, parm_slot;
 | |
|   int data_bands, ch_fac;
 | |
|   int ps;
 | |
| 
 | |
|   int i1, i2, x1, xi, x2;
 | |
|   int band_start = 0;
 | |
|   int ext_frame_flag = self->ext_frame_flag;
 | |
|   int *param_slots = self->param_slots;
 | |
|   int num_parameter_sets = self->num_parameter_sets;
 | |
|   int band_stop = self->bs_param_bands;
 | |
|   int default_val = 0;
 | |
| 
 | |
|   set_index = 0;
 | |
| 
 | |
|   for (i = 0; i < num_parameter_sets; i++) {
 | |
|     if (frame_xxx_data->bs_xxx_data_mode[i] == 0) {
 | |
|       frame_xxx_data->quant_coarse_xxx_flag[i] = 0;
 | |
|       for (band = band_start; band < band_stop; band++) {
 | |
|         out_idx_data[i][band] = default_val;
 | |
|       }
 | |
|       for (band = band_start; band < band_stop; band++) {
 | |
|         idx_prev[band] = out_idx_data[i][band];
 | |
|       }
 | |
| 
 | |
|       frame_xxx_data->bs_quant_coarse_xxx_prev = 0;
 | |
|     }
 | |
| 
 | |
|     if (frame_xxx_data->bs_xxx_data_mode[i] == 1) {
 | |
|       for (band = band_start; band < band_stop; band++) {
 | |
|         out_idx_data[i][band] = idx_prev[band];
 | |
|       }
 | |
|       frame_xxx_data->quant_coarse_xxx_flag[i] =
 | |
|           frame_xxx_data->bs_quant_coarse_xxx_prev;
 | |
|     }
 | |
| 
 | |
|     if (frame_xxx_data->bs_xxx_data_mode[i] == 2) {
 | |
|       for (band = band_start; band < band_stop; band++) {
 | |
|         out_idx_data[i][band] = idx_prev[band];
 | |
|       }
 | |
|       frame_xxx_data->quant_coarse_xxx_flag[i] =
 | |
|           frame_xxx_data->bs_quant_coarse_xxx_prev;
 | |
|       interpolate_local[i] = 1;
 | |
|     } else {
 | |
|       interpolate_local[i] = 0;
 | |
|     }
 | |
| 
 | |
|     if (frame_xxx_data->bs_xxx_data_mode[i] == 3) {
 | |
|       parm_slot = i;
 | |
|       ch_fac =
 | |
|           ixheaacd_mps_stride_table[frame_xxx_data
 | |
|                                         ->bs_freq_res_stride_xxx[set_index]];
 | |
|       data_bands = (band_stop - band_start - 1) / ch_fac + 1;
 | |
|       ixheaacd_mps_createmapping(map, band_start, band_stop, ch_fac);
 | |
|       ixheaacd_mps_mapfrequency(&cmp_idx_data[set_index][0],
 | |
|                                 &out_idx_data[parm_slot][0], map, data_bands);
 | |
| 
 | |
|       for (band = band_start; band < band_stop; band++) {
 | |
|         idx_prev[band] = out_idx_data[parm_slot][band];
 | |
|       }
 | |
| 
 | |
|       frame_xxx_data->bs_quant_coarse_xxx_prev =
 | |
|           frame_xxx_data->bs_quant_coarse_xxx[set_index];
 | |
|       frame_xxx_data->quant_coarse_xxx_flag[i] =
 | |
|           frame_xxx_data->bs_quant_coarse_xxx[set_index];
 | |
| 
 | |
|       set_index++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (i = 0; i < num_parameter_sets; i++) {
 | |
|     if (frame_xxx_data->quant_coarse_xxx_flag[i] == 1) {
 | |
|       ixheaacd_mps_coarse2fine(out_idx_data[i], param_type, band_start,
 | |
|                                band_stop - band_start);
 | |
|       frame_xxx_data->quant_coarse_xxx_flag[i] = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   i1 = -1;
 | |
|   x1 = 0;
 | |
|   i2 = 0;
 | |
|   for (i = 0; i < num_parameter_sets; i++) {
 | |
|     if (interpolate_local[i] != 1) {
 | |
|       i1 = i;
 | |
|     }
 | |
|     i2 = i;
 | |
|     while (interpolate_local[i2] == 1) {
 | |
|       i2++;
 | |
|     }
 | |
|     if (i1 == -1) {
 | |
|       x1 = 0;
 | |
|       i1 = 0;
 | |
|     } else {
 | |
|       x1 = param_slots[i1];
 | |
|     }
 | |
|     xi = param_slots[i];
 | |
|     x2 = param_slots[i2];
 | |
| 
 | |
|     if (interpolate_local[i] == 1) {
 | |
|       if (i2 < num_parameter_sets) {
 | |
|         return -1;
 | |
|       }
 | |
|       for (band = band_start; band < band_stop; band++) {
 | |
|         int yi, y1, y2;
 | |
|         yi = 0;
 | |
|         y1 = out_idx_data[i1][band];
 | |
|         y2 = out_idx_data[i2][band];
 | |
|         if (param_type == IPD) {
 | |
|           if (y2 - y1 > 8) y1 += 16;
 | |
|           if (y1 - y2 > 8) y2 += 16;
 | |
| 
 | |
|           if (x2 != x1) {
 | |
|             yi = (y1 + (xi - x1) * (y2 - y1) / (x2 - x1)) % 16;
 | |
|           }
 | |
|         } else {
 | |
|           if (x2 != x1) {
 | |
|             yi = y1 + (xi - x1) * (y2 - y1) / (x2 - x1);
 | |
|           }
 | |
|         }
 | |
|         out_idx_data[i][band] = yi;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (ps = 0; ps < num_parameter_sets; ps++) {
 | |
|     for (band = band_start; band < band_stop; band++) {
 | |
|       if (param_type == CLD) {
 | |
|         out_idx_data[ps][band] = bound_check(out_idx_data[ps][band], -15, 15);
 | |
|       } else if (param_type == ICC)  // param_type is ICC
 | |
|       {
 | |
|         out_idx_data[ps][band] = bound_check(out_idx_data[ps][band], 0, 7);
 | |
|       }
 | |
|       out_data[ps][band] =
 | |
|           ixheaacd_mps_de_quantize(out_idx_data[ps][band], param_type);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (ext_frame_flag) {
 | |
|     for (band = band_start; band < band_stop; band++) {
 | |
|       out_data[num_parameter_sets][band] =
 | |
|           out_data[num_parameter_sets - 1][band];
 | |
|       out_idx_data[num_parameter_sets][band] =
 | |
|           out_idx_data[num_parameter_sets - 1][band];
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static WORD32 ixheaacd_mps_dec_and_mapframeott(ia_mps_dec_state_struct *self) {
 | |
|   ia_mps_bs_frame *cur_bit_stream_ptr = &(self->bs_frame);
 | |
|   WORD32 err_code = 0;
 | |
| 
 | |
|   err_code = ixheaacd_mps_mapindexdata(
 | |
|       self, &cur_bit_stream_ptr->cld_data, self->cld_data,
 | |
|       cur_bit_stream_ptr->cld_idx, cur_bit_stream_ptr->cmp_cld_idx,
 | |
|       cur_bit_stream_ptr->cld_idx_pre, CLD);
 | |
|   if (err_code != 0) return err_code;
 | |
| 
 | |
|   err_code = ixheaacd_mps_mapindexdata(
 | |
|       self, &cur_bit_stream_ptr->icc_data, self->icc_data,
 | |
|       cur_bit_stream_ptr->icc_idx, cur_bit_stream_ptr->cmp_icc_idx,
 | |
|       cur_bit_stream_ptr->icc_idx_pre, ICC);
 | |
|   if (err_code != 0) return err_code;
 | |
|   if ((self->config->bs_phase_coding)) {
 | |
|     err_code = ixheaacd_mps_mapindexdata(
 | |
|         self, &cur_bit_stream_ptr->ipd_data, self->ipd_data,
 | |
|         cur_bit_stream_ptr->ipd_idx, cur_bit_stream_ptr->ipd_idx_data,
 | |
|         cur_bit_stream_ptr->ipd_idx_prev, IPD);
 | |
| 
 | |
|     if (err_code != 0) return err_code;
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static VOID ixheaacd_mps_dec_and_mapframesmg(ia_mps_dec_state_struct *self) {
 | |
|   int ps, pb, pg, ch_fac, data_bands, param_band_start, param_band_stop,
 | |
|       group_to_band[MAX_PARAMETER_BANDS + 1];
 | |
|   ia_mps_bs_frame *frame = &(self->bs_frame);
 | |
|   for (ps = 0; ps < self->num_parameter_sets; ps++) {
 | |
|     switch (frame->bs_smooth_mode[ps]) {
 | |
|       case 0:
 | |
|         self->smoothing_time[ps] = 256;
 | |
|         self->inv_smoothing_time[ps] = 4194304;
 | |
| 
 | |
|         for (pb = 0; pb < self->bs_param_bands; pb++) {
 | |
|           self->smoothing_data[ps][pb] = 0;
 | |
|         }
 | |
|         break;
 | |
| 
 | |
|       case 1:
 | |
|         if (ps > 0) {
 | |
|           self->smoothing_time[ps] = self->smoothing_time[ps - 1];
 | |
|           self->inv_smoothing_time[ps] = self->inv_smoothing_time[ps - 1];
 | |
|         } else {
 | |
|           self->smoothing_time[ps] = self->smoothing_filt_state.prev_smg_time;
 | |
|           self->inv_smoothing_time[ps] =
 | |
|               self->smoothing_filt_state.inv_prev_smg_time;
 | |
|         }
 | |
| 
 | |
|         for (pb = 0; pb < self->bs_param_bands; pb++) {
 | |
|           if (ps > 0)
 | |
|             self->smoothing_data[ps][pb] = self->smoothing_data[ps - 1][pb];
 | |
|           else
 | |
|             self->smoothing_data[ps][pb] =
 | |
|                 self->smoothing_filt_state.prev_smg_data[pb];
 | |
|         }
 | |
|         break;
 | |
| 
 | |
|       case 2:
 | |
|         self->smoothing_time[ps] =
 | |
|             ixheaacd_smoothing_time_table[frame->bs_smooth_time[ps]];
 | |
|         self->inv_smoothing_time[ps] =
 | |
|             ixheaacd_inverse_smoothing_time_table_q30[frame
 | |
|                                                           ->bs_smooth_time[ps]];
 | |
|         for (pb = 0; pb < self->bs_param_bands; pb++) {
 | |
|           self->smoothing_data[ps][pb] = 1;
 | |
|         }
 | |
|         break;
 | |
| 
 | |
|       case 3:
 | |
|         self->smoothing_time[ps] =
 | |
|             ixheaacd_smoothing_time_table[frame->bs_smooth_time[ps]];
 | |
|         self->inv_smoothing_time[ps] =
 | |
|             ixheaacd_inverse_smoothing_time_table_q30[frame
 | |
|                                                           ->bs_smooth_time[ps]];
 | |
| 
 | |
|         ch_fac = ixheaacd_mps_stride_table[frame->bs_freq_res_stride_smg[ps]];
 | |
|         data_bands = (self->bs_param_bands - 1) / ch_fac + 1;
 | |
|         ixheaacd_mps_createmapping(group_to_band, 0, self->bs_param_bands,
 | |
|                                    ch_fac);
 | |
|         for (pg = 0; pg < data_bands; pg++) {
 | |
|           param_band_start = group_to_band[pg];
 | |
|           param_band_stop = group_to_band[pg + 1];
 | |
|           for (pb = param_band_start; pb < param_band_stop; pb++) {
 | |
|             self->smoothing_data[ps][pb] = frame->bs_smg_data[ps][pg];
 | |
|           }
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   self->smoothing_filt_state.prev_smg_time =
 | |
|       self->smoothing_time[self->num_parameter_sets - 1];
 | |
|   self->smoothing_filt_state.inv_prev_smg_time =
 | |
|       self->inv_smoothing_time[self->num_parameter_sets - 1];
 | |
|   for (pb = 0; pb < self->bs_param_bands; pb++) {
 | |
|     self->smoothing_filt_state.prev_smg_data[pb] =
 | |
|         self->smoothing_data[self->num_parameter_sets - 1][pb];
 | |
|   }
 | |
| 
 | |
|   if (self->ext_frame_flag) {
 | |
|     self->smoothing_time[self->num_parameter_sets] =
 | |
|         self->smoothing_time[self->num_parameter_sets - 1];
 | |
|     self->inv_smoothing_time[self->num_parameter_sets] =
 | |
|         self->inv_smoothing_time[self->num_parameter_sets - 1];
 | |
|     for (pb = 0; pb < self->bs_param_bands; pb++) {
 | |
|       self->smoothing_data[self->num_parameter_sets][pb] =
 | |
|           self->smoothing_data[self->num_parameter_sets - 1][pb];
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| WORD32 ixheaacd_mps_frame_decode(ia_mps_dec_state_struct *self) {
 | |
|   int i;
 | |
|   WORD32 err_code = 0;
 | |
|   if (self->parse_nxt_frame == 1) return 0;
 | |
| 
 | |
|   self->ext_frame_flag = 0;
 | |
|   if (self->param_slots[self->num_parameter_sets - 1] != self->time_slots - 1) {
 | |
|     self->ext_frame_flag = 1;
 | |
|   }
 | |
| 
 | |
|   err_code = ixheaacd_mps_dec_and_mapframeott(self);
 | |
| 
 | |
|   if (err_code != 0) return err_code;
 | |
| 
 | |
|   ixheaacd_mps_dec_and_mapframesmg(self);
 | |
| 
 | |
|   if (self->ext_frame_flag) {
 | |
|     self->num_parameter_sets++;
 | |
|     self->param_slots[self->num_parameter_sets - 1] = self->time_slots - 1;
 | |
|   }
 | |
|   self->param_slot_diff[0] = self->param_slots[0] + 1;
 | |
|   self->inv_param_slot_diff[0] = (float)1 / self->param_slot_diff[0];
 | |
|   self->inv_param_slot_diff_Q30[0] =
 | |
|       (int)floor(self->inv_param_slot_diff[0] * 1073741824 + 0.5);
 | |
|   for (i = 1; i < self->num_parameter_sets; i++) {
 | |
|     self->param_slot_diff[i] = self->param_slots[i] - self->param_slots[i - 1];
 | |
|     self->inv_param_slot_diff[i] = (float)1 / self->param_slot_diff[i];
 | |
|     self->inv_param_slot_diff_Q30[i] =
 | |
|         (int)floor(self->inv_param_slot_diff[i] * 1073741824 + 0.5);
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| WORD32 ixheaacd_mps_header_decode(ia_mps_dec_state_struct *self) {
 | |
|   self->time_slots = self->frame_length;
 | |
|   self->frame_len = self->time_slots * self->qmf_band_count;
 | |
|   self->bs_param_bands = ixheaacd_freq_res_table[self->config->bs_freq_res];
 | |
| 
 | |
|   self->hyb_band_count = self->qmf_band_count - QMF_BANDS_TO_HYBRID + 10;
 | |
| 
 | |
|   switch (self->bs_param_bands) {
 | |
|     case 4:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_4_map;
 | |
|       break;
 | |
|     case 5:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_5_map;
 | |
|       break;
 | |
|     case 7:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_7_map;
 | |
|       break;
 | |
|     case 10:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_10_map;
 | |
|       break;
 | |
|     case 14:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_14_map;
 | |
|       break;
 | |
|     case 20:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_20_map;
 | |
|       break;
 | |
|     case 28:
 | |
| 
 | |
|       self->hyb_band_to_processing_band_table =
 | |
|           ixheaacd_hybrid_band_71_to_processing_band_28_map;
 | |
|       break;
 | |
|     default:
 | |
|       self->hyb_band_to_processing_band_table = NULL;
 | |
|       return -1;
 | |
|       break;
 | |
|   };
 | |
| 
 | |
|   self->in_ch_count = 1;
 | |
|   self->out_ch_count = 2;
 | |
| 
 | |
|   self->input_gain =
 | |
|       ixheaacd_mps_clip_gain_table[self->config->bs_fixed_gain_dmx];
 | |
| 
 | |
|   if (self->config->bs_ott_bands_phase_present) {
 | |
|     self->num_bands_ipd = self->config->bs_ott_bands_phase;
 | |
|   } else {
 | |
|     switch (self->bs_param_bands) {
 | |
|       case 4:
 | |
|       case 5:
 | |
|         self->num_bands_ipd = 2;
 | |
|         break;
 | |
|       case 7:
 | |
|         self->num_bands_ipd = 3;
 | |
|         break;
 | |
|       case 10:
 | |
|         self->num_bands_ipd = 5;
 | |
|         break;
 | |
|       case 14:
 | |
|         self->num_bands_ipd = 7;
 | |
|         break;
 | |
|       case 20:
 | |
|       case 28:
 | |
|         self->num_bands_ipd = 10;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0);
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (self->residual_coding) {
 | |
|     self->num_bands_ipd = max(self->bs_residual_bands, self->num_bands_ipd);
 | |
|     self->max_res_bands = 0;
 | |
|     if (self->bs_residual_present) {
 | |
|       self->res_bands = self->bs_residual_bands;
 | |
|       if (self->res_bands > self->max_res_bands) {
 | |
|         self->max_res_bands = self->res_bands;
 | |
|       }
 | |
|     } else {
 | |
|       self->res_bands = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (self->num_bands_ipd > MAX_PARAMETER_BANDS) return -1;
 | |
| 
 | |
|   self->dir_sig_count = 1;
 | |
|   self->decor_sig_count = 1;
 | |
| 
 | |
|   self->bs_high_rate_mode = self->config->bs_high_rate_mode;
 | |
| 
 | |
|   return 0;
 | |
| }
 |