welcome: please sign in
location: Diff for "FFTFunctions"
Differences between revisions 8 and 9
Revision 8 as of 2012-08-23 20:34:02
Size: 5467
Editor: guest
Comment:
Revision 9 as of 2012-08-23 20:34:17
Size: 5469
Editor: guest
Comment:
Deletions are marked like this. Additions are marked like this.
Line 11: Line 11:

Arduino FFT Library

FFT Functions

There are multiple functions you can call to perform the FFT. The reason they are broken up into these sections, is so you can tailor the FFT to your needs. If you don't neet particular parts, you can eliminate them and save time.

fft_run() - This is the main FFT function call. It takes no variables and returns no variables. It assumes there is a block of data already in SRAM, and that it is already re-ordered. The data is stored in array called fft_input[], which contains 2 16b values per FFT data point - one for real, the other for imaginary. If you are filling the array yourself, place the real values in the even bins, and the imaginary values in the odd bins. For example:

  • fft_input[0] = real1, fft_input[1] = imaginary1. fft_input[2] = real2, fft_input[3] = imaginary2.

Therefore, there are 2 times as many points in the array as there are FFT bins. If you are using only real data (i.e. values sampled from the ADC), then put those values into the even numbered bins, and be sure to write 0 to the odd valued bins.

The final output is kept in fft_input[], with the even bins being the real magnitudes, and the odd bins being the imaginary magnitudes. The bins are in sequence of increasing frequncy. For example:

fft_input[0] & fft_input[1] = bin0 magnitudes (0hz -> Fs/N) fft_input[2] & fft_input[3] = bin1 magnitudes (Fs/N -> 2Fs/N)

You will have to run one of the magnitude functions to get useful data from these bins.

fft_reorder() - this reorders the fft inputs to get them ready for the special way in which the fft algorithm processes data. unless you do this yourself with another piece of code, you have to call this before running fft_run(). it takes no variables and returns no variables. this runs on the array fft_input[], so the data must be first filled into that array before this function is called.

fft_window() - this function multiplies the input data by a window function to help increase the frequency resolution of the fft data. this takes no variables, and returns no variables. this processes the data in fft_input[], so that data must first be placed in that array before it is called. it must be called before fft_reorder() or fft_run().

fft_mag_lin8() - this gives the magnitude of each bin in from the fft. it sums the squares of the imaginary and real, and then takes the square root, rounding the answer to 8b precision (it uses a lookup table, and scales the values to fit the full 8b range. scale factor = 255/(181*256)). this takes no variables, and returns no variables. it operates on fft_input, and returns the data in an array called fft_lin_out8[]. you can then use the data in fft_lin_out8[]. the magnitude is only calculated for the first N/2 bins, as the second half of an fft is identical to the first half for all real inputs. so fft_lin_out8[] has N/2 8b values, with each index equaliing the bin order. for example:

fft_lin_out8[0] = first bin magnitude (0hz -> Fs/N) fft_lin_out8[1] = second bin magnitude (Fs/N -> 2Fs/N)

fft_mag_lin() - this gives the magnitude of each bin in the fft. it sums the squares of the imaginary and real, and then takes the square root. it uses a lookup table to calculate the square root, so it has limited precision. you can think of it as 8b of value times 4b of exponent. so it covers the full 16b range, but only has 8b of precision at any point in that range. the data is taken in on fft_input[] and returned on fft_lin_out[]. the values are in sequential order, and there are only N/2 values total, as the fft of a real signal is symetric about the center frequency.

fft_mag_log() - this gives the magnitude of each bin in the fft. it sums the squares of the imaginary and real, and then takes the square root, and then takes the log base 2 of that value. so the output is compressed in a logrithmic fashion, and is essentially in decibels (times a scaling factor). it takes no variables, and returns no variables. it uses a lookup table to calculate the log of the square root, and scales the output over the full 8b range {the equation is 16*(log2((img2 + real2)^0.5))}. it is only an 8b value, and the values are taken from fft_input[], and returned at fft_log_out[]. the output values are in sequential order of fft frequency bins, and there are only N/2 total bins, as the second half of the fft result is redundant for real inputs.

fft_mag_octave() - this outputs the RMS value of the bins in an octave (doubling of frequencies) format. this is more useful in some ways, as it is closer to how humans percieve sound. it doesnt take any variables, and doesnt return any variables. the input is taken from fft_output[] and returned on fft_oct_out[]. the data is represented in and 8b value of 16*log2(sqrt(mag)). there are LOG_N bins. and they are given as follows:

FFT_N = 256 :: bins = [0, 1, 2:4, 5:8, 9:16, 17:32, 3:64, 65:128] FFT_N = 128 :: bins = [0, 1, 2:4, 5:8, 9:16, 17:32, 3:64]

where (5:8) is a summation of all bins, 5 through 8. the data for each bin is squared, imaginary and real parts, and then added with all the squared magnitudes for the range. it is then divided down by the numbe of bins (which can be turned off - see #defines below), and then the square root is taken, and then the log is taken.

FFTFunctions (last edited 2012-08-23 21:02:09 by guest)