【发布时间】:2014-07-11 10:59:22
【问题描述】:
我正在尝试通过使用 fftw3 库来获取真实数据集的 PSD
为了测试我写了一个如下所示的小程序,它生成一个遵循正弦函数的信号
#include <stdio.h>
#include <math.h>
#define PI 3.14
int main (){
double value= 0.0;
float frequency = 5;
int i = 0 ;
double time = 0.0;
FILE* outputFile = NULL;
outputFile = fopen("sinvalues","wb+");
if(outputFile==NULL){
printf(" couldn't open the file \n");
return -1;
}
for (i = 0; i<=5000;i++){
value = sin(2*PI*frequency*zeit);
fwrite(&value,sizeof(double),1,outputFile);
zeit += (1.0/frequency);
}
fclose(outputFile);
return 0;
}
现在我正在读取上述程序的输出文件并尝试计算其 PSD,如下所示
#include <stdio.h>
#include <fftw3.h>
#include <complex.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14
int main (){
FILE* inp = NULL;
FILE* oup = NULL;
double* value;// = 0.0;
double* result;
double spectr = 0.0 ;
int windowsSize =512;
double power_spectrum = 0.0;
fftw_plan plan;
int index=0,i ,k;
double multiplier =0.0;
inp = fopen("1","rb");
oup = fopen("psd","wb+");
value=(double*)malloc(sizeof(double)*windowsSize);
result = (double*)malloc(sizeof(double)*(windowsSize)); // what is the length that I have to choose here ?
plan =fftw_plan_r2r_1d(windowsSize,value,result,FFTW_R2HC,FFTW_ESTIMATE);
while(!feof(inp)){
index =fread(value,sizeof(double),windowsSize,inp);
// zero padding
if( index != windowsSize){
for(i=index;i<windowsSize;i++){
value[i] = 0.0;
}
}
// windowing Hann
for (i=0; i<windowsSize; i++){
multiplier = 0.5*(1-cos(2*PI*i/(windowsSize-1)));
value[i] *= multiplier;
}
fftw_execute(plan);
for(i = 0;i<(windowsSize/2 +1) ;i++){ //why only tell the half size of the window
power_spectrum = result[i]*result[i] +result[windowsSize/2 +1 -i]*result[windowsSize/2 +1 -i];
printf("%lf \t\t\t %d \n",power_spectrum,i);
fprintf(oup," %lf \n ",power_spectrum);
}
}
fclose(oup);
fclose(inp);
return 0;
}
我不确定我这样做的方式是否正确,但以下是我得到的结果:
任何人都可以帮助我追踪上述方法的错误
提前致谢 *更新 在 hartmut 回答之后,我已经编辑了代码,但仍然得到了相同的结果:
输入数据如下:
更新 在增加采样频率和 2048 的窗口大小之后,我得到了: 更新 在此处使用 ADD-ON 后,使用窗口的结果如何:
【问题讨论】:
-
在第一个程序中,您似乎声明了
time并使用zeit。这不应该编译,除非你的编译器懂德语。 -
不,我只是更改了 SO 的变量名
-
@Engine 您正在以读取模式( rb )打开“sinvalues”并对其进行 fwrite。你不应该在做 fopen 的时候使用“wb”吗?
-
我重写了程序,但我忘了更正我的 sinvalues 是正确的谢谢
-
你“重写”了多少?如发布的那样,它以采样率(如果初始相位为 0,则相同地为 0)生成 sin。我希望
value=sin(2*PI*frequency*time)和time += (1.0/samplingrate)能够获得频率可控的音调。
标签: c signal-processing fftw