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

📄 fft.h

📁 快速傅里叶变换fft算法
💻 H
字号:
/* fix_fft.c - Fixed-point in-place Fast Fourier Transform  */
/*
  All data are fixed-point short integers, in which -32768
  to +32768 represent -1.0 to +1.0 respectively. Integer
  arithmetic is used for speed, instead of the more natural
  floating-point.

  For the forward FFT (time -> freq), fixed scaling is
  performed to prevent arithmetic overflow, and to map a 0dB
  sine/cosine wave (i.e. amplitude = 32767) to two -6dB freq
  coefficients. The return value is always 0.

  Henceforth "short" implies 16-bit word. If this is not
  the case in your architecture, please replace "short"
  with a type definition which *is* a 16-bit word.

  所有数据均定点短整数,用-32768~32768代表-1.0至+1.0。整
  形数运算加速运算,代替浮点运算。 

  前向FFT中,采用固定缩放以防止算术溢出,并映射零分贝正弦/
  余弦波(即振幅= 32767 )成两个6分贝频率系数。

*/

#define N_WAVE      1024    /* full length of Sinewave[] */
#define LOG2_N_WAVE 10      /* log2(N_WAVE) */

#include "reverse_table.h"
#include "SIN_WAVE.h"

inline short FIX_MPY(short a, short b)
{
	int c = ((int)a * (int)b ) >> 14;
	b = c & 0x01;
	a = (c >> 1) + b;
	return a;
}
//=========fft核心算法=================
void fix_fft1(short fr[], short fi[], short m)
{
	int i, j, k, power_2, N,a,b,c;
	short qr,qi,tr,ti,wr, wi;	
	short *r;
	N = 1 << m;	

	////////////////洗序////////////////
	switch(N)
	{
		case 4:		{ r = r_Table4; a = 1;break;}
		case 8:		{ r = r_Table8; a = 3;break;}
		case 16:	{ r = r_Table16; a = 11;break;}
		case 32:	{ r = r_Table32; a = 23;break;}
		case 64:	{ r = r_Table64; a = 55;break;}
		case 128:	{ r = r_Table128; a = 111;break;}
		case 256:	{ r = r_Table256; a = 239;break;}
		case 512:	{ r = r_Table512; a = 479;break;}
		case 1024:	{ r = r_Table1024; a = 991;break;}
	}
	for(i=0;i<a;i=i+2)	
	{ 
		tr = fr[r[i]];
		fr[r[i]] = fr[r[i+1]];
		fr[r[i+1]] = tr;
		ti = fi[r[i]];
		fi[r[i]] = fi[r[i+1]];
		fi[r[i+1]] = ti;
	}
	//////////////fft核心算法/////////////////

    for(i=0;i<m;i++)
    {
        power_2 = 1 << i;
        for(j=0;j<N;j=j+power_2*2)
        {
            for(k=0;k<power_2;k++)
            {
				a = k*N_WAVE/(2*power_2);
				b = j + k;
				c = b + power_2;
				
                wr =  Sinewave[a+N_WAVE/4];
				wi = - Sinewave[a];

                tr = FIX_MPY(wr,fr[c]) - FIX_MPY(wi,fi[c]);
				ti = FIX_MPY(wr,fi[c]) + FIX_MPY(wi,fr[c]);
				
				qr = fr[b];
				qi = fi[b];

				//short型溢出报错,-32767~32767
				if((qr-tr>32767)|(qi-ti>32767)|(qr+tr>32767)|(qi+ti>32767))
				{
					printf("overflow !!!!\n");
					break;
				}

				fr[c] = qr - tr;
				fi[c] = qi - ti;
				fr[b] = qr + tr;
				fi[b] = qi + ti;
            }
        }
    }
}

//====================================================
//		fix_fftr1----未整合函数,采用sin表,无放缩
//====================================================
short fix_fftr1(short f[], short m)
{
	int i, N = 1<<m, scale = 0;		//N = 128
    short *fr = f;
	short *fi = new short[N];
    for(i=0;i<N;i++)
		fi[i] = 0;
	fix_fft1(fr, fi, m);
	for(i=0; i<N; i++)
	{
		f[i] = sqrt(pow(double(fr[i]),2)+pow(double(fi[i]),2));
	}
	return scale;
}

