我正在使用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 (cufft)的频率设置为250赫兹?
谢谢
詹姆斯
发布于 2016-04-23 01:38:04
N个点的FFT是相同的,不管这N个点的采样频率是多少。
此外,每秒500.000个整数是500.000 hz的采样率,也就是500 kHz。这就给了你250千赫的奈奎斯特极限。
发布于 2016-04-24 03:01:44
如果我没理解错的话,你只需要知道输出向量中的哪个元素是250 is。
FFT给出了根据时间矢量的长度和时间分辨率计算的所有频率。要计算的简单规则是:-频率范围=1/时间分辨率。-频率分辨率=1/时间长度。
此外,人们必须知道,实函数(时间向量的无数据虚部)的FFT产生具有冗余的对称谱。频谱范围从- 1/2频率范围到+1/2频率范围。范围)。在实时向量的情况下,可以丢弃负频率数据。不过,这有点复杂。FFT的标准实现(这是一种就地操作)首先给出正频率,然后是负频率。由于您只对正频率感兴趣,因此可以丢弃FFT向量的后半部分。在您的情况下,只需忽略索引250k以上的数据。
在您的例子中,频率范围从- 250 kHz到250 kHz,分辨率为1 kHz,但由于上述原因,前250k点实际上是正频率,间隔为1 kHz。
因此,取(未移位的,即原始的) FFT中的第250个点,你就得到了250 Hz的信号。我会绘制从0到500左右的数据,看看峰值在250 Hz左右有多宽。信号强度是这些非零频率的积分(这里松散地应用非零频率来表示噪声之上的一切)。信号宽度表示应用于信号的调制(可能包括其他测量伪像)。如果信号从250 Hz移位,您可能会有多普勒频移(您的信号源或您正在移动)。
如果您只对有限的频率范围感兴趣,那么只计算这几个频率点的傅立叶积分(O(n^2))可能会更快。通常人们使用FFT是因为它是O(n*log(n)),但如果你只需要10个频点,那么O(10*n)也没有太大区别。
https://stackoverflow.com/questions/36800069
复制相似问题