项目目标是将时域下的采集的曲线进行傅里叶变换看频域下的幅度。
学习总结如下:
一、总结Visual Studio生成fftw库文件的步骤如下
① 开始菜单——打开VS2015开发人员命令提示窗口
② 找到lib.exe所在文件夹路径,输入命令cd D:\Microsoft Visual Studio 14.0\VC\bin\amd64转到该路径下
③ 将下载的fftw3压缩包解压,文件夹fftw-3.3.5-dll64中的libfftw3-3.def、libfftw3f3.def、libfftw3l-3.def复制到lib.exe所在的文件夹中
④ /MACHINE:X86:表示机器类型,32位机器;/MACHINE:X64:表示64位机器。
在命令窗口内依次输入以下指令(例如32位如下):
lib /MACHINE:X86 /def:libfftw3-3.def
lib /MACHINE:X86 /def:libfftw3f-3.def
lib /MACHINE:X86 /def:libfftw3l-3.def
⑤ 可见amd64目录下生成了lib库文件和exp文件,将上面生成的文件复制到fftw-3.3.5-dll64文件夹中。
二、Qt添加fftw文件步骤如下
① 将fftw-3.3.5-dll64文件夹复制到项目工程的文件夹下
Qt中在pro文件中添加lib和头文件:
HEADERS += \
fftw-3.3.5-dll32/fftw3.h
LIBS += $$PWD\fftw-3.3.5-dll32\libfftw3-3.lib
② QT运行需将libfftw3-3.dll,libfftw3f-3.dll和libfftw3l-3.dll拷贝到工程的build目录下
代码示例
int N=50*20;//样本数长度 默认时间轴长度20s
int fs=50;//采样率
int calcu_number=1;//计算次数
double ts= 1.0/fs;//采样间隔
void CurveWindow::on_pBtn_loadtest_clicked()
{
//设置时域绘图的线型
pGraph_test->data()->clear();
pGraph_test->setLineStyle(QCPGraph::lsNone);
pGraph_test->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDot,4));
double ymax;
for (int i=0; i<N; i++)
{
double t = ts*i;
double y = 3*sin(2*4*PI*t);//+8*sin(2*9*PI*t)+6*sin(2*20*PI*t)+4*sin(2*15*PI*t);//real
if(y>ymax)
{
ymax=y;
}
pGraph_test->addData(t,y);
qDebug()<<"输入t"<<QString::number(t,'f',3)<<"输入y"<<QString::number(y,'f',3);
}
pGraph_test->setVisible(true);
cPlot0->yAxis->setRange(0,ymax*20, Qt::AlignBottom);
cPlot0->xAxis->setRange(0,N*ts);
cPlot0->replot();
}
void CurveWindow::on_pBtn_fft_I_clicked()
{
//设置fft幅度谱绘图的线型
pGraph_test->setLineStyle(QCPGraph::lsImpulse);
pGraph_test->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc,4));
double *in=NULL;
fftw_complex *out=NULL;
fftw_plan p;
//定义输入、输出与计算方法
in = (double*)fftw_malloc(sizeof(double) * N);//开辟输入空间
out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);//开辟输出空间
p = fftw_plan_dft_r2c_1d(N,in,out,FFTW_ESTIMATE);//初始化计算方法 r2c总为forward
//读取输入数据
for (int i=0; i<N; i++)
{
in[i]=pGraph_test->data().data()->at(i)->value;
qDebug()<<"输入【i】"<<QString::number(in[i],'f',3);
}
pGraph_test->data()->clear();//清空原有曲线数据
double Cmax;
//建立输出
for(int j=0;j<calcu_number;j++)
{
fftw_execute(p);//执行方法
for(int i=0;i<N/2+1;i++)
{
double f_i=(double)fs/N*i;//各频率
double C_abs=sqrt(out[i][0]*out[i][0]+out[i][1]*out[i][1])*2/N;//|Cn|
if(C_abs>Cmax)
{
Cmax=C_abs;
}
pGraph_test->addData(f_i,C_abs);
qDebug()<<"输出fs"<<QString::number(f_i,'f',3)<<"输出c"<<QString::number(C_abs,'f',3);
}
}
//释放
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
pGraph_test->setVisible(true);
cPlot0->yAxis->setRange(Cmax*0.6,Cmax*1.2, Qt::AlignBottom);
cPlot0->xAxis->setRange(0,(double)fs/2);
cPlot0->replot();
}