C++ 袖口设定频率?

C++ 袖口设定频率?,c++,cuda,fft,cufft,C++,Cuda,Fft,Cufft,我正在使用CUDA的Cufft来处理从水听器接收到的数据(每秒50万个整数,在250赫兹的高频和低频信道下)。现在作为Cufft工作原理的一个基本示例 void runTest(int argc, char** argv) { printf("[1DCUFFT] is starting...\n"); cufftComplex* h_signal = (cufftComplex*)malloc(sizeof(cufftComplex)* SIGNAL_SIZE); // All

我正在使用CUDA的Cufft来处理从水听器接收到的数据(每秒50万个整数,在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();
}
void运行测试(int argc,char**argv)
{
printf(“[1dcupt]正在启动…\n”);
cufftComplex*h_信号=(cufftComplex*)malloc(sizeof(cufftComplex)*信号_大小);
//为信号分配主机内存
//复数*h_信号=(复数*)malloc(sizeof(复数)*信号大小);
//初始化信号的存储器
for(无符号整数i=0;i
现在我想知道的是,如何将FFT的频率设置为250赫兹

谢谢


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


此外,每秒500.000个整数是500.000 hz采样率,也称为500 kHz。这给了你250千赫的奈奎斯特极限。

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


此外,每秒500.000个整数是500.000 hz采样率,也称为500 kHz。这会给你一个250 khz的奈奎斯特极限。

如果我理解正确,你只需要知道输出向量中的哪个元素是250 Hz

FFT将根据时间向量的长度和时间分辨率计算所有频率。 计算的简单规则是: -频率范围=1/时间分辨率。 -频率分辨率=1/时间长度

此外,必须知道实函数(时间向量的无数据虚部)的FFT产生具有冗余的对称频谱。频谱范围从(-1/2频率范围到+1/2频率范围)。在实时向量的情况下,可以丢弃负频率数据。不过这有点复杂。FFT的标准实现(这是一种就地操作)首先给出正频率,然后给出负频率。因为您只对正频率感兴趣,所以可以丢弃FFT向量的第二部分。在您的情况下,只需忽略索引250k以上的数据

在您的情况下,频率范围从-250kHz到250kHz,分辨率为1Hz,但由于上述原因,前250k点实际上是正频率,间隔为1Hz

以(未移位,即原始)FFT的第250点为例,信号为250 Hz。我会画出从0到500的数据,看看峰值有多宽,大约250赫兹。信号强度是这些非零频率的积分(此处松散地应用非零表示高于噪声的一切)。信号宽度表示应用于信号的调制(可能包括其他测量伪影)。如果信号从250 Hz偏移,则可能出现多普勒频移(您的震源或正在移动)


如果您只对有限的频率范围感兴趣,那么只计算这几个频率点的傅里叶积分(O(n^2))可能会更快。通常人们使用FFT是因为它是O(n*log(n)),但是如果你只需要说10个频率点,那么O(10*n)就没有太大的不同。

如果我理解正确,你只需要知道输出向量中的哪个元素是250Hz

FFT将根据时间向量的长度和时间分辨率计算所有频率。 计算的简单规则是: -频率范围=1/时间分辨率。 -频率分辨率=1/时间长度

此外,必须知道实函数(时间向量的无数据虚部)的FFT产生具有冗余的对称频谱。频谱范围从(-1/2频率范围到+1/2频率范围)。在实时向量的情况下,可以丢弃负频率数据。不过这有点复杂。FFT的标准实现(这是一种就地操作)首先给出正频率,然后给出负频率。因为您只对正频率感兴趣,所以可以丢弃FFT向量的第二部分。在您的情况下,只需忽略索引250k以上的数据

在您的情况下,频率范围从-250kHz到250kHz,分辨率为1Hz,但由于上述原因,前250k点实际上是正频率,间隔为1Hz

以(未移位,即原始)FFT的第250点为例,信号为250 Hz。我会画出从0到500的数据,看看b