Noise and FFT condundrum

This is meant as a fun little condundrum about measuring noise from FFT style plots - some of you will know this stuff, others might be surprized.

I'm using a notional 44.1kHz sample rate and 256-point FFTs.

Imagine a signal with a -60dBV sine wave (that's 1mV rms just to be clear) added to white noise of 1µV/√Hz voltage noise density (-120dBV). Here's a plot, the tone itself is 4kHz:

noisy_signal.png



The amplitude of the tone is 1.414mV as you'd expect from 1mV rms, and the noise is about 0.15mV rms over the 22kHz bandwidth of the sampled signal. [ √(22050) * 1µV ~= 0.15mV ]

Seems straight forward, 1mV rms of signal tone and about 0.15mV rms of noise.

So we take its spectrum using a 256-point FFT and Hann window, and display in dBV:

example_spectrum.png


The 4kHz tone peak is at -60dBV as expected. However the noise floor is around -95dBV.

But 0.15mV rms is about -76dBV.

And our noise-floor was supposed to be -120dBV anyway.

Neither of those correspond to the -95dBV we see in the plot. What's going on?
 
First point is that the amount of noise depends on the bandwidth of the measurement, whereas the amount of signal doesn't (so long as its somewhere in the passband).

And secondly an FFT is really a series of measurements each with a bandwidth equal to fs/N where fs is the sampling frequency and N is the number of points in the FFT.

Changing the sampling frequency or changing the number of points of the FFT both affect the apparent noise level in an FFT spectrum (and so does the choice of FFT window). The difference in dB between signal peaks and noise floor is not just a property of the circuit being measured.


For instance here are some plots of that same signal (averaged to reduce variation in the noise floor), with 256, 1024 and 8192 point FFTs. In each case the raw data is identical.
spect_256.png

spect_1024.png

spect_8192.png

They are plotted with two scales, the left one for signal level, the right hand one for noise density, aka power spectral density (well amplitude-squared rather than power to be precise).

When measuring noise you normally want to talk about power spectral density, as this is a property of the system being measured, be it an amplifier or whatever.

If you take an FFT without recording the sample-rate and number of points and window function, you cannot subsequently determine the absolute noise level even if you know the absolute signal levels.

Another subtlety is that very low signal peaks can be buried in the noise in one measurement, but clearly discernable in another - increasing the number of FFT points, or decreasing the sampling rate, or both will lower the apparent noise floor in a spectrum to reveal buried peaks.


If you reduce the sampling rate its required that the pre-digitization anti-aliasing filter scales to match otherwise aliased noise won't be removed. However these days its not hard to increase the FFT size to 10^6 or more which can reveal more detail.


Many simple audio analysis packages don't present spectral densities, high-end equipment may give a choice of spectrum or spectral density, but I quite like the presentation of both using dual axes as in the graphs above. I'll post the Python code for this if anyone's interested.
 

NickKUK

Member
2019-12-28 9:16 pm
Do you have Matlab/octave models?

First point is that the amount of noise depends on the bandwidth of the measurement, whereas the amount of signal doesn't (so long as its somewhere in the passband).

Noise in the signal vs noise in the sampling. The sine wave is infinite detail, adding noise at that scale (ie adding noise to the sine generation function) vs adding noise to the measurement sampling?

For single tones you can ignore the point - for music and multiple tones, then adding noise to the tone/music frequencies vs adding noise to the sample is different. Adding noise to a sample is essentially adding probabilistic noise to all the frequencies with magnitude >0 during that sample period.

And secondly an FFT is really a series of measurements each with a bandwidth equal to fs/N where fs is the sampling frequency and N is the number of points in the FFT.

Yup Discrete FT (DFT) rather than grouping everything as FFT.


One last point. most of this is ADC - thus if you have a full song FFT then you can identify all the frequencies in the Digital recording and reject those that are out of a 5-25Khz range as noise reduction via analysing the bytes.

I've not seen a DAC run a corrective ADC feedback loop for example.
 
Last edited:
I use Python, mainly numpy, scipy.signal, matplotlib.

I am not sure what you are trying to say about the point I am making re noise v. signal in FFT plot used for measurements.

One last point. most of this is ADC - thus if you have a full song FFT then you can identify all the frequencies in the Digital recording and reject those that are out of a 5-25Khz range as noise reduction via analysing the bytes.
Not sure that makes any sense - why would you take an FFT of a whole piece of music other than to collect statistics on power/frequency distribution?

Why would you need to reject any out-of-band stuff - you're already taking the spectrum, you can see the whole picture and ignore out-of-band easily.
 

NickKUK

Member
2019-12-28 9:16 pm
I use Python, mainly numpy, scipy.signal, matplotlib.

I am not sure what you are trying to say about the point I am making re noise v. signal in FFT plot used for measurements.

Not sure that makes any sense - why would you take an FFT of a whole piece of music other than to collect statistics on power/frequency distribution?

Why would you need to reject any out-of-band stuff - you're already taking the spectrum, you can see the whole picture and ignore out-of-band easily.

Just thoughts and too often I extrapolate the answer without leading people to it - I should have a play then I might understand it a bit better.

The reason I mentioned octave (has the same libraries basically) is that I found vectorisation easier with octave vs lots of for loops in python.
 

NickKUK

Member
2019-12-28 9:16 pm
Do you know Python's numpy library and numpy arrays? It may be just what you need for avoiding many for loops.

Hehe more the python.. the two are sort of like COBOL compared to FORTRAN..

I have memories of the biz-science grads hammering spacebars (cobol loops) and we had the luxury if fortran77 and fortran90 as part of numerical computation classes.
 
Noise itself is quite tricky thing. Besides the peak and RMS levels and FFT's ENBW, it has noise density function, as well as bandwidth (when you take rand(), it has frequencies above Fs/2 and they fold into baseband).
I prefer using natural noise sources over synthesized as they are... real :)
 

NickKUK

Member
2019-12-28 9:16 pm
Noise itself is quite tricky thing. Besides the peak and RMS levels and FFT's ENBW, it has noise density function, as well as bandwidth (when you take rand(), it has frequencies above Fs/2 and they fold into baseband).
I prefer using natural noise sources over synthesized as they are... real :)

I drove a global bank’s first use if quantum computing - the beauty is a qubit is naturally random (not an approximation) if you model with a QC they are higher accuracy too - no chance of random number generation algorithmic bias.

You can then use quantum FFT to get a better approximate answer (rather than having 0 or 1).

Also have a little experience with photonic quantum computers for random number generation :)