我正在使用CUDA的Cufft处理从水听器接收的数据(250赫兹,高通道和低通道每秒500,000个整数)。现在作为Cufft如何工作的基本例子就在这里......
void runTest(int argc, char** argv)
{
printf("[1DCUFFT] is starting...\n");
cufftComplex* h_signal = (cufftComplex*)malloc(sizeof(cufftComplex)* SIGNAL_SIZE);
// Allocate host memory for the signal
//Complex* h_signal = (Complex*)malloc(sizeof(Complex) * SIGNAL_SIZE);
// Initalize the memory for the signal
for (unsigned int i = 0; i < SIGNAL_SIZE; ++i) {
h_signal[i].x = rand() / (float)RAND_MAX;
h_signal[i].y = 0;
}
int mem_size = sizeof(cufftComplex)* SIGNAL_SIZE;
// Allocate device memory for signal
cufftComplex* d_signal;
cudaMalloc((void**)&d_signal, mem_size);
// Copy host memory to device
cudaMemcpy(d_signal, h_signal, mem_size,
cudaMemcpyHostToDevice);
// CUFFT plan
cufftHandle plan;
cufftPlan1d(&plan, mem_size, CUFFT_C2C, 1);
// Transform signal
printf("Transforming signal cufftExecC2C\n");
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_FORWARD);
// Transform signal back
printf("Transforming signal back cufftExecC2C\n");
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_INVERSE);
// Copy device memory to host
cufftComplex* h_inverse_signal = (cufftComplex*)malloc(sizeof(cufftComplex)* SIGNAL_SIZE);;
cudaMemcpy(h_inverse_signal, d_signal, mem_size,
cudaMemcpyDeviceToHost);
for (int i = 0; i < SIGNAL_SIZE; i++){
h_inverse_signal[i].x = h_inverse_signal[i].x / (float)SIGNAL_SIZE;
h_inverse_signal[i].y = h_inverse_signal[i].y / (float)SIGNAL_SIZE;
printf("first : %f %f after %f %f \n", h_signal[i].x, h_signal[i].y, h_inverse_signal[i].x, h_inverse_signal[i].y);
}
//Destroy CUFFT context
cufftDestroy(plan);
// cleanup memory
free(h_signal);
free(h_inverse_signal);
cudaFree(d_signal);
cudaDeviceReset();
}
现在我想知道的是,我如何将FFT(袖带)的频率设置为250赫兹?
由于
詹姆斯
答案 0 :(得分:2)
你不是。无论采样这些N点的频率如何,N点的FFT都是相同的。
此外,每秒500.000个整数是500.000赫兹的采样率,即500 kHz。这给你一个250赫兹的奈奎斯特限制。
答案 1 :(得分:2)
如果我理解你的话,你只需要知道输出向量中的哪个元素是250Hz。
FFT根据时间向量的长度和时间分辨率为您提供所有合理计算的频率。 要计算的简单规则是: - 频率范围= 1 /时间分辨率。 - 频率分辨率= 1 /时间长度。
此外,必须知道实函数的FFT(没有时间矢量的数据虚部)产生具有冗余的对称频谱。频谱从( - 1/2频率范围到+1/2频率范围)。在实时矢量的情况下可以丢弃负频率数据。不过,这有点复杂。 FFT的标准实现(这是一种就地操作)首先给出正频率,然后给出负频率。由于您只对正频率感兴趣,因此可以丢弃FFT矢量的后半部分。在您的情况下,只需忽略索引250k以上的数据。
在你的情况下,频率范围从-250kHz到250kHz,分辨率为1Hz,但由于上述原因,前250k点实际上是正频率,相隔1Hz。
因此,取(未移位,即原始)FFT中的第250个点,您将获得250 Hz的信号。我会绘制从0到500左右的数据,以查看该峰值在250 Hz附近的宽度。信号强度是那些非零频率的积分(这里松散地应用非零值以表示噪声之上的所有值)。信号宽度表示正在应用于信号的调制(可能包括其他测量伪像)。如果信号从250 Hz移位,您可能会有多普勒频移(您的信号源或您正在移动)。
如果您只对有限的频率范围感兴趣,那么仅为这几个频率点计算傅里叶积分(O(n ^ 2))可能会更快。通常人们使用FFT是因为它是O(n * log(n)),但是如果你只需要说10个频率点那么O(10 * n)就没那么大了。