FFT变换的C语言实现
1、安装FFTW3库文件
FFTW是用来计算一维或者多维的离散傅里叶变换,输入可以为实数序列也可以为复数序列的C语言的子函数库,FFTW是免费软件,是作为fft函数库的各种应用的上佳选择,这一开发库为美国麻省理工学院开发,是迄今为止世界上做好用的快速傅里叶变换的开发库,并且完全免费。
可以到下面链接:http://www.fftw.org/install/windows.html下载最新的已编译版本。
这里提供有32和64两个版本的下载链接,同时还有生成lib文件命令。即32位系统命令为: lib /def:libfftw3-3.def,而64位系统为:
lib /machine:x64 /def:libfftw3-3.def
下载适合自己版本解压后,会发现只有dll和头文件,在没有lib文件时,由于应用fftw编程时需要lib文件,所以这里需要使用上面的命令生成lib文件。首先打开VS命令提示工具。本人安装的为VS2015,选择打开vs2015开发人员命令提示(其他版本的也可以)。如下图所示:
打开命令行窗口后,使用cd命令切换到刚才下载文件的目录下,如图
运行lib /def:libfftw3-3.def lib/def:libfftw3f-3.def lib /def:libfftw3l-3.def
将生成的我们需要的库文件libfftw3-3.liblibfftw3f-3.lib libfftw3l-3.lib。
2、FFTW库文件的使用
这里主要是指开发包中动态链接库libfftw3f-3.dll和静态链接库libfftw3f-3.lib
在第一步分别生成了double、float、long double三个版本,实际使用时可根据项目需要,选择相应精度的版本。
double版本: libfftw3-3.dll libfftw3-3.dll
float版本: libfftw3f-3.dll libfftw3f-3.dll
long double版本: libfftw3l-3.dll libfftw3l-3.dll
(一)、动态链接库(libfftw3-3.dll)的调用方法
(1)、直接将动态链接库(libfftw3-3.dll)复制到项目的当前目录即可使用
(2)、将动态链接库(libfftw3-3.dll)复制到系统文件夹下,windows/system32中。
问题一:本人是64位window7,有三个文件夹,windows/system、windows/system32、windows/SysWOW64,当放在system和SysWOW64文件夹下面时,可以正常使用,但当放在system32文件夹(不放在其他文件夹)下面时,会出现缺失此动态链接库(libfftw3-3.dll)的错误。
为此本人搜索了网上的关于这3个系统文件夹的区别,但还是不能解决问题
32位和64位操作系统与System,System32,Syswow64的区别
https://www.ssdax.com/196.html
32位的Windows操作系统可以同时运行32位和16位代码,而64位Windows操作系统可以直接运行64位代码,同时通过使用WoW64(Windows on Windows 64)也能运行32位代码。
32位版本的Windows在如何允许32为和16位代码并肩运行方面有着很复杂的机制,然而64位版本的Windows就不同了,32位代码与64位代码单独运行,有着两个Program Files,有着system32和syswow64两个DLL文件夹,甚至两个注册表。
在32位操作系统的Windows文件夹中,SYSTEM和SYSTEM32两个文件夹,分别用来存放16位和32位的DLL文件。
如果按照这个规律,存放64位系统的DLL文件的文件夹应该叫:System64,但实际上存放64位DLL的文件夹依然叫:System32,同时又多了一个SysWow64文件夹。
现在的软件大多是32位软件,所以默认会将DLL文件放到System32文件夹中,而微软为了保障兼容性,所以无论是32位还是64位的DLL文件都是放到了System32文件夹中。
那SysWoW64文件夹又是干什么用的呢?这是因为32位软件并不能在64位系统中直接运行,所以微软设计了WoW64(Windows-on-Windows 64-bit),通过Wow64.dll、Wow64win.dll、Wow64cpu.dl三个DLL文件进行32位和64位系统的切换来运行32位软件。
所以在64位系统中,DLL复制到System32文件夹中即可
(二)、静态链接库(libfftw3-3.lib)的调用方法
(1)、当直接讲.lib文件复制到项目的当前文件夹时,在程序的中只需要使用#pragma comment(lib,”******”);语句即可
(2)、当不使用#pragma comment(lib,”******”)时,这时候需要做两个事情,第一个是需要将.lib文件拷贝到vc++6.0的安装目录的lib文件下。我这里的是C:\Program Files (x86)\MicrosoftVisual Studio\VC98\Lib第二步需要配置一下vc++6.0的链接环境,以便能够顺利的链接需要的库文件,这里配置vc++6.0:projectàsettingsàlinkàCateGory中选择inputà将.lib文件名加入到Object/library modules中,如图所示
做完这些,既可以开始用FFTW3开始顺利开发了(这里有个提示:操作系统版本虽然是64位的,但是vc++6.0是32位的,所以使用FFTW3时要使用32位的,不然程序在链接时会出现机器类型不匹配的错误)
这里贴出调试过的源代码:参考出处:http://blog.csdn.net/grafx/article/details/38750107?utm_source=tuicool&utm_medium=referral
#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include"include/fftw3.h"
#pragma comment(lib,"libfftw3-3.lib");//加载静态链接库
#define PI 3.1415926
int main()
{
int len=8;
double *in= NULL;
//如果要使用float版本,需先引用float版本的lib库,
//然后在fftw后面加上f后缀即可
fftw_complex*out = NULL;//fftwf_complex -->即为float版本
fftw_planp;
in =(double *)fftw_malloc(sizeof(double)*len);
out =(fftw_complex *)fftw_malloc(sizeof(fftw_complex)*len);
double dx= 1.0/len;
//输入纯实数
for(inti=0; i<len; i++)
{
in[i] =sin(2*PI*dx*i) + sin(4*PI*dx*i);
printf("%.2f ",in[i]);
}
printf("\n\n");
//傅里叶变换
p =fftw_plan_dft_r2c_1d(len,in,out,FFTW_ESTIMATE);
fftw_execute(p);
//输出幅度谱
for(intj=0; j<len; j++)
{
floatlen = sqrt(out[j][0]*out[j][0] + out[j][1]*out[j][1]);
printf("%.2f ",len);
}
printf("\n");
//释放资源
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
system("pause");
return 0;
}
FFTW的使用指南:参考:http://wenku.baidu.com/link?url=vKDRs7cwF4pQq-IjMlxwAsg3YkV-GxH5Ih2wLK7B40HoK7mPboNNmT9yxJ1U1zn8ynbyC6URg6Mgw84w-OC0lWfrELPvW_QgtUR9SiuBglG
1、fftw基本结构