【发布时间】:2016-04-06 11:45:31
【问题描述】:
我正在尝试使用 FFTW 库计算 53k 双样本的 FFT,并在此基础上猜测信号的基频是多少。样本由 sndfile 库在 wav 输入文件的基础上生成(程序加载到 wav 文件中,生成双数据样本并保存到文本文件中)。每个样本的数量级范围从 -0.0009 到 +0.0009。使用下面介绍的函数计算 FFT 后,我收到 in[0][0] = -2.142。这是检索数据的不正确方法,或者输入文件不正确。我究竟做错了什么?是传递给 FFTW 函数的数据错误,是文件中存储的数据不正确还是我编写的函数不正确? Buffer 是一个包含样本的浮点数组。
static fftw_complex* calculateFourier(float* buffer, const unsigned int bufferLen)
{
unsigned int i;
//const unsigned short windowSize = 1024;
fftw_plan result;
fftw_complex *out, *in;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * bufferLen);
out = (fftw_complex*) fftw_malloc( sizeof(fftw_complex) * bufferLen);
double* doubleBuffer = castToDouble(buffer, bufferLen);
for(i = 0; i < bufferLen; i++)
{
in[i][0] = doubleBuffer[i];
in[i][1] = 0.000000000000;
}
result = fftw_plan_dft_1d(bufferLen, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
//result = fftw_plan_dft_r2c_1d(fileSize, castToDouble(buffer, bufferLen), out, FFTW_MEASURE);
fftw_execute(result);
fftw_destroy_plan(result);
return out;
}
static double* castToDouble(float* buffer, const unsigned int bufferLen)
{
unsigned int i;
double* doubleBuffer = (double*)malloc( sizeof(double) * bufferLen);
for(i = 0; i < bufferLen; i++)
doubleBuffer[i] = (double)buffer[i];
return doubleBuffer;
}
【问题讨论】:
-
castToDouble是做什么的? -
由于 sndfile 库将样本保存为浮点数,而 fftw 需要 double 类型的样本,它只是将每个样本强制转换为 double。
-
fftw 的 fft 未标准化。参见fftw.org/doc/…:如果缓冲区长度为 53000,则 out[0][0](“零频率”)是缓冲区平均值的 53000 倍,即缓冲区所有项的总和。
标签: c fft fftw libsndfile