袖口设定频率?

时间:2016-04-22 17:35:29

标签: c++ cuda fft cufft

我正在使用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赫兹?

由于

詹姆斯

2 个答案:

答案 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)就没那么大了。