/******************************************************************************
 *                                                                            *
 * 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 <stdlib.h>
#include <string.h>
#include <math.h>

#include "ixheaacd_type_def.h"
#include "ixheaacd_bitbuffer.h"
#include "ixheaacd_interface.h"
#include "ixheaacd_tns_usac.h"
#include "ixheaacd_cnst.h"
#include "ixheaacd_acelp_info.h"
#include "ixheaacd_td_mdct.h"
#include "ixheaacd_sbrdecsettings.h"
#include "ixheaacd_info.h"
#include "ixheaacd_sbr_common.h"
#include "ixheaacd_drc_data_struct.h"
#include "ixheaacd_drc_dec.h"
#include "ixheaacd_sbrdecoder.h"
#include "ixheaacd_mps_polyphase.h"
#include "ixheaacd_sbr_const.h"
#include "ixheaacd_main.h"
#include "ixheaacd_arith_dec.h"
#include "ixheaacd_windows.h"
#include "ixheaacd_constants.h"
#include "ixheaacd_basic_ops32.h"
#include "ixheaacd_basic_ops40.h"
#include "ixheaacd_func_def.h"
#include "ixheaacd_acelp_com.h"

static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
  WORD32 result;
  WORD64 temp_result;

  temp_result = (WORD64)a * (WORD64)b;
  result = (WORD32)(temp_result >> 31);

  return (result);
}

static VOID ixheaacd_weighted_synthesis_filter(WORD32 *a, WORD32 *ap) {
  WORD32 f;
  WORD32 i;
  ap[0] = a[0];
  f = IGAMMA1;
  for (i = 1; i <= ORDER; i++) {
    ap[i] = ixheaacd_mult32_m(f, a[i]);
    f = ixheaacd_mult32_m(f, IGAMMA1);
  }
  return;
}

static VOID ixheaacd_synthesis_tool(WORD32 a[], WORD32 x[], WORD32 l,
                                    WORD32 qshift, WORD32 *preshift) {
  WORD32 s;
  WORD32 i, j;

  for (i = 0; i < l; i++) {
    s = x[i];
    for (j = 1; j <= ORDER; j += 4) {
      s = ixheaacd_sub32_sat(
          s, ixheaacd_mul32_sh(a[j], x[i - j], (WORD8)(qshift)));
      s = ixheaacd_sub32_sat(
          s, ixheaacd_mul32_sh(a[j + 1], x[i - (j + 1)], (WORD8)(qshift)));
      s = ixheaacd_sub32_sat(
          s, ixheaacd_mul32_sh(a[j + 2], x[i - (j + 2)], (WORD8)(qshift)));
      s = ixheaacd_sub32_sat(
          s, ixheaacd_mul32_sh(a[j + 3], x[i - (j + 3)], (WORD8)(qshift)));
    }
    x[i] = s;
  }

  (*preshift)++;
  return;
}

WORD32 ixheaacd_fwd_alias_cancel_tool(
    ia_usac_data_struct *usac_data, ia_td_frame_data_struct *pstr_td_frame_data,
    WORD32 fac_length, FLOAT32 *lp_filt_coeff, WORD32 gain) {
  WORD32 i;
  FLOAT32 lp_filt_coeff_a[ORDER + 1];
  WORD32 qshift = 0;
  WORD32 err = 0;

  WORD32 *x_in = pstr_td_frame_data->fac_data;
  WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
  WORD32 *fac_signal = &usac_data->x_ac_dec[16];
  FLOAT32 fac_signal_flt[128 + 16];
  FLOAT32 *ptr_fac_signal_flt = &fac_signal_flt[16];
  WORD32 *ptr_overlap_buf =
      &(usac_data->overlap_data_ptr[usac_data->present_chan]
                                   [(usac_data->ccfl / 2) - fac_length]);

  memset(fac_signal - 16, 0, ORDER * sizeof(WORD32));

  err = ixheaacd_acelp_mdct(x_in, fac_signal, &qshift, fac_length, ptr_scratch);
  if (err == -1) return err;

  ixheaacd_lpc_coeff_wt_apply(lp_filt_coeff, lp_filt_coeff_a);

  for (i = 0; i < fac_length; i++)
    ptr_fac_signal_flt[i] =
        (FLOAT32)((FLOAT32)fac_signal[i] / (1 << (16 - qshift)));

  memset(ptr_fac_signal_flt - 16, 0, 16 * sizeof(FLOAT32));

  ixheaacd_synthesis_tool_float1(lp_filt_coeff_a, ptr_fac_signal_flt,
                                 fac_length);

  for (i = 0; i < fac_length; i++)
    fac_signal[i] = (WORD32)(ptr_fac_signal_flt[i] * (1 << (16 - qshift)));

  for (i = 0; i < fac_length; i++)
    ptr_overlap_buf[i] = ixheaacd_add32_sat(
        ptr_overlap_buf[i],
        (WORD32)ixheaacd_mul32_sh(fac_signal[i], gain, (WORD8)(16 - qshift)));

  return err;
}

WORD32 ixheaacd_fr_alias_cnx_fix(WORD32 *x_in, WORD32 len, WORD32 fac_length,
                                 WORD32 *lp_filt_coeff, WORD32 *izir,
                                 WORD32 *fac_data_out, WORD8 *qshift1,
                                 WORD8 qshift2, WORD8 qshift3, WORD32 *preshift,
                                 WORD32 *ptr_scratch) {
  WORD32 i;
  const WORD32 *sine_window;
  WORD32 fac_window[2 * FAC_LENGTH];
  WORD32 lp_filt_coeff_a[ORDER + 1];
  WORD32 err = 0;

  if (fac_length == 48) {
    sine_window = ixheaacd_sine_win_96;
  } else if (fac_length == 64) {
    sine_window = ixheaacd_sine_win_128;
  } else if (fac_length == 96) {
    sine_window = ixheaacd_sine_win_192;
  } else {
    sine_window = ixheaacd_sine_win_256;
  }
  if (FAC_LENGTH < fac_length) {
    return -1;
  }

  if (FAC_LENGTH < fac_length) {
    return -1;
  }
  if ((1 + (len / 2)) < (fac_length + 1)) {
    return -1;
  }
  if ((len / 2 + 1) > (2 * LEN_FRAME - fac_length - 1)) {
    return -1;
  }

  if (lp_filt_coeff != NULL && fac_data_out != NULL) {
    memset(fac_data_out - 16, 0, ORDER * sizeof(WORD32));
    err = ixheaacd_acelp_mdct(x_in, fac_data_out, preshift, fac_length,
                              ptr_scratch);
    if (err == -1) return err;

    ixheaacd_weighted_synthesis_filter(lp_filt_coeff, lp_filt_coeff_a);

    memset(fac_data_out + fac_length, 0, fac_length * sizeof(WORD32));

    ixheaacd_synthesis_tool(lp_filt_coeff_a, fac_data_out, 2 * fac_length,
                            qshift2, preshift);

    if (izir != NULL) {
      for (i = 0; i < fac_length; i++) {
        fac_window[i] = ixheaacd_mult32_m(
            sine_window[i], sine_window[(2 * fac_length) - 1 - i]);
        fac_window[fac_length + i] =
            2147483647 - ixheaacd_mult32_m(sine_window[fac_length + i],
                                           sine_window[fac_length + i]);
      }
      for (i = 0; i < fac_length; i++) {
        WORD32 temp1;
        WORD32 temp2;

        temp1 = ixheaacd_mul32_sh(
            izir[1 + (len / 2) + i], fac_window[fac_length + i],
            (char)((qshift3 - *qshift1 + 31 + (WORD8)(*preshift))));

        temp2 = ixheaacd_mul32_sh(
            izir[1 + (len / 2) - 1 - i], fac_window[fac_length - 1 - i],
            (char)((qshift3 - *qshift1 + 31 + (WORD8)(*preshift))));

        fac_data_out[i] =
            ixheaacd_add32_sat3((fac_data_out[i] / 2), temp1, temp2);

        fac_data_out[fac_length + i] = (fac_data_out[fac_length + i] / 2);
      }
    }
  }

  return err;
}
