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

📄 fft.c

📁 使用Ti提供的支持库编写的1024、2048或4096点FFT
💻 C
字号:
/***********************************************************
*
* FFT library. SWUST, rhodesn@163.com
* MAX point is 4096 dot
* 2006-06-24
************************************************************/

#define PI 3.14159265358979

#include <math.h>
#include <string.h>
#include <dsp_radix2.h>
#include <dsp_bitrev_cplx.h>
#include "fft.h"
/*global functions*/

void digitrev_index(short *index, int n,int radix);
void gen_twiddle(short *w, int n, double scale);

/*global vars*/
#pragma DATA_SECTION(g_DSPFFTData,".dsp_fft_sect")
#pragma DATA_ALIGN(g_DSPFFTData,8)
static unsigned char g_DSPFFTData[40960+128];

#pragma DATA_ALIGN(g_x1,8)
short *g_x1;
//#pragma DATA_ALIGN(g_x2,8)
//int *g_x2;
#pragma DATA_ALIGN(g_window,8)
short *g_window;
#pragma DATA_ALIGN(g_index,8)
short *g_index;

/*
static short g_index[64];
static short g_window[numlength];
static short g_x1[numlength*2];
static int   g_x2[numlength];
*/

static int radix;
int nx1;

/*
	initializing the DSP_FFT functions, generate the table and index for FFT useing
	DotNumber: 1024/2048/4096... 2' power
	iRadix   : 2
*/
void DSP_FFT_init(int DotNumber,int iRadix)
{
	double scale;
	scale = 32767.5;
	radix = iRadix;
	nx1	  = DotNumber;
	
	memset(g_DSPFFTData,0,40960+128);
	g_x1 = (short *)g_DSPFFTData;
//	g_x2 = (int *)(g_x1+2*DotNumber);
	g_window = (short *)(g_x1+2*DotNumber);
	g_index = (short *)(g_window+DotNumber);

	/*init the index for fft bitrev*/
	digitrev_index(g_index,nx1,radix);
	/*init the fft coefficients*/
	gen_twiddle(g_window,nx1,scale);

}

/*
	test FFT algorithm. three kinds of frequency.
	and result of FFT is R0 I0, R1 I1,.....
*/
void DSP_FFT_test(short *OutData)
{
	int i;
	
	/*构造要做FFT的序列,按实部0、虚部0,实部1、虚部1...序列构造*/
	for (i=0; i<nx1; i++){
		g_x1[2*i]=(short)((cos(PI*i/5.0)+cos(PI*i/10.0)+cos(PI*i/20.0))*128);//
		g_x1[2*i+1]=0;
	}
	/*FFT algorithm*/
	DSP_radix2(nx1,g_x1,g_window);
	DSP_bitrev_cplx((int *)g_x1, g_index, nx1);
	
	memcpy((void *)OutData,(void *)g_x1,nx1*4);
	
	//calculate the magnitude of FFT
/*
	for (i=0;i<nx1; i++)
		//g_x2[i]=sqrt(g_x1[2*i]*g_x1[2*i]+g_x1[2*i+1]*g_x1[2*i+1]);
		g_x2[i] = sqrt(OutData[2*i]*OutData[2*i]+OutData[2*i+1]*OutData[2*i+1]);
*/
	
}

/*
	FFT core. 
	input : AudioData: real data, counter is DotNumber
	output: FftData  : magnitude of FFT, sqrt(R*R+I*I)
*/
void DSP_FFT_core(short *AudioData,short *FftData)
{
	int i;
	/*construct the sequence of input data*/
#pragma MUST_ITERATE(1024,,2)	
	for (i=0; i<nx1; i++)
	{
		g_x1[2*i] = AudioData[i];
		g_x1[2*i+1]=0;
	}
	/*radix 2 of fft*/
	DSP_radix2(nx1,g_x1,g_window);
	/*bit reversal of complex*/
	DSP_bitrev_cplx((int *)g_x1, g_index, nx1);
	
	memcpy((void *)FftData,(void *)g_x1,nx1*4);
	
/*	
	for (i=0;i<nx1; i++){
		g_x2[i]=sqrt(g_x1[2*i]*g_x1[2*i]+g_x1[2*i+1]*g_x1[2*i+1]);
	}
*/	
}

void digitrev_index(short *index, int n,int radix)              
{                                                                   
    int   i, j, k;//, radix = 2;                                                  
    short nbits, nbot, ntop, ndiff, n2, raddiv2;                    
                                                                    
    nbits = 0;                                                      
    i = n;                                                          
    while (i > 1)                                                   
    {                                                               
        i = i >> 1;                                                 
        nbits++;                                                    
    }                                                               
                                                                    
    raddiv2 = radix >> 1;                                           
    nbot    = nbits >> raddiv2;                                     
    nbot    = nbot << raddiv2 - 1;                                  
    ndiff   = nbits & raddiv2;                                      
    ntop    = nbot + ndiff;                                         
    n2      = 1 << ntop;                                            
                                                                    
    index[0] = 0;                                                   
    for ( i = 1, j = n2/radix + 1; i < n2 - 1; i++)                 
    {                                                               
        index[i] = j - 1;                                           
                                                                    
        for (k = n2/radix; k*(radix-1) < j; k /= radix)             
            j -= k*(radix-1);                                       
                                                                    
        j += k;                                                     
    }                                                               
    index[n2 - 1] = n2 - 1;                                         
} 

/* ======================================================================== */
/*  D2S -- Truncate a 'double' to a 'short', with clamping.                 */
/* ======================================================================== */
static short d2s(double d)
{
    if (d >=  32767.0) return  32767;
    if (d <= -32768.0) return -32768;
    return (short)d;
}
    
void gen_twiddle(short *w, int n, double scale)
{
    double angle, step;
    int i;

    step = (2.0 * PI) / (double)n;
    for (i = 0, angle = 0.0; i < n; i += 2, angle += step)
    {
        w[i + 0] = d2s(scale * -cos(angle));
        w[i + 1] = d2s(scale * -sin(angle));
    }

    return ;
}                                                                                           

⌨️ 快捷键说明

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