⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpifft.c

📁 OFDMA 物理层开发的matlab 源码.飞思卡尔提供.对物理层开发的工程师有帮助!
💻 C
字号:
/* ==============================================================================
   Property of Freescale
   Freescale Confidential Proprietary
   Freescale Copyright (C) 2006 All rights reserved
   ------------------------------------------------------------------------------
   $RCSfile: fpifft.c.rca $
   Tag $Name:  $
   $Revision: 1.2 $
   $Target Processor: MATLAB
   ============================================================================== */

#include <stdlib.h>
#include <math.h>
#include "mex.h"
#undef _ENTERPRISE_C_
#define __USEINTRINSICS
#include "StarCoreMath.c"
#include "prototype.c"
#include "math_funcs.c"
#include "Radix2_First_Loop.c"
#include "Radix4_First_Loop.c"
#define I_mpy(siVar1,siVar2) ((Word32)siVar1*(Word32)siVar2)
#include "GenBitReverse.c"
#include "GenWiddles.c"

// Globals
Word16 *gpasiBitReverse;
signed   long  int     liFFTMode=IFFT_MODE;


// Additionnal struc type used in the following includes
typedef struct stAlignedMem
{
    void  *pMem;
    void  *pAMem;
} stAlignedMem;

stAlignedMem AlignedMalloc(int liSize, int liAlignment, int liOffset)
{
    stAlignedMem stMemory;
    int  liMemoryAligned;
    
    stMemory.pMem = malloc(liSize+liAlignment);
    liMemoryAligned = ((int)stMemory.pMem & (0-liAlignment))+liAlignment;
    liMemoryAligned -= liOffset;
    if (liMemoryAligned < (int)stMemory.pMem) liMemoryAligned += liAlignment;
    stMemory.pAMem = (void *)liMemoryAligned;
    return(stMemory);
}
#include "Radix4_Last_Loop.c"
#include "Radix4_Main_Loops.c"
#include "SBX_CMSPK_FFT.c"

// Input Arguments (not all might be used)
#define	X1_IN	prhs[0]
#define	X2_IN	prhs[1]
#define	X3_IN	prhs[2]

// Output Arguments (not all might be used)
#define	Y1_OUT	plhs[0]
#define	Y2_OUT	plhs[1]

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    /* Matlab input dimensions (not all might be used) */
    unsigned long mx1,nx1;
    
    /* Matlab output dimensions (not all might be used) */
    unsigned long my1,ny1;
    
    // Others
    int i,k;
    unsigned long  int uliScaleMode;
    //unsigned long  int additionnalScale;
    double additionnalScale;
    double *temp6, *temp7;
    
    // additionnal parameters due to use of global "gpasiBitReverse"
    stFFT_arg *pstFft;
    stAlignedMem    stBitReverse;
    stAlignedMem    stWCTwiddles;
    stAlignedMem    stWDTwiddles;
    stAlignedMem    stWBTwiddles;
    stAlignedMem    stTwiddles;
    Word16          *pasiTwiddles;
    Word16          *pasiWCTwiddles;
    Word16          *pasiWDTwiddles;
    Word16          *pasiWBTwiddles;
    signed long int liNumOfPoint;
    signed short int  *X1;
    double *Y1r,*Y1i,*Y2r;
    double *temp1,*temp2;
    
    
    /* Check for proper number of arguments */
    if (   (nlhs != 1) &  (nlhs!=2) )
    {
        mexErrMsgTxt("Error: 1 or 2 output arguments required.");
    }
    
    if (  ((nrhs!=1) &  (nrhs!=2) &  (nrhs!=3))  )
    {
        mexErrMsgTxt("Error: 1,2 or 3 input arguments required.");
    }
    
    /* Check the input format */
    if ( (!mxIsDouble(X1_IN))) // || !mxIsComplex(X1_IN)))
    {
        mexErrMsgTxt("Error: Input 1 data must be complex of class 'double'.");
    }
    
    /* get input dimensions (not all might be used) */
    mx1=mxGetM(X1_IN); nx1=mxGetN(X1_IN);
    
    /*if ( nx1!=1  )
    {
        mexErrMsgTxt("Error: Input 1 data must be a col vector.");
    }*/
    
    if ( ((mx1!=512) &  (mx1!=1024))   )
    {
        mexErrMsgTxt("Error: Input 1 data must have 512 or 1024 rows.");
    }
    liNumOfPoint=mx1;
    
    if (   nrhs==1 ) {
        uliScaleMode= 0x00008000 ;
        additionnalScale=32;}
    else {
            /* Check the input format */
        if ( (!mxIsDouble(X2_IN) || mxIsComplex(X2_IN)))
        {
            mexErrMsgTxt("Error: Input 2 data must be real of class 'double'.");
        }
        /* collect data : scaling*/
        temp6   = (double *)mxGetPr(X2_IN);
        uliScaleMode = (unsigned long  int)temp6[0];
        
        
        
        if (   nrhs==2 ) {
            additionnalScale=32;}
        else if  (   nrhs==3 ) {
            /* Check the input format */
            if ( (!mxIsDouble(X3_IN) || mxIsComplex(X3_IN)))
            {
                mexErrMsgTxt("Error: Input 3 data must be real of class 'double'.");
            }
            /* collect data : scaling*/
            temp7   = (double *)mxGetPr(X3_IN);
            //additionnalScale = (unsigned long  int)temp7[0];
            additionnalScale = (double)temp7[0];
        }
        
        
    }
    /*mexPrintf("uliScaleMode=%x ",uliScaleMode);
    mexPrintf("additionnalScale=%d ",(int) additionnalScale);*/
    
    Y2_OUT = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
    Y2r = (double*) mxGetPr(Y2_OUT);
    Y2r[0] = (double) uliScaleMode ; // (double)
    
    
    //Allocate memory to hold the bit reverse table and generate tables
    //Bit reverse table is only used for generating Twiddle factors in assembly code version
    stBitReverse = AlignedMalloc(liNumOfPoint*sizeof(Word16),2,0);
    gpasiBitReverse = stBitReverse.pAMem;
    generate_bit_reverse(gpasiBitReverse, (Word16)liNumOfPoint);
    
    //Allocate memory to hold the twiddle table and generate tables
    stWCTwiddles   = AlignedMalloc(liNumOfPoint/2*sizeof(Word16),8,0);
    stWDTwiddles   = AlignedMalloc(liNumOfPoint/2*sizeof(Word16),8,0);
    stWBTwiddles   = AlignedMalloc(liNumOfPoint/2*sizeof(Word16),8,0);
    pasiWCTwiddles = stWCTwiddles.pAMem;
    pasiWDTwiddles = stWDTwiddles.pAMem;
    pasiWBTwiddles = stWBTwiddles.pAMem;
    
    // updated generate_twiddles function :
    stTwiddles   = AlignedMalloc(liNumOfPoint*3/2*sizeof(Word16),2,0);
	pasiTwiddles = stTwiddles.pAMem;
    generate_twiddles(pasiTwiddles, (Word16)liNumOfPoint, gpasiBitReverse);

    
    for (k=0;k< (int) liNumOfPoint/2;k++)
    {
     pasiWCTwiddles[k] =  pasiTwiddles[k];
     pasiWDTwiddles[k] = pasiTwiddles[k+liNumOfPoint/2];   
     pasiWBTwiddles[k] = pasiTwiddles[k+liNumOfPoint];  
    }
    
    
    pstFft = (struct stFFT_arg *)mxMalloc(sizeof(signed short int)*2*liNumOfPoint +  \
    sizeof(signed short int)*1 + sizeof(unsigned long int)*1 + sizeof(signed short int)*1 + \
    sizeof(signed short int)*(3*liNumOfPoint/2) + \
    sizeof(signed short int)*2*liNumOfPoint );
    
    
    pstFft->uliScaleMode=uliScaleMode;	// Scaling mode
    pstFft->liNumOfPoint=liNumOfPoint;	// Num of IFFT pointsliNumPts
    pstFft->liFFTMode=liFFTMode;	    // IFFT mode
    pstFft->pasiWCTwiddles = pasiWCTwiddles; //twiddles
    pstFft->pasiWDTwiddles = pasiWDTwiddles; //twiddles
    pstFft->pasiWBTwiddles = pasiWBTwiddles; //twiddles
    pstFft->pasiOutBuf = mxMalloc(sizeof(signed short int)*2*liNumOfPoint);
    
    
    Y1_OUT = mxCreateNumericMatrix(liNumOfPoint,nx1,mxDOUBLE_CLASS,mxCOMPLEX);
    Y1r = (double*)mxGetPr(Y1_OUT); Y1i = (double*)mxGetPi(Y1_OUT);
    
    /* collect data : X1*/
    X1 = mxMalloc(sizeof(unsigned short int*)*mx1*1*2);
    
    if ( (mxIsComplex(X1_IN)))
    {
        temp1   = (double *)mxGetPr(X1_IN);
        temp2   = (double *)mxGetPi(X1_IN);
    }
    else {
        temp1   = (double *)mxGetPr(X1_IN);
    }
    
    
    
    
    // loop over columns
    for(k=0;k<(nx1);k++)
    {
        
        // Check the input format
        if ( (mxIsComplex(X1_IN)))
        {
            for(i=0;i<mx1;i++)
            {
                X1[2*i] = (signed short int) (temp1[i+mx1*k]) ;
                X1[2*i+1] = (signed short int) (temp2[i+mx1*k]) ; //
            }
        }
        else {
            for(i=0;i<mx1*nx1;i++)
            {
                X1[2*i] = (signed short int) (temp1[i+mx1*k]) ;
                X1[2*i+1] = (signed short int) 0;
            }
        }
        
        pstFft->pasiInBuf=X1;   // Input vector
        
        // call the MAIN C function
        SBX_CMSPK_FFT(pstFft);
        
        
        for(i=0;i<(mx1*1);i++)
        {
            Y1r[i+k*mx1] = (double) ((pstFft->pasiOutBuf[2*i])) / additionnalScale;
            Y1i[i+k*mx1] = (double) ((pstFft->pasiOutBuf[2*i+1])) / additionnalScale ;
        }
        
    }
    
    
    
    return;
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -