FFT 的C 语言实现

FFT 的C 语言实现

说好的C 语言实现,必须搞定它!

理论介绍:

http://blog.csdn.net/cinmyheart/article/details/39052739

这里有之前matlab & Octave 的实现

http://blog.csdn.net/cinmyheart/article/details/39042623

先介绍一下总体的实现文件

最主要的是fft.c这个文件是算法实现的核心

fft.h

/***************************************************************
code writer	:	EOF
code file	:	fft.h
code date	:	2014.09.17
e-mail		:	[email protected]

****************************************************************/
#ifndef _FFT_IN_C_H
#define _FFT_IN_C_H

	#include <stdio.h>
	#include <stdlib.h>
	#include <math.h>

	#define PI 3.1415926
	#define DEBUG

	struct complex_number
	{
		double real;
		double imagine;
	};

	struct signal
	{
		int size;//how many points in this domain.
		struct complex_number points[0];
	};

	int reverse_bits(int num,int bits);
	int get_r_in_Wn(int k, int m, int bits);

	void init_signal(struct signal* p_signal,double* array,int size);

	struct signal* fft(struct signal* p_signal);

	struct complex_number complex_mul(struct complex_number* x,struct complex_number* y);

	struct complex_number complex_add(struct complex_number* x, struct complex_number *y);

	struct complex_number complex_sub(struct complex_number* x, struct complex_number *y);

	void show_signal(struct signal* const signal);

	void show_complex_number(struct complex_number * x);
#endif

complex_add.c

/***************************************************************
code writer	:	EOF
code file	:	complex_add.c
code date	:	2014.09.17
e-mail		:	[email protected]

code purpose	:
	We need add operation between complex number, so here is
my method.

	If you find something wrong with my code, please touch
me by e-mail. Thank you :)

****************************************************************/
#include "fft.h"
#include "fft.h"

struct complex_number complex_add(struct complex_number* x, struct complex_number *y)
{
	struct complex_number ret;

	if(!x || !y)
	{
		printf("You passed NULL into %s()\n",__FUNCTION__);
		goto out ;
	}

	ret.real    = x->real    + y->real;
	ret.imagine = x->imagine + y->imagine;
out:
	return ret;
}

complex_mul.c

/***************************************************************
code writer	:	EOF
code file	:	complex_mul.c
code date	:	2014.09.17
e-mail		:	[email protected]

code purpose	:
	We need multiple(*) operation between complex number, so here is
my method.

	If you find something wrong with my code, please touch
me by e-mail. Thank you :)

****************************************************************/
#include "fft.h"

struct complex_number complex_mul(struct complex_number* x,struct complex_number *y)
{
	struct complex_number ret;
	if(!x || !y)
	{
		printf("You passed NULL into %s()\n",__FUNCTION__);
		goto out ;
	}

	ret.real    = (x->real) * (y->real)    - (x->imagine)*(y->imagine);
	ret.imagine = (x->real) * (y->imagine) + (x->imagine)* (y->real);

out:
	return ret;
}

complex_sub.c

#include "fft.h"

struct complex_number complex_sub(struct complex_number* x, struct complex_number *y)
{
	struct complex_number ret;

	if(!x || !y)
	{
		printf("You passed NULL into %s()\n",__FUNCTION__);
		goto out ;
	}

	ret.real    = x->real    - y->real;
	ret.imagine = x->imagine - y->imagine;
out:
	return ret;
}

get_r_in_Wn.c

/******************************************************************************
code writer	:	EOF
code file	:	get_r_in_Wn.c
code date	:	2014.09.17
e-mail		:	[email protected]

	Input Parameter : @k, the location of input signal
                          @m, the current layyer
                          @N, the total number of inputed signal
                          @bits, how many bits should be used to represent 'N'

	Output Parameter: @ret , the value of 'r'
*******************************************************************************/
int get_r_in_Wn(int k, int m, int bits)
{
	int tmp = k<<(bits-m);

	return tmp&((1<<m) -1);
}

reverse_bits.c

/***************************************************************
code writer	:	EOF
code file	:	reverse_bits.c
code date	:	2014.09.17
e-mail		:	[email protected]

code purpose	:

	 	Reverse the bits of input number

	If you find something wrong with my code, please touch
me by e-mail. Thank you :)

****************************************************************/

int reverse_bits(int num,int bits)
{
	int ret  = 0;
	int copy_num = 0;

	for(ret = 0,copy_num = num; bits > 0; bits--)
	{
		ret  += (copy_num % 2) * (1<<(bits-1));

		copy_num >>= 1;
	}

	return ret;
}

show_complex_number.c

