C 用FFTW计算PSD

C 用FFTW计算PSD,c,signal-processing,fftw,C,Signal Processing,Fftw,我是使用“ALSA”库通过以下设置录制的声音文件: Fs = 96000; // sample frequency channelNumber = 1 ; format =int16 ; length = 5sec; 这意味着我得到480000个16位值。现在我想计算这组的PSD,得到如下结果: 我想做的是将结果保存为一堆额外数据中的双倍值,这样我就可以绘制它们的评估图(我不确定这是否正确): #包括 #包括 #包括 #包括 int main(){ char fileName[]=“so

我是使用“ALSA”库通过以下设置录制的声音文件:

Fs = 96000; // sample frequency 
channelNumber = 1 ;
format =int16 ; 
length = 5sec;
这意味着我得到480000个16位值。现在我想计算这组的PSD,得到如下结果:

我想做的是将结果保存为一堆额外数据中的双倍值,这样我就可以绘制它们的评估图(我不确定这是否正确):

#包括
#包括
#包括
#包括
int main(){
char fileName[]=“sound.raw”;
char magnFile[]=“data.txt”;
文件*inp=NULL;
文件*oup=NULL;
浮点*数据=NULL;
fftwf_复合体*out;
int指数=0;
fftwf_计划;
双var=0;
短wert=0;
浮子r,i,magn;
int N=512;
数据=(浮动*)fftwf_malloc(大小浮动)*N;
out=(fftwf_复合体*)fftwf_malloc(sizeof(fftwf_复合体)*N);
//为输入数据分配内存
plan=fftwf_plan_dft_r2c_1d(N,数据,输出,FFTW_度量);
//打开文件进行读取
inp=fopen(文件名,“r”);
oup=fopen(magnFile,“w+”);
如果(inp==NULL){
printf(“无法打开文件\n”);
返回-1;
}
如果(oup==NULL){
printf(“无法打开输出文件\n”);
}
而(!feof(inp)){
如果(索引对于(index=0;index,这里是一个在FFT之前将a应用于数据的简单示例:

for (int i = 0; i < N; ++i)
{
    data[i] *= 0.5 * (1.0 + cos(2.0 * M_PI * (double)i / (double)(N - 1)));
}
for(int i=0;i
Three points*您的屏幕截图看起来像Windows。在这种情况下,您必须使用“rb”打开文件。在任何情况下都应该这样做,以提高兼容性。*使用已知输入测试您的代码(使用已知频率的正弦函数)*此外,您可能需要获取Magnitute的日志。您的代码应该可以工作(您仅处理前512个样本)。如果在FFT之前应用合适的方法,您将获得更好的结果。关于这个主题,已经有很多关于SO的问题,并且有一些很好的答案,因此您可以只搜索这些问题,而不必再重复相同的内容。在英语中,这被称为“本末倒置”!;-)@引擎尝试增加N。512个样本对应于5毫秒。我建议10毫秒能够捕获较低的频率。如果您怀疑您的代码:加载一个长样本,并将其转换为24kHz的纯正弦波。如果这起作用,您可以继续执行重叠和相加之类的操作。因此,现在我将在频域中获得这512个值的值,我应该只使用第513个元素的窗口,一次又一次地这样做,如何知道新数据中哪个值精确到哪个频率[]vector?回答起来很难!在FFT之前,即在时域中,对每个N个样本块应用窗函数。然后对加窗数据应用FFT,计算输出箱的幅度等。如果您关心幅度数据的绝对值,则可以应用适当的校正r以补偿窗口功能,但对于大多数实际应用而言,这通常不会完成,或作为整体校准常数的一部分包括在内。
for (int i = 0; i < N; ++i)
{
    data[i] *= 0.5 * (1.0 + cos(2.0 * M_PI * (double)i / (double)(N - 1)));
}