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

tim
  • 33
  • 3
  • I don't see how this is a programming question.... – talonmies Apr 22 '16 at 17:41
  • 2
    An fft does not have a single frequency. It's vector basis covers the entire range from DC (0 Hz) to Fs/2 (250kHz?). – hotpaw2 Apr 22 '16 at 18:13
  • Your question is indeed misleading, which is reflected in the comments. If I understand it right, you are sampling at 500 kSa/sec and you are interested in the signal strength at frequencies around 250 Hz. – roadrunner66 Apr 23 '16 at 19:09

2 Answers2

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.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Oh... Well I need to know how to then, transform 500,000 integers (audio data essentially) into an FFT at 250Hz? – tim Apr 22 '16 at 17:52
  • 5
    @tim : I suspect somebody asked you to do this. Go ask that person what they really want. You misunderstood, probably – MSalters Apr 22 '16 at 18:23
  • I think the 2nd sentence could be misunderstood. I think the OP wants to know what physical frequencies his data represent, given the parameters of his time vector. – roadrunner66 Apr 23 '16 at 19:05
2

If I understand you right, you just need to know which element in the output vector is 250Hz.

The FFT gives you all the frequencies that are justified to be calculated based on the length and time resolution of your time vector. The simple rule to calculate is : - frequency range = 1/time resolution. - frequency resolution = 1/time length.

In addition one has to know that the FFT of a real function (no data imaginary portion of the time vector) yields a symmetric spectrum with redundancy. The spectrum reaches from (- 1/2 frequency range to +1/2 freq. range). The negative frequency data can be discarded in the case of a real time vector. It's a little more complicated, though. The standard implementation of the FFT (which is an inplace operation) gives you the positive frequencies first , then the negative frequencies. Since you are only interested in the positive frequencies, the 2nd half of the FFT vector can be discarded. In your case, just ignore data above index 250k.

In your case the frequencies span from -250kHz to 250 kHz with a resolution of 1Hz, but because of the above, the first 250k points are actually the positive frequencies, at a separation of 1Hz.

So take the 250th point in the (unshifted, i.e. raw) FFT and you have the signal at 250 Hz. I would plot the data from 0 to around 500 to see how broad that peak is around 250 Hz. The signal strength is the integral of those non-zero frequencies (non-zero applied loosely here to indicate everything above noise). The signal width indicates the modulation that is being applied to the signal (which could include other measurement artifacts). If the signal is shifted from 250 Hz you might have a Doppler shift (either your source or you are moving).

If you are only interested in a finite frequency range, it might be faster to calculate the Fourier integral (O(n^2)) just for those few frequency points. Generally people use the FFT because it is O(n*log(n)), but if you need only say 10 frequency points then O(10*n) is not much different.

roadrunner66
  • 7,772
  • 4
  • 32
  • 38