Home | History | Annotate | Download | only in armv7
      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 <string.h>
     21 
     22 #include "ixheaacd_sbr_common.h"
     23 #include <ixheaacd_type_def.h>
     24 
     25 #include "ixheaacd_constants.h"
     26 #include "ixheaacd_basic_ops32.h"
     27 #include "ixheaacd_basic_ops16.h"
     28 #include "ixheaacd_basic_ops40.h"
     29 #include "ixheaacd_basic_ops.h"
     30 
     31 #include "ixheaacd_intrinsics.h"
     32 #include "ixheaacd_common_rom.h"
     33 #include "ixheaacd_bitbuffer.h"
     34 #include "ixheaacd_sbrdecsettings.h"
     35 #include "ixheaacd_sbr_scale.h"
     36 #include "ixheaacd_lpp_tran.h"
     37 #include "ixheaacd_env_extr_part.h"
     38 #include "ixheaacd_sbr_rom.h"
     39 #include "ixheaacd_hybrid.h"
     40 #include "ixheaacd_ps_dec.h"
     41 #include "ixheaacd_env_extr.h"
     42 #include "ixheaacd_qmf_dec.h"
     43 
     44 #include <ixheaacd_basic_op.h>
     45 #include "ixheaacd_env_calc.h"
     46 
     47 #include "ixheaacd_interface.h"
     48 
     49 #include "ixheaacd_function_selector.h"
     50 #include "ixheaacd_audioobjtypes.h"
     51 
     52 #define mult16x16_16(a, b) ixheaacd_mult16((a), (b))
     53 #define mac16x16(a, b, c) ixheaacd_mac16x16in32((a), (b), (c))
     54 #define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b))
     55 #define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b))
     56 #define mpy_32x32(a, b) ixheaacd_mult32((a), (b))
     57 #define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b))
     58 #define msu16x16(a, b, c) msu16x16in32((a), (b), (c))
     59 
     60 #define DCT3_LEN (32)
     61 #define DCT2_LEN (64)
     62 
     63 #define LP_SHIFT_VAL 7
     64 #define HQ_SHIFT_64 4
     65 #define RADIXSHIFT 1
     66 #define ROUNDING_SPECTRA 1
     67 #define HQ_SHIFT_VAL 4
     68 
     69 VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X,
     70                       ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
     71                       WORD16 *filter_states) {
     72   ixheaacd_pretwdct2(x, X);
     73 
     74   ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x,
     75                                qmf_dec_tables_ptr->dig_rev_table2_128,
     76                                qmf_dec_tables_ptr->dig_rev_table2_128,
     77                                qmf_dec_tables_ptr->dig_rev_table2_128,
     78                                qmf_dec_tables_ptr->dig_rev_table2_128);
     79 
     80   ixheaacd_fftposttw(x, qmf_dec_tables_ptr);
     81 
     82   ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr);
     83 
     84   return;
     85 }
     86 
     87 VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf,
     88                                 ia_sbr_scale_fact_struct *sbr_scale_factor,
     89                                 WORD32 **qmf_real, WORD32 **qmf_imag,
     90                                 ia_sbr_qmf_filter_bank_struct *qmf_bank,
     91                                 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
     92                                 WORD32 ch_fac, WORD32 low_pow_flag,
     93                                 WORD audio_object_type) {
     94   WORD32 i, k;
     95   WORD32 num_time_slots = qmf_bank->num_time_slots;
     96 
     97   WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS];
     98   WORD16 *filter_states = qmf_bank->core_samples_buffer;
     99 
    100   WORD16 *fp1, *fp2, *tmp;
    101 
    102   WORD16 *filter_1;
    103   WORD16 *filter_2;
    104   WORD16 *filt_ptr;
    105   if (audio_object_type != AOT_ER_AAC_ELD &&
    106       audio_object_type != AOT_ER_AAC_LD) {
    107     qmf_bank->filter_pos +=
    108         (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff);
    109     qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c;
    110   } else {
    111     qmf_bank->filter_pos +=
    112         (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff);
    113     qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3;
    114   }
    115 
    116   filter_1 = qmf_bank->filter_pos;
    117 
    118   if (audio_object_type != AOT_ER_AAC_ELD &&
    119       audio_object_type != AOT_ER_AAC_LD) {
    120     filter_2 = filter_1 + 64;
    121   } else {
    122     filter_2 = filter_1 + 32;
    123   }
    124 
    125   sbr_scale_factor->st_lb_scale = 0;
    126   sbr_scale_factor->lb_scale = -10;
    127   if (!low_pow_flag) {
    128     if (audio_object_type != AOT_ER_AAC_ELD &&
    129         audio_object_type != AOT_ER_AAC_LD) {
    130       sbr_scale_factor->lb_scale = -8;
    131     } else {
    132       sbr_scale_factor->lb_scale = -9;
    133     }
    134     qmf_bank->cos_twiddle =
    135         (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
    136     qmf_bank->alt_sin_twiddle =
    137         (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
    138     if (audio_object_type != AOT_ER_AAC_ELD &&
    139         audio_object_type != AOT_ER_AAC_LD) {
    140       qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32;
    141     } else {
    142       qmf_bank->t_cos =
    143           (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld;
    144     }
    145   }
    146 
    147   fp1 = qmf_bank->anal_filter_states;
    148   fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS;
    149 
    150   if (audio_object_type == AOT_ER_AAC_ELD ||
    151       audio_object_type == AOT_ER_AAC_LD) {
    152     filter_2 = qmf_bank->filter_2;
    153     fp1 = qmf_bank->fp1_anal;
    154     fp2 = qmf_bank->fp2_anal;
    155   }
    156 
    157   for (i = 0; i < num_time_slots; i++) {
    158     for (k = 0; k < NO_ANALYSIS_CHANNELS; k++)
    159       filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k];
    160 
    161     if (audio_object_type != AOT_ER_AAC_ELD &&
    162         audio_object_type != AOT_ER_AAC_LD) {
    163       ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2,
    164                                      analysis_buffer, filter_states,
    165                                      time_sample_buf, ch_fac);
    166     } else {
    167       ixheaacd_sbr_qmfanal32_winadds_eld(fp1, fp2, filter_1, filter_2,
    168                                          analysis_buffer, filter_states,
    169                                          time_sample_buf, ch_fac);
    170     }
    171 
    172     time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac;
    173 
    174     filter_states -= NO_ANALYSIS_CHANNELS;
    175     if (filter_states < qmf_bank->anal_filter_states) {
    176       filter_states = qmf_bank->anal_filter_states + 288;
    177     }
    178 
    179     tmp = fp1;
    180     fp1 = fp2;
    181     fp2 = tmp;
    182     if (audio_object_type != AOT_ER_AAC_ELD &&
    183         audio_object_type != AOT_ER_AAC_LD) {
    184       filter_1 += 64;
    185       filter_2 += 64;
    186     } else {
    187       filter_1 += 32;
    188       filter_2 += 32;
    189     }
    190 
    191     filt_ptr = filter_1;
    192     filter_1 = filter_2;
    193     filter_2 = filt_ptr;
    194     if (audio_object_type != AOT_ER_AAC_ELD &&
    195         audio_object_type != AOT_ER_AAC_LD) {
    196       if (filter_2 > (qmf_bank->analy_win_coeff + 640)) {
    197         filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
    198         filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64;
    199       }
    200     } else {
    201       if (filter_2 > (qmf_bank->analy_win_coeff + 320)) {
    202         filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
    203         filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32;
    204       }
    205     }
    206 
    207     if (!low_pow_flag) {
    208       ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i],
    209                               qmf_bank, qmf_dec_tables_ptr);
    210     } else {
    211       ixheaacd_dct3_32(
    212           (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw,
    213           qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16,
    214           qmf_dec_tables_ptr->dig_rev_table4_16);
    215     }
    216   }
    217 
    218   qmf_bank->filter_pos = filter_1;
    219   qmf_bank->core_samples_buffer = filter_states;
    220 
    221   if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD)
    222 
    223   {
    224     qmf_bank->fp1_anal = fp1;
    225     qmf_bank->fp2_anal = fp2;
    226     qmf_bank->filter_2 = filter_2;
    227   }
    228 }
    229 
    230 VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states,
    231                                 ia_sbr_qmf_filter_bank_struct *syn_qmf,
    232                                 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
    233   WORD32 L = syn_qmf->no_channels;
    234   const WORD32 M = (L >> 1);
    235   WORD32 *dct_in = qmf_real;
    236   WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS];
    237 
    238   WORD32 ui_rem = ((WORD32)(&time_out[0]) % 8);
    239   WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem);
    240 
    241   if (L == 64)
    242     ixheaacd_dec_DCT2_64_asm(dct_in, ptime_out, qmf_dec_tables_ptr->w1024,
    243                              qmf_dec_tables_ptr->dig_rev_table2_128,
    244                              qmf_dec_tables_ptr->post_fft_tbl,
    245                              qmf_dec_tables_ptr->dct23_tw, filter_states + M);
    246   else
    247     ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states);
    248 
    249   filter_states[3 * M] = 0;
    250 }
    251 
    252 VOID ixheaacd_inv_emodulation(WORD32 *qmf_real,
    253                               ia_sbr_qmf_filter_bank_struct *syn_qmf,
    254                               ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
    255   ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024,
    256                        (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128);
    257 }
    258 
    259 VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband,
    260                                ia_sbr_qmf_filter_bank_struct *qmf_bank,
    261                                WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) {
    262   WORD32 z;
    263   WORD32 temp[128];
    264   WORD32 scaleshift = 0;
    265 
    266   WORD32 M_2;
    267   WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1);
    268 
    269   const WORD32 *p_sin;
    270   const WORD32 *p_sin_cos;
    271 
    272   WORD32 subband_tmp[128];
    273 
    274   p_sin_cos = qmf_bank->esbr_cos_twiddle;
    275   ixheaacd_esbr_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp);
    276 
    277   M_2 = ixheaacd_shr32(M, 1);
    278   if (M == 32) {
    279     ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8);
    280     ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2);
    281     ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32);
    282 
    283     ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8);
    284     ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2);
    285     ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl,
    286                                32);
    287 
    288   }
    289 
    290   else if (M == 16) {
    291     ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4);
    292     ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16);
    293 
    294     ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4);
    295     ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl,
    296                                16);
    297 
    298   }
    299 
    300   else if (M == 12) {
    301     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    302       temp[z] = subband_tmp[2 * z];
    303       temp[12 + z] = subband_tmp[2 * z + 1];
    304     }
    305 
    306     ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
    307 
    308     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    309       subband[2 * z] = temp[z];
    310       subband[2 * z + 1] = temp[z + 12];
    311     }
    312     scaleshift = 0;
    313     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    314       temp[z] = subband_tmp[64 + 2 * z];
    315       temp[12 + z] = subband_tmp[64 + 2 * z + 1];
    316     }
    317 
    318     ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
    319 
    320     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    321       subband[64 + 2 * z] = temp[z];
    322       subband[64 + 2 * z + 1] = temp[z + 12];
    323     }
    324 
    325   }
    326 
    327   else {
    328     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    329       temp[z] = subband_tmp[2 * z];
    330       temp[8 + z] = subband_tmp[2 * z + 1];
    331     }
    332 
    333     (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
    334 
    335     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    336       subband[2 * z] = temp[z] << scaleshift;
    337       subband[2 * z + 1] = temp[z + 8] << scaleshift;
    338     }
    339     scaleshift = 0;
    340     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    341       temp[z] = subband_tmp[64 + 2 * z];
    342       temp[8 + z] = subband_tmp[64 + 2 * z + 1];
    343     }
    344 
    345     (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
    346 
    347     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
    348       subband[64 + 2 * z] = temp[z] << scaleshift;
    349       subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift;
    350     }
    351   }
    352   p_sin = qmf_bank->esbr_alt_sin_twiddle;
    353   ixheaacd_esbr_cos_sin_mod_loop2(subband, p_sin, M);
    354 }
    355