3
$\begingroup$

I’m looking to use an FFT to generate a frequency spectrum in 1/3 octave bands. After reading many posts on this site as well as others, I believe the appropriate approach is set out below. I’ve dry-run the calculations in Excel and the results look reasonable, but reasonable is not necessarily correct.

To ask a specific question, is the method I’m using valid? In particular, I question if the method applied in Step 2 is correct.

Background. I’m sampling the electric signal on the output of a pre-amp and my goal is a frequency spectrum in dB. My reference (denominator in the dB calc) is arbitrary and chosen to set an appropriate scale for the spectrum output display. I’m not attempting to take measurements from the output and don’t need to calibrate it against an objective reference. My project will be implemented in C++.

Step 1. Start with a 1024 sample FFT at 48,000 Hz (513 bins at 46.9 Hz each). Result is the DFT, Fn for n = 0 – 512. Units are in V.

Note, normally, I’d normalize the FFT output by multiplying each bin by 2/N (N is number of samples, i.e. 1024). However, because we eventually plot the spectra in dB relative to an arbitrary amplitude, any normalizing I do here will be washed away when I compute the results in dB so I don’t bother with it in my project.

Step 2. Convert the DFT into 1/3 octave bands.

I obtained the following formulas from here: https://www.ap.com/technical-library/deriving-fractional-octave-spectra-from-the-fft-with-apx/

The amplitude in V for each 1/3 octave band is:

Octave bands

Where Lb is the amplitude for each 1/3 octave band in V, for b = 1 to 32, and gn,b is the gain multiplier for FFT bin n and 1/3 octave band b:

gain multiplier

Where fn is the frequency of bin n and fb is the center frequency of band b. k is the octave bandwidth designator, 1 for full octave and 3 for 1/3 octave.

Result is Lb for b = 1 to 32 in V.

Step 3. Disregard lower bands.

Below about 250 Hz, for an FFT of length 1024, there are not enough FFT bins within each band to make the results meaningful. Therefore, we disregard the lower bands and keep only the 1/3 octave bands starting with b13 = 251 Hz.

Step 4. Convert the amplitude data in each band to dB.

For this computation, I’m computing the dB value relative to the approximate maximum amplitude likely to appear in any frequency band. This will be Lref.

Final value in dB for each 1/3 octave frequency band above 250 Hz is:

LdB

Below is a sample of individual gn,b terms (FFT bins down the left, 1/3 octave bands across the top): gbn terms

Assistance, input, corrections and comments appreciated. Thanks!

$\endgroup$
1
$\begingroup$

It seems like you’ve by and large got it, but I did notice a couple things. You’ll probably want to include support for windowing and the corresponding correction factor as shown by APs article on FFT noise. Rectangular windows aren’t great for RMS type measurements (at least in my opinion) for all the side lobe type explanations that are common with windows. Second, I’m pretty sure you need to sum from 1 to N, not N/2. You may have realized that because the input signal is real, that there is redundant data that doesn’t need to be calculated twice. That is true, with the exception of the 0 and N/2 (if N is even) bins. Granted this probably wouldn’t make the output too wrong, but it would be off a bit.

Edit: you know what, AP may have designed those coefficients so that windowing either isn’t necessary, or would do more harm than good. You may still want to try it, since it’s easy enough to support, but it may not help. Also, I don’t see how this would be more computationally efficient than doing the calculations directly in the time domain.

$\endgroup$
3
  • 2
    $\begingroup$ Thanks, Dan. I appreciate the input. Regarding the window, I agree that windowing is not needed. AP uses a correction factor for the type of window used, and the factor is 1 for no window at all, so the term goes away. Please clarify your comment regarding the sum limits. To clarify, N = 1024, the full length of the FFT. As you note, this results in 513 bins (N/2 + 1) for bins 0 through 512. Bins 512 to 1024 are symmetrical. I discount any DC, so bin 0 is always 0. If I sum 0 to N, I'm going to count the data twice. Is that what you intended? Thanks. $\endgroup$
    – Quercus47
    Nov 9 '20 at 15:47
  • 1
    $\begingroup$ You are correct regarding symmetry, the data is redundant because almost every bin is the conjugate of another bin. You can maths your way to show that you don’t need to do this operation on every bin. The exceptions being bins 0 (strangely referred to as bin N by AP) and N/2. Throw away bin 0 at your own peril. The side lobes caused by windowing the data means it isn’t DC proper, and I’d hazard a guess that it would affect the output at the lower frequencies. $\endgroup$
    – Dan Szabo
    Nov 9 '20 at 17:11
  • 1
    $\begingroup$ Thanks, Dan. I'll look more closely at how bin 0 affects the lower frequencies. I'm going to mark this as answered, thank you. If anyone else has more comments, please let me know. $\endgroup$
    – Quercus47
    Nov 9 '20 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.