0

I am using CUDA's Cufft to process data i receive from a hydrophone(500,000 integers a second at 250hertz, high and low channels). Now as a basic example of how Cufft works is here...

 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();
}

Now all I want to know is, how do i set the frequency of the FFT (cufft) to be 250hertz?

Thanks

James

4

2 に答える 2

2

You don't. The FFT of N points is the same, regardless of the frequency at which those N points were sampled.

Also, 500.000 integers per second is 500.000 hz sample rate, aka 500 kHz. That gives you a Nyquist limit of 250 khz.

于 2016-04-22T17:38:03.710 に答える
2

私の理解が正しければ、出力ベクトルのどの要素が 250Hz であるかを知る必要があります。

FFT は、時間ベクトルの長さと時間分解能に基づいて計算することが正当化されるすべての周波数を提供します。計算するための簡単なルールは次のとおりです。 - 周波数範囲 = 1/時間分解能。- 周波数分解能 = 1/時間の長さ。

さらに、実関数の FFT (時間ベクトルのデータの虚数部分ではない) は、冗長性を備えた対称スペクトルを生成することを知っておく必要があります。スペクトルは (-1/2 周波数範囲から +1/2 周波数範囲) に達します。リアルタイム ベクトルの場合、負の周波数データは破棄できます。ただし、もう少し複雑です。FFT の標準実装 (インプレース操作) では、最初に正の周波数が得られ、次に負の周波数が得られます。正の周波数のみに関心があるため、FFT ベクトルの後半は破棄できます。あなたの場合、インデックス 250k を超えるデータは無視してください。

あなたの場合、周波数は1Hzの分解能で-250kHzから250kHzに及びますが、上記のため、最初の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 に答える