Go Down

Topic: FFT Library (Read 42295 times)previous topic - next topic

Feb 10, 2015, 03:25 pmLast Edit: Feb 10, 2015, 03:30 pm by Shadorc
Hello!

For a school project, we are looking for an Arduino FFT library able to give the fundamental frequency of a single music notes (no chord).

I tried with this fix_fft . The problem is that it doesn't give a constant specific result, for example a constant frequency of 82.41 Hz (which corresponds to a E1, the low string of a guitar) the library returned a fundamental which varies between the 1, 2 and 3 place in the array (data[]).

I also found a library, which seems more official. The problem is that I didn't understand how it's work.

If you have a library or a means, using the two mentioned ones above, to obtain a single output value, it would help us a lot.

Ps991

#1
Feb 10, 2015, 10:13 pmLast Edit: Feb 10, 2015, 10:14 pm by Ps991
Unfortunately there is no "single output value". There is simply how accurate your microphone is picking up the frequency and how fast your arduino is sampling it.

I used that 2nd library you found (except I used the FFT version, which is pretty much the same)
The way it works is this. If you sample at 10,000 hz, then you can map frequencies 0-5,000 hz. Depending on your FFT_N size, you can get more and more accurate readings. Example: If you sample at 10Khz, you can map 0-5Khz, if your FFT_N size is 256, then the first 128 (maybe 127) bins contain useful information. This means that you have 128 bins to represent 5000hz. Thus you can calculte that each bin represents (5000 / 128) = 39hz.

So the problem with your 82.41hz is that it is so low that it is hard to pin down which bin it belongs to.

If you really needed to detect 1 specific frequency, then you may consider using an online calculator to calculate capacitor values for a low-pass and a high-pass filter. These filters will block out higher/lower frequencies.

http://forum.arduino.cc/index.php?topic=292834.msg2046136#msg2046136
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

tmd3

#2
Feb 11, 2015, 02:37 am
Does your assignment require you to use the Fourier transform to determine the frequency, or can you use other techniques?

What's the sound source?  Is it a sine input, or the signal from a musical instrument?

Ps991

#3
Feb 11, 2015, 07:25 am
The method I proposed was using the FFT, however there are other techniques to detecting frequencies, each with their own pros and cons. My program used a standard electret microphone and an op-amp and performed the FFT on each 128 samples, but yes, it was basically a sine wave, it was sound.
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

tmd3

#4
Feb 12, 2015, 02:51 pm

Do you have to use the Fourier transform to estimate frequency, or do you have some latitude in selecting your method?  I'm concerned about Fourier, because I've never seen a post where anyone claimed that it worked well as a method frequency estimation.  I've seen a lot that echoed your concerns - it gave inconsistent results.  Another method - maybe autocorrelation - might be better in your application.

You mention getting inconsistent results for an input frequency of 82.4 Hz, and you mention a guitar string.  That makes me wonder what the input source will be.  Is it a pure sine input, like from a signal generator, or is the source a musical instrument, or a recording of one?  A sine signal will be easier to analyze.  A musical instrument will normally have considerable harmonic content, and low-order harmonics will often have a higher magnitude than the fundamental - sometimes a lot higher.  If you use the Fourier transform, you may have to look for the lowest-frequency peak with significant content, rather than the highest peak.  And, you'll likely have to empirically determine what "significant" means.  I think that it may vary for different instruments.  This notion is strictly conceptual, and speculative at that; I've never tried it.

jremington

#5
Feb 12, 2015, 06:08 pm
Autocorrelation analysis can work better than Fourier methods to determine the fundamental frequency of a musical note, and was discussed in this thread. http://forum.arduino.cc/index.php?topic=195085.0

tmd3

#6
Feb 13, 2015, 04:36 am
Autocorrelation analysis can work better than Fourier methods ...
Indeed.  I'd recommend reviewing the sketch at the referenced link carefully.  It looks to me that it returns a value that's one larger than the advertised value.  And, I'm dubious about the value of examining lag values larger than half the number of samples.

jremington

#7
Feb 13, 2015, 04:57 amLast Edit: Feb 13, 2015, 04:58 am by jremington
Quote
And, I'm dubious about the value of examining lag values larger than half the number of samples.
Agreed. In addition to abusing the procedure, the original sketch was not normalized correctly for the lag.

#8
Feb 17, 2015, 01:27 pmLast Edit: Feb 17, 2015, 03:30 pm by Shadorc
Does your assignment require you to use the Fourier transform to determine the frequency, or can you use other techniques?

What's the sound source?  Is it a sine input, or the signal from a musical instrument?
No, we don't need to use FFT to determine the frequency, but it's the only one we have heard of, we can use other technique.
The sound source is a musical instrument, a guitar but for the moment we only simulate it with ISIS with a sine input.

Is there any other way to detect a note of music based on a sound?

Thanks for your suggestions, we're gonna study it !

tmd3

#9
Feb 17, 2015, 05:59 pm
Some other techniques are:

The Wikipedia article on pitch detection algorithms lists several ways to estimate pitch.

Is my memory accurate?  Have we ever seen an Arduino implementation of the Fourier transform give usable results in estimating pitch?

KeithRB

#10
Feb 17, 2015, 06:13 pm
I am currently using an FFT and while I know what frequencies I am using, they always show up in the same bins. Of course, I am using 4,000,000 points. 8^)

#11
Mar 08, 2015, 10:49 amLast Edit: Mar 08, 2015, 10:53 am by Shadorc
KeithRB: Do you use the fix_fft library ? And if so, how do you do to increase the number of points ?

And for the fix_fft library, what is the utility of the second array (for imaginary numbers) ?

KeithRB

#12
Mar 09, 2015, 03:56 pm
No, I am using a PC and MatLab.

The arduino's memory won't allow for 4,000,000 points! Note the smiley in my post.

#13
Mar 10, 2015, 02:11 pm
So it is not possible to increase the number of points with fix_fft library ? Can't it be possible to be more specific than that ?
And I wanted to know, I understood how the library worked but the second argument, the array of imaginary numbers, what it is ?

Thanks

KeithRB

#14
Mar 10, 2015, 02:33 pm
You can have as many points as your RAM allows, which aren't many.

The imaginary array contains the imaginary part of your signal, which in your case is 0. In my case I was using a 1 bit ADC with quadrature output so I used the quadrature data from the ADC for the imaginary data.

Go Up