/***************************************************************
code writer	:	EOF
code file	:	show_complex_number.c
code date	:	2014.09.17
e-mail		:	[email protected]

	If you find something wrong with my code, please touch
me by e-mail. Thank you :)

****************************************************************/
#include "fft.h"

void show_complex_number(struct complex_number * x)
{
	printf("real:%lf  imagine:%lf\n",x->real,x->imagine);
}

show_signal.c

/***************************************************************
code writer	:	EOF
code file	:	show_signal.c
code date	:	2014.09.17
e-mail		:	[email protected]

code purpose	:
	If you want to see the detail about signal that @p_signal point to, just call this API.

	If you find something wrong with my code, please touch
me by e-mail. Thank you :)

****************************************************************/
#include "fft.h"

void show_signal(struct signal* const p_signal)
{
	if(!p_signal)
	{
		printf("You passed NULL into function %s  line:%d\n",__FUNCTION__,__LINE__);

		return ;
	}

	int tmp = 0;

	for(tmp = 0; tmp < p_signal->size;tmp++)
	{
		printf("point %d real : %lf imagine %lf\n",		tmp,		p_signal->points[tmp].real,		p_signal->points[tmp].imagine);
	}
	printf("\n\n");
}

fft.c

/***************************************************************
code writer	:	EOF
code file	:	fft.c
code date	:	2014.09.17
e-mail		:	[email protected]

code purpose	:

	This code core-part of fft in my implementation.
	If you find something wrong with my code, please touch
me by e-mail. Thank you :)

****************************************************************/
#include "fft.h"

struct signal* fft(struct signal* p_signal)
{
	struct signal*  p_input_signal = 	(struct signal*) malloc(sizeof(struct complex_number)*(p_signal->size) + sizeof(p_signal->size));

	struct signal*  p_out_put_signal =  	(struct signal*)malloc(sizeof(struct complex_number)*(p_signal->size) + sizeof(p_signal->size));

	*p_input_signal   = *p_signal;
	*p_out_put_signal = *p_signal;

	int tmp   = 0;
	int index = 0;
	int bits  = 0;

	int layyer= 0;
	int selected_point = 0;
	int pre_half	   = 0;	

	int    r  = 0;
	double x  = 0;
	struct complex_number W_rN ;
	struct complex_number complex_tmp ;

	/*
	**	We caculate how many bits should be used to
	** represent the size of the number of input signal.
	*/
	for(tmp = p_signal->size-1;tmp > 0;tmp>>=1)
	{
		bits++;
	}

	/*
	**	We should re-sequence the input signal
	** by bit-reverse.
	*/
	for(tmp = 0;tmp < p_signal->size;tmp++)
	{
		index = reverse_bits(tmp,bits);
		p_input_signal->points[tmp] = p_signal->points[index];
#ifdef DEBUG
		printf(" tmp:%5d index:%5d  ",tmp,index);
		show_complex_number(&p_signal->points[index]);
#endif
	}

	for(layyer = 1;layyer <= bits;layyer++)
	{

		#ifdef DEBUG
			printf("layyer %d input\n",layyer);
			show_signal(p_input_signal);
		#endif

		for(selected_point = 0;selected_point < p_signal->size;selected_point += 1<<(layyer))
		{
			for(pre_half = selected_point,r = 0,x = 0;
			    pre_half < (selected_point + (1<<(layyer-1)));
			    pre_half++)
			{
				r = get_r_in_Wn(pre_half,layyer,bits);

				#ifdef DEBUG
					printf("r: %d\n",r);
				#endif

				x = -2*PI*r/((double)(p_input_signal->size));
				W_rN.real    = cos(x);
				W_rN.imagine = sin(x);

				complex_tmp = complex_mul(&W_rN , &(p_input_signal->points[pre_half + (1<<(layyer-1))])  );

				#ifdef DEBUG
					show_complex_number(&complex_tmp);
				#endif

				p_out_put_signal->points[pre_half] = 				complex_add(&p_input_signal->points[pre_half],&complex_tmp);

				p_out_put_signal->points[pre_half + (1<<(layyer-1))] = 				complex_sub(&p_input_signal->points[pre_half],&complex_tmp);

			}

		}

		#ifdef DEBUG
			printf("layyer%d output\n",layyer);
			show_signal(p_out_put_signal);
		#endif

		for(tmp = 0;tmp < p_out_put_signal->size;tmp++)
		{
			p_input_signal->points[tmp] = p_out_put_signal->points[tmp];
		}

	}

	free(p_input_signal);
	return p_out_put_signal;
}
时间: 2024-08-10 14:54:29

FFT 的C 语言实现的相关文章

FFT 的C 语言

