tags:

views:

417

answers:

4
+6  A: 

Assuming oSignal is filled with complex numbers in such a way, that real and imaginary parts alternate, it might help to change

for(int y=0;y< 8191;y++)

to

for(int y=0;y< 8191;y+=2)

Edit: I didn't even notice that you're passing only 1024 samples. You must pass as many time-domain samples as there will be frequency-domain samples, in your case 4096.

Edit: One more thing: you're obviously trying to find the base frequency of something. Unless that something is a computer generated tone or a human whistle (both of which are very pure tones), you might be disappointed by the result. The simple method you posted barely works for flute.

Edit: For voice and guitar you're out of luck. I wrote a program some time ago that displays the frequency domain, try it out, you'll see the problem. There are also sources available, if you're interested.

Final edit: You might want to read the Wikipedia article on pitch detection. Concentrate on time-domain approaches.

avakar
To second what avakar said, detecting the pitch of an audio recording accurately enough for musical purposes (i.e. to within 1/100 of a semi-tone) is essentially impossible with FFT, because the frequency resolution obtained is proportional to the FFT windows size. Auto-correlation is a more appropriate technique for this purpose.
MusiGenesis
A: 

"random frequencies from 0 to about 1050" - doesn't the typical audio signal consist of a combination of frequencies? Since your sample rate is 8192 Hz, your FFT can detect up to 8192/2 = 4096 Hz. I would expect that you'd see a combination of many frequencies, but I wouldn't call them "random".

Why are you surprised? What did I miss?

duffymo
+1  A: 

It seems iSignal[1025]..iSignal[8191] contain random data. You could try to set it to 0. But why do you pass 8192 to fft() if your data length is 1024 (or is it 1025)?

Also, you loose some precision in the integer division. Change it to double pitchF = pitch / (8192.0/1024);

Does your fft function expect real or complex input data? In case it expects complex data, you have to set every other entry of iSignal to 0.

Henrik
A: 

Two things:

  • Are you sure you're using your fft function correctly? You treat the output as if it is a complex array organized [R_1 I_1 R_2 I_2 ...], but you treat the input array as if it is Organized [R_1 R_2 R_3 ... R_1024 I_1 I_2 ...] and as Henrik says then leave the complex parts uninitialized.
  • Your peak detection is extremely primitive, though it should do for simple input (like a single guitar sting). For use with a human voice, you almost certainly want a more sophisticated approach.

Have you tried putting a known simple (i.e. pure sine) signal as input?

dmckee