Home | History | Annotate | Download | only in arm
      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 file was originally licensed as follows. It has been
     11  *  relicensed with permission from the copyright holders.
     12  */
     13 
     14 /**
     15  *
     16  * File Name:  omxSP_FFTInit_R_S16S32.c
     17  * OpenMAX DL: v1.0.2
     18  * Last Modified Revision:   7777
     19  * Last Modified Date:       Thu, 27 Sep 2007
     20  *
     21  * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
     22  *
     23  *
     24  * Description:
     25  * Initialize the real forward-FFT specification information struct.
     26  */
     27 
     28 #include <stdint.h>
     29 
     30 #include "dl/api/arm/armOMX.h"
     31 #include "dl/api/omxtypes.h"
     32 #include "dl/sp/api/armSP.h"
     33 #include "dl/sp/api/omxSP.h"
     34 
     35 /**
     36  * Function: omxSP_FFTInit_R_S16_S32
     37  *
     38  * Description:
     39  * Initialize the real forward-FFT specification information struct.
     40  *
     41  * Remarks:
     42  * This function is used to initialize the specification structures
     43  * for functions <ippsFFTFwd_RToCCS_S16_S32_Sfs> and
     44  * <ippsFFTInv_CCSToR_S32_S16_Sfs>. Memory for *pFFTSpec must be
     45  * allocated prior to calling this function. The number of bytes
     46  * required for *pFFTSpec can be determined using
     47  * <FFTGetBufSize_R_S16_S32>.
     48  *
     49  * Parameters:
     50  * [in]  order       base-2 logarithm of the desired block length;
     51  *			   valid in the range [0,12].
     52  * [out] pFFTFwdSpec pointer to the initialized specification structure.
     53  *
     54  * Return Value:
     55  * Standard omxError result. See enumeration for possible result codes.
     56  *
     57  */
     58 
     59 OMXResult omxSP_FFTInit_R_S16S32(
     60      OMXFFTSpec_R_S16S32* pFFTSpec,
     61      OMX_INT order
     62 )
     63 {
     64     OMX_INT     i,j;
     65     OMX_SC32    *pTwiddle,*pTwiddle1,*pTwiddle2,*pTwiddle3,*pTwiddle4;
     66     OMX_S32     *pBuf;
     67     OMX_U16     *pBitRev;
     68     OMX_U32     pTmp;
     69     OMX_INT     Nby2,N,M,diff, step;
     70     OMX_S32     x,y,xNeg;
     71     ARMsFFTSpec_R_SC32 *pFFTStruct = 0;
     72 
     73 
     74     pFFTStruct = (ARMsFFTSpec_R_SC32 *) pFFTSpec;
     75 
     76     /* if order zero no init is needed */
     77     if (order == 0)
     78     {
     79         pFFTStruct->N = 1;
     80         pFFTStruct->pTwiddle = NULL;
     81         pFFTStruct->pBuf = (OMX_S32 *)
     82                (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec);
     83 
     84         return OMX_Sts_NoErr;
     85     }
     86 
     87     /* Do the initializations */
     88     Nby2 = 1 << (order - 1);
     89     N = Nby2 << 1;
     90 
     91 
     92 
     93     pBitRev = NULL ;                /* optimized implementations don't use bitreversal */
     94 
     95     pTwiddle = (OMX_SC32 *)
     96         (sizeof(ARMsFFTSpec_R_SC32) + (OMX_S8*) pFFTSpec);
     97 
     98     /* Align to 32 byte boundary */
     99     pTmp = ((uintptr_t)pTwiddle)&31;              /* (OMX_U32)pTwiddle % 32 */
    100     if(pTmp != 0)
    101         pTwiddle = (OMX_SC32*) ((OMX_S8*)pTwiddle + (32-pTmp));
    102 
    103 
    104     pBuf = (OMX_S32*)
    105         (sizeof(OMX_SC32) * (5*N/8) + (OMX_S8*) pTwiddle);
    106 
    107     /* Align to 32 byte boundary */
    108     pTmp = ((uintptr_t)pBuf)&31;                 /* (OMX_U32)pBuf % 32 */
    109     if(pTmp != 0)
    110         pBuf = (OMX_S32*) ((OMX_S8*)pBuf + (32-pTmp));
    111 
    112 
    113 
    114 
    115     /*
    116      * Filling Twiddle factors : exp^(-j*2*PI*k/ (N/2) ) ; k=0,1,2,...,3/4(N/2)
    117      * N/2 point complex FFT is used to compute N point real FFT
    118      * The original twiddle table "armSP_FFT_S32TwiddleTable" is of size (MaxSize/8 + 1)
    119      * Rest of the values i.e., upto MaxSize are calculated using the symmetries of sin and cos
    120      * The max size of the twiddle table needed is 3/4(N/2) for a radix-4 stage
    121      *
    122      * W = (-2 * PI) / N
    123      * N = 1 << order
    124      * W = -PI >> (order - 1)
    125      */
    126 
    127     M = Nby2>>3;
    128     diff = 12 - (order-1);
    129     step = 1<<diff;             /* step into the twiddle table for the current order */
    130 
    131     x = armSP_FFT_S32TwiddleTable[0];
    132     y = armSP_FFT_S32TwiddleTable[1];
    133     xNeg = 0x7FFFFFFF;
    134 
    135     if((order-1) >=3)
    136     {
    137             /* i = 0 case */
    138             pTwiddle[0].Re = x;
    139             pTwiddle[0].Im = y;
    140             pTwiddle[2*M].Re = -y;
    141             pTwiddle[2*M].Im = xNeg;
    142             pTwiddle[4*M].Re = xNeg;
    143             pTwiddle[4*M].Im = y;
    144 
    145 
    146         for (i=1; i<=M; i++)
    147           {
    148             j = i*step;
    149 
    150             x = armSP_FFT_S32TwiddleTable[2*j];
    151             y = armSP_FFT_S32TwiddleTable[2*j+1];
    152 
    153             pTwiddle[i].Re = x;
    154             pTwiddle[i].Im = y;
    155             pTwiddle[2*M-i].Re = -y;
    156             pTwiddle[2*M-i].Im = -x;
    157             pTwiddle[2*M+i].Re = y;
    158             pTwiddle[2*M+i].Im = -x;
    159             pTwiddle[4*M-i].Re = -x;
    160             pTwiddle[4*M-i].Im = y;
    161             pTwiddle[4*M+i].Re = -x;
    162             pTwiddle[4*M+i].Im = -y;
    163             pTwiddle[6*M-i].Re = y;
    164             pTwiddle[6*M-i].Im = x;
    165         }
    166 
    167 
    168     }
    169     else
    170     {
    171         if ((order-1) == 2)
    172         {
    173             pTwiddle[0].Re = x;
    174             pTwiddle[0].Im = y;
    175             pTwiddle[1].Re = -y;
    176             pTwiddle[1].Im = xNeg;
    177             pTwiddle[2].Re = xNeg;
    178             pTwiddle[2].Im = y;
    179 
    180         }
    181         if ((order-1) == 1)
    182         {
    183             pTwiddle[0].Re = x;
    184             pTwiddle[0].Im = y;
    185 
    186         }
    187 
    188 
    189     }
    190 
    191 
    192     /*
    193      * Now fill the last N/4 values : exp^(-j*2*PI*k/N) ;  k=1,3,5,...,N/2-1
    194      * These are used for the final twiddle fix-up for converting complex to real FFT
    195      */
    196 
    197     M = N>>3;
    198     diff = 12 - order;
    199     step = 1<<diff;
    200 
    201     pTwiddle1 = pTwiddle + 3*N/8;
    202     pTwiddle4 = pTwiddle1 + (N/4-1);
    203     pTwiddle3 = pTwiddle1 + N/8;
    204     pTwiddle2 = pTwiddle1 + (N/8-1);
    205 
    206     x = armSP_FFT_S32TwiddleTable[0];
    207     y = armSP_FFT_S32TwiddleTable[1];
    208     xNeg = 0x7FFFFFFF;
    209 
    210     if((order) >=3)
    211     {
    212 
    213 
    214         for (i=1; i<=M; i+=2 )
    215           {
    216             j = i*step;
    217 
    218             x = armSP_FFT_S32TwiddleTable[2*j];
    219             y = armSP_FFT_S32TwiddleTable[2*j+1];
    220 
    221             pTwiddle1[0].Re = x;
    222             pTwiddle1[0].Im = y;
    223             pTwiddle1 += 1;
    224             pTwiddle2[0].Re = -y;
    225             pTwiddle2[0].Im = -x;
    226             pTwiddle2 -= 1;
    227             pTwiddle3[0].Re = y;
    228             pTwiddle3[0].Im = -x;
    229             pTwiddle3 += 1;
    230             pTwiddle4[0].Re = -x;
    231             pTwiddle4[0].Im = y;
    232             pTwiddle4 -= 1;
    233 
    234         }
    235 
    236 
    237     }
    238     else
    239     {
    240         if (order == 2)
    241         {
    242 
    243             pTwiddle1[0].Re = -y;
    244             pTwiddle1[0].Im = xNeg;
    245 
    246         }
    247 
    248 
    249     }
    250 
    251 
    252     /* Update the structure */
    253     pFFTStruct->N = N;
    254     pFFTStruct->pTwiddle = pTwiddle;
    255     pFFTStruct->pBitRev = pBitRev;
    256     pFFTStruct->pBuf = pBuf;
    257 
    258     return OMX_Sts_NoErr;
    259 }
    260 /*****************************************************************************
    261  *                              END OF FILE
    262  *****************************************************************************/
    263 
    264