# I need advice about how to make an audio frequency analyzer

I just need some clarification of some very basic aspects of creating a frequency analyzer. I am writing a c++ program, so far it is just a media player, with a custom explorer. You can make playlists, shuffle, repeat etc.

But my goal is to continue to add functionality. So far, I just have a signal level meter, and I am now trying to add a frequency analyzer.

I am using fftReal. So I am at the stage where I have the output, and I am scaling to dbfs like so which I think is correct, but not exactly sure.

for (int i=0; i < fftsize/2; ++i)
db[i]=20*log(sqrt(imaginary[i]*imaginary[i]+real[i]*real[i]));


So I know I should apply a window function somewhere, and I'm trying to understand how to do that. But I am wondering this as well. If I want to display the data as rectangles popping up and down rather than plotting points and connecting with lines, and I want to limit the amount of rectangles to about 50 or so. Do I take the average db of a range.

I notice that in many applications, the frequency scale is skewed, where the higher frequency, the small distance between units. What kind of scale is used, and how can I break up the spectrum so that I have a nice visual?

I'm sorry if this has all been discussed before, I have been googling for a while now, and overall I am overwhelmed with information, but there are a just a few key thing which I need to understand first.

Thanks

This really depends on how fancy you want to get. A "good" analyzer will typically do the following things.

1. Split the input into frames. The frames typically overlap and are windowed. Good choices are an overlap of 50% and a Hanning window.
2. Do an FFT
3. Select the center frequencies of bands. For audio good choices are octaves or third octaves (see http://www.engineeringtoolbox.com/octave-bands-frequency-limits-d_1602.html)
4. For each integrate the FFT energy around the center frequency. There are different choices for the integration windows. Good choices are trapezoids or butterworth windows. A really good window choice will make sure that all the energy is accounted for, i.e. that the sum of the band energies equals the sum of all FFT bins.

If the number of frequency bands is relatively small, it is more efficient and easier to simply use a bank of parallel bandpass filters and an RMS detector. This also allows to dial in the temporal behavior of the display nicely.

As endolith said, you want to use log-scale bins. The easiest way to do that is to combine multiple bins at the higher frequencies. To do it right you need to add the energy in the different bins, not average them.

Also, you are calculating dB incorrectly. "log" does the natural logarithm. You want "log10". Also, you don't need to do sqrt. You can get rid of the sqrt and change the 20 multiplier to 10.

db[i]=10*log10(imaginary[i]*imaginary[i]+real[i]*real[i]);


EDIT: When adding the energy in the various bins together, add them as linear values, not dB. Once you have finished adding them, then convert to dB.

So I know I should apply a window function somewhere, and I'm trying to understand how to do that.

Multiply the chunk of signal by the window function before doing the FFT. The FFT operates on the signal as if it were wrapping around and repeating forever, so if the beginning and end don't line up (and they almost never do), it produces a discontinuity, which produces big "skirts" on the frequency peaks. The window function tapers the signal off the beginning and end (fades in and out) so that there are no discontinuities.

and I want to limit the amount of rectangles to about 50 or so. Do I take the average db of a range.

Don't take the average of the dB. Probably the maximum bin in the range is what you want.

I notice that in many applications, the frequency scale is skewed, where the higher frequency, the small distance between units. What kind of scale is used, and how can I break up the spectrum so that I have a nice visual?

This is just a logarithmic frequency axis. Since dB is logarithmic, the combination is actually a log-log plot.

Are you going to do a log freq axis and then divide it up into equally-spaced bins? So they'll actually be logarithmically-spaced bins? The FFT bins are linearly-spaced, so each logarithmically-spaced bin would contain different numbers of FFT bins.

• Yes that is what I would like to do. Thanks for the clarification. I'm now researching logarithmically-spaced bins. – MVTC Apr 20 '12 at 0:50