Home | History | Annotate | Download | only in drc_src
      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 "impd_type_def.h"
     22 #include "impd_memory_standards.h"
     23 #include "impd_drc_peak_limiter.h"
     24 #include "impd_drc_extr_delta_coded_info.h"
     25 #include "impd_drc_common.h"
     26 #include "impd_drc_struct.h"
     27 #include "impd_drc_interface.h"
     28 #include "impd_drc_bitbuffer.h"
     29 #include "impd_drc_bitstream_dec_api.h"
     30 #include "impd_drc_gain_dec.h"
     31 #include "impd_drc_filter_bank.h"
     32 #include "impd_drc_multi_band.h"
     33 #include "impd_drc_process_audio.h"
     34 #include "impd_parametric_drc_dec.h"
     35 #include "impd_drc_eq.h"
     36 #include "impd_drc_gain_decoder.h"
     37 #include "impd_drc_selection_process.h"
     38 #include "impd_drc_api_struct_def.h"
     39 #include "impd_drc_hashdefines.h"
     40 #include "impd_drc_rom.h"
     41 
     42 VOID process_qmf_syn_filt_bank(ia_drc_qmf_filt_struct *qmf_filt, FLOAT64 *buff,
     43                                FLOAT32 *input_real, FLOAT32 *input_imag,
     44                                FLOAT32 *output) {
     45   WORD32 i, j;
     46   FLOAT64 U[10 * QMF_NUM_FILT_BANDS];
     47   FLOAT64 W[10 * QMF_NUM_FILT_BANDS];
     48 
     49   FLOAT64 tmp;
     50 
     51   for (i = 20 * QMF_FILT_RESOLUTION - 1; i >= 2 * QMF_FILT_RESOLUTION; i--) {
     52     buff[i] = buff[i - 2 * QMF_FILT_RESOLUTION];
     53   }
     54 
     55   for (i = 0; i < 2 * QMF_FILT_RESOLUTION; i++) {
     56     tmp = 0.0;
     57     for (j = 0; j < QMF_FILT_RESOLUTION; j++) {
     58       tmp = tmp + input_real[j] * qmf_filt->syn_tab_real[i][j] -
     59             input_imag[j] * qmf_filt->syn_tab_imag[i][j];
     60     }
     61     buff[i] = tmp;
     62   }
     63 
     64   for (i = 0; i < 5; i++) {
     65     for (j = 0; j < QMF_FILT_RESOLUTION; j++) {
     66       U[2 * QMF_FILT_RESOLUTION * i + j] =
     67           buff[4 * QMF_FILT_RESOLUTION * i + j];
     68       U[2 * QMF_FILT_RESOLUTION * i + QMF_FILT_RESOLUTION + j] =
     69           buff[4 * QMF_FILT_RESOLUTION * i + 3 * QMF_FILT_RESOLUTION + j];
     70     }
     71   }
     72 
     73   for (i = 0; i < 10 * QMF_FILT_RESOLUTION; i++) {
     74     W[i] = U[i] * qmf_filter_coeff[i];
     75   }
     76 
     77   for (i = 0; i < QMF_FILT_RESOLUTION; i++) {
     78     tmp = 0.0;
     79     for (j = 0; j < 10; j++) {
     80       tmp = tmp + W[QMF_FILT_RESOLUTION * j + i];
     81     }
     82     output[i] = (FLOAT32)tmp;
     83   }
     84 }
     85 
     86 VOID process_qmf_ana_filt_bank(ia_drc_qmf_filt_struct *qmf_filt, FLOAT64 *buff,
     87                                FLOAT32 *input, FLOAT32 *output_real,
     88                                FLOAT32 *output_imag) {
     89   WORD32 i, j;
     90   FLOAT32 Z[10 * QMF_NUM_FILT_BANDS];
     91   FLOAT32 Y[2 * QMF_NUM_FILT_BANDS];
     92 
     93   for (i = 10 * QMF_FILT_RESOLUTION - 1; i >= QMF_FILT_RESOLUTION; i--) {
     94     buff[i] = buff[i - QMF_FILT_RESOLUTION];
     95   }
     96 
     97   for (i = QMF_FILT_RESOLUTION - 1; i >= 0; i--) {
     98     buff[i] = input[QMF_FILT_RESOLUTION - 1 - i];
     99   }
    100 
    101   for (i = 0; i < 10 * QMF_FILT_RESOLUTION; i++) {
    102     Z[i] = (FLOAT32)(buff[i] * qmf_filter_coeff[i]);
    103   }
    104 
    105   for (i = 0; i < 2 * QMF_FILT_RESOLUTION; i++) {
    106     Y[i] = 0.0f;
    107     for (j = 0; j < 5; j++) {
    108       Y[i] += Z[i + j * 2 * QMF_FILT_RESOLUTION];
    109     }
    110   }
    111 
    112   for (i = 0; i < QMF_FILT_RESOLUTION; i++) {
    113     output_real[i] = 0.0f;
    114     output_imag[i] = 0.0f;
    115     for (j = 0; j < 2 * QMF_FILT_RESOLUTION; j++) {
    116       output_real[i] += (FLOAT32)(Y[j] * qmf_filt->ana_tab_real[i][j]);
    117       output_imag[i] += (FLOAT32)(Y[j] * qmf_filt->ana_tab_imag[i][j]);
    118     }
    119   }
    120 }
    121 
    122 static WORD32 impd_down_mix(
    123     ia_drc_sel_proc_output_struct *uni_drc_sel_proc_output,
    124     FLOAT32 **input_audio, WORD32 frame_len) {
    125   WORD32 num_base_ch = uni_drc_sel_proc_output->base_channel_count;
    126   WORD32 num_target_ch = uni_drc_sel_proc_output->target_channel_count;
    127   WORD32 i, i_ch, o_ch;
    128   FLOAT32 tmp_out[MAX_CHANNEL_COUNT];
    129 
    130   if (num_target_ch > MAX_CHANNEL_COUNT) return -1;
    131 
    132   if (num_target_ch > num_base_ch) return -1;
    133 
    134   for (i = 0; i < frame_len; i++) {
    135     for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
    136       tmp_out[o_ch] = 0.0f;
    137       for (i_ch = 0; i_ch < num_base_ch; i_ch++) {
    138         tmp_out[o_ch] += input_audio[i_ch][i] *
    139                          uni_drc_sel_proc_output->downmix_matrix[i_ch][o_ch];
    140       }
    141     }
    142     for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
    143       input_audio[o_ch][i] = tmp_out[o_ch];
    144     }
    145     for (; o_ch < num_base_ch; o_ch++) {
    146       input_audio[o_ch][i] = 0.0f;
    147     }
    148   }
    149 
    150   return 0;
    151 }
    152 
    153 WORD32 impd_init_process_audio_main_td_qmf(ia_drc_api_struct *p_obj_drc)
    154 
    155 {
    156   WORD32 error, i, j, num_samples_per_channel;
    157   FLOAT32 *input_buffer;
    158   WORD16 *input_buffer16, *output_buffer16;
    159   FLOAT32 *output_buffer;
    160   FLOAT32 *audio_io_buf_real[10];
    161   FLOAT32 *audio_io_buf_imag[10];
    162   FLOAT32 *audio_in_out_buf[10];
    163   FLOAT32 *scratch_buffer;
    164   WORD32 last_frame = 0;
    165   error = 0;
    166   scratch_buffer = (FLOAT32 *)p_obj_drc->pp_mem[1];
    167   input_buffer = (FLOAT32 *)p_obj_drc->pp_mem[2];
    168   output_buffer = (FLOAT32 *)p_obj_drc->pp_mem[3];
    169 
    170   input_buffer16 = (WORD16 *)p_obj_drc->pp_mem[2];
    171   output_buffer16 = (WORD16 *)p_obj_drc->pp_mem[3];
    172 
    173   if (p_obj_drc->p_state->ui_in_bytes <= 0) {
    174     p_obj_drc->p_state->ui_out_bytes = 0;
    175     return 0;
    176   }
    177 
    178   if ((p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in /
    179        (p_obj_drc->str_config.pcm_size >> 3)) <
    180       (UWORD32)p_obj_drc->str_config.frame_size)
    181     last_frame = 1;
    182 
    183   for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    184     audio_in_out_buf[i] = scratch_buffer;
    185     scratch_buffer = scratch_buffer + (p_obj_drc->str_config.frame_size + 32);
    186     audio_io_buf_real[i] =
    187         scratch_buffer +
    188         (p_obj_drc->str_config.frame_size * p_obj_drc->str_config.num_ch_in +
    189          512);
    190     audio_io_buf_imag[i] = scratch_buffer +
    191                            2 * (p_obj_drc->str_config.frame_size *
    192                                     p_obj_drc->str_config.num_ch_in +
    193                                 512);
    194     ;
    195     for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    196       if (p_obj_drc->str_config.pcm_size == 16) {
    197         audio_in_out_buf[i][j] =
    198             ((FLOAT32)input_buffer16[j * p_obj_drc->str_config.num_ch_in + i]) /
    199             32767.0f;
    200       } else {
    201         audio_in_out_buf[i][j] =
    202             input_buffer[j * p_obj_drc->str_config.num_ch_in + i];
    203       }
    204     }
    205   }
    206 
    207   error = impd_process_drc_bitstream_dec_gain(
    208       p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
    209       p_obj_drc->str_payload.pstr_drc_config,
    210       p_obj_drc->str_payload.pstr_drc_gain,
    211       &p_obj_drc->str_bit_handler
    212            .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
    213       p_obj_drc->str_bit_handler.num_bytes_bs,
    214       p_obj_drc->str_bit_handler.num_bits_offset_bs,
    215       &p_obj_drc->str_bit_handler.num_bits_read_bs);
    216 
    217   if (error > PROC_COMPLETE) return -1;
    218 
    219   p_obj_drc->str_bit_handler.num_bytes_read_bs =
    220       (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
    221   p_obj_drc->str_bit_handler.num_bits_offset_bs =
    222       (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
    223   p_obj_drc->str_bit_handler.byte_index_bs +=
    224       p_obj_drc->str_bit_handler.num_bytes_read_bs;
    225   if (p_obj_drc->str_bit_handler.gain_stream_flag ==
    226       0)  // ITTIAM: Flag for applying gain frame by frame
    227   {
    228     p_obj_drc->str_bit_handler.num_bytes_bs -=
    229         p_obj_drc->str_bit_handler.num_bytes_read_bs;
    230   }
    231   if (p_obj_drc->str_config.bitstream_file_format ==
    232       BITSTREAM_FILE_FORMAT_SPLIT) {
    233     /* shift over fill-bits for frame byte alignment */
    234     if (p_obj_drc->str_bit_handler.num_bits_offset_bs != 0) {
    235       p_obj_drc->str_bit_handler.num_bits_read_bs =
    236           p_obj_drc->str_bit_handler.num_bits_read_bs + 8 -
    237           p_obj_drc->str_bit_handler.num_bits_offset_bs;
    238       p_obj_drc->str_bit_handler.num_bytes_read_bs =
    239           p_obj_drc->str_bit_handler.num_bytes_read_bs + 1;
    240       p_obj_drc->str_bit_handler.num_bits_offset_bs = 0;
    241       p_obj_drc->str_bit_handler.byte_index_bs =
    242           p_obj_drc->str_bit_handler.byte_index_bs + 1;
    243       if (p_obj_drc->str_bit_handler.gain_stream_flag ==
    244           0)  // ITTIAM: Flag for applying gain frame by frame
    245       {
    246         p_obj_drc->str_bit_handler.num_bytes_bs =
    247             p_obj_drc->str_bit_handler.num_bytes_bs - 1;
    248       }
    249     }
    250   }
    251 
    252   for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    253     for (j = 0; j < p_obj_drc->str_config.frame_size; j += 64) {
    254       process_qmf_ana_filt_bank(
    255           p_obj_drc->str_payload.pstr_qmf_filter,
    256           p_obj_drc->str_payload.pstr_qmf_filter->ana_buff +
    257               i * 4 * p_obj_drc->str_config.frame_size,
    258           &(audio_in_out_buf[i][j]), &(audio_io_buf_real[i][j]),
    259           &(audio_io_buf_imag[i][j]));
    260     }
    261   }
    262   error = impd_drc_process_freq_domain(
    263       p_obj_drc->str_payload.pstr_gain_dec[0],
    264       p_obj_drc->str_payload.pstr_drc_config,
    265       p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real,
    266       audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    267                              ->loudness_normalization_gain_db,
    268       p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
    269       p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
    270       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    271           ->drc_characteristic_target);
    272 
    273   if (error) return error;
    274 
    275   if (p_obj_drc->str_payload.pstr_drc_sel_proc_output->target_channel_count <
    276       p_obj_drc->str_payload.pstr_drc_sel_proc_output->base_channel_count) {
    277     error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
    278                           audio_io_buf_real, p_obj_drc->str_config.frame_size);
    279     if (error) return error;
    280 
    281     error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
    282                           audio_io_buf_imag, p_obj_drc->str_config.frame_size);
    283     if (error) return error;
    284   }
    285 
    286   error = impd_drc_process_freq_domain(
    287       p_obj_drc->str_payload.pstr_gain_dec[1],
    288       p_obj_drc->str_payload.pstr_drc_config,
    289       p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real,
    290       audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    291                              ->loudness_normalization_gain_db,
    292       p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
    293       p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
    294       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    295           ->drc_characteristic_target);
    296   if (error) return -1;
    297   for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    298     for (j = 0; j < p_obj_drc->str_config.frame_size; j += 64) {
    299       process_qmf_syn_filt_bank(
    300           p_obj_drc->str_payload.pstr_qmf_filter,
    301           p_obj_drc->str_payload.pstr_qmf_filter->syn_buff +
    302               i * 4 * p_obj_drc->str_config.frame_size,
    303           &(audio_io_buf_real[i][j]), &(audio_io_buf_imag[i][j]),
    304           &(audio_in_out_buf[i][j]));
    305     }
    306   }
    307 
    308   if (p_obj_drc->str_payload.pstr_drc_sel_proc_output
    309           ->loudness_normalization_gain_db != 0.0f) {
    310     FLOAT32 loudness_normalization_gain =
    311         (FLOAT32)pow(10.0, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    312                                    ->loudness_normalization_gain_db /
    313                                20.0);
    314     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    315       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    316         audio_io_buf_real[i][j] *= loudness_normalization_gain;
    317         audio_io_buf_imag[i][j] *= loudness_normalization_gain;
    318       }
    319     }
    320   }
    321 
    322   num_samples_per_channel = p_obj_drc->str_config.frame_size;
    323 
    324   for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    325     for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    326       if (p_obj_drc->str_config.pcm_size == 16) {
    327         output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] =
    328             (WORD16)(audio_in_out_buf[i][j] * 32767.0f);
    329       } else {
    330         output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
    331             audio_in_out_buf[i][j];
    332       }
    333     }
    334   }
    335   p_obj_drc->p_state->ui_out_bytes =
    336       p_obj_drc->str_config.num_ch_out *
    337       (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in);
    338 
    339   if (p_obj_drc->str_config.bitstream_file_format !=
    340       BITSTREAM_FILE_FORMAT_SPLIT) {
    341     error = impd_process_drc_bitstream_dec(
    342         p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
    343         p_obj_drc->str_payload.pstr_drc_config,
    344         p_obj_drc->str_payload.pstr_loudness_info,
    345         &p_obj_drc->str_bit_handler
    346              .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
    347         p_obj_drc->str_bit_handler.num_bytes_bs,
    348         p_obj_drc->str_bit_handler.num_bits_offset_bs,
    349         &p_obj_drc->str_bit_handler.num_bits_read_bs);
    350 
    351     if (error > PROC_COMPLETE) return -1;
    352 
    353     p_obj_drc->str_bit_handler.num_bytes_read_bs =
    354         (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
    355     p_obj_drc->str_bit_handler.num_bits_offset_bs =
    356         (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
    357     p_obj_drc->str_bit_handler.byte_index_bs +=
    358         p_obj_drc->str_bit_handler.num_bytes_read_bs;
    359     p_obj_drc->str_bit_handler.num_bytes_bs -=
    360         p_obj_drc->str_bit_handler.num_bytes_read_bs;
    361   }
    362 
    363   return error;
    364 }
    365