Menu Close

SDR系列 傅里叶变换软件库FFTW的使用

前面我们介绍了傅里叶变换,复平面,IQ信号的意义,现在我们来进行傅里叶变换的实际软件实现。

运行环境:Windows,Linux

程序名称:FFTW

运行语言:C

FFTW软件库介绍:

FFTW ( the Faster Fourier Transform in the West) 是一个快速计算离散傅里叶变换的标准C语言程序集,其由麻省理工大学的M.Frigo 博士和S. Johnson 博士开发的一个完全免费的软件包。FFTW 最初的 release 版本于 1997 年发布,最新的 release 版本 fftw-3.3.9。

FFTW软件库特点:

1.可计算一维或多维实和复数据以及任意规模的DFT。

2.FFTW 还包含对共享和分布式存储系统的并行变换,它可自动适应你的机器, 缓存,存储器大小,寄存器个数。

3.正如它的名字声称的,号称是最快的FFT软件包。

Windows下软件的安装:

在Windows下的安装:

第一步:下载最新的fftw库

这一步很简单,只要在google里搜索fftw,很容易就可以定位到fftw的官网。为了方便,贴出fftw的Windows版本的下载页面:

http://www.fftw.org/install/windows.html

根据自己的系统选择32位或者64位的系统。

第二步:解压+生成lib

1、解压很简单,搞一个解压软件解压就行了。

2、启动CMD,切换到解压后的fftw目录下。

3、比如如果使用Visual Studio 2008,在CMD下执行如下命令:

执行下面的命令:

lib /machine:ix86 /def:libfftw3-3.def

lib /machine:ix86 /def:libfftw3f-3.def

lib /machine:ix86 /def:libfftw3l-3.def

4. 在 VC 中指定 libfftw3l-3.lib, libfftw3f-3.lib, libfftw3-3.li這3個lib文件及 fftw3.h 文件所在的目录。也就是在vc++的tools->options的 Directories选项中的Include Files和Library Files中把这两个目录加上,使得以后VC编译的时候知道该到哪个目录中去找。

Linux下FFTW中的安装:

APT安装:sudo apt-get install libgfftw3-dev pkg-config

压缩包安装:

FFTW官网www.fftw.org上可以下载软件包fftw-3.3.9.tar.gz

解压tar -xzvf fftw-3.3.9.tar.gz

1 ./configure

2 make
3 make install

以编译float版本为例:

./configure –prefix=/home/tuzb/fftw –enable-shared –enable-float –disable-fortran

make

make install

  1. FFTW有三个版本的数据类型float , double , long double。
    2.都使用同样的头文件fftw3.h
    3.所有以小写fftw_开头的函数替换为fftwf_或者fftwl_
    4.函数参数中double替换成float或者long double

FFTW函数的使用步骤如下:

  1. 使用fftw_malloc分配需要进行fft变换使用的输入输出输出,可以是实数,复数多种形式。
  2. 选择fft进行变换的计划,用来包含所有fft所需要的数据,当使用FFTW_MEASURE方式创建执行计划时,需要先将计划执行一遍,测算出该转换规模在当前硬件环境下的最优的转换方式,这个步骤可能会花费大约好几秒,之后的执行就比较快速。
  3. 利用先前生成的plan作为参数,调用fftw_execute进行傅里叶变换,需要多次执行时,可以用同样的plan调用多次fftw_execute进行傅里叶变换。
  4. 完成变换后释放内存,使用fftw_destroy_plan,fftw_free进行内存释放。

FFTW代码示范:

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <fftw3.h> //FFTW的头文件

#define PI 3.1415926 //定义π

int do_fft_example()

{

int n_samples = 8; //FFT的数据样本

double *in = NULL; //定义输入信号

fftw_complex *out = NULL; //定义输出信号

fftw_plan p; //FFTW的计划

in = (double *)fftw_malloc(sizeof(double) * n_samples);

out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * n_samples); // fftw_malloc是内存分配程序

double fs = 1.0 / n_samples; //定义采样率

int freq1 = 1; //信号频率1

int freq2 = 2; //信号频率2

// 输入纯实数

printf(“time waveform:”);

for (int i = 0; i < n_samples; i++)

{

in = sin(2*PI*freq1*fs*i) + sin(2*PI*freq2*fs*i);

//sin(wt)和sin(2wt)的波形合成

printf(“%.2f “, in); //打印输出波形,离散时域

}

printf(“\n\n”);

// 傅里叶变换

p = fftw_plan_dft_r2c_1d(n_samples, in, out, FFTW_ESTIMATE);

fftw_execute(p);

//FFTW_ESTIMATE是FFTW的自适应算法plan

// 输出幅度谱

for (int i = 0; i < n_samples; i++)

{

float amplitude = sqrt(out[0]*out[0] + out[1]*out[1]);

printf(“freq amplitude: %.2f, I :%.2f, Q:%.2f,\n”, amplitude,out[0],out[1]);

//以fs为分辨率,n_samples*fs为FFT采样带宽的显示

}

printf(“\n”);

// 释放资源

fftw_destroy_plan(p);

fftw_free(in);

fftw_free(out);

return 0;

}

时域打印信息为两个正弦波离散时域波形:(频率为1和2)

%title插图%num

经过FFT后频域的Fs为分辨率的频率幅度:(频率为1和2)

%title插图%num

我们从以前介绍的IQ信号和复平面的知识知道,经过FFT转到复平面,Sin(2*Pi*f*t)为Q信号,如果是cos(2*Pi*f*t)则会再复平面I信号上映射。

本文重点在以最简单的实例,介绍FFTW的安装和应用,具体FFTW的应用和不同的配置会逐步丰富和更新。

 

Posted in SDR 软件无线电

发表评论

相关链接