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 <math.h>
     21 #include <stdio.h>
     22 
     23 #include <ixheaacd_type_def.h>
     24 #include "ixheaacd_bitbuffer.h"
     25 
     26 #include "ixheaacd_interface.h"
     27 
     28 #include "ixheaacd_tns_usac.h"
     29 #include "ixheaacd_cnst.h"
     30 
     31 #include "ixheaacd_acelp_info.h"
     32 
     33 #include "ixheaacd_sbrdecsettings.h"
     34 #include "ixheaacd_info.h"
     35 #include "ixheaacd_sbr_common.h"
     36 #include "ixheaacd_drc_data_struct.h"
     37 #include "ixheaacd_drc_dec.h"
     38 #include "ixheaacd_sbrdecoder.h"
     39 #include "ixheaacd_mps_polyphase.h"
     40 #include "ixheaacd_sbr_const.h"
     41 
     42 #include "ixheaacd_main.h"
     43 #include "ixheaacd_arith_dec.h"
     44 #include "ixheaacd_function_selector.h"
     45 #include <ixheaacd_constants.h>
     46 #include <ixheaacd_basic_ops32.h>
     47 #include <ixheaacd_basic_ops40.h>
     48 
     49 #define sfb_offset(x) (((x) > 0) ? sfb_top[(x)-1] : 0)
     50 
     51 static VOID ixheaacd_tns_dec_coef_usac(ia_usac_data_struct *usac_data,
     52                                        ia_tns_filter_struct *filter,
     53                                        WORD32 coef_res, WORD32 *par_coeff) {
     54   WORD32 resolution;
     55   WORD32 *ptr_par_coeff = par_coeff;
     56   const WORD32 *tns_coeff_ptr;
     57   WORD32 ixheaacd_drc_offset = 4;
     58   WORD16 *ptr_coeff = filter->coef;
     59   WORD32 order;
     60 
     61   resolution = coef_res - 3;
     62   tns_coeff_ptr = usac_data->tns_coeff3_32;
     63   if (resolution) {
     64     tns_coeff_ptr = usac_data->tns_coeff4_32;
     65     ixheaacd_drc_offset = ixheaacd_drc_offset << 1;
     66   }
     67   order = filter->order;
     68 
     69   do {
     70     WORD16 temp = *ptr_coeff++;
     71     *ptr_par_coeff++ = tns_coeff_ptr[temp + ixheaacd_drc_offset];
     72     order--;
     73   } while (order != 0);
     74 }
     75 
     76 static VOID ixheaacd_tns_parcor_lpc_convert_usac(WORD32 *parcor,
     77                                                  WORD32 *lpc_coeff,
     78                                                  WORD32 *scale, WORD order)
     79 
     80 {
     81   WORD i, j, status;
     82   WORD32 accu;
     83   WORD32 temp_buf1[TNS_MAX_ORDER + 1];
     84   WORD32 temp_buf2[TNS_MAX_ORDER + 1];
     85   WORD32 accu1, accu2;
     86 
     87   status = 1;
     88   *scale = 1;
     89 
     90   while (status) {
     91     status = 0;
     92 
     93     for (i = TNS_MAX_ORDER; i >= 0; i--) {
     94       temp_buf1[i] = 0;
     95       temp_buf2[i] = 0;
     96     }
     97 
     98     accu1 = (0x40000000 >> (*scale - 1));
     99 
    100     for (i = 0; i <= order; i++) {
    101       accu = accu1;
    102 
    103       for (j = 0; j < order; j++) {
    104         temp_buf2[j] = (accu1);
    105 
    106         accu1 = ixheaacd_add32_sat(
    107             accu1, ixheaacd_mult32_shl_sat(parcor[j], temp_buf1[j]));
    108         if (ixheaacd_abs32_sat(accu1) == 0x7fffffff) status = 1;
    109       }
    110 
    111       for (j = (order - 1); j >= 0; j--) {
    112         accu2 = (temp_buf1[j]);
    113         accu2 = ixheaacd_add32_sat(
    114             accu2, ixheaacd_mult32_shl_sat(parcor[j], temp_buf2[j]));
    115         temp_buf1[j + 1] = (accu2);
    116 
    117         if (ixheaacd_abs32_sat(accu2) == 0x7fffffff) status = 1;
    118       }
    119 
    120       temp_buf1[0] = (accu);
    121       lpc_coeff[i] = (accu1);
    122       accu1 = 0;
    123     }
    124 
    125     accu1 = (status - 1);
    126 
    127     if (accu1 == 0) {
    128       *scale = *scale + 1;
    129     }
    130   }
    131 }
    132 
    133 static VOID ixheaacd_tns_ar_filter_usac(WORD32 *spectrum, WORD32 size,
    134                                         WORD32 inc, WORD32 *lpc_coeff,
    135                                         WORD32 order, WORD32 shift_value,
    136                                         WORD32 *ptr_filter_state) {
    137   WORD32 i, j;
    138   WORD32 y;
    139   WORD64 acc;
    140 
    141   if ((order & 3) != 0) {
    142     for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
    143       lpc_coeff[i] = 0;
    144     }
    145     lpc_coeff[i] = 0;
    146     order = ((order & 0xfffffffc) + 4);
    147   }
    148 
    149   for (i = 0; i < order; i++) {
    150     y = *spectrum;
    151     acc = 0;
    152 
    153     for (j = i; j > 0; j--) {
    154       acc = ixheaacd_add64_sat(
    155           acc, ixheaacd_mult64(ptr_filter_state[j - 1], lpc_coeff[j]));
    156       ptr_filter_state[j] = ptr_filter_state[j - 1];
    157     }
    158 
    159     y = ixheaacd_sub32_sat(y, (WORD32)(acc >> 31));
    160     ptr_filter_state[0] = ixheaacd_shl32(y, shift_value);
    161     *spectrum = y;
    162     spectrum += inc;
    163   }
    164 
    165   for (i = order; i < size; i++) {
    166     y = *spectrum;
    167     acc = 0;
    168     for (j = order; j > 0; j--) {
    169       acc = ixheaacd_add64_sat(
    170           acc, ixheaacd_mult64(ptr_filter_state[j - 1], lpc_coeff[j]));
    171       ;
    172       ptr_filter_state[j] = ptr_filter_state[j - 1];
    173     }
    174     y = ixheaacd_sub32_sat(y, (WORD32)(acc >> 31));
    175     ptr_filter_state[0] = ixheaacd_shl32(y, shift_value);
    176     *spectrum = y;
    177     spectrum += inc;
    178   }
    179 }
    180 
    181 VOID ixheaacd_tns_apply(ia_usac_data_struct *usac_data, WORD32 *spec,
    182                         WORD32 nbands, ia_sfb_info_struct *pstr_sfb_info,
    183                         ia_tns_frame_info_struct *pstr_tns) {
    184   WORD32 f, max_order, start, stop, size, inc;
    185   WORD32 n_filt, coef_res, order, direction;
    186   WORD32 *ptr_spec;
    187   WORD32 scale_spec;
    188   WORD32 scale_lpc;
    189   WORD32 guard_band;
    190   WORD32 shift;
    191   WORD32 lpc_coeff[TNS_MAX_ORDER + 1];
    192   WORD32 par_coeff[TNS_MAX_ORDER + 1];
    193   ia_tns_filter_struct *filt;
    194 
    195   const WORD16 *sfb_top;
    196 
    197   WORD32 nbins = (pstr_sfb_info->islong) ? 1024 : 128;
    198   WORD32 i, j, idx;
    199 
    200   max_order = (pstr_sfb_info->islong) ? 15 : 7;
    201   idx = (pstr_sfb_info->islong) ? 0 : 1;
    202 
    203   ptr_spec = &usac_data->scratch_buffer[0];
    204 
    205   for (j = 0; j < pstr_tns->n_subblocks; j++) {
    206     sfb_top = pstr_sfb_info->ptr_sfb_tbl;
    207 
    208     for (i = 0; i < nbins; i++) {
    209       ptr_spec[i] = spec[i];
    210     }
    211 
    212     if (pstr_tns->str_tns_info[j].n_filt) {
    213       n_filt = pstr_tns->str_tns_info[j].n_filt;
    214 
    215       for (f = 0; f < n_filt; f++) {
    216         WORD32 tmp;
    217 
    218         coef_res = pstr_tns->str_tns_info[j].coef_res;
    219         filt = &pstr_tns->str_tns_info[j].str_filter[f];
    220         order = filt->order;
    221         direction = filt->direction;
    222         start = filt->start_band;
    223         stop = filt->stop_band;
    224 
    225         if (order > max_order) {
    226           fprintf(stderr, "Error in tns max order: %d %d\n", order, max_order);
    227         }
    228 
    229         if (!order) continue;
    230 
    231         ixheaacd_tns_dec_coef_usac(usac_data, filt, coef_res,
    232                                    (WORD32 *)par_coeff);
    233 
    234         ixheaacd_tns_parcor_lpc_convert_usac(par_coeff, lpc_coeff, &scale_lpc,
    235                                              filt->order);
    236 
    237         tmp = (*usac_data->tns_max_bands_tbl_usac)[usac_data->sampling_rate_idx]
    238                                                   [idx];
    239 
    240         start = ixheaacd_min32(start, tmp);
    241 
    242         start = ixheaacd_min32(start, nbands);
    243         start = sfb_offset(start);
    244 
    245         stop = ixheaacd_min32(stop, tmp);
    246         stop = ixheaacd_min32(stop, nbands);
    247         stop = sfb_offset(stop);
    248 
    249         guard_band = 31 - ixheaacd_norm32(filt->order);
    250 
    251         if ((size = stop - start) <= 0) continue;
    252 
    253         if (direction) {
    254           inc = -1;
    255           shift = stop - 1;
    256         }
    257 
    258         else {
    259           inc = 1;
    260           shift = start;
    261         }
    262 
    263         {
    264           WORD32 *ptr_temp = ptr_spec + start;
    265           scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_temp, size);
    266         }
    267 
    268         scale_spec = ((scale_spec - guard_band) - scale_lpc);
    269 
    270         if (scale_spec > 0) {
    271           ixheaacd_tns_ar_filter_usac(&ptr_spec[shift], size, inc, lpc_coeff,
    272                                       filt->order, scale_lpc,
    273                                       usac_data->x_ac_dec);
    274         }
    275 
    276         else {
    277           WORD32 *ptr_temp = ptr_spec + start;
    278 
    279           scale_spec = -scale_spec;
    280           scale_spec = ixheaacd_min32(scale_spec, 31);
    281 
    282           for (i = size; i != 0; i--) {
    283             *ptr_temp = *ptr_temp >> scale_spec;
    284             ptr_temp++;
    285           }
    286 
    287           {
    288             ixheaacd_tns_ar_filter_usac(&ptr_spec[shift], size, inc, lpc_coeff,
    289                                         filt->order, scale_lpc,
    290                                         usac_data->x_ac_dec);
    291           }
    292 
    293           {
    294             ptr_temp = ptr_spec + start;
    295             i = size;
    296 
    297             do {
    298               *ptr_temp = *ptr_temp << scale_spec;
    299               ptr_temp++;
    300               i--;
    301             } while (i != 0);
    302           }
    303         }
    304 
    305         for (i = start; i <= stop - 1; i++) {
    306           spec[i] = ptr_spec[i];
    307         }
    308       }
    309     }
    310 
    311     spec += pstr_sfb_info->bins_per_sbk;
    312   }
    313 }
    314