0

我正在使用 CUDA 的 Cufft 处理从水听器接收的数据(每秒 500,000 个整数,频率为 250 赫兹,高通道和低通道)。现在作为 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 赫兹?

谢谢

詹姆士

4

2 回答 2

2

你没有。N 个点的 FFT 是相同的,无论这 N 个点的采样频率如何。

此外,每秒 500.000 个整数是 500.000 hz 采样率,也就是 500 kHz。这为您提供了 250 khz 的奈奎斯特限制。

于 2016-04-22T17:38:03.710 回答
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) 并没有太大的不同。

于 2016-04-23T19:01:44.113 回答