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 <stdio.h>
     21 #include <stdlib.h>
     22 #include <math.h>
     23 #include <string.h>
     24 #include <assert.h>
     25 
     26 #include <ixheaacd_type_def.h>
     27 #include "ixheaacd_bitbuffer.h"
     28 #include "ixheaacd_config.h"
     29 
     30 #include "ixheaacd_mps_polyphase.h"
     31 #include "ixheaacd_mps_dec.h"
     32 #include "ixheaacd_mps_interface.h"
     33 
     34 #include "ixheaacd_mps_polyphase.h"
     35 
     36 #include "ixheaacd_mps_decor.h"
     37 #include "ixheaacd_mps_hybfilter.h"
     38 
     39 #include "ixheaacd_constants.h"
     40 
     41 static WORD32 ixheaacd_decorr_delay[] = {11, 10, 5, 2};
     42 
     43 static WORD32 ixheaacd_qmf_split_freq_0[] = {3, 15, 24, 65};
     44 static WORD32 ixheaacd_qmf_split_freq_1[] = {3, 50, 65, 65};
     45 static WORD32 ixheaacd_qmf_split_freq_2[] = {0, 15, 65, 65};
     46 
     47 static FLOAT32 ixheaacd_lattice_coeff_0_filt_den_coeff[DECORR_FILT_0_ORD + 1] =
     48     {1.000000f, -0.314818f, -0.256828f, -0.173641f, -0.115077f, 0.000599f,
     49      0.033343f, 0.122672f,  -0.356362f, 0.128058f,  0.089800f};
     50 static FLOAT32 ixheaacd_lattice_coeff_0_filt_num_coeff[DECORR_FILT_0_ORD + 1] =
     51     {0.089800f,  0.128058f,  -0.356362f, 0.122672f,  0.033343f, 0.000599f,
     52      -0.115077f, -0.173641f, -0.256828f, -0.314818f, 1.000000f};
     53 
     54 static FLOAT32 ixheaacd_lattice_coeff_1_filt_den_coeff[DECORR_FILT_1_ORD + 1] =
     55     {1.000000f, -0.287137f, -0.088940f, 0.123204f, -0.126111f,
     56      0.064218f, 0.045768f,  -0.016264f, -0.122100f};
     57 static FLOAT32 ixheaacd_lattice_coeff_1_filt_num_coeff[DECORR_FILT_1_ORD + 1] =
     58     {-0.122100f, -0.016264f, 0.045768f,  0.064218f, -0.126111f,
     59      0.123204f,  -0.088940f, -0.287137f, 1.000000f};
     60 
     61 static FLOAT32 ixheaacd_lattice_coeff_2_filt_den_coeff[DECORR_FILT_2_ORD + 1] =
     62     {1.000000f, 0.129403f, -0.032633f, 0.035700f};
     63 static FLOAT32 ixheaacd_lattice_coeff_2_filt_num_coeff[DECORR_FILT_2_ORD + 1] =
     64     {0.035700f, -0.032633f, 0.129403f, 1.000000f};
     65 
     66 static FLOAT32 ixheaacd_lattice_coeff_3_filt_den_coeff[DECORR_FILT_3_ORD + 1] =
     67     {1.000000f, 0.034742f, -0.013000f};
     68 static FLOAT32 ixheaacd_lattice_coeff_3_filt_num_coeff[DECORR_FILT_3_ORD + 1] =
     69     {-0.013000f, 0.034742f, 1.000000f};
     70 
     71 extern WORD32
     72     ixheaacd_hybrid_band_71_to_processing_band_28_map[MAX_HYBRID_BANDS_MPS];
     73 
     74 static WORD32 ixheaacd_hybrid_to_qmf_map[MAX_HYBRID_BANDS_MPS] = {
     75     0,  0,  0,  0,  0,  0,  1,  1,  2,  2,  3,  4,  5,  6,  7,  8,  9,  10,
     76     11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
     77     29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
     78     47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
     79 
     80 static void ixheaacd_mps_decor_filt_init(ia_mps_decor_filt_struct *self,
     81                                          WORD32 reverb_band) {
     82   switch (reverb_band) {
     83     case 0:
     84       self->num_len = self->den_len = DECORR_FILT_0_ORD + 1;
     85       self->num = ixheaacd_lattice_coeff_0_filt_num_coeff;
     86       self->den = ixheaacd_lattice_coeff_0_filt_den_coeff;
     87 
     88       break;
     89     case 1:
     90       self->num_len = self->den_len = DECORR_FILT_1_ORD + 1;
     91       self->num = ixheaacd_lattice_coeff_1_filt_num_coeff;
     92       self->den = ixheaacd_lattice_coeff_1_filt_den_coeff;
     93 
     94       break;
     95     case 2:
     96       self->num_len = self->den_len = DECORR_FILT_2_ORD + 1;
     97       self->num = ixheaacd_lattice_coeff_2_filt_num_coeff;
     98       self->den = ixheaacd_lattice_coeff_2_filt_den_coeff;
     99       break;
    100     case 3:
    101       self->num_len = self->den_len = DECORR_FILT_3_ORD + 1;
    102       self->num = ixheaacd_lattice_coeff_3_filt_num_coeff;
    103       self->den = ixheaacd_lattice_coeff_3_filt_den_coeff;
    104       break;
    105   }
    106 
    107   self->state_len = self->num_len;
    108   memset(self->state, 0,
    109          sizeof(ia_cmplx_flt_struct) * (MAX_DECORR_FIL_ORDER + 1));
    110 
    111   return;
    112 }
    113 
    114 static VOID ixheaacd_mps_allpass_apply(ia_mps_decor_filt_struct *self,
    115                                        ia_cmplx_flt_struct *input, WORD32 len,
    116                                        ia_cmplx_flt_struct *output) {
    117   WORD32 i, j;
    118 
    119   for (i = 0; i < len; i++) {
    120     output[i].re = self->state[0].re + input[i].re * self->num[0];
    121     output[i].im = self->state[0].im + input[i].im * self->num[0];
    122 
    123     for (j = 1; j < self->num_len; j++) {
    124       self->state[j - 1].re = self->state[j].re + self->num[j] * input[i].re -
    125                               self->den[j] * output[i].re;
    126       self->state[j - 1].im = self->state[j].im + self->num[j] * input[i].im -
    127                               self->den[j] * output[i].im;
    128     }
    129   }
    130 }
    131 
    132 static VOID ixheaacd_mps_decor_energy_adjustment(
    133     ixheaacd_mps_decor_energy_adjust_filt_struct *handle,
    134     ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
    135     ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
    136     WORD32 time_slots) {
    137   ixheaacd_mps_decor_energy_adjust_filt_struct *self =
    138       (ixheaacd_mps_decor_energy_adjust_filt_struct *)handle;
    139   FLOAT32 in_energy[MAX_PARAMETER_BANDS] = {0};
    140   FLOAT32 out_energy[MAX_PARAMETER_BANDS] = {0};
    141   FLOAT32 gain[MAX_PARAMETER_BANDS];
    142   WORD32 i, j, k;
    143 
    144   for (i = 0; i < time_slots; i++) {
    145     memset(in_energy, 0, sizeof(FLOAT32) * MAX_PARAMETER_BANDS);
    146     memset(out_energy, 0, sizeof(FLOAT32) * MAX_PARAMETER_BANDS);
    147 
    148     for (j = 0; j < self->num_bins; j++) {
    149       k = ixheaacd_hybrid_band_71_to_processing_band_28_map[j];
    150 
    151       in_energy[k] += in[i][j].re * in[i][j].re + in[i][j].im * in[i][j].im;
    152       out_energy[k] +=
    153           out[i][j].re * out[i][j].re + out[i][j].im * out[i][j].im;
    154     }
    155 
    156     for (k = 0; k < MAX_PARAMETER_BANDS; k++) {
    157       self->smooth_in_energy[k] = self->smooth_in_energy[k] * DECOR_ALPHA +
    158                                   in_energy[k] * ONE_MINUS_DECOR_ALPHA;
    159       self->smooth_out_energy[k] = self->smooth_out_energy[k] * DECOR_ALPHA +
    160                                    out_energy[k] * ONE_MINUS_DECOR_ALPHA;
    161 
    162       gain[k] = 1.0f;
    163 
    164       if (self->smooth_out_energy[k] >
    165           self->smooth_in_energy[k] * DECOR_GAMMA) {
    166         gain[k] = (FLOAT32)sqrt(self->smooth_in_energy[k] * DECOR_GAMMA /
    167                                 (self->smooth_out_energy[k] + ABS_THR));
    168       }
    169 
    170       if (self->smooth_in_energy[k] >
    171           self->smooth_out_energy[k] * DECOR_GAMMA) {
    172         gain[k] =
    173             min(2.0f, (FLOAT32)sqrt(self->smooth_in_energy[k] /
    174                                     (DECOR_GAMMA * self->smooth_out_energy[k] +
    175                                      ABS_THR)));
    176       }
    177     }
    178 
    179     for (j = 0; j < self->num_bins; j++) {
    180       k = ixheaacd_hybrid_band_71_to_processing_band_28_map[j];
    181 
    182       out[i][j].re *= gain[k];
    183       out[i][j].im *= gain[k];
    184     }
    185   }
    186 }
    187 
    188 void ixheaacd_mps_decor_init(ia_mps_decor_struct_handle self, WORD32 subbands,
    189                              WORD32 decor_config) {
    190   WORD32 i, reverb_band;
    191   WORD32 *splitfreq;
    192 
    193   switch (decor_config) {
    194     case 0:
    195       splitfreq = ixheaacd_qmf_split_freq_0;
    196       break;
    197     case 1:
    198       splitfreq = ixheaacd_qmf_split_freq_1;
    199       break;
    200     case 2:
    201       splitfreq = ixheaacd_qmf_split_freq_2;
    202       break;
    203     default:
    204       return;
    205   }
    206 
    207   self->num_bins = subbands;
    208 
    209   for (i = 0; i < self->num_bins; i++) {
    210     reverb_band = 0;
    211     while ((reverb_band < 3) &&
    212            (ixheaacd_hybrid_to_qmf_map[i] >= (splitfreq[reverb_band] - 1)))
    213       reverb_band++;
    214 
    215     self->delay_sample_count[i] = ixheaacd_decorr_delay[reverb_band];
    216     ixheaacd_mps_decor_filt_init(&self->filter[i], reverb_band);
    217   }
    218 
    219   self->decor_nrg_smooth.num_bins = self->num_bins;
    220 
    221   return;
    222 }
    223 
    224 VOID ixheaacd_mps_decor_apply(
    225     ia_mps_decor_struct_handle self,
    226     ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
    227     ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
    228     WORD32 length) {
    229   WORD32 idx, sb_sample;
    230 
    231   ia_cmplx_flt_struct scratch[MAX_TIME_SLOTS];
    232 
    233   for (idx = 0; idx < self->num_bins; idx++) {
    234     for (sb_sample = 0; sb_sample < length; sb_sample++) {
    235       self->decor_delay_buffer[idx][self->delay_sample_count[idx] + sb_sample]
    236           .re = in[sb_sample][idx].re;
    237       self->decor_delay_buffer[idx][self->delay_sample_count[idx] + sb_sample]
    238           .im = in[sb_sample][idx].im;
    239     }
    240     ixheaacd_mps_allpass_apply(&self->filter[idx],
    241                                self->decor_delay_buffer[idx], length, scratch);
    242 
    243     for (sb_sample = 0; sb_sample < length; sb_sample++) {
    244       out[sb_sample][idx].re = scratch[sb_sample].re;
    245       out[sb_sample][idx].im = scratch[sb_sample].im;
    246     }
    247 
    248     for (sb_sample = 0; sb_sample < self->delay_sample_count[idx];
    249          sb_sample++) {
    250       self->decor_delay_buffer[idx][sb_sample].re =
    251           self->decor_delay_buffer[idx][length + sb_sample].re;
    252       self->decor_delay_buffer[idx][sb_sample].im =
    253           self->decor_delay_buffer[idx][length + sb_sample].im;
    254     }
    255   }
    256 
    257   ixheaacd_mps_decor_energy_adjustment(&self->decor_nrg_smooth, in, out,
    258                                        length);
    259 }
    260