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 <string.h>
     22 #include "impd_type_def.h"
     23 #include "impd_error_standards.h"
     24 #include "impd_memory_standards.h"
     25 #include "impd_drc_peak_limiter.h"
     26 #include "impd_drc_extr_delta_coded_info.h"
     27 #include "impd_drc_common.h"
     28 #include "impd_drc_struct.h"
     29 #include "impd_drc_interface.h"
     30 #include "impd_drc_bitbuffer.h"
     31 #include "impd_drc_bitstream_dec_api.h"
     32 #include "impd_drc_gain_dec.h"
     33 #include "impd_drc_filter_bank.h"
     34 #include "impd_drc_multi_band.h"
     35 #include "impd_drc_process_audio.h"
     36 #include "impd_parametric_drc_dec.h"
     37 #include "impd_drc_eq.h"
     38 #include "impd_drc_gain_decoder.h"
     39 #include "impd_drc_selection_process.h"
     40 #include "impd_drc_api_struct_def.h"
     41 #include "impd_drc_hashdefines.h"
     42 #include "impd_drc_peak_limiter.h"
     43 
     44 static IA_ERRORCODE impd_down_mix(
     45     ia_drc_sel_proc_output_struct *uni_drc_sel_proc_output,
     46     FLOAT32 **input_audio, WORD32 frame_len) {
     47   WORD32 num_base_ch = uni_drc_sel_proc_output->base_channel_count;
     48   WORD32 num_target_ch = uni_drc_sel_proc_output->target_channel_count;
     49   WORD32 i, i_ch, o_ch;
     50   FLOAT32 tmp_out[MAX_CHANNEL_COUNT];
     51 
     52   if (num_target_ch > MAX_CHANNEL_COUNT) return -1;
     53 
     54   if (num_target_ch > num_base_ch) return -1;
     55 
     56   for (i = 0; i < frame_len; i++) {
     57     for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
     58       tmp_out[o_ch] = 0.0f;
     59       for (i_ch = 0; i_ch < num_base_ch; i_ch++) {
     60         tmp_out[o_ch] += input_audio[i_ch][i] *
     61                          uni_drc_sel_proc_output->downmix_matrix[i_ch][o_ch];
     62       }
     63     }
     64     for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
     65       input_audio[o_ch][i] = tmp_out[o_ch];
     66     }
     67     for (; o_ch < num_base_ch; o_ch++) {
     68       input_audio[o_ch][i] = 0.0f;
     69     }
     70   }
     71 
     72   return IA_NO_ERROR;
     73 }
     74 
     75 IA_ERRORCODE impd_process_time_domain(ia_drc_api_struct *p_obj_drc) {
     76   IA_ERRORCODE err_code = IA_NO_ERROR;
     77   WORD32 i, j;
     78   FLOAT32 *input_buffer;
     79   WORD16 *input_buffer16, *output_buffer16;
     80   FLOAT32 *output_buffer;
     81   FLOAT32 *audio_buff[10];
     82   FLOAT32 *scratch_buffer;
     83   WORD32 last_frame = 0;
     84   WORD32 num_sample_to_process;
     85   scratch_buffer = (FLOAT32 *)p_obj_drc->pp_mem[1];
     86   input_buffer = (FLOAT32 *)p_obj_drc->pp_mem[2];
     87   output_buffer = (FLOAT32 *)p_obj_drc->pp_mem[3];
     88   input_buffer16 = (WORD16 *)p_obj_drc->pp_mem[2];
     89   output_buffer16 = (WORD16 *)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 IA_NO_ERROR;
     94   }
     95 
     96   err_code = impd_process_drc_bitstream_dec_gain(
     97       p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
     98       p_obj_drc->str_payload.pstr_drc_config,
     99       p_obj_drc->str_payload.pstr_drc_gain,
    100       &p_obj_drc->str_bit_handler
    101            .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
    102       p_obj_drc->str_bit_handler.num_bytes_bs,
    103       p_obj_drc->str_bit_handler.num_bits_offset_bs,
    104       &p_obj_drc->str_bit_handler.num_bits_read_bs);
    105 
    106   if (err_code > PROC_COMPLETE) return -1;
    107 
    108   p_obj_drc->str_bit_handler.num_bytes_read_bs =
    109       (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
    110   p_obj_drc->str_bit_handler.num_bits_offset_bs =
    111       (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
    112   p_obj_drc->str_bit_handler.byte_index_bs +=
    113       p_obj_drc->str_bit_handler.num_bytes_read_bs;
    114   if (p_obj_drc->str_bit_handler.gain_stream_flag ==
    115       0)  // ITTIAM: Flag for applying gain frame by frame
    116   {
    117     p_obj_drc->str_bit_handler.num_bytes_bs -=
    118         p_obj_drc->str_bit_handler.num_bytes_read_bs;
    119   }
    120 
    121   if (p_obj_drc->str_config.bitstream_file_format ==
    122       BITSTREAM_FILE_FORMAT_SPLIT) {
    123     if (p_obj_drc->str_bit_handler.num_bits_offset_bs != 0) {
    124       p_obj_drc->str_bit_handler.num_bits_read_bs =
    125           p_obj_drc->str_bit_handler.num_bits_read_bs + 8 -
    126           p_obj_drc->str_bit_handler.num_bits_offset_bs;
    127       p_obj_drc->str_bit_handler.num_bytes_read_bs =
    128           p_obj_drc->str_bit_handler.num_bytes_read_bs + 1;
    129       p_obj_drc->str_bit_handler.num_bits_offset_bs = 0;
    130       p_obj_drc->str_bit_handler.byte_index_bs =
    131           p_obj_drc->str_bit_handler.byte_index_bs + 1;
    132       if (p_obj_drc->str_bit_handler.gain_stream_flag == 0) {
    133         p_obj_drc->str_bit_handler.num_bytes_bs =
    134             p_obj_drc->str_bit_handler.num_bytes_bs - 1;
    135       }
    136     }
    137   }
    138 
    139   num_sample_to_process =
    140       (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in /
    141        (p_obj_drc->str_config.pcm_size >> 3));
    142 
    143   p_obj_drc->str_config.frame_size = num_sample_to_process;
    144 
    145   if (num_sample_to_process < p_obj_drc->str_config.frame_size) last_frame = 1;
    146 
    147   if (p_obj_drc->str_config.pcm_size == 16) {
    148     for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    149       audio_buff[i] =
    150           scratch_buffer + i * (p_obj_drc->str_config.frame_size + 32);
    151 
    152       for (j = 0; j < num_sample_to_process; j++) {
    153         audio_buff[i][j] =
    154             ((FLOAT32)input_buffer16[j * p_obj_drc->str_config.num_ch_in + i]) /
    155             32767.0f;
    156       }
    157     }
    158   } else {
    159     for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    160       audio_buff[i] =
    161           scratch_buffer + i * (p_obj_drc->str_config.frame_size + 32);
    162 
    163       for (j = 0; j < num_sample_to_process; j++) {
    164         audio_buff[i][j] =
    165             input_buffer[j * p_obj_drc->str_config.num_ch_in + i];
    166       }
    167     }
    168   }
    169 
    170   err_code = impd_drc_process_time_domain(
    171       p_obj_drc->str_payload.pstr_gain_dec[0],
    172       p_obj_drc->str_payload.pstr_drc_config,
    173       p_obj_drc->str_payload.pstr_drc_gain, audio_buff,
    174       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    175           ->loudness_normalization_gain_db,
    176       p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
    177       p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
    178       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    179           ->drc_characteristic_target);
    180 
    181   if (err_code != IA_NO_ERROR) return err_code;
    182 
    183   if (p_obj_drc->str_payload.pstr_drc_sel_proc_output->downmix_matrix_present !=
    184       0)
    185     err_code = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
    186                              audio_buff, p_obj_drc->str_config.frame_size);
    187 
    188   if (err_code != IA_NO_ERROR) return err_code;
    189 
    190   err_code = impd_drc_process_time_domain(
    191       p_obj_drc->str_payload.pstr_gain_dec[1],
    192       p_obj_drc->str_payload.pstr_drc_config,
    193       p_obj_drc->str_payload.pstr_drc_gain, audio_buff,
    194       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    195           ->loudness_normalization_gain_db,
    196       p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
    197       p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
    198       p_obj_drc->str_payload.pstr_drc_sel_proc_output
    199           ->drc_characteristic_target);
    200 
    201   if (err_code != IA_NO_ERROR) return err_code;
    202 
    203   if (p_obj_drc->str_payload.pstr_drc_sel_proc_output
    204           ->loudness_normalization_gain_db != 0.0f) {
    205     FLOAT32 gain_value =
    206         (FLOAT32)pow(10.0, p_obj_drc->str_payload.pstr_drc_sel_proc_output
    207                                    ->loudness_normalization_gain_db /
    208                                20.0);
    209     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    210       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    211         audio_buff[i][j] *= gain_value;
    212       }
    213     }
    214   }
    215 
    216   if (p_obj_drc->str_config.peak_limiter) {
    217     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    218       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    219         output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
    220             audio_buff[i][j];
    221       }
    222     }
    223 
    224     err_code =
    225         impd_limiter_process(p_obj_drc->str_payload.pstr_peak_limiter,
    226                              output_buffer, p_obj_drc->str_config.frame_size);
    227 
    228     if (err_code != IA_NO_ERROR) return err_code;
    229 
    230     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    231       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    232         audio_buff[i][j] =
    233             output_buffer[j * p_obj_drc->str_config.num_ch_out + i];
    234       }
    235     }
    236   }
    237 
    238   if (p_obj_drc->str_config.pcm_size == 16) {
    239     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    240       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    241         if (audio_buff[i][j] < -1.0f)
    242           output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] = -32767;
    243 
    244         else if (audio_buff[i][j] > 1.0f)
    245           output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] = 32767;
    246 
    247         else
    248           output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] =
    249               (WORD16)(audio_buff[i][j] * 32767.0f);
    250       }
    251     }
    252   } else {
    253     for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
    254       for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
    255         output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
    256             audio_buff[i][j];
    257       }
    258     }
    259   }
    260 
    261   p_obj_drc->p_state->ui_out_bytes =
    262       p_obj_drc->str_config.num_ch_out *
    263       (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in);
    264 
    265   if (p_obj_drc->p_state->delay_in_output != 0) {
    266     p_obj_drc->p_state->ui_out_bytes = p_obj_drc->str_config.num_ch_out *
    267                                        (p_obj_drc->str_config.frame_size -
    268                                         p_obj_drc->p_state->delay_in_output) *
    269                                        (p_obj_drc->str_config.pcm_size >> 3);
    270     if (p_obj_drc->str_config.pcm_size == 16)
    271       memcpy(output_buffer16,
    272              (output_buffer16 + (p_obj_drc->p_state->delay_in_output *
    273                                  p_obj_drc->str_config.num_ch_out)),
    274              p_obj_drc->p_state->ui_out_bytes);
    275     else
    276       memcpy(output_buffer,
    277              (output_buffer + (p_obj_drc->p_state->delay_in_output *
    278                                p_obj_drc->str_config.num_ch_out)),
    279              p_obj_drc->p_state->ui_out_bytes);
    280 
    281     p_obj_drc->p_state->delay_adjust_samples =
    282         p_obj_drc->p_state->delay_in_output;
    283     p_obj_drc->p_state->delay_in_output = 0;
    284   }
    285   if (last_frame == 1) {
    286     if ((num_sample_to_process + p_obj_drc->p_state->delay_adjust_samples) <=
    287         p_obj_drc->str_config.frame_size)
    288       p_obj_drc->p_state->ui_out_bytes =
    289           (num_sample_to_process + p_obj_drc->p_state->delay_adjust_samples) *
    290           p_obj_drc->str_config.num_ch_out *
    291           (p_obj_drc->str_config.pcm_size >> 3);
    292     else
    293       p_obj_drc->p_state->ui_out_bytes = (p_obj_drc->str_config.frame_size) *
    294                                          p_obj_drc->str_config.num_ch_out *
    295                                          (p_obj_drc->str_config.pcm_size >> 3);
    296   }
    297 
    298   if (last_frame == 0) {
    299     if (p_obj_drc->str_config.bitstream_file_format !=
    300         BITSTREAM_FILE_FORMAT_SPLIT) {
    301       err_code = impd_process_drc_bitstream_dec(
    302           p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
    303           p_obj_drc->str_payload.pstr_drc_config,
    304           p_obj_drc->str_payload.pstr_loudness_info,
    305           &p_obj_drc->str_bit_handler
    306                .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
    307           p_obj_drc->str_bit_handler.num_bytes_bs,
    308           p_obj_drc->str_bit_handler.num_bits_offset_bs,
    309           &p_obj_drc->str_bit_handler.num_bits_read_bs);
    310 
    311       if (err_code > PROC_COMPLETE) return -1;
    312 
    313       p_obj_drc->str_bit_handler.num_bytes_read_bs =
    314           (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
    315       p_obj_drc->str_bit_handler.num_bits_offset_bs =
    316           (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
    317       p_obj_drc->str_bit_handler.byte_index_bs +=
    318           p_obj_drc->str_bit_handler.num_bytes_read_bs;
    319       p_obj_drc->str_bit_handler.num_bytes_bs -=
    320           p_obj_drc->str_bit_handler.num_bytes_read_bs;
    321     }
    322   }
    323 
    324   return err_code;
    325 }
    326