【问题标题】:Cufft set frequency?袖带设定频率?
【发布时间】:2016-08-16 10:52:40
【问题描述】:

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

谢谢

詹姆斯

【问题讨论】:

  • 我不明白这是一个编程问题......
  • 一个 fft 没有单一频率。它的矢量基覆盖了从 DC (0 Hz) 到 Fs/2 (250kHz?) 的整个范围。
  • 您的问题确实具有误导性,这在 cmets 中有所体现。如果我理解正确,您正在以 500 kSa/秒的速度进行采样,并且您对 250 Hz 左右频率的信号强度感兴趣。

标签: c++ cuda fft cufft


【解决方案1】:

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

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

【讨论】:

  • 哦...我需要知道如何将 500,000 个整数(本质上是音频数据)转换为 250Hz 的 FFT?
  • @tim :我怀疑有人要求你这样做。去问问那个人他们真正想要什么。你误会了,可能
  • 我认为第二句话可能被误解了。考虑到他的时间向量参数,我认为 OP 想知道他的数据代表什么物理频率。
【解决方案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) 差别不大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多