FFT 的C 语言 说好的C 语言实现.必须搞定它! 理论介绍: http://blog.csdn.net/cinmyheart/article/details/39052739 这里有之前matlab & Octave 的实现 http://blog.csdn.net/cinmyheart/article/details/39042623 先介绍一下整体的实现文件 最基本的是fft.c这个文件是算法实现的核心 fft.h /***********************************

FFT算法的完整DSP实现(转)

源:FFT算法的完整DSP实现 傅里叶变换或者FFT的理论参考: [1] http://www.dspguide.com/ch12/2.htm The Scientist and Engineer's Guide to Digital Signal Processing,   By Steven W. Smith, Ph.D. [2] http://blog.csdn.net/v_JULY_v/article/details/6196862,可当作[1]的中文参考 [3] 任意一本数字信号处理教

用于ARM上的FFT与IFFT源代码-C语言

/********************************************************************************* 程序名称:快速傅里叶变换(FFT) ** 程序描述:本程序实现快速傅里叶变换 ** 程序作者:宋元瑞 ** 最后修改:2011年4月5日 *******************************************************************************/#include <stdio.h>

二维FFT,IFFT,c语言实现

学习DIP第6天 网上关于FFT的实例有很多,具体也可以参照上一篇,其实Matlab,OpenCV都可以很轻松的实现相关操作,但是对于学习其原理,还是自己操作下比较好. 二维FFT的是实现方法是先对行做FFT将结果放回该行,然后再对列做FFT结果放在该列,计算完所有的列以后,结果就是响应的二维FFT. 本次所有操作都是对基2的数据进行的操作. 二维IFFT网上很少见到,操作过程是:上述的傅里叶变换结果,先对每行做一维IFFT,结果放在该行,对偶数列取其共轭,然后再按照每列做一维IFFT,其结果放

数字信号处理C语言(3) ------FFT

快速傅里叶变换 fft.c #include"math.h" void fft(double *x,double *y,int n,int sign) { int i,j,k,l,m,n1,n2; double c,c1,e,s,s1,t,tr,ti; for(j=1,i=1;i<16;i++) { m=i; j=2*j; if(j==n)break; } n1=n-1; for(j=0,i=0;i<n1;i++) { if(i<j) { tr=x[j]; ti=y[

学习DIP第5天--FFT算法与c语言的实现

为什么需要FFT        第一个问题是为什么要创造FFT,简单的说,为了速度.我们承认DFT很有用,但是我们发现他的速度不是很快,1D的DFT原始算法的时间复杂度是O(n^2),这个可以通过公式观察出来,对于2D的DFT其时间复杂度是O(n^4),这个速度真的很难接受,也就是说,你计算一幅1024x768的图像时,你将等大概...大概...我也没试过,反正很久.不信的自己去试试.所以找到一种快速方法的方法计算FFT势在必行. 以下为DFT公式 计算一个4点DFT.计算量如下: 如何得到FF

Python语言学习笔记

获得人生中的成功需要的专注与坚持不懈多过天才与机会.  ——C.W. Wendte Python将很快成为你最喜欢的编程语言! Qt库?  PyQt  Perl-Qt 简单易学,功能强大,高效率的高层数据结构,简单而有效地实现面向对象编程. Python简洁的语法和对动态输入的支持,再加上解释性语言的本质,使得它在大多数平台上的许多领域都是一个理想的脚本语言,特别适用于快速的应用程序开发. 注重的是如何解决问题而不是编程语言的语法和结构. wxPython,Twisted,Boa Constru

MFCC特征提取(C语言版本)

音频分析中,MFCC参数是经典参数之一.之前对于它的计算流程和原理,大体上是比较清楚的,所以仿真的时候,都是直接调用matlab的voicebox工具或者开发的时候直接调用第三方库.最近想整理一个纯C语言版本的MFCC函数,发现第三方开源的一部分是C++的,有些纯C的开源代码是针对语音固定了某些参数,不太灵活.干脆自己动手写一下,发现matlab写习惯了,都弱化了写C的思维,磕磕碰碰弄了2天,初版总算是完成了. 计算的大体流程:预加重->分帧->加窗->FFT->能量->Me

C 语言资源大全中文版

C 语言资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-c 是 koz.ross 发起维护的 C 语言资源列表,内容包括了:构建系统.编译器.数据库.加密.初中高的教程/指南.书籍.库等等. Awesome 系列虽然挺全,但基本只对收录的资源做了极为简要的介绍,如果有更详细的中文介绍,对相应开发者的帮助会更大.这也是我们发起这个开源项目的初衷. 我们要做什么? 基于 awesome-c 列表,我们将对其中的各个资源项进行