/******************************************************************************
 *
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <math.h>
#include <string.h>
#include "impd_type_def.h"
#include "impd_error_standards.h"
#include "impd_memory_standards.h"
#include "impd_drc_peak_limiter.h"
#include "impd_drc_extr_delta_coded_info.h"
#include "impd_drc_common.h"
#include "impd_drc_struct.h"
#include "impd_drc_interface.h"
#include "impd_drc_bitbuffer.h"
#include "impd_drc_bitstream_dec_api.h"
#include "impd_drc_gain_dec.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_multi_band.h"
#include "impd_drc_process_audio.h"
#include "impd_parametric_drc_dec.h"
#include "impd_drc_eq.h"
#include "impd_drc_gain_decoder.h"
#include "impd_drc_selection_process.h"
#include "impd_drc_api_struct_def.h"
#include "impd_drc_hashdefines.h"
#include "impd_drc_peak_limiter.h"

static IA_ERRORCODE impd_down_mix(
    ia_drc_sel_proc_output_struct *uni_drc_sel_proc_output,
    FLOAT32 **input_audio, WORD32 frame_len) {
  WORD32 num_base_ch = uni_drc_sel_proc_output->base_channel_count;
  WORD32 num_target_ch = uni_drc_sel_proc_output->target_channel_count;
  WORD32 i, i_ch, o_ch;
  FLOAT32 tmp_out[MAX_CHANNEL_COUNT];

  if (num_target_ch > MAX_CHANNEL_COUNT) return -1;

  if (num_target_ch > num_base_ch) return -1;

  for (i = 0; i < frame_len; i++) {
    for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
      tmp_out[o_ch] = 0.0f;
      for (i_ch = 0; i_ch < num_base_ch; i_ch++) {
        tmp_out[o_ch] += input_audio[i_ch][i] *
                         uni_drc_sel_proc_output->downmix_matrix[i_ch][o_ch];
      }
    }
    for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
      input_audio[o_ch][i] = tmp_out[o_ch];
    }
    for (; o_ch < num_base_ch; o_ch++) {
      input_audio[o_ch][i] = 0.0f;
    }
  }

  return IA_NO_ERROR;
}

IA_ERRORCODE impd_process_time_domain(ia_drc_api_struct *p_obj_drc) {
  IA_ERRORCODE err_code = IA_NO_ERROR;
  WORD32 i, j;
  FLOAT32 *input_buffer;
  WORD16 *input_buffer16, *output_buffer16;
  FLOAT32 *output_buffer;
  FLOAT32 *audio_buff[10];
  FLOAT32 *scratch_buffer;
  WORD32 last_frame = 0;
  WORD32 num_sample_to_process;
  scratch_buffer = (FLOAT32 *)p_obj_drc->pp_mem[1];
  input_buffer = (FLOAT32 *)p_obj_drc->pp_mem[2];
  output_buffer = (FLOAT32 *)p_obj_drc->pp_mem[3];
  input_buffer16 = (WORD16 *)p_obj_drc->pp_mem[2];
  output_buffer16 = (WORD16 *)p_obj_drc->pp_mem[3];

  if (p_obj_drc->p_state->ui_in_bytes <= 0) {
    p_obj_drc->p_state->ui_out_bytes = 0;
    return IA_NO_ERROR;
  }

  err_code = impd_process_drc_bitstream_dec_gain(
      p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
      p_obj_drc->str_payload.pstr_drc_config,
      p_obj_drc->str_payload.pstr_drc_gain,
      &p_obj_drc->str_bit_handler
           .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
      p_obj_drc->str_bit_handler.num_bytes_bs,
      p_obj_drc->str_bit_handler.num_bits_offset_bs,
      &p_obj_drc->str_bit_handler.num_bits_read_bs);

  if (err_code > PROC_COMPLETE) return -1;

  p_obj_drc->str_bit_handler.num_bytes_read_bs =
      (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
  p_obj_drc->str_bit_handler.num_bits_offset_bs =
      (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
  p_obj_drc->str_bit_handler.byte_index_bs +=
      p_obj_drc->str_bit_handler.num_bytes_read_bs;
  if (p_obj_drc->str_bit_handler.gain_stream_flag ==
      0)  // ITTIAM: Flag for applying gain frame by frame
  {
    p_obj_drc->str_bit_handler.num_bytes_bs -=
        p_obj_drc->str_bit_handler.num_bytes_read_bs;
  }

  if (p_obj_drc->str_config.bitstream_file_format ==
      BITSTREAM_FILE_FORMAT_SPLIT) {
    if (p_obj_drc->str_bit_handler.num_bits_offset_bs != 0) {
      p_obj_drc->str_bit_handler.num_bits_read_bs =
          p_obj_drc->str_bit_handler.num_bits_read_bs + 8 -
          p_obj_drc->str_bit_handler.num_bits_offset_bs;
      p_obj_drc->str_bit_handler.num_bytes_read_bs =
          p_obj_drc->str_bit_handler.num_bytes_read_bs + 1;
      p_obj_drc->str_bit_handler.num_bits_offset_bs = 0;
      p_obj_drc->str_bit_handler.byte_index_bs =
          p_obj_drc->str_bit_handler.byte_index_bs + 1;
      if (p_obj_drc->str_bit_handler.gain_stream_flag == 0) {
        p_obj_drc->str_bit_handler.num_bytes_bs =
            p_obj_drc->str_bit_handler.num_bytes_bs - 1;
      }
    }
  }

  num_sample_to_process =
      (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in /
       (p_obj_drc->str_config.pcm_size >> 3));

  p_obj_drc->str_config.frame_size = num_sample_to_process;

  if (num_sample_to_process < p_obj_drc->str_config.frame_size) last_frame = 1;

  if (p_obj_drc->str_config.pcm_size == 16) {
    for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
      audio_buff[i] =
          scratch_buffer + i * (p_obj_drc->str_config.frame_size + 32);

      for (j = 0; j < num_sample_to_process; j++) {
        audio_buff[i][j] =
            ((FLOAT32)input_buffer16[j * p_obj_drc->str_config.num_ch_in + i]) /
            32767.0f;
      }
    }
  } else {
    for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
      audio_buff[i] =
          scratch_buffer + i * (p_obj_drc->str_config.frame_size + 32);

      for (j = 0; j < num_sample_to_process; j++) {
        audio_buff[i][j] =
            input_buffer[j * p_obj_drc->str_config.num_ch_in + i];
      }
    }
  }

  err_code = impd_drc_process_time_domain(
      p_obj_drc->str_payload.pstr_gain_dec[0],
      p_obj_drc->str_payload.pstr_drc_config,
      p_obj_drc->str_payload.pstr_drc_gain, audio_buff,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output
          ->loudness_normalization_gain_db,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output
          ->drc_characteristic_target);

  if (err_code != IA_NO_ERROR) return err_code;

  if (p_obj_drc->str_payload.pstr_drc_sel_proc_output->downmix_matrix_present !=
      0)
    err_code = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
                             audio_buff, p_obj_drc->str_config.frame_size);

  if (err_code != IA_NO_ERROR) return err_code;

  err_code = impd_drc_process_time_domain(
      p_obj_drc->str_payload.pstr_gain_dec[1],
      p_obj_drc->str_payload.pstr_drc_config,
      p_obj_drc->str_payload.pstr_drc_gain, audio_buff,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output
          ->loudness_normalization_gain_db,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
      p_obj_drc->str_payload.pstr_drc_sel_proc_output
          ->drc_characteristic_target);

  if (err_code != IA_NO_ERROR) return err_code;

  if (p_obj_drc->str_payload.pstr_drc_sel_proc_output
          ->loudness_normalization_gain_db != 0.0f) {
    FLOAT32 gain_value =
        (FLOAT32)pow(10.0, p_obj_drc->str_payload.pstr_drc_sel_proc_output
                                   ->loudness_normalization_gain_db /
                               20.0);
    for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
      for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
        audio_buff[i][j] *= gain_value;
      }
    }
  }

  if (p_obj_drc->str_config.peak_limiter) {
    for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
      for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
        output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
            audio_buff[i][j];
      }
    }

    err_code =
        impd_limiter_process(p_obj_drc->str_payload.pstr_peak_limiter,
                             output_buffer, p_obj_drc->str_config.frame_size);

    if (err_code != IA_NO_ERROR) return err_code;

    for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
      for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
        audio_buff[i][j] =
            output_buffer[j * p_obj_drc->str_config.num_ch_out + i];
      }
    }
  }

  if (p_obj_drc->str_config.pcm_size == 16) {
    for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
      for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
        if (audio_buff[i][j] < -1.0f)
          output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] = -32767;

        else if (audio_buff[i][j] > 1.0f)
          output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] = 32767;

        else
          output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] =
              (WORD16)(audio_buff[i][j] * 32767.0f);
      }
    }
  } else {
    for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
      for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
        output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
            audio_buff[i][j];
      }
    }
  }

  p_obj_drc->p_state->ui_out_bytes =
      p_obj_drc->str_config.num_ch_out *
      (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in);

  if (p_obj_drc->p_state->delay_in_output != 0) {
    p_obj_drc->p_state->ui_out_bytes = p_obj_drc->str_config.num_ch_out *
                                       (p_obj_drc->str_config.frame_size -
                                        p_obj_drc->p_state->delay_in_output) *
                                       (p_obj_drc->str_config.pcm_size >> 3);
    if (p_obj_drc->str_config.pcm_size == 16)
      memcpy(output_buffer16,
             (output_buffer16 + (p_obj_drc->p_state->delay_in_output *
                                 p_obj_drc->str_config.num_ch_out)),
             p_obj_drc->p_state->ui_out_bytes);
    else
      memcpy(output_buffer,
             (output_buffer + (p_obj_drc->p_state->delay_in_output *
                               p_obj_drc->str_config.num_ch_out)),
             p_obj_drc->p_state->ui_out_bytes);

    p_obj_drc->p_state->delay_adjust_samples =
        p_obj_drc->p_state->delay_in_output;
    p_obj_drc->p_state->delay_in_output = 0;
  }
  if (last_frame == 1) {
    if ((num_sample_to_process + p_obj_drc->p_state->delay_adjust_samples) <=
        p_obj_drc->str_config.frame_size)
      p_obj_drc->p_state->ui_out_bytes =
          (num_sample_to_process + p_obj_drc->p_state->delay_adjust_samples) *
          p_obj_drc->str_config.num_ch_out *
          (p_obj_drc->str_config.pcm_size >> 3);
    else
      p_obj_drc->p_state->ui_out_bytes = (p_obj_drc->str_config.frame_size) *
                                         p_obj_drc->str_config.num_ch_out *
                                         (p_obj_drc->str_config.pcm_size >> 3);
  }

  if (last_frame == 0) {
    if (p_obj_drc->str_config.bitstream_file_format !=
        BITSTREAM_FILE_FORMAT_SPLIT) {
      err_code = impd_process_drc_bitstream_dec(
          p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
          p_obj_drc->str_payload.pstr_drc_config,
          p_obj_drc->str_payload.pstr_loudness_info,
          &p_obj_drc->str_bit_handler
               .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
          p_obj_drc->str_bit_handler.num_bytes_bs,
          p_obj_drc->str_bit_handler.num_bits_offset_bs,
          &p_obj_drc->str_bit_handler.num_bits_read_bs);

      if (err_code > PROC_COMPLETE) return -1;

      p_obj_drc->str_bit_handler.num_bytes_read_bs =
          (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
      p_obj_drc->str_bit_handler.num_bits_offset_bs =
          (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
      p_obj_drc->str_bit_handler.byte_index_bs +=
          p_obj_drc->str_bit_handler.num_bytes_read_bs;
      p_obj_drc->str_bit_handler.num_bytes_bs -=
          p_obj_drc->str_bit_handler.num_bytes_read_bs;
    }
  }

  return err_code;
}
