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_bitbuffer.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_peak_limiter.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 
     40 #define BITSTREAM_FILE_FORMAT_SPLIT 1
     41 
     42 static WORD32 impd_down_mix(
     43     ia_drc_sel_proc_output_struct *uni_drc_sel_proc_output,
     44     FLOAT32 **input_audio, WORD32 frame_len) {
     45   WORD32 num_base_ch = uni_drc_sel_proc_output->base_channel_count;
     46   WORD32 num_target_ch = uni_drc_sel_proc_output->target_channel_count;
     47   WORD32 i, i_ch, o_ch;
     48   FLOAT32 tmp_out[MAX_CHANNEL_COUNT];
     49 
     50   if (uni_drc_sel_proc_output->downmix_matrix_present == 0) return 0;
     51 
     52   if (input_audio == 0) return 0;
     53 
     54   if (num_target_ch > MAX_CHANNEL_COUNT) return -1;
     55 
     56   if (num_target_ch > num_base_ch) return -1;
     57 
     58   for (i = 0; i < frame_len; i++) {
     59     for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
     60       tmp_out[o_ch] = 0.0f;
     61       for (i_ch = 0; i_ch < num_base_ch; i_ch++) {
     62         tmp_out[o_ch] += input_audio[i_ch][i] *
     63                          uni_drc_sel_proc_output->downmix_matrix[i_ch][o_ch];
     64       }
     65     }
     66     for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
     67       input_audio[o_ch][i] = tmp_out[o_ch];
     68     }
     69     for (; o_ch < num_base_ch; o_ch++) {
     70       input_audio[o_ch][i] = 0.0f;
     71     }
     72   }
     73 
     74   return 0;
     75 }
     76 
     77 WORD32 impd_init_process_audio_main_stft(ia_drc_api_struct *p_obj_drc)
     78 
     79 {
     80   WORD32 error = 0, i, j, num_samples_per_channel;
     81   FLOAT32 *input_buffer;
     82   FLOAT32 *output_buffer;
     83   FLOAT32 *audio_io_buf_real[10];
     84   FLOAT32 *audio_io_buf_imag[10];
     85   FLOAT32 *scratch_buffer;
     86   WORD32 last_frame = 0;
     87   scratch_buffer = (FLOAT32 *)p_obj_drc->pp_mem[1];
     88   input_buffer = (FLOAT32 *)p_obj_drc->pp_mem[2];
     89   output_buffer = (FLOAT32 *)p_obj_drc->pp_mem[3];
     90 
     91   if (p_obj_drc->p_state->ui_in_bytes <= 0) {
     92     p_obj_drc->p_state->ui_out_bytes = 0;
     93     return 0;
     94   }
     95 
     96   if ((p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in /
     97        (p_obj_drc->str_config.pcm_size >> 3)) <
     98       (UWORD32)p_obj_drc->str_config.frame_size)
     99     last_frame = 1;
    100   for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    101     audio_io_buf_real[i] =
    102         scratch_buffer + i * (p_obj_drc->str_config.frame_size + 32);
    103     audio_io_buf_imag[i] =
    104         scratch_buffer +
    105         p_obj_drc->str_config.num_ch_in * p_obj_drc->str_config.frame_size +
    106         p_obj_drc->str_config.num_ch_in * 64 +
    107         i * (p_obj_drc->str_config.frame_size + 64);
    108     for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    109       audio_io_buf_real[i][j] =
    110           input_buffer[j * p_obj_drc->str_config.num_ch_in + i];
    111       audio_io_buf_imag[i][j] =
    112           input_buffer[p_obj_drc->str_config.num_ch_in *
    113                            p_obj_drc->str_config.frame_size +
    114                        j * p_obj_drc->str_config.num_ch_in + i];
    115     }
    116   }
    117 
    118   error = impd_process_drc_bitstream_dec_gain(
    119       p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
    120       p_obj_drc->str_payload.pstr_drc_config,
    121       p_obj_drc->str_payload.pstr_drc_gain,
    122       &p_obj_drc->str_bit_handler
    123            .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
    124       p_obj_drc->str_bit_handler.num_bytes_bs,
    125       p_obj_drc->str_bit_handler.num_bits_offset_bs,
    126       &p_obj_drc->str_bit_handler.num_bits_read_bs);
    127 
    128   if (error > PROC_COMPLETE) return -1;
    129 
    130   p_obj_drc->str_bit_handler.num_bytes_read_bs =
    131       (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
    132   p_obj_drc->str_bit_handler.num_bits_offset_bs =
    133       (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
    134   p_obj_drc->str_bit_handler.byte_index_bs +=
    135       p_obj_drc->str_bit_handler.num_bytes_read_bs;
    136   if (p_obj_drc->str_bit_handler.gain_stream_flag ==
    137       0)  // ITTIAM: Flag for applying gain frame by frame
    138   {
    139     p_obj_drc->str_bit_handler.num_bytes_bs -=
    140         p_obj_drc->str_bit_handler.num_bytes_read_bs;
    141   }
    142 
    143   if (p_obj_drc->str_config.bitstream_file_format ==
    144       BITSTREAM_FILE_FORMAT_SPLIT) {
    145     if (p_obj_drc->str_bit_handler.num_bits_offset_bs != 0) {
    146       p_obj_drc->str_bit_handler.num_bits_read_bs =
    147           p_obj_drc->str_bit_handler.num_bits_read_bs + 8 -
    148           p_obj_drc->str_bit_handler.num_bits_offset_bs;
    149       p_obj_drc->str_bit_handler.num_bytes_read_bs =
    150           p_obj_drc->str_bit_handler.num_bytes_read_bs + 1;
    151       p_obj_drc->str_bit_handler.num_bits_offset_bs = 0;
    152       p_obj_drc->str_bit_handler.byte_index_bs =
    153           p_obj_drc->str_bit_handler.byte_index_bs + 1;
    154       if (p_obj_drc->str_bit_handler.gain_stream_flag ==
    155           0)  // ITTIAM: Flag for applying gain frame by frame
    156       {
    157         p_obj_drc->str_bit_handler.num_bytes_bs =
    158             p_obj_drc->str_bit_handler.num_bytes_bs - 1;
    159       }
    160     }
    161   }
    162 
    163   error = impd_drc_process_freq_domain(
    164       p_obj_drc->str_payload.pstr_gain_dec[0],
    165       p_obj_drc->str_payload.pstr_drc_config,
    166       p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real,
    167       audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    168                              ->loudness_normalization_gain_db,
    169       p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
    170       p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
    171       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    172           ->drc_characteristic_target);
    173   if (error) return -1;
    174 
    175   error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
    176                         audio_io_buf_real, p_obj_drc->str_config.frame_size);
    177   if (error) return -1;
    178 
    179   error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
    180                         audio_io_buf_imag, p_obj_drc->str_config.frame_size);
    181   if (error) return -1;
    182 
    183   error = impd_drc_process_freq_domain(
    184       p_obj_drc->str_payload.pstr_gain_dec[1],
    185       p_obj_drc->str_payload.pstr_drc_config,
    186       p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real,
    187       audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    188                              ->loudness_normalization_gain_db,
    189       p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
    190       p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
    191       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    192           ->drc_characteristic_target);
    193   if (error) return -1;
    194 
    195   if (p_obj_drc->str_payload.pstr_drc_sel_proc_output
    196           ->loudness_normalization_gain_db != 0.0f) {
    197     FLOAT32 loudness_normalization_gain =
    198         (FLOAT32)pow(10.0, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    199                                    ->loudness_normalization_gain_db /
    200                                20.0);
    201     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    202       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    203         audio_io_buf_real[i][j] *= loudness_normalization_gain;
    204         audio_io_buf_imag[i][j] *= loudness_normalization_gain;
    205       }
    206     }
    207   }
    208 
    209   num_samples_per_channel = p_obj_drc->str_config.frame_size;
    210 
    211   for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    212     for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    213       output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
    214           audio_io_buf_real[i][j];
    215       output_buffer[p_obj_drc->str_config.frame_size *
    216                         p_obj_drc->str_config.num_ch_in +
    217                     j * p_obj_drc->str_config.num_ch_out + i] =
    218           audio_io_buf_imag[i][j];
    219     }
    220   }
    221   p_obj_drc->p_state->ui_out_bytes =
    222       p_obj_drc->str_config.num_ch_out * (p_obj_drc->str_config.frame_size) * 4;
    223   p_obj_drc->p_state->ui_out_bytes =
    224       p_obj_drc->str_config.num_ch_out *
    225       (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in);
    226 
    227   if (last_frame == 0) {
    228     if (p_obj_drc->str_config.bitstream_file_format !=
    229         BITSTREAM_FILE_FORMAT_SPLIT) {
    230       error = impd_process_drc_bitstream_dec(
    231           p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
    232           p_obj_drc->str_payload.pstr_drc_config,
    233           p_obj_drc->str_payload.pstr_loudness_info,
    234           &p_obj_drc->str_bit_handler
    235                .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
    236           p_obj_drc->str_bit_handler.num_bytes_bs,
    237           p_obj_drc->str_bit_handler.num_bits_offset_bs,
    238           &p_obj_drc->str_bit_handler.num_bits_read_bs);
    239 
    240       if (error > PROC_COMPLETE) return -1;
    241 
    242       p_obj_drc->str_bit_handler.num_bytes_read_bs =
    243           (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
    244       p_obj_drc->str_bit_handler.num_bits_offset_bs =
    245           (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
    246       p_obj_drc->str_bit_handler.byte_index_bs +=
    247           p_obj_drc->str_bit_handler.num_bytes_read_bs;
    248       p_obj_drc->str_bit_handler.num_bytes_bs -=
    249           p_obj_drc->str_bit_handler.num_bytes_read_bs;
    250     }
    251   }
    252 
    253   return error;
    254 }
    255