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 <ixheaacd_type_def.h>
     21 #include "ixheaacd_bitbuffer.h"
     22 #include "ixheaacd_config.h"
     23 #include "ixheaacd_mps_polyphase.h"
     24 #include "ixheaacd_mps_dec.h"
     25 #include "ixheaacd_mps_interface.h"
     26 
     27 #include "ixheaacd_mps_process.h"
     28 
     29 #include <math.h>
     30 #include <float.h>
     31 #include <memory.h>
     32 
     33 #include <assert.h>
     34 
     35 #include "ixheaacd_common_rom.h"
     36 #include "ixheaacd_defines.h"
     37 
     38 #include "ixheaacd_pns.h"
     39 
     40 #include <ixheaacd_aac_rom.h>
     41 #include "ixheaacd_pulsedata.h"
     42 
     43 #include "ixheaacd_sbrdecsettings.h"
     44 #include "ixheaacd_sbr_scale.h"
     45 #include "ixheaacd_lpp_tran.h"
     46 #include "ixheaacd_env_extr_part.h"
     47 #include <ixheaacd_sbr_rom.h>
     48 #include "ixheaacd_hybrid.h"
     49 #include "ixheaacd_ps_dec.h"
     50 #include "ixheaacd_env_extr.h"
     51 
     52 #include "ixheaacd_qmf_dec.h"
     53 
     54 #include "ixheaacd_env_calc.h"
     55 #include "ixheaacd_sbr_const.h"
     56 #include "ixheaacd_pvc_dec.h"
     57 #include "ixheaacd_sbr_dec.h"
     58 
     59 #define HP_SIZE (9)
     60 
     61 #define STP_LPF_COEFF1 (0.950f)
     62 #define STP_LPF_COEFF2 (0.450f)
     63 #define STP_UPDATE_ENERGY_RATE (32)
     64 #define STP_SCALE_LIMIT (2.82f)
     65 #define STP_DAMP (0.1f)
     66 
     67 #define max(a, b) ((a > b) ? (a) : (b))
     68 #define min(a, b) ((a < b) ? (a) : (b))
     69 
     70 static FLOAT32 ixheaacd_bp[BP_SIZE] = {
     71     0.0000f, 0.0005f, 0.0092f, 0.0587f, 0.2580f, 0.7392f, 0.9791f,
     72     0.9993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9984f,
     73     0.9908f, 0.9639f, 0.8952f, 0.7711f, 0.6127f, 0.4609f, 0.3391f,
     74     0.2493f, 0.1848f, 0.1387f, 0.1053f};
     75 
     76 static FLOAT32 ixheaacd_gf[BP_SIZE] = {
     77     0.f,         0.f,         0.f,         0.f,         0.f,
     78     0.f,         1e-008f,     8.1e-007f,   3.61e-006f,  8.41e-006f,
     79     1.6e-005f,   2.704e-005f, 3.969e-005f, 5.625e-005f, 7.396e-005f,
     80     9.801e-005f, 0.00012321f, 0.00015625f, 0.00019881f, 0.00024964f,
     81     0.00032041f, 0.00041209f, 0.00053824f, 0.00070756f, 0.00094249f};
     82 
     83 static VOID ixheaacd_mps_temp_process_scale_calc(ia_mps_dec_state_struct* self,
     84                                                  WORD32 ts, FLOAT32* scale) {
     85   FLOAT32 dir_energy;
     86   FLOAT32 diff_energy[2];
     87   FLOAT32 temp;
     88 
     89   WORD32 ch, n;
     90   WORD32 left_ch = 0, right_ch = 1;
     91 
     92   if (self->subband_var.init_flag == 0) {
     93     for (ch = 0; ch < 2; ch++) {
     94       self->subband_var.tp_scale_last[ch] = 1.0f;
     95       self->subband_var.nrg_diff_prev[ch] = 32768 * 32768;
     96     }
     97 
     98     self->subband_var.nrg_dir_prev = 32768 * 32768;
     99     self->subband_var.init_flag = 1;
    100   }
    101 
    102   if (self->subband_var.update_old_ener == STP_UPDATE_ENERGY_RATE) {
    103     self->subband_var.update_old_ener = 1;
    104     self->subband_var.nrg_dir_prev = self->subband_var.nrg_dir;
    105     for (ch = 0; ch < self->out_ch_count; ch++)
    106       self->subband_var.nrg_diff_prev[ch] = self->subband_var.nrg_diff[ch];
    107   } else
    108     self->subband_var.update_old_ener++;
    109 
    110   dir_energy = 0;
    111 
    112   for (n = 6; n < BP_SIZE; n++) {
    113     FLOAT32 dir_left_re = self->hyb_dir_out[left_ch][ts][n + 7].re;
    114     FLOAT32 dir_right_re = self->hyb_dir_out[right_ch][ts][n + 7].re;
    115     FLOAT32 dir_left_im = self->hyb_dir_out[left_ch][ts][n + 7].im;
    116     FLOAT32 dir_right_im = self->hyb_dir_out[right_ch][ts][n + 7].im;
    117 
    118     temp = ((dir_left_re + dir_right_re) * (dir_left_re + dir_right_re)) +
    119            ((dir_left_im + dir_right_im) * (dir_left_im + dir_right_im));
    120     dir_energy += temp * ixheaacd_bp[n] * ixheaacd_bp[n] * ixheaacd_gf[n] *
    121                   ixheaacd_gf[n];
    122   }
    123 
    124   self->subband_var.nrg_dir =
    125       (FLOAT32)(STP_LPF_COEFF1 * self->subband_var.nrg_dir +
    126                 (1.0 - STP_LPF_COEFF1) * dir_energy);
    127 
    128   dir_energy /= (self->subband_var.nrg_dir_prev + ABS_THR);
    129 
    130   for (ch = 0; ch < self->out_ch_count; ch++) {
    131     diff_energy[ch] = 0;
    132     for (n = 6; n < BP_SIZE; n++) {
    133       FLOAT32 diff_re = self->hyb_diff_out[ch][ts][n + 7].re;
    134       FLOAT32 diff_im = self->hyb_diff_out[ch][ts][n + 7].im;
    135 
    136       temp = (diff_re * diff_re) + (diff_im * diff_im);
    137       diff_energy[ch] += temp * ixheaacd_bp[n] * ixheaacd_bp[n] *
    138                          ixheaacd_gf[n] * ixheaacd_gf[n];
    139     }
    140 
    141     self->subband_var.nrg_diff[ch] =
    142         (FLOAT32)(STP_LPF_COEFF1 * self->subband_var.nrg_diff[ch] +
    143                   (1.0 - STP_LPF_COEFF1) * diff_energy[ch]);
    144     diff_energy[ch] /= (self->subband_var.nrg_diff_prev[ch] + ABS_THR);
    145   }
    146 
    147   scale[left_ch] = (FLOAT32)sqrt((dir_energy) / (diff_energy[left_ch] + 1e-9));
    148   scale[right_ch] =
    149       (FLOAT32)sqrt((dir_energy) / (diff_energy[right_ch] + 1e-9));
    150 
    151   for (ch = 0; ch < self->out_ch_count; ch++) {
    152     scale[ch] = STP_DAMP + (1 - STP_DAMP) * scale[ch];
    153   }
    154 
    155   for (ch = 0; ch < self->out_ch_count; ch++) {
    156     scale[ch] =
    157         min(max(scale[ch], (FLOAT32)(1.0 / STP_SCALE_LIMIT)), STP_SCALE_LIMIT);
    158   }
    159 
    160   for (ch = 0; ch < self->out_ch_count; ch++) {
    161     scale[ch] =
    162         (FLOAT32)(STP_LPF_COEFF2 * scale[ch] +
    163                   (1.0 - STP_LPF_COEFF2) * self->subband_var.tp_scale_last[ch]);
    164     self->subband_var.tp_scale_last[ch] = scale[ch];
    165   }
    166 }
    167 
    168 static VOID ixheaacd_mps_subbandtp(ia_mps_dec_state_struct* self, WORD32 ts) {
    169   FLOAT32 scale[2];
    170   WORD32 ch, n;
    171   WORD32 no_scaling;
    172   FLOAT32 temp;
    173   const WORD32 ixheaacd_hybrid_to_qmf_map[] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2};
    174 
    175   ixheaacd_mps_temp_process_scale_calc(self, ts, scale);
    176 
    177   for (ch = 0; ch < self->out_ch_count; ch++) {
    178     no_scaling = 1;
    179 
    180     if ((self->config->bs_temp_shape_config == 1) ||
    181         (self->config->bs_temp_shape_config == 2))
    182       no_scaling = !self->temp_shape_enable_ch_stp[ch];
    183 
    184     if (no_scaling == 1) {
    185       for (n = 0; n < self->hyb_band_count; n++) {
    186         self->hyb_dir_out[ch][ts][n].re += self->hyb_diff_out[ch][ts][n].re;
    187         self->hyb_dir_out[ch][ts][n].im += self->hyb_diff_out[ch][ts][n].im;
    188       }
    189     } else {
    190       for (n = 0; n < 10; n++) {
    191         temp =
    192             (FLOAT32)(scale[ch] * ixheaacd_bp[ixheaacd_hybrid_to_qmf_map[n]]);
    193         self->hyb_dir_out[ch][ts][n].re +=
    194             (self->hyb_diff_out[ch][ts][n].re * temp);
    195         self->hyb_dir_out[ch][ts][n].im +=
    196             (self->hyb_diff_out[ch][ts][n].im * temp);
    197       }
    198       for (; n < HP_SIZE - 3 + 10; n++) {
    199         temp = (FLOAT32)(scale[ch] * ixheaacd_bp[n + 3 - 10]);
    200         self->hyb_dir_out[ch][ts][n].re +=
    201             (self->hyb_diff_out[ch][ts][n].re * temp);
    202         self->hyb_dir_out[ch][ts][n].im +=
    203             (self->hyb_diff_out[ch][ts][n].im * temp);
    204       }
    205       for (; n < self->hyb_band_count; n++) {
    206         temp = (FLOAT32)(scale[ch]);
    207         self->hyb_dir_out[ch][ts][n].re +=
    208             (self->hyb_diff_out[ch][ts][n].re * temp);
    209         self->hyb_dir_out[ch][ts][n].im +=
    210             (self->hyb_diff_out[ch][ts][n].im * temp);
    211       }
    212     }
    213   }
    214 }
    215 
    216 WORD32 ixheaacd_mps_temp_process(ia_mps_dec_state_struct* self) {
    217   WORD32 ch, ts, hyb;
    218   WORD32 err = 0;
    219 
    220   for (ch = 0; ch < self->out_ch_count; ch++) {
    221     for (ts = 0; ts < self->time_slots; ts++) {
    222       for (hyb = 0; hyb < HYBRID_BAND_BORDER; hyb++) {
    223         self->hyb_dir_out[ch][ts][hyb].re += self->hyb_diff_out[ch][ts][hyb].re;
    224         self->hyb_dir_out[ch][ts][hyb].im += self->hyb_diff_out[ch][ts][hyb].im;
    225         self->hyb_diff_out[ch][ts][hyb].re = 0;
    226         self->hyb_diff_out[ch][ts][hyb].im = 0;
    227       }
    228     }
    229   }
    230 
    231   for (ts = 0; ts < self->time_slots; ts++) ixheaacd_mps_subbandtp(self, ts);
    232 
    233   ixheaacd_mps_qmf_hyb_synthesis(self);
    234 
    235   for (ch = 0; ch < self->out_ch_count; ch++) {
    236     err = ixheaacd_sbr_dec_from_mps(&self->qmf_out_dir[ch][0][0].re,
    237                                     self->p_sbr_dec[ch], self->p_sbr_frame[ch],
    238                                     self->p_sbr_header[ch]);
    239     if (err) return err;
    240   }
    241 
    242   ixheaacd_mps_synt_calc(self);
    243   return err;
    244 }
    245