FFT Help: Music LED Display

Hi all! I've been doing a lot of research lately on FFT to develop what I thought to be a simple project but it seems I keep hitting road blocks. What I'm doing is I'm using an Arduino Uno to light 3 different LED's depending on the beat of the music. Searching the internet I've found tons of similar projects, but their programs seem to do random beats and not actually analyze the frequency. I know of music labs FFT library and the 8-bit library by defi, I just need more understanding on using them.

This is what I want my program to do. Read in an audio source from the A0 port. Analyze this audio using FFT and determine the frequency of the audio. Depending on the frequency light a certain LED. For example if frequency is < 150 light red, if it's between 150 and 300 light blue and if it's greater than 300 light green.

Any and all help would be appreciated! Below are some questions that would really help me out if answered!

Learning FFT, I've picked up on most concepts except for one major thing. What is it exactly that the FFT arrays store? What do the numbers derived from the audio sources mean and what do I have to do to use them for my purpose?

Thanks!

I'm no FFT expert, but I believe that FFT converts normal audio (which is amplitude over time) into frequency over time by storing the amplitudes in an array and then doing some shuffling around to derive the frequency.

Put it this way, an instantaneous sample (one sample) can't possibly give the frequency because frequency is based on time. However it can give the amplitude.

What is it exactly that the FFT arrays store?

It depends what arrays do you mean. Generally, output of the FFT is a complex numbers array, but in some cases it easier to manage two separate arrays - real and imaginary part of the complex.

What do the numbers derived from the audio sources mean and what do I have to do to use them for my purpose?

Click on a link in the signature, it provides a few examples.

From my current understanding I know the FFT creates imaginary and real arrays, my question is what is stored in these arrays both imaginary and real. Viewing the Serial Monitor it looks like integer values. I want to know what these integer values mean and how I can use them to determine the frequency of the sound.

Magician your link is very helpful.

I want to know what these integer values mean and how I can use them to determine the frequency of the sound.

In short, you can get magnitude (voltage, for example), taking square root of sum of squared values, M = sqrt ( A^2 + B^2).
Or you can calculate a phase of the sinewaveforms, that compose an input signal, using acrTan function. For more,
I'd refer to this site: 101 Digital Signal Processing - www.101science.com
Bins specific frequency is determined completely by sampling rate. Sampling at 40 kHz, you may obtain spectral composition up to 20 kHz. The width of each bin depends on FFT - size, simply dividing 20kHz by 128, 256, 1024 etc = 156,25 ; 78,125; 19,53 Hz

Okay so let me re-cap your information real quick. When I apply FFT and get the arrays, I take the two that contain real numbers, run it through a loop to square two values obtained from the same position in the array and add them together to get the magnitude. Once I have the magnitude I divide it by the sampling rate (which in my case is 256) and that will give me my frequency value?

When I apply FFT and get the arrays, I take the two that contain real numbers, run it through a loop to square two values obtained from the same position in the array and add them together to get the magnitude. Once I have the magnitude I divide it by the sampling rate (which in my case is 256) and that will give me my frequency value?

There is a little I can comprehend in your question. First of all, you need to ask yourself what frequency you need to find?
Secondly, what is the bandwidth of the input. For example, you want to get an audio spectrum 20 - 20 000, which means sampling rate has to be 40 000 and up. But, if there is an interference at 22 500, you have two option:
suppress interference using analog (RC, LC, RLC) filter, or increase sampling over 45 000. So at this stage, it's you, who is setting a framework, and FFT is just simple mathematical procedure, that searching in a data pull it's was feed with by you.
Magnitude calculation last stage, here is the example from my earliest project:

 //Performing FFT, getting fx[] array, where each element represents
 //frequency bin with width 65 Hz.

   fix_fftr( fx, log2N );

 // Calculation of the magnitude:
   for (i=0; i<N/2; i++)
   {
     fx[i] = sqrt((long)fx[i] * (long)fx[i] + (long)fx[i+N/2] * (long)fx[i+N/2]);
   }

http://coolarduino.wordpress.com/2011/02/10/color-organ-spectrum-analyzer-on-arduino/

Thank you for all your help so far, I've been reading your color organ code and it's very impressive. Just a couple more questions/clarifications.

When I use FFT and determine the magnitudes I'll get bins that have a certain frequency width right?
I'm using 3 LED's, so I section off the bins into 3 parts to get 3 frequency ranges right?

So how do I determine what frequency range the current sound is in?

Here is an example from the same first project:

   for ( count = 1; count < 11; count++ )
   {
     kraccumn = kraccumn + fx[count]; //Red band, no zero bin, don't use DC component.
   }

   for ( count = 11; count < 21; count++ )
   {
     zlaccumn = zlaccumn + fx[count]; //Green band
   }

   for ( count = 21; count < 32; count++ )
   {
     snaccumn = snaccumn + fx[count]; //Blue band
   }

See, all bins split in 3 groups, about 10 in each. And this from the blog:
http://coolarduino.wordpress.com/2011/02/10/color-organ-spectrum-analyzer-on-arduino/

fx[1] is amplitude in a range 35 <—> 105 Hz;
fx[2] is amplitude in a range 105 <—> 175 Hz;
fx[3] is amplitude in a range 175 <—> 245 Hz;
fx[4] is amplitude in a range 245 <—> 315 Hz;
………………………………………………………..
fx[31] is amplitude in a range 2135 <—> 2170 Hz;

So, band 35 Hz - 700 plus something - red lighting, 700 - 1400 green, and 1400 - 2170 blue. Of course you may change proportion of each group. In advance version of music color bog, I even make band width adjustable via serial monitor,

http://coolarduino.wordpress.com/2012/06/21/tears-of-rainbow/

jerrodcrook:
Thank you for all your help so far, I've been reading your color organ code and it's very impressive. Just a couple more questions/clarifications.

When I use FFT and determine the magnitudes I'll get bins that have a certain frequency width right?
I'm using 3 LED's, so I section off the bins into 3 parts to get 3 frequency ranges right?

So how do I determine what frequency range the current sound is in?

The frequency range that each array element contains, is pre-determined by your choice of number of samples, and the sampling frequency.

You don't get the magnitude to determine the frequency. The frequencies are pre-determined. What you get, is the magnitude of the signal at each frequency.