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 <stdio.h>
     22 #include <string.h>
     23 #include <math.h>
     24 #include <ixheaacd_type_def.h>
     25 #include <ixheaacd_interface.h>
     26 #include "ixheaacd_mps_polyphase.h"
     27 #include <ixheaacd_type_def.h>
     28 #include "ixheaacd_bitbuffer.h"
     29 #include "ixheaacd_config.h"
     30 #include "ixheaacd_mps_dec.h"
     31 #include "ixheaacd_mps_interface.h"
     32 #include "ixheaacd_constants.h"
     33 #include <ixheaacd_basic_ops32.h>
     34 #include "ixheaacd_function_selector.h"
     35 
     36 extern const WORD32
     37     ixheaacd_mps_polyphase_filter_coeff_fix[10 * MAX_NUM_QMF_BANDS_SAC / 2];
     38 extern WORD32 ixheaacd_mps_pre_re[64];
     39 extern WORD32 ixheaacd_mps_pre_im[64];
     40 extern WORD32 ixheaacd_mps_post_re[128];
     41 extern WORD32 ixheaacd_mps_post_im[128];
     42 
     43 static PLATFORM_INLINE WORD32 ixheaacd_mult32(WORD32 a, WORD32 b) {
     44   WORD32 result;
     45   WORD64 temp_result;
     46 
     47   temp_result = (WORD64)a * (WORD64)b;
     48   result = (WORD32)(temp_result >> 31);
     49 
     50   return (result);
     51 }
     52 
     53 VOID ixheaacd_mps_synt_create(ia_mps_poly_phase_struct *kernel,
     54                               WORD32 resolution) {
     55   kernel->resolution = resolution;
     56 }
     57 
     58 VOID ixheaacd_mps_synt_init(ia_mps_poly_phase_synth_struct *self) {
     59   memset(self->state, 0, sizeof(WORD32) * 64 * 20);
     60 }
     61 
     62 static VOID ixheaacd_float_to_int32(FLOAT32 *in, WORD32 *out, WORD32 q_factor,
     63                                     WORD32 sample) {
     64   WORD32 loop;
     65   UWORD32 temp = (1 << q_factor);
     66 
     67   for (loop = 0; loop < sample; loop++) out[loop] = (WORD32)(in[loop] * temp);
     68 }
     69 
     70 VOID ixheaacd_mps_synt_pre_twiddle_dec(WORD32 *ptr_in, WORD32 *table_re,
     71                                        WORD32 *table_im, WORD32 resolution) {
     72   WORD32 tmp, k;
     73   for (k = 0; k < 2 * resolution; k += 2) {
     74     tmp = ixheaacd_add32_sat(ixheaacd_mult32(ptr_in[k], table_re[k >> 1]),
     75                              ixheaacd_mult32(ptr_in[k + 1], table_im[k >> 1]));
     76 
     77     ptr_in[k + 1] =
     78         ixheaacd_add32_sat(ixheaacd_mult32(-ptr_in[k], table_im[k >> 1]),
     79                            ixheaacd_mult32(ptr_in[k + 1], table_re[k >> 1]));
     80 
     81     ptr_in[k] = tmp;
     82   }
     83 }
     84 
     85 VOID ixheaacd_mps_synt_post_twiddle_dec(WORD32 *ptr_in, WORD32 *table_re,
     86                                         WORD32 *table_im, WORD32 resolution) {
     87   WORD32 tmp, k;
     88   for (k = 0; k < 2 * resolution; k += 2) {
     89     tmp = ixheaacd_add32_sat(ixheaacd_mult32(ptr_in[k], table_re[k]),
     90                              ixheaacd_mult32(ptr_in[k + 1], table_im[k]));
     91 
     92     ptr_in[k + 1] =
     93         ixheaacd_add32_sat(ixheaacd_mult32(-ptr_in[k], table_im[k]),
     94                            ixheaacd_mult32(ptr_in[k + 1], table_re[k]));
     95 
     96     ptr_in[k] = tmp;
     97   }
     98 }
     99 
    100 VOID ixheaacd_mps_synt_post_fft_twiddle_dec(WORD32 resolution, WORD32 *fin_re,
    101                                             WORD32 *fin_im, WORD32 *table_re,
    102                                             WORD32 *table_im, WORD32 *state) {
    103   WORD32 l;
    104   for (l = 0; l < 2 * resolution; l++) {
    105     state[2 * resolution - l - 1] =
    106         ixheaacd_add32_sat(ixheaacd_mult32(fin_re[l], table_re[l]),
    107                            ixheaacd_mult32(fin_im[l], table_im[l]));
    108   }
    109 }
    110 
    111 VOID ixheaacd_mps_synt_out_calc_dec(WORD32 resolution, WORD32 *out,
    112                                     WORD32 *state, const WORD32 *filter_coeff) {
    113   WORD32 l, k;
    114   WORD32 *out1, *out2, *state1, *state2;
    115   out1 = out;
    116   out2 = out + resolution;
    117   state1 = state;
    118   state2 = state + (3 * resolution);
    119 
    120   for (k = 0; k < 5; k++) {
    121     for (l = 0; l < resolution; l++) {
    122       *out1++ = (WORD32)(((WORD64)(*state1++) * (*filter_coeff++)) >> 31);
    123       *out2++ = (WORD32)(((WORD64)(*state2++) * (*filter_coeff++)) >> 31);
    124     }
    125     out1 += resolution;
    126     out2 += resolution;
    127     state1 += (3 * resolution);
    128     state2 += (3 * resolution);
    129   }
    130 }
    131 
    132 VOID ixheaacd_mps_synt_calc(ia_mps_dec_state_struct *self) {
    133   WORD32 k, l, ts, ch;
    134   WORD64 acc;
    135   WORD32 ptr_in[128];
    136   WORD32 fin_re[128];
    137   WORD32 fin_im[128];
    138   FLOAT32 temp;
    139   WORD32 *state, *tmp_state, *out;
    140   const WORD32 *filt_coeff;
    141   WORD32 *tmp_buf = self->tmp_buf;
    142 
    143   ia_mps_poly_phase_struct kernel = self->poly_phase_filt_kernel;
    144   WORD32 resolution = kernel.resolution;
    145   for (ch = 0; ch < self->out_ch_count; ch++) {
    146     tmp_state = (&self->qmf_filt_state[ch])->state;
    147     state = &tmp_buf[self->time_slots * 2 * resolution];
    148     memcpy(state, tmp_state, sizeof(WORD32) * 20 * resolution);
    149     out = &tmp_buf[74 * MAX_NUM_QMF_BANDS_SAC];
    150 
    151     for (ts = 0; ts < self->time_slots; ts++) {
    152       ixheaacd_float_to_int32(&self->qmf_out_dir[ch][ts][0].re, ptr_in, 10,
    153                               resolution * 2);
    154 
    155       filt_coeff = ixheaacd_mps_polyphase_filter_coeff_fix;
    156 
    157       state -= (2 * resolution);
    158       (*ixheaacd_mps_synt_pre_twiddle)(ptr_in, ixheaacd_mps_pre_re,
    159                                        ixheaacd_mps_pre_im, resolution);
    160 
    161       (*ixheaacd_mps_complex_fft_64)(ptr_in, fin_re, fin_im, resolution);
    162 
    163       (*ixheaacd_mps_synt_post_twiddle)(ptr_in, ixheaacd_mps_post_re,
    164                                         ixheaacd_mps_post_im, resolution);
    165 
    166       (*ixheaacd_mps_complex_fft_64)(ptr_in, &fin_re[1], &fin_im[1],
    167                                      resolution);
    168 
    169       (*ixheaacd_mps_synt_post_fft_twiddle)(resolution, fin_re, fin_im,
    170                                             ixheaacd_mps_post_re,
    171                                             ixheaacd_mps_post_im, state);
    172       (*ixheaacd_mps_synt_out_calc)(resolution, out, state, filt_coeff);
    173 
    174       for (k = 0; k < resolution; k++) {
    175         acc = 0;
    176         for (l = 0; l < 10; l++) {
    177           acc = acc + out[resolution * l + k];
    178         }
    179         if (acc >= 2147483647)
    180           temp = 1.0;
    181         else if (acc <= -2147483647 - 1)
    182           temp = -1.0f;
    183         else
    184           temp = (FLOAT32)((WORD32)acc) / ((FLOAT32)(1 << 10));
    185 
    186         self->output_buffer[ch][self->qmf_band_count * ts + k] = (FLOAT32)temp;
    187       }
    188     }
    189 
    190     memcpy(tmp_state, state, sizeof(WORD32) * 20 * resolution);
    191   }
    192 }
    193