FFT-based Spectrum Meter
Posted: Mon Jun 24, 2013 1:35 am
Here is FFT-based Spectrum Meter. It takes one audio stream as input, and plots the frequency content.
Actually there are three different implementations basing on different graphing engines :
- Lines being plotted by the Green component "Graph Lines"
- Dots being plotted by the Green component "GraphDots"
- Bargraph being plotted by the Ruby Graph component, using a Pen.
The most accurate one, sticking to the FFT definition is the one looking like a bargraph, implemented using the Ruby Graph component, using a Pen.
Ruby allows representing first spectral band and the last spectral band like it must, both having half the bandwidth compared to the others.
Observe how many spectral band there are, in function N (the FFT length). There are (N/2)+1 spectral bands. This is compliant with the FFT definition.
Observe the energy displayed by the first spectral band, in presence of DC. It seems to over-estimate DC by 6 dB. Actually, most commercially available FFT graphers are unclear about the first spectral band.
- Some keep the FFT output as is, warning you that the measurement will get corrupt if your signal contains DC. By warning you, they hope that you won't call their field engineer support, complaining about a 10mV DC offset getting over-estimated by 6dB.
- Some apply a radical fix, removing DC from the measured signal, using a high pass filter before the A/D conversion, or using a digital high-pass filter within the A/D conversion, or more simply, hiding the first spectral band.
- Some others apply the -6dB fix, but doing so they need to warn you that albeit any DC offset won't get over-estimated, on random signals the FFT low-end (the first spectral band) will tend to exhibit a kind of -6dB bump.
When there is DC in the signal, the only "honest" window is the Rectangular one. Only the Rectangular window will ensure that the next spectral band, won't be contaminated by the DC, and show AC energy that's actually not there. This reinforces the widespread idea, rule of thumb, that putting a signal containing DC, into a spectrum analyzer, can lead to wrong results. In reality, it depends the windowing function you are using.
On this spectrum meter, there are controls for applying any of the DC fixes described above : keep the FFT results as it (thus overestimate DC by 6dB), remove the DC in digital domain, or apply a -6dB fix on the DC.
Observe the energy displayed by the last spectral band, in presence of a frequency that's very close to Fs/2. Say 22,049 Hz when Fs = 44,100 Hz. The last spectral band will oscillate at a beat frequency, rendering the measurement unstable, quite unreadable.
Actually, most commercially available FFT graphers are unclear about the last spectral band.
Continue observing the way a 22,049 Hz signal gets measured. The surprise is when the cycle is high. The instantaneous reading is 6dB above the level that you would expect. Okay, when considering the pulsating nature of the measurement, one cannot say that there is a steady 6dB overestimation. However, the uncertainty is clear.
On this Spectrum Meter, there is a control for eventually applying a -6dB fix on the last spectral band. If you activate it, you'll face the same paradox we described above (see the discussion about DC), because on random signals the FFT high-end (the last spectral band) will tend to exhibit a kind of -6dB bump.
I'm not saying here that Flowstone delivers wrong result. All I'm saying here, is that Flowstone enables you to realize the inherent pitfalls of any FFT-based analyzer, that most vendors don't want you to know about, and possibly, that some vendor don't know about.
While undertaking the Ruby Bargraph, I feared that the Ruby speed penalty would not enable a decent screen refresh rate. Using this implementation, a 1024 FFT triggered every 200ms tends to saturate my PC. This remains okay for me.
I'll try improving the Spectrum Meter, like the rendering of the X axis labels and the rendering of the vertical lines of the grid, especially when using a log frequency scale.
Any hints welcome,
Steph
Actually there are three different implementations basing on different graphing engines :
- Lines being plotted by the Green component "Graph Lines"
- Dots being plotted by the Green component "GraphDots"
- Bargraph being plotted by the Ruby Graph component, using a Pen.
The most accurate one, sticking to the FFT definition is the one looking like a bargraph, implemented using the Ruby Graph component, using a Pen.
Ruby allows representing first spectral band and the last spectral band like it must, both having half the bandwidth compared to the others.
Observe how many spectral band there are, in function N (the FFT length). There are (N/2)+1 spectral bands. This is compliant with the FFT definition.
Observe the energy displayed by the first spectral band, in presence of DC. It seems to over-estimate DC by 6 dB. Actually, most commercially available FFT graphers are unclear about the first spectral band.
- Some keep the FFT output as is, warning you that the measurement will get corrupt if your signal contains DC. By warning you, they hope that you won't call their field engineer support, complaining about a 10mV DC offset getting over-estimated by 6dB.
- Some apply a radical fix, removing DC from the measured signal, using a high pass filter before the A/D conversion, or using a digital high-pass filter within the A/D conversion, or more simply, hiding the first spectral band.
- Some others apply the -6dB fix, but doing so they need to warn you that albeit any DC offset won't get over-estimated, on random signals the FFT low-end (the first spectral band) will tend to exhibit a kind of -6dB bump.
When there is DC in the signal, the only "honest" window is the Rectangular one. Only the Rectangular window will ensure that the next spectral band, won't be contaminated by the DC, and show AC energy that's actually not there. This reinforces the widespread idea, rule of thumb, that putting a signal containing DC, into a spectrum analyzer, can lead to wrong results. In reality, it depends the windowing function you are using.
On this spectrum meter, there are controls for applying any of the DC fixes described above : keep the FFT results as it (thus overestimate DC by 6dB), remove the DC in digital domain, or apply a -6dB fix on the DC.
Observe the energy displayed by the last spectral band, in presence of a frequency that's very close to Fs/2. Say 22,049 Hz when Fs = 44,100 Hz. The last spectral band will oscillate at a beat frequency, rendering the measurement unstable, quite unreadable.
Actually, most commercially available FFT graphers are unclear about the last spectral band.
Continue observing the way a 22,049 Hz signal gets measured. The surprise is when the cycle is high. The instantaneous reading is 6dB above the level that you would expect. Okay, when considering the pulsating nature of the measurement, one cannot say that there is a steady 6dB overestimation. However, the uncertainty is clear.
On this Spectrum Meter, there is a control for eventually applying a -6dB fix on the last spectral band. If you activate it, you'll face the same paradox we described above (see the discussion about DC), because on random signals the FFT high-end (the last spectral band) will tend to exhibit a kind of -6dB bump.
I'm not saying here that Flowstone delivers wrong result. All I'm saying here, is that Flowstone enables you to realize the inherent pitfalls of any FFT-based analyzer, that most vendors don't want you to know about, and possibly, that some vendor don't know about.
While undertaking the Ruby Bargraph, I feared that the Ruby speed penalty would not enable a decent screen refresh rate. Using this implementation, a 1024 FFT triggered every 200ms tends to saturate my PC. This remains okay for me.
I'll try improving the Spectrum Meter, like the rendering of the X axis labels and the rendering of the vertical lines of the grid, especially when using a log frequency scale.
Any hints welcome,
Steph