/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 *
 *  This is a modification of omxSP_FFTInit_C_SC32.c to support
 *  complex float instead of SC32.
 */

#include "dl/api/armCOMM.h"
#include "dl/api/armOMX.h"
#include "dl/api/omxtypes.h"
#include "dl/sp/api/armSP.h"
#include "dl/sp/api/omxSP.h"


/**
 * Function: omxSP_FFTInit_C_FC32
 *
 * Description:
 * Initializes the specification structures required for the
 * complex FFT and IFFT functions.
 *
 * Remarks:
 * Desired block length is specified as an input. The function is used to
 * initialize the specification structures for functions <FFTFwd_CToC_FC32_Sfs>
 * and <FFTInv_CToC_FC32_Sfs>. Memory for the specification structure *pFFTSpec
 * must be allocated prior to calling this function. The space required for
 * *pFFTSpec, in bytes, can be determined using <FFTGetBufSize_C_FC32>.
 *
 * Parameters:
 * [in]  order       base-2 logarithm of the desired block length;
 *                     valid in the range [0,12].
 * [out] pFFTSpec    pointer to initialized specification structure.
 *
 * Return Value:
 * Standard omxError result. See enumeration for possible result codes.
 *
 */

OMXResult omxSP_FFTInit_C_FC32(OMXFFTSpec_C_FC32* pFFTSpec, OMX_INT order) {
  OMX_INT i;
  OMX_INT j;
  OMX_FC32* pTwiddle;
  OMX_FC32* pBuf;
  OMX_U16* pBitRev;
  OMX_U32 pTmp;
  OMX_INT Nby2;
  OMX_INT N;
  OMX_INT M;
  OMX_INT diff;
  OMX_INT step;
  ARMsFFTSpec_FC32* pFFTStruct = 0;
  OMX_F32 x;
  OMX_F32 y;
  OMX_F32 xNeg;

  pFFTStruct = (ARMsFFTSpec_FC32 *) pFFTSpec;

  /* if order zero no init is needed */
  if (order == 0) {
    pFFTStruct->N = 1;
    return OMX_Sts_NoErr;
  }

  /* Validate args */
  if (!pFFTSpec || (order < 0) || (order > TWIDDLE_TABLE_ORDER))
    return OMX_Sts_BadArgErr;

  /* Do the initializations */
  Nby2 = 1 << (order - 1);
  N = Nby2 << 1;
  M = N >> 3;

  /* optimized implementations don't use bitreversal */
  pBitRev = NULL;

  pTwiddle = (OMX_FC32 *) (sizeof(ARMsFFTSpec_FC32) + (OMX_S8*) pFFTSpec);

  /* Align to 32 byte boundary */
  pTmp = ((OMX_U32) pTwiddle) & 31;
  if (pTmp)
    pTwiddle = (OMX_FC32*) ((OMX_S8*)pTwiddle + (32 - pTmp));

  pBuf = (OMX_FC32*) (sizeof(OMX_FC32) * (3 * N / 4) + (OMX_S8*) pTwiddle);

  /* Align to 32 byte boundary */
  pTmp = ((OMX_U32)pBuf) & 31;
  if (pTmp)
    pBuf = (OMX_FC32*) ((OMX_S8*)pBuf + (32 - pTmp));

  /*
   * Filling Twiddle factors :
   *
   * The original twiddle table "armSP_FFT_S32TwiddleTable" is of size
   * (MaxSize/8 + 1) Rest of the values i.e., upto MaxSize are
   * calculated using the symmetries of sin and cos The max size of
   * the twiddle table needed is 3N/4 for a radix-4 stage
   *
   * W = (-2 * PI) / N
   * N = 1 << order
   * W = -PI >> (order - 1)
   */

  diff = TWIDDLE_TABLE_ORDER - order;
  /* step into the twiddle table for the current order */
  step = 1 << diff;

  x = armSP_FFT_F32TwiddleTable[0];
  y = armSP_FFT_F32TwiddleTable[1];
  xNeg = 1;

  if (order >= 3) {
    /* i = 0 case */
    pTwiddle[0].Re = x;
    pTwiddle[0].Im = y;
    pTwiddle[2 * M].Re = -y;
    pTwiddle[2 * M].Im = xNeg;
    pTwiddle[4 * M].Re = xNeg;
    pTwiddle[4 * M].Im = y;

    for (i = 1; i <= M; i++) {
      j = i * step;

      x = armSP_FFT_F32TwiddleTable[2 * j];
      y = armSP_FFT_F32TwiddleTable[2 * j + 1];

      pTwiddle[i].Re = x;
      pTwiddle[i].Im = y;
      pTwiddle[2 * M - i].Re = -y;
      pTwiddle[2 * M - i].Im = -x;
      pTwiddle[2 * M + i].Re = y;
      pTwiddle[2 * M + i].Im = -x;
      pTwiddle[4 * M - i].Re = -x;
      pTwiddle[4 * M - i].Im = y;
      pTwiddle[4 * M + i].Re = -x;
      pTwiddle[4 * M + i].Im = -y;
      pTwiddle[6 * M - i].Re = y;
      pTwiddle[6 * M - i].Im = x;
    }
  } else if (order == 2) {
    pTwiddle[0].Re = x;
    pTwiddle[0].Im = y;
    pTwiddle[1].Re = -y;
    pTwiddle[1].Im = xNeg;
    pTwiddle[2].Re = xNeg;
    pTwiddle[2].Im = y;
  } else if (order == 1) {
    pTwiddle[0].Re = x;
    pTwiddle[0].Im = y;
  }

  /* Update the structure */
  pFFTStruct->N = N;
  pFFTStruct->pTwiddle = pTwiddle;
  pFFTStruct->pBitRev = pBitRev;
  pFFTStruct->pBuf = pBuf;

  return OMX_Sts_NoErr;
}

/*****************************************************************************
 *                              END OF FILE
 *****************************************************************************/
