permaculture playing cards*
The moose likes Game Development and the fly likes Basic FFT to identify frequency Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Game Development
Bookmark "Basic FFT to identify frequency" Watch "Basic FFT to identify frequency" New topic
Author

Basic FFT to identify frequency

Jose Hidalgo
Greenhorn

Joined: Aug 24, 2013
Posts: 2
For some reason my code seams to work but with the frequencies off.




This is how I cast from byte[2] => double:



And this is the format I use:



What am I doing wrong ?

Richard Tookey
Ranch Hand

Joined: Aug 27, 2012
Posts: 1035
    
  10

Jose Hidalgo wrote:For some reason my code seams to work but with the frequencies off.



Define 'work' and 'off' in this context. Is your frequency a factor of N out always or is it a random value that seems to have nothing to do with the input ?

I do a lot of work with the FFT and before using real data I always create test data with exactly known characteristics and use it to test my code.

Points to note -
1) Your byteToDouble() method aught really to return the number of points placed in the doubleData array since this is the number of points to transform and not necessarily the array length.
2) Using 44100 Hz sampling rate with 1024 samples means you can only resolve to about 43 Hz. Whether or not this matters depends on the frequency you are trying to measure.
3) I suspect you should be using a 'window' . Hamming is normally adequate for this type of application. Google is your friend here.
4) The creation of the 'transformer' only needs to be done once and can be made an instance variable initialized in the constructor of the enclosing class.
5) The zero frequency term is usually of little use and probably should be ignored when scanning for the peak magnitude.
6) I would expect your findFrequency() method to return the estimated frequency.
Jose Hidalgo
Greenhorn

Joined: Aug 24, 2013
Posts: 2
Thanks Richard, you are totally right about the bad parameters I am using.

Richard Tookey wrote:
2) Using 44100 Hz sampling rate with 1024 samples means you can only resolve to about 43 Hz. Whether or not this matters depends on the frequency you are trying to measure.


I think the problem I am having is that the frequency bins I am using are not accurate enough. I am trying to identify what note of a piano has been played, but seems like my code is good identifying it, but since the exact bin is not there it resolves to a harmonic that is closer. I think this because there are some frequencies that it can identify easily while others are always matched with high values ( harmonics )

I changed it to 8000 Hz and 8196 samples which should give a 1:1 resolution, but seems like it didn't help

Is there a way to have more accuracy than what the frequency bins offer ?, because if I am always limited to those bins I can only increase the number of samples I read, but that adds more noise making it worst !

Attached is a test program you can use to change parameters, it reads audio from the microphone. I use my cellphone with a free guitar tuner to check frequencies, and an guitar to generate the sound !

Richard Tookey
Ranch Hand

Joined: Aug 27, 2012
Posts: 1035
    
  10

Jose Hidalgo wrote:Thanks Richard, you are totally right about the bad parameters I am using.

Richard Tookey wrote:
2) Using 44100 Hz sampling rate with 1024 samples means you can only resolve to about 43 Hz. Whether or not this matters depends on the frequency you are trying to measure.


I think the problem I am having is that the frequency bins I am using are not accurate enough. I am trying to identify what note of a piano has been played, but seems like my code is good identifying it, but since the exact bin is not there it resolves to a harmonic that is closer. I think this because there are some frequencies that it can identify easily while others are always matched with high values ( harmonics )

I changed it to 8000 Hz and 8196 samples which should give a 1:1 resolution, but seems like it didn't help

Is there a way to have more accuracy than what the frequency bins offer ?, because if I am always limited to those bins I can only increase the number of samples I read, but that adds more noise making it worst !


The best one can resolve to is 1/sample_period (equivalent to the sample_frequency/number_of_samples) so you must either decrease the sample frequency or increase the number of samples. This resolution constraint is fundamental to the physics of the process. In my music player I sample for about 0.1 second (a resolution of about 10 Hz) and adjust the FFT order as a function of the sample rate (frame rate) to keep the 0.1 second. I use my own mixed radix (2,3 and 5) FFT so don't have the power of 2 limitation you have with the Commons library.

I can't see harmonics being the problem though in the spectral density plot of my music player I do see the harmonics being significant relative to the fundamental. Maybe you should scale the DFT modulus values prior to looking for the maximum; say something along the lines of 1/f or 1/sqrt(f) .

I still think you should apply a Window to reduce the energy collecting side lobes. I have this as an option on my music player and it does make some difference. Unfortunately using a window will reduce the resolution by an amount that is dependent on the Window but typically by about 40%.

One significant effect can be due to very low frequencies which over the sample period can look like a ramp. A way to reduce the effect of these is to remove the best straight line from the samples before performing the DFT.

You can reduce the effect of noise by averaging the spectral density estimates taken over a number of periods. For orchestral music this is not a good ideal but for a single note on a Piano it might be worth looking at.

Finally - instead of taking the frequency of the maximum power spectral density you should maybe take the weighted average over the maximum and the two values either side. A Radar project I was involved in many many years ago used this technique to get a better speed estimate. This gives one a better estimate of frequency in the mean (less systematic bias) but worse in STD.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Basic FFT to identify frequency
 
Similar Threads
How do I handle "The Matrix" ?
byte to String conversion
Recognize dial tone in audio file(FFT)
audio visualization graphics
Writing byte to a particular location in a file header