blob: 564f166627451653cdfd0f10aa8afa32996e3baf [file] [log] [blame]
/*
* 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_R_S32.c to support float
* instead of S32.
*/
#include "dl/api/omxtypes.h"
#include "dl/sp/api/omxSP.h"
#include "dl/sp/api/x86SP.h"
/**
* Function: omxSP_FFTInit_R_F32
*
* Description:
* Initialize the real forward-FFT specification information struct.
*
* Remarks:
* This function is used to initialize the specification structures
* for functions |omxSP_FFTFwd_RToCCS_F32_Sfs| and
* |omxSP_FFTInv_CCSToR_F32_Sfs|. Memory for *pFFTSpec must be
* allocated prior to calling this function. The number of bytes
* required for *pFFTSpec can be determined using
* |omxSP_FFTGetBufSize_R_F32|.
*
* 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] pFFTFwdSpec pointer to the initialized specification structure.
*
* Return Value:
* Standard omxError result. See enumeration for possible result codes.
*
*/
OMXResult omxSP_FFTInit_R_F32(OMXFFTSpec_R_F32 *pFFTSpec, OMX_INT order)
{
OMX_F32 *pTwiddle;
OMX_F32 *pBuf;
OMX_INT i;
OMX_INT j;
OMX_INT N;
OMX_INT NBy2;
OMX_INT NBy4;
OMX_INT diff;
OMX_U32 pTmp;
X86FFTSpec_R_FC32 *pFFTStruct = (X86FFTSpec_R_FC32 *) pFFTSpec;
OMX_F32 real;
OMX_F32 imag;
if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER))
return OMX_Sts_BadArgErr;
N = 1 << order;
NBy2 = N >> 1;
pTwiddle = (OMX_F32*) (sizeof(X86FFTSpec_R_FC32) + (OMX_S8*) pFFTSpec);
// Align to 32 byte boundary.
pTmp = ((OMX_U32)pTwiddle) & 31;
if (pTmp)
pTwiddle = (OMX_F32*) ((OMX_S8*)pTwiddle + (32 - pTmp));
pBuf = (OMX_F32*) (sizeof(OMX_F32) * (N << 1) + (OMX_S8*) pTwiddle);
// Align to 32 byte boundary.
pTmp = ((OMX_U32)pBuf) & 31;
if (pTmp)
pBuf = (OMX_F32*) ((OMX_S8*)pBuf + (32 - pTmp));
// Calculating Twiddle Factors.
diff = 1 << (TWIDDLE_TABLE_ORDER - order + 1);
// For SSE optimization, using twiddle with split format by which the real and
// imag data are stored into first and last halves of the buffer separately
// The negatives are moved when generating pTwiddle table.
if (order > 1) {
NBy4 = N >> 2;
for (i = 0, j = 0; i <= NBy4 >> 1; ++i, j += diff) {
real = armSP_FFT_F32TwiddleTable[j];
imag = armSP_FFT_F32TwiddleTable[j + 1];
pTwiddle[i] = -real;
pTwiddle[i + N] = -imag;
pTwiddle[NBy4 - i] = imag;
pTwiddle[NBy4 - i + N] = real;
pTwiddle[NBy4 + i] = -imag;
pTwiddle[NBy4 + i + N] = real;
pTwiddle[NBy2 - i] = real;
pTwiddle[NBy2 - i + N] = -imag;
pTwiddle[NBy2 + i] = real;
pTwiddle[NBy2 + i + N] = imag;
pTwiddle[NBy4 * 3 - i] = -imag;
pTwiddle[NBy4 * 3 - i + N] = -real;
pTwiddle[NBy4 * 3 + i] = imag;
pTwiddle[NBy4 * 3 + i + N] = -real;
pTwiddle[N - i - 1] = -real;
pTwiddle[(N << 1) - i - 1] = imag;
}
} else {
pTwiddle[0] = armSP_FFT_F32TwiddleTable[0];
pTwiddle[2] = armSP_FFT_F32TwiddleTable[1];
pTwiddle[1] = -pTwiddle[0];
pTwiddle[3] = pTwiddle[2];
}
pFFTStruct->N = N;
pFFTStruct->pTwiddle = pTwiddle;
pFFTStruct->pBuf1 = pBuf;
pFFTStruct->pBuf2 = pBuf + N + 4;
return OMX_Sts_NoErr;
}