/* * 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/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 * and . 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 . * * Parameters: * [in] order base-2 logarithm of the desired block length; * valid in the range [1,12]. ([1,15] if * BIG_FFT_TABLE is defined.) * [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; /* Validate args */ if (!pFFTSpec || (order < 1) || (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 *****************************************************************************/