2016-04-22 14 views
0

私はハイドロホンから受信したデータを処理するためにCUDAのカフを使用しています(250ヘルツ、ハイとローのチャンネルで毎秒50万の整数)。今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(); 
} 

は今、私が知りたいすべては私が250hertzされるFFT(CUFFT)の周波数を設定するのですか、ですか?

おかげ

ジェームズ

+0

これはプログラミングに関する質問ではありません.... – talonmies

+2

fftには単一の周波数がありません。ベクトルベースは、DC(0Hz)からFs/2(250kHz?)までの全範囲をカバーします。 – hotpaw2

+0

あなたの質問は本当に誤解を招くものであり、コメントに反映されています。私がそれを正しく理解すれば、あなたは500kSa /秒でサンプリングしており、およそ250Hzの周波数での信号強度に興味があります。 – roadrunner66

答えて

2

あなたにはありません。 N点のFFTは、N点がサンプリングされた頻度にかかわらず同じです。

また、毎秒500.000の整数は500,000Hzのサンプルレート、別名500kHzです。それはあなたに250khzのナイキスト限界を与えます。

+0

ああ...そうですね、250,000の整数(本質的にオーディオデータ)を250HzのFFTに変換する方法を知っておく必要がありますか? – tim

+5

@tim:私は誰かがあなたにこれをするように頼んだ疑いがあります。その人に本当に欲しいものを尋ねなさい。あなたは誤解している、おそらく – MSalters

+0

私は2番目の文が誤解される可能性があると思う。私は、彼の時間ベクトルのパラメータを考えると、彼のデータが表す物理周波数をOPが知りたいと思う。 – roadrunner66

1

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

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

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

周波数が-250kHzから250kHz、分解能が1Hzですが、上記のため、最初の250kポイントは実際には1Hzの間隔で正の周波数です。

(シフトされていない生の)FFTの250番目のポイントを取ると、250 Hzの信号が得られます。そのピークが250Hz付近でどのくらい広がっているかを見るために、0から500までのデータをプロットします。信号の強さは、これらの非ゼロ周波数の積分です(ノイズ以外のすべてを示すためにゼロ以外の値をここに緩やかに適用します)。信号幅は、信号に適用されている変調(他の測定アーチファクトを含む可能性があります)を示します。信号が250 Hzからシフトされた場合は、ドップラーシフト(ソースまたは移動中のいずれか)が発生する可能性があります。

有限周波数範囲のみに興味がある場合は、それらの周波数点の数だけフーリエ積分(O(n^2))を計算する方が速い場合があります。一般に人々はO(n * log(n))なのでFFTを使用しますが、10の周波数ポイントしか必要としない場合、O(10 * n)はそれほど違いはありません。