/******************************************************************************
 *
 * 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 "impd_type_def.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_rom.h"

VOID process_qmf_syn_filt_bank(ia_drc_qmf_filt_struct *qmf_filt, FLOAT64 *buff,
                               FLOAT32 *input_real, FLOAT32 *input_imag,
                               FLOAT32 *output) {
  WORD32 i, j;
  FLOAT64 U[10 * QMF_NUM_FILT_BANDS];
  FLOAT64 W[10 * QMF_NUM_FILT_BANDS];

  FLOAT64 tmp;

  for (i = 20 * QMF_FILT_RESOLUTION - 1; i >= 2 * QMF_FILT_RESOLUTION; i--) {
    buff[i] = buff[i - 2 * QMF_FILT_RESOLUTION];
  }

  for (i = 0; i < 2 * QMF_FILT_RESOLUTION; i++) {
    tmp = 0.0;
    for (j = 0; j < QMF_FILT_RESOLUTION; j++) {
      tmp = tmp + input_real[j] * qmf_filt->syn_tab_real[i][j] -
            input_imag[j] * qmf_filt->syn_tab_imag[i][j];
    }
    buff[i] = tmp;
  }

  for (i = 0; i < 5; i++) {
    for (j = 0; j < QMF_FILT_RESOLUTION; j++) {
      U[2 * QMF_FILT_RESOLUTION * i + j] =
          buff[4 * QMF_FILT_RESOLUTION * i + j];
      U[2 * QMF_FILT_RESOLUTION * i + QMF_FILT_RESOLUTION + j] =
          buff[4 * QMF_FILT_RESOLUTION * i + 3 * QMF_FILT_RESOLUTION + j];
    }
  }

  for (i = 0; i < 10 * QMF_FILT_RESOLUTION; i++) {
    W[i] = U[i] * qmf_filter_coeff[i];
  }

  for (i = 0; i < QMF_FILT_RESOLUTION; i++) {
    tmp = 0.0;
    for (j = 0; j < 10; j++) {
      tmp = tmp + W[QMF_FILT_RESOLUTION * j + i];
    }
    output[i] = (FLOAT32)tmp;
  }
}

VOID process_qmf_ana_filt_bank(ia_drc_qmf_filt_struct *qmf_filt, FLOAT64 *buff,
                               FLOAT32 *input, FLOAT32 *output_real,
                               FLOAT32 *output_imag) {
  WORD32 i, j;
  FLOAT32 Z[10 * QMF_NUM_FILT_BANDS];
  FLOAT32 Y[2 * QMF_NUM_FILT_BANDS];

  for (i = 10 * QMF_FILT_RESOLUTION - 1; i >= QMF_FILT_RESOLUTION; i--) {
    buff[i] = buff[i - QMF_FILT_RESOLUTION];
  }

  for (i = QMF_FILT_RESOLUTION - 1; i >= 0; i--) {
    buff[i] = input[QMF_FILT_RESOLUTION - 1 - i];
  }

  for (i = 0; i < 10 * QMF_FILT_RESOLUTION; i++) {
    Z[i] = (FLOAT32)(buff[i] * qmf_filter_coeff[i]);
  }

  for (i = 0; i < 2 * QMF_FILT_RESOLUTION; i++) {
    Y[i] = 0.0f;
    for (j = 0; j < 5; j++) {
      Y[i] += Z[i + j * 2 * QMF_FILT_RESOLUTION];
    }
  }

  for (i = 0; i < QMF_FILT_RESOLUTION; i++) {
    output_real[i] = 0.0f;
    output_imag[i] = 0.0f;
    for (j = 0; j < 2 * QMF_FILT_RESOLUTION; j++) {
      output_real[i] += (FLOAT32)(Y[j] * qmf_filt->ana_tab_real[i][j]);
      output_imag[i] += (FLOAT32)(Y[j] * qmf_filt->ana_tab_imag[i][j]);
    }
  }
}

static WORD32 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 0;
}

WORD32 impd_init_process_audio_main_td_qmf(ia_drc_api_struct *p_obj_drc)

{
  WORD32 error, i, j, num_samples_per_channel;
  FLOAT32 *input_buffer;
  WORD16 *input_buffer16, *output_buffer16;
  FLOAT32 *output_buffer;
  FLOAT32 *audio_io_buf_real[10];
  FLOAT32 *audio_io_buf_imag[10];
  FLOAT32 *audio_in_out_buf[10];
  FLOAT32 *scratch_buffer;
  WORD32 last_frame = 0;
  error = 0;
  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 0;
  }

  if ((p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in /
       (p_obj_drc->str_config.pcm_size >> 3)) <
      (UWORD32)p_obj_drc->str_config.frame_size)
    last_frame = 1;

  for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    audio_in_out_buf[i] = scratch_buffer;
    scratch_buffer = scratch_buffer + (p_obj_drc->str_config.frame_size + 32);
    audio_io_buf_real[i] =
        scratch_buffer +
        (p_obj_drc->str_config.frame_size * p_obj_drc->str_config.num_ch_in +
         512);
    audio_io_buf_imag[i] = scratch_buffer +
                           2 * (p_obj_drc->str_config.frame_size *
                                    p_obj_drc->str_config.num_ch_in +
                                512);
    ;
    for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
      if (p_obj_drc->str_config.pcm_size == 16) {
        audio_in_out_buf[i][j] =
            ((FLOAT32)input_buffer16[j * p_obj_drc->str_config.num_ch_in + i]) /
            32767.0f;
      } else {
        audio_in_out_buf[i][j] =
            input_buffer[j * p_obj_drc->str_config.num_ch_in + i];
      }
    }
  }

  error = 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 (error > 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) {
    /* shift over fill-bits for frame byte alignment */
    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)  // 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_bs - 1;
      }
    }
  }

  for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
    for (j = 0; j < p_obj_drc->str_config.frame_size; j += 64) {
      process_qmf_ana_filt_bank(
          p_obj_drc->str_payload.pstr_qmf_filter,
          p_obj_drc->str_payload.pstr_qmf_filter->ana_buff +
              i * 4 * p_obj_drc->str_config.frame_size,
          &(audio_in_out_buf[i][j]), &(audio_io_buf_real[i][j]),
          &(audio_io_buf_imag[i][j]));
    }
  }
  error = impd_drc_process_freq_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_io_buf_real,
      audio_io_buf_imag, 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 (error) return error;

  if (p_obj_drc->str_payload.pstr_drc_sel_proc_output->target_channel_count <
      p_obj_drc->str_payload.pstr_drc_sel_proc_output->base_channel_count) {
    error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
                          audio_io_buf_real, p_obj_drc->str_config.frame_size);
    if (error) return error;

    error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
                          audio_io_buf_imag, p_obj_drc->str_config.frame_size);
    if (error) return error;
  }

  error = impd_drc_process_freq_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_io_buf_real,
      audio_io_buf_imag, 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 (error) return -1;
  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 += 64) {
      process_qmf_syn_filt_bank(
          p_obj_drc->str_payload.pstr_qmf_filter,
          p_obj_drc->str_payload.pstr_qmf_filter->syn_buff +
              i * 4 * p_obj_drc->str_config.frame_size,
          &(audio_io_buf_real[i][j]), &(audio_io_buf_imag[i][j]),
          &(audio_in_out_buf[i][j]));
    }
  }

  if (p_obj_drc->str_payload.pstr_drc_sel_proc_output
          ->loudness_normalization_gain_db != 0.0f) {
    FLOAT32 loudness_normalization_gain =
        (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_io_buf_real[i][j] *= loudness_normalization_gain;
        audio_io_buf_imag[i][j] *= loudness_normalization_gain;
      }
    }
  }

  num_samples_per_channel = p_obj_drc->str_config.frame_size;

  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 (p_obj_drc->str_config.pcm_size == 16) {
        output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] =
            (WORD16)(audio_in_out_buf[i][j] * 32767.0f);
      } else {
        output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
            audio_in_out_buf[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->str_config.bitstream_file_format !=
      BITSTREAM_FILE_FORMAT_SPLIT) {
    error = 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 (error > 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 error;
}
