199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com/*
299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  Use of this source code is governed by a BSD-style license
599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  that can be found in the LICENSE file in the root of the source
699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  tree. An additional intellectual property rights grant can be found
799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  in the file PATENTS.  All contributing project authors may
899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  be found in the AUTHORS file in the root of the source tree.
999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
1099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  This is a modification of omxSP_FFTInit_C_SC32.c to support
1199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *  complex float instead of SC32.
1299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com */
1399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
145537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org#include <stdint.h>
155537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org
16bdf981cb383b7ec472ee86d2fedb53937285f894rtoy@google.com#include "dl/api/arm/armOMX.h"
17048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.com#include "dl/api/omxtypes.h"
18048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.com#include "dl/sp/api/armSP.h"
19048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.com#include "dl/sp/api/omxSP.h"
2099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
2199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com/**
2299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Function: omxSP_FFTInit_C_FC32
2399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
2499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Description:
2599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Initializes the specification structures required for the
2699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * complex FFT and IFFT functions.
2799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
2899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Remarks:
2999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Desired block length is specified as an input. The function is used to
3099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * initialize the specification structures for functions <FFTFwd_CToC_FC32_Sfs>
3199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * and <FFTInv_CToC_FC32_Sfs>. Memory for the specification structure *pFFTSpec
3299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * must be allocated prior to calling this function. The space required for
3399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * *pFFTSpec, in bytes, can be determined using <FFTGetBufSize_C_FC32>.
3499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
3599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Parameters:
3699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * [in]  order       base-2 logarithm of the desired block length;
376ae14cb23aa5d478d267519f29d05558fd8f2f0drtoy@google.com *                     valid in the range [1,12]. ([1,15] if
386ae14cb23aa5d478d267519f29d05558fd8f2f0drtoy@google.com *                     BIG_FFT_TABLE is defined.)
3999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * [out] pFFTSpec    pointer to initialized specification structure.
4099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
4199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Return Value:
4299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com * Standard omxError result. See enumeration for possible result codes.
4399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *
4499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com */
4599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
4699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comOMXResult omxSP_FFTInit_C_FC32(OMXFFTSpec_C_FC32* pFFTSpec, OMX_INT order) {
4799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT i;
4899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT j;
4999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_FC32* pTwiddle;
5099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_FC32* pBuf;
5199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_U16* pBitRev;
5299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_U32 pTmp;
5399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT Nby2;
5499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT N;
5599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT M;
5699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT diff;
5799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_INT step;
5899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  ARMsFFTSpec_FC32* pFFTStruct = 0;
5999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_F32 x;
6099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_F32 y;
6199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  OMX_F32 xNeg;
6299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
6399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pFFTStruct = (ARMsFFTSpec_FC32 *) pFFTSpec;
6499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
6599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* Validate args */
666ae14cb23aa5d478d267519f29d05558fd8f2f0drtoy@google.com  if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER))
6799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    return OMX_Sts_BadArgErr;
6899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
6999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* Do the initializations */
7099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  Nby2 = 1 << (order - 1);
7199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  N = Nby2 << 1;
7299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  M = N >> 3;
7399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
7499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* optimized implementations don't use bitreversal */
7599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pBitRev = NULL;
7699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
7799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pTwiddle = (OMX_FC32 *) (sizeof(ARMsFFTSpec_FC32) + (OMX_S8*) pFFTSpec);
7899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
7999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* Align to 32 byte boundary */
805537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org  pTmp = ((uintptr_t) pTwiddle) & 31;
8199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  if (pTmp)
8299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle = (OMX_FC32*) ((OMX_S8*)pTwiddle + (32 - pTmp));
8399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
8499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pBuf = (OMX_FC32*) (sizeof(OMX_FC32) * (3 * N / 4) + (OMX_S8*) pTwiddle);
8599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
8699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* Align to 32 byte boundary */
875537f70dff0bb4566ebb1ec645d2020974e93493turaj@webrtc.org  pTmp = ((uintptr_t)pBuf) & 31;
8899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  if (pTmp)
8999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pBuf = (OMX_FC32*) ((OMX_S8*)pBuf + (32 - pTmp));
9099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
9199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /*
9299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * Filling Twiddle factors :
9399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   *
9499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * The original twiddle table "armSP_FFT_S32TwiddleTable" is of size
9599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * (MaxSize/8 + 1) Rest of the values i.e., upto MaxSize are
9699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * calculated using the symmetries of sin and cos The max size of
9799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * the twiddle table needed is 3N/4 for a radix-4 stage
9899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   *
9999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * W = (-2 * PI) / N
10099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * N = 1 << order
10199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   * W = -PI >> (order - 1)
10299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com   */
10399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
10499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  diff = TWIDDLE_TABLE_ORDER - order;
10599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* step into the twiddle table for the current order */
10699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  step = 1 << diff;
10799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
10899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  x = armSP_FFT_F32TwiddleTable[0];
10999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  y = armSP_FFT_F32TwiddleTable[1];
11099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  xNeg = 1;
11199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
11299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  if (order >= 3) {
11399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /* i = 0 case */
11499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[0].Re = x;
11599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[0].Im = y;
11699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[2 * M].Re = -y;
11799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[2 * M].Im = xNeg;
11899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[4 * M].Re = xNeg;
11999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[4 * M].Im = y;
12099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
12199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    for (i = 1; i <= M; i++) {
12299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      j = i * step;
12399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
12499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      x = armSP_FFT_F32TwiddleTable[2 * j];
12599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      y = armSP_FFT_F32TwiddleTable[2 * j + 1];
12699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
12799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[i].Re = x;
12899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[i].Im = y;
12999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[2 * M - i].Re = -y;
13099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[2 * M - i].Im = -x;
13199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[2 * M + i].Re = y;
13299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[2 * M + i].Im = -x;
13399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[4 * M - i].Re = -x;
13499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[4 * M - i].Im = y;
13599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[4 * M + i].Re = -x;
13699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[4 * M + i].Im = -y;
13799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[6 * M - i].Re = y;
13899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com      pTwiddle[6 * M - i].Im = x;
13999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
14099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  } else if (order == 2) {
14199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[0].Re = x;
14299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[0].Im = y;
14399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[1].Re = -y;
14499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[1].Im = xNeg;
14599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[2].Re = xNeg;
14699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[2].Im = y;
14799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  } else if (order == 1) {
14899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[0].Re = x;
14999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    pTwiddle[0].Im = y;
15099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  }
15199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
15299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  /* Update the structure */
15399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pFFTStruct->N = N;
15499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pFFTStruct->pTwiddle = pTwiddle;
15599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pFFTStruct->pBitRev = pBitRev;
15699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  pFFTStruct->pBuf = pBuf;
15799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
15899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com  return OMX_Sts_NoErr;
15999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com}
16099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
16199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com/*****************************************************************************
16299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *                              END OF FILE
16399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com *****************************************************************************/
164