//====================================================
//		fix_fftr2----整合函数,采用sin表,有放缩
//====================================================
void fix_fftr2(short f[], short m)
{
	unsigned short i,j,k,a,b,c,power_2, N = 1<<m;
	short qr,qi,tr,ti,wr, wi;
    short *fr = f;
	short *fi = new short[N];
    for(i=0;i<N;i++)
		fi[i] = 0;
	short *r;
	////////////////洗序////////////////
	switch(N)
	{
		case 4:		{ r = r_Table4; a = 1;break;}
		case 8:		{ r = r_Table8; a = 3;break;}
		case 16:	{ r = r_Table16; a = 11;break;}
		case 32:	{ r = r_Table32; a = 23;break;}
		case 64:	{ r = r_Table64; a = 55;break;}
		case 128:	{ r = r_Table128; a = 111;break;}
		case 256:	{ r = r_Table256; a = 239;break;}
		case 512:	{ r = r_Table512; a = 479;break;}
		case 1024:	{ r = r_Table1024; a = 991;break;}
	}
	for(i=0;i<a;i=i+2)	
	{ 
		tr = fr[r[i]];
		fr[r[i]] = fr[r[i+1]];
		fr[r[i+1]] = tr;
		ti = fi[r[i]];
		fi[r[i]] = fi[r[i+1]];
		fi[r[i+1]] = ti;
	}
	//////////////fft核心算法/////////////////
    for(i=0;i<m;i++)
    {
        power_2 = 1 << i;
        for(j=0;j<N;j=j+power_2*2)
        {
            for(k=0;k<power_2;k++)
            {
				a = k*N_WAVE/(2*power_2);
				b = j + k;
				c = b + power_2;
				
                wr =  (Sinewave[a+N_WAVE/4]>>2);
				wi = - (Sinewave[a]>>2);


                tr = FIX_MPY(wr,fr[c]) - FIX_MPY(wi,fi[c]);
				ti = FIX_MPY(wr,fi[c]) + FIX_MPY(wi,fr[c]);
				
				qr = (fr[b]>>2);
				qi = (fi[b]>>2);

				//short型溢出报错,-32767~32767
				if((qr-tr>32767)|(qi-ti>32767)|(qr+tr>32767)|(qi+ti>32767))
				{
					printf("overflow !!!!\n");
					break;
				}

				fr[c] = qr - tr;
				fi[c] = qi - ti;
				fr[b] = qr + tr;
				fi[b] = qi + ti;
            }
        }
    }

	///////////////////////////////
	for(i=0; i<N; i++)
	{
		f[i] = sqrt(pow(double(fr[i]),2)+pow(double(fi[i]),2));
		f[i] = 3096/(f[i] + 1);
		if(f[i]>=1548)
			f[i] = 0;
	}
}



//====================================================
//		fix_fftr3----整合函数,采用sin表,无放缩
//====================================================
void fix_fftr3(short f[], short m)
{
	unsigned short i,j,k,a,b,c,power_2, N = 1<<m;
	short qr,qi,tr,ti,wr, wi;
    short *fr = f;
	short *fi = new short[N];
    for(i=0;i<N;i++)
		fi[i] = 0;
	
	short *r;
	////////////////洗序////////////////
	switch(N)
	{
		case 4:		{ r = r_Table4; a = 1;break;}
		case 8:		{ r = r_Table8; a = 3;break;}
		case 16:	{ r = r_Table16; a = 11;break;}
		case 32:	{ r = r_Table32; a = 23;break;}
		case 64:	{ r = r_Table64; a = 55;break;}
		case 128:	{ r = r_Table128; a = 111;break;}
		case 256:	{ r = r_Table256; a = 239;break;}
		case 512:	{ r = r_Table512; a = 479;break;}
		case 1024:	{ r = r_Table1024; a = 991;break;}
	}
	for(i=0;i<a;i=i+2)	
	{ 
		tr = fr[r[i]];
		fr[r[i]] = fr[r[i+1]];
		fr[r[i+1]] = tr;
		ti = fi[r[i]];
		fi[r[i]] = fi[r[i+1]];
		fi[r[i+1]] = ti;
	}
	//////////////fft核心算法/////////////////
    for(i=0;i<m;i++)
    {
        power_2 = 1 << i;
        for(j=0;j<N;j=j+power_2*2)
        {
            for(k=0;k<power_2;k++)
            {
				a = k*N_WAVE/(2*power_2);
				b = j + k;
				c = b + power_2;

                wr =  Sinewave[a+N_WAVE/4];
				wi = - Sinewave[a];

                tr = FIX_MPY(wr,fr[c]) - FIX_MPY(wi,fi[c]);
				ti = FIX_MPY(wr,fi[c]) + FIX_MPY(wi,fr[c]);
				
				qr = fr[b];
				qi = fi[b];

				//short型溢出报错,-32767~32767
				if((qr-tr>32767)|(qi-ti>32767)|(qr+tr>32767)|(qi+ti>32767))
				{
					printf("overflow !!!!\n");
					break;
				}

				fr[c] = qr - tr;
				fi[c] = qi - ti;
				fr[b] = qr + tr;
				fi[b] = qi + ti;
            }
        }
    }

///////////////////////////////
	for(i=0; i<N; i++)
	{
		f[i] = sqrt(pow(double(fr[i]),2)+pow(double(fi[i]),2));
	}
}

⌨️ 快捷键说明

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