Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2  *                                                                            *
      3  * Copyright (C) 2018 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at:
      8  *
      9  * http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  *****************************************************************************
     18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 */
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #include <math.h>
     23 
     24 #include <ixheaacd_type_def.h>
     25 #include "ixheaacd_bitbuffer.h"
     26 #include "ixheaacd_interface.h"
     27 #include "ixheaacd_tns_usac.h"
     28 #include "ixheaacd_cnst.h"
     29 #include "ixheaacd_acelp_info.h"
     30 #include "ixheaacd_td_mdct.h"
     31 #include "ixheaacd_sbrdecsettings.h"
     32 #include "ixheaacd_info.h"
     33 #include "ixheaacd_sbr_common.h"
     34 #include "ixheaacd_drc_data_struct.h"
     35 #include "ixheaacd_drc_dec.h"
     36 #include "ixheaacd_sbrdecoder.h"
     37 #include "ixheaacd_mps_polyphase.h"
     38 #include "ixheaacd_sbr_const.h"
     39 #include "ixheaacd_main.h"
     40 #include "ixheaacd_arith_dec.h"
     41 #include "ixheaacd_windows.h"
     42 #include "ixheaacd_constants.h"
     43 #include <ixheaacd_type_def.h>
     44 #include <ixheaacd_basic_ops32.h>
     45 #include <ixheaacd_basic_ops40.h>
     46 #include "ixheaacd_func_def.h"
     47 #include "ixheaacd_acelp_com.h"
     48 
     49 static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
     50   WORD32 result;
     51   WORD64 temp_result;
     52 
     53   temp_result = (WORD64)a * (WORD64)b;
     54   result = (WORD32)(temp_result >> 31);
     55 
     56   return (result);
     57 }
     58 
     59 static VOID ixheaacd_weighted_synthesis_filter(WORD32 *a, WORD32 *ap) {
     60   WORD32 f;
     61   WORD32 i;
     62   ap[0] = a[0];
     63   f = IGAMMA1;
     64   for (i = 1; i <= ORDER; i++) {
     65     ap[i] = ixheaacd_mult32_m(f, a[i]);
     66     f = ixheaacd_mult32_m(f, IGAMMA1);
     67   }
     68   return;
     69 }
     70 
     71 static VOID ixheaacd_synthesis_tool(WORD32 a[], WORD32 x[], WORD32 l,
     72                                     WORD32 qshift, WORD32 *preshift) {
     73   WORD32 s;
     74   WORD32 i, j;
     75 
     76   for (i = 0; i < l; i++) {
     77     s = x[i];
     78     for (j = 1; j <= ORDER; j += 4) {
     79       s = ixheaacd_sub32_sat(
     80           s, ixheaacd_mul32_sh(a[j], x[i - j], (WORD8)(qshift)));
     81       s = ixheaacd_sub32_sat(
     82           s, ixheaacd_mul32_sh(a[j + 1], x[i - (j + 1)], (WORD8)(qshift)));
     83       s = ixheaacd_sub32_sat(
     84           s, ixheaacd_mul32_sh(a[j + 2], x[i - (j + 2)], (WORD8)(qshift)));
     85       s = ixheaacd_sub32_sat(
     86           s, ixheaacd_mul32_sh(a[j + 3], x[i - (j + 3)], (WORD8)(qshift)));
     87     }
     88     x[i] = s;
     89   }
     90 
     91   (*preshift)++;
     92   return;
     93 }
     94 
     95 WORD32 ixheaacd_fwd_alias_cancel_tool(
     96     ia_usac_data_struct *usac_data, ia_td_frame_data_struct *pstr_td_frame_data,
     97     WORD32 fac_length, FLOAT32 *lp_filt_coeff, WORD32 gain) {
     98   WORD32 i;
     99   FLOAT32 lp_filt_coeff_a[ORDER + 1];
    100   WORD32 qshift = 0;
    101   WORD32 err = 0;
    102 
    103   WORD32 *x_in = pstr_td_frame_data->fac_data;
    104   WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
    105   WORD32 *fac_signal = &usac_data->x_ac_dec[16];
    106   FLOAT32 fac_signal_flt[128 + 16];
    107   FLOAT32 *ptr_fac_signal_flt = &fac_signal_flt[16];
    108   WORD32 *ptr_overlap_buf =
    109       &(usac_data->overlap_data_ptr[usac_data->present_chan]
    110                                    [(usac_data->ccfl / 2) - fac_length]);
    111 
    112   memset(fac_signal - 16, 0, ORDER * sizeof(WORD32));
    113 
    114   err = ixheaacd_acelp_mdct(x_in, fac_signal, &qshift, fac_length, ptr_scratch);
    115   if (err == -1) return err;
    116 
    117   ixheaacd_lpc_coeff_wt_apply(lp_filt_coeff, lp_filt_coeff_a);
    118 
    119   for (i = 0; i < fac_length; i++)
    120     ptr_fac_signal_flt[i] =
    121         (FLOAT32)((FLOAT32)fac_signal[i] / (1 << (16 - qshift)));
    122 
    123   memset(ptr_fac_signal_flt - 16, 0, 16 * sizeof(FLOAT32));
    124 
    125   ixheaacd_synthesis_tool_float1(lp_filt_coeff_a, ptr_fac_signal_flt,
    126                                  fac_length);
    127 
    128   for (i = 0; i < fac_length; i++)
    129     fac_signal[i] = (WORD32)(ptr_fac_signal_flt[i] * (1 << (16 - qshift)));
    130 
    131   for (i = 0; i < fac_length; i++)
    132     ptr_overlap_buf[i] = ixheaacd_add32_sat(
    133         ptr_overlap_buf[i],
    134         (WORD32)ixheaacd_mul32_sh(fac_signal[i], gain, (WORD8)(16 - qshift)));
    135 
    136   return err;
    137 }
    138 
    139 WORD32 ixheaacd_fr_alias_cnx_fix(WORD32 *x_in, WORD32 len, WORD32 fac_length,
    140                                  WORD32 *lp_filt_coeff, WORD32 *izir,
    141                                  WORD32 *fac_data_out, WORD8 *qshift1,
    142                                  WORD8 qshift2, WORD8 qshift3, WORD32 *preshift,
    143                                  WORD32 *ptr_scratch) {
    144   WORD32 i;
    145   const WORD32 *sine_window;
    146   WORD32 fac_window[2 * FAC_LENGTH];
    147   WORD32 lp_filt_coeff_a[ORDER + 1];
    148   WORD32 err = 0;
    149 
    150   if (fac_length == 48) {
    151     sine_window = ixheaacd_sine_win_96;
    152   } else if (fac_length == 64) {
    153     sine_window = ixheaacd_sine_win_128;
    154   } else if (fac_length == 96) {
    155     sine_window = ixheaacd_sine_win_192;
    156   } else {
    157     sine_window = ixheaacd_sine_win_256;
    158   }
    159   if (FAC_LENGTH < fac_length) {
    160     return -1;
    161   }
    162 
    163   if (FAC_LENGTH < fac_length) {
    164     return -1;
    165   }
    166   if ((1 + (len / 2)) < (fac_length + 1)) {
    167     return -1;
    168   }
    169   if ((len / 2 + 1) > (2 * LEN_FRAME - fac_length - 1)) {
    170     return -1;
    171   }
    172 
    173   if (lp_filt_coeff != NULL && fac_data_out != NULL) {
    174     memset(fac_data_out - 16, 0, ORDER * sizeof(WORD32));
    175     err = ixheaacd_acelp_mdct(x_in, fac_data_out, preshift, fac_length,
    176                               ptr_scratch);
    177     if (err == -1) return err;
    178 
    179     ixheaacd_weighted_synthesis_filter(lp_filt_coeff, lp_filt_coeff_a);
    180 
    181     memset(fac_data_out + fac_length, 0, fac_length * sizeof(WORD32));
    182 
    183     ixheaacd_synthesis_tool(lp_filt_coeff_a, fac_data_out, 2 * fac_length,
    184                             qshift2, preshift);
    185 
    186     if (izir != NULL) {
    187       for (i = 0; i < fac_length; i++) {
    188         fac_window[i] = ixheaacd_mult32_m(
    189             sine_window[i], sine_window[(2 * fac_length) - 1 - i]);
    190         fac_window[fac_length + i] =
    191             2147483647 - ixheaacd_mult32_m(sine_window[fac_length + i],
    192                                            sine_window[fac_length + i]);
    193       }
    194       for (i = 0; i < fac_length; i++) {
    195         WORD32 temp1;
    196         WORD32 temp2;
    197 
    198         temp1 = ixheaacd_mul32_sh(
    199             izir[1 + (len / 2) + i], fac_window[fac_length + i],
    200             (char)((qshift3 - *qshift1 + 31 + (WORD8)(*preshift))));
    201 
    202         temp2 = ixheaacd_mul32_sh(
    203             izir[1 + (len / 2) - 1 - i], fac_window[fac_length - 1 - i],
    204             (char)((qshift3 - *qshift1 + 31 + (WORD8)(*preshift))));
    205 
    206         fac_data_out[i] =
    207             ixheaacd_add32_sat3((fac_data_out[i] / 2), temp1, temp2);
    208 
    209         fac_data_out[fac_length + i] = (fac_data_out[fac_length + i] / 2);
    210       }
    211     }
    212   }
    213 
    214   return err;
    215 }
    216