📄 fpifft.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 + -