Home | History | Annotate | Download | only in x86
      1 /*
      2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  *
     10  *  This is a modification of omxSP_FFTInit_R_S32.c to support float
     11  *  instead of S32.
     12  */
     13 
     14 #include <stdint.h>
     15 
     16 #include "dl/api/omxtypes.h"
     17 #include "dl/sp/api/omxSP.h"
     18 #include "dl/sp/api/x86SP.h"
     19 
     20 /**
     21  * Function: omxSP_FFTInit_R_F32
     22  *
     23  * Description:
     24  * Initialize the real forward-FFT specification information struct.
     25  *
     26  * Remarks:
     27  * This function is used to initialize the specification structures
     28  * for functions |omxSP_FFTFwd_RToCCS_F32_Sfs| and
     29  * |omxSP_FFTInv_CCSToR_F32_Sfs|. Memory for *pFFTSpec must be
     30  * allocated prior to calling this function. The number of bytes
     31  * required for *pFFTSpec can be determined using
     32  * |omxSP_FFTGetBufSize_R_F32|.
     33  *
     34  * Parameters:
     35  * [in]  order       base-2 logarithm of the desired block length;
     36  *                         valid in the range [1,12].  ([1,15] if
     37  *                         BIG_FFT_TABLE is defined.)
     38  * [out] pFFTFwdSpec pointer to the initialized specification structure.
     39  *
     40  * Return Value:
     41  * Standard omxError result. See enumeration for possible result codes.
     42  *
     43  */
     44 
     45 OMXResult omxSP_FFTInit_R_F32(OMXFFTSpec_R_F32 *pFFTSpec, OMX_INT order)
     46 {
     47   OMX_F32 *pTwiddle;
     48   OMX_F32 *pBuf;
     49   OMX_INT i;
     50   OMX_INT j;
     51   OMX_INT N;
     52   OMX_INT NBy2;
     53   OMX_INT NBy4;
     54   OMX_INT diff;
     55   OMX_U32 pTmp;
     56   X86FFTSpec_R_FC32  *pFFTStruct = (X86FFTSpec_R_FC32 *) pFFTSpec;
     57   OMX_F32 real;
     58   OMX_F32 imag;
     59 
     60   if (!pFFTSpec || (order < 1) || (order > TWIDDLE_TABLE_ORDER))
     61     return OMX_Sts_BadArgErr;
     62 
     63   N = 1 << order;
     64   NBy2 = N >> 1;
     65 
     66   pTwiddle = (OMX_F32*) (sizeof(X86FFTSpec_R_FC32) + (OMX_S8*) pFFTSpec);
     67 
     68   // Align to 32 byte boundary.
     69   pTmp = ((uintptr_t)pTwiddle) & 31;
     70   if (pTmp)
     71     pTwiddle = (OMX_F32*) ((OMX_S8*)pTwiddle + (32 - pTmp));
     72 
     73   pBuf = (OMX_F32*) (sizeof(OMX_F32) * (N << 1) + (OMX_S8*) pTwiddle);
     74 
     75   // Align to 32 byte boundary.
     76   pTmp = ((uintptr_t)pBuf) & 31;
     77   if (pTmp)
     78     pBuf = (OMX_F32*) ((OMX_S8*)pBuf + (32 - pTmp));
     79 
     80   // Calculating Twiddle Factors.
     81   diff = 1 << (TWIDDLE_TABLE_ORDER - order + 1);
     82 
     83   // For SSE optimization, using twiddle with split format by which the real and
     84   // imag data are stored into first and last halves of the buffer separately
     85   // The negatives are moved when generating pTwiddle table.
     86   if (order > 1) {
     87     NBy4 = N >> 2;
     88     for (i = 0, j = 0; i <= NBy4 >> 1; ++i, j += diff) {
     89       real = armSP_FFT_F32TwiddleTable[j];
     90       imag = armSP_FFT_F32TwiddleTable[j + 1];
     91 
     92       pTwiddle[i] = -real;
     93       pTwiddle[i + N] = -imag;
     94 
     95       pTwiddle[NBy4 - i] = imag;
     96       pTwiddle[NBy4 - i + N] = real;
     97 
     98       pTwiddle[NBy4 + i] = -imag;
     99       pTwiddle[NBy4 + i + N] = real;
    100 
    101       pTwiddle[NBy2 - i] = real;
    102       pTwiddle[NBy2 - i + N] = -imag;
    103 
    104       pTwiddle[NBy2 + i] = real;
    105       pTwiddle[NBy2 + i + N] = imag;
    106 
    107       pTwiddle[NBy4 * 3 - i] = -imag;
    108       pTwiddle[NBy4 * 3 - i + N] = -real;
    109 
    110       pTwiddle[NBy4 * 3 + i] = imag;
    111       pTwiddle[NBy4 * 3 + i + N] = -real;
    112 
    113       pTwiddle[N - i - 1] = -real;
    114       pTwiddle[(N << 1) - i - 1] = imag;
    115     }
    116   } else {
    117     pTwiddle[0] = armSP_FFT_F32TwiddleTable[0];
    118     pTwiddle[2] = armSP_FFT_F32TwiddleTable[1];
    119     pTwiddle[1] = -pTwiddle[0];
    120     pTwiddle[3] = pTwiddle[2];
    121   }
    122   pFFTStruct->N = N;
    123   pFFTStruct->pTwiddle = pTwiddle;
    124   pFFTStruct->pBuf1 = pBuf;
    125   pFFTStruct->pBuf2 = pBuf + N + 4;
    126 
    127   return OMX_Sts_NoErr;
    128 }
    129