Part Number:TMS320C6748
我需要调用dsplib进行256点的FFT,我参考了starterware中的FFT例程并利用DSPF_sp_fftSPxSP函数计算,问题在于,结果的长度似乎和常规的复数FFT不同,比如256点的复数FFT结果应该是256个复数,即按float储存应该是512个,而例程中,额外分配了4个float的空间,我不明白这些空间是用来储存什么内容的
2148.main.c
/****************************************************************************/ /**/ /*���ٸ���Ҷ�任 / ���ٸ���Ҷ��任����*/ /**/ /*2014��04��20��*/ /**/ /****************************************************************************/ #include <stdio.h>// C ���Ա�������������� #include <math.h>// C ��ѧ������ #include "mathlib.h"// DSP ��ѧ������ #include "dsplib.h"// DSP ������ /****************************************************************************/ /**/ /*�궨��*/ /**/ /****************************************************************************/ // ����ϵ� #define SW_BREAKPOINTasm(" SWBP 0 "); // ���ٸ���Ҷ�任 // �� �� ��������Сֵ #define PI3.14159 #define F_TOL(1e-06) /****************************************************************************/ /**/ /*ȫ�ֱ���*/ /**/ /****************************************************************************/ // ���ٸ���Ҷ�任���� // ���Կ��ٸ���Ҷ�任���� // ע��:TI DSP�� ���֧��һ���Լ��� 128K ����� FFT #define Tn 1024 // ����Ƶ�� #define Fs 1000.0 // �ź� float Input[2*Tn+4]; // FFT �����ź� #pragma DATA_ALIGN(CFFT_In, 8); float CFFT_In[2*Tn+4]; // FFT �����ź� ���� float CFFT_InOrig[2*Tn+4]; // FFT ��� #pragma DATA_ALIGN(CFFT_Out, 8); float CFFT_Out[2*Tn+4]; // IFFT ��� #pragma DATA_ALIGN(CFFT_InvOut, 8); float CFFT_InvOut[2*Tn+4]; // �м�������ʱ���� float CTemp[2*Tn+4]; // �洢��ת���� float Cw[2*Tn]; // ģ float Cmo[Tn+2]; // ������λ��ת #pragma DATA_ALIGN (brev, 8); unsigned char brev[64]= { 0x0, 0x20, 0x10, 0x30, 0x8, 0x28, 0x18, 0x38, 0x4, 0x24, 0x14, 0x34, 0xc, 0x2c, 0x1c, 0x3c, 0x2, 0x22, 0x12, 0x32, 0xa, 0x2a, 0x1a, 0x3a, 0x6, 0x26, 0x16, 0x36, 0xe, 0x2e, 0x1e, 0x3e, 0x1, 0x21, 0x11, 0x31, 0x9, 0x29, 0x19, 0x39, 0x5, 0x25, 0x15, 0x35, 0xd, 0x2d, 0x1d, 0x3d, 0x3, 0x23, 0x13, 0x33, 0xb, 0x2b, 0x1b, 0x3b, 0x7, 0x27, 0x17, 0x37, 0xf, 0x2f, 0x1f, 0x3f }; /****************************************************************************/ /**/ /*��������*/ /**/ /****************************************************************************/ // ������ת���� void tw_gen(float *w, int n); // FFT ���� void FFTTest(); /****************************************************************************/ /**/ /*������*/ /**/ /****************************************************************************/ int main(void) { // FFT ���� FFTTest(); // �ϵ� SW_BREAKPOINT; } /****************************************************************************/ /**/ /*���ٸ���Ҷ�任����*/ /**/ /****************************************************************************/ // ������ת���� void tw_gen(float *w, int n) { int i,j,k; double x_t,y_t,theta1,theta2,theta3; for(j=1,k=0;j<=n>>2;j=j<<2) { for(i=0;i<n>>2;i += j) { theta1=2*PI*i/n; x_t=cos(theta1); y_t=sin(theta1); w[k]=(float)x_t; w[k+1]=(float)y_t; theta2=4*PI*i/n; x_t=cos(theta2); y_t=sin(theta2); w[k+2]=(float)x_t; w[k+3]=(float)y_t; theta3=6*PI*i/n; x_t=cos(theta3); y_t=sin(theta3); w[k+4]=(float)x_t; w[k+5]=(float)y_t; k+=6; } } } // ���ٸ���Ҷ�任 void FFTTest(void) { // �����������ź� unsigned int i; for (i=0;i<Tn;i++) Input[i]=5*sin(2*PI*150*(i/Fs))+15*sin(2*PI*350*(i/Fs)); // ȷ�����ٸ���Ҷ�任�� unsigned char rad; if(Tn==16 || Tn==64 || Tn==256 || Tn==1024 || Tn==4096 || Tn==16384 || Tn==65536) rad=4; else if(Tn==8 || Tn==32 || Tn==128 || Tn==512 || Tn==2048 || Tn==8192 || Tn==32768) rad=2; else { printf ("��֧�� ���� %d ����ٸ���Ҷ�任��\n",Tn); return; } // ���� FFT for (i=0;i<2*Tn;i++) CFFT_In[i]=0.0; for (i=0;i<Tn;i++) { CFFT_In[2*i]=Input[i]; // ʵ�� CFFT_In[2*i+1]=0; // �鲿Ϊ 0 } // ����һ�������źŸ��� memcpy(CFFT_InOrig,CFFT_In,2*Tn*sizeof(float)); // ������ת���� tw_gen(Cw,Tn); // FFT ���� DSPF_sp_fftSPxSP(Tn,CFFT_In,Cw,CFFT_Out,brev,rad,0,Tn); // ������� for(i=0;i<Tn;i++) Cmo[i]=0.0; for(i=0;i<Tn+2;i++) { Cmo[i]=sqrtsp(CFFT_Out[2*i]*CFFT_Out[2*i]+CFFT_Out[2*i+1]*CFFT_Out[2*i+1]); Cmo[i]=Cmo[i]*2/Tn; } // ����һ�� FFT ������� memcpy(CTemp,CFFT_Out,2*Tn*sizeof(float)); // IFFT ���� DSPF_sp_ifftSPxSP(Tn,CFFT_Out,Cw,CFFT_InvOut,brev,rad,0,Tn); // �ָ� FFT ��� memcpy(CFFT_Out,CTemp,2*Tn*sizeof(float)); printf("\n���� FFT ���Խ��:"); unsigned char Flag; for(i=0;i<Tn;i++) if(abs(CFFT_InOrig[i]-CFFT_InvOut[i])>F_TOL) Flag=1; if(Flag==1) printf ("ʧ�ܣ�\n"); else printf ("�ɹ���\n"); }
Gary Lu:
jiuchao yin 说:,结果的长度似乎和常规的复数FFT不同,比如256点的复数FFT结果应该是256个复数,即按float储存应该是512个,而例程中,额外分配了4个float的空间,
在主函数中,使用`DSPF_sp_fftSPxSP`函数进行FFT,FFT输入和输出分配了`2*Tn+4`个`float`的空间,`Tn`是FFT的点数。这里额外的4个`float`空间是DSP库函数`DSPF_sp_fftSPxSP`的要求。这些额外的空间用于辅助计算,涉及到算法内部的缓存对齐为了避免边界条件下的读写错误。
在TI的DSPs中,在DSP优化的FFT实现中,,经常会有一些特定要求确保性能优化,比如数据对齐。这是DSP库特定实现的一部分,并且这种做法并非在所有FFT库中都会看到。