Random Quote Board

How to Measure Sinusoids and Noise Spectrally using Gnu Radio

Gary Schafer, 3 January 2026

Happy New Year to you all! I'm going to finish up a few loose ends with respect to my last post discussing issues measuring SNR using a spectral display. For this post, I'm going to explain some of the complexity of measuring sinusoids and noise using the Gnu Radio QT GUI Frequency Sink.

Measuring Power of a Sinusoid

Signals can either be coherent or noncoherent. Sinusoids are coherent. Let's take a look at measuring their power using a spectral display, specifically the "QT GUI Frequency Sink" in Gnu Radio.

There are two problems when measuring the power of a sinusoid in a spectrum. These are:

  1. Scalloping loss: This occurs due to spectral leakage, a problem that only occurs in DFT / FFT displays. You won't find this in analog spectrum analyzers.
  2. Window processing gain: To alleviate the problems of spectral leakage, FFT-based systems use windowing. Windows might alleviate some (or almost all) scalloping loss, but they also reduce the signal energy at the same time.

Let's take a look at an actual display of a sinusoid. I'm using a basic Gnu Radio flowgraph to create a sinusoid and display its spectrum.

Block diagram showing two horizontal rows of blocks. The bottom row has the block in the center connected to each of the blocks on either side by a thin line.
Flowgraph to display a sinusoid's spectrum. The Signal Source passes through a Throttle block and straight into the QT GUI Frequency Sink, which is a spectral display.
Graph showing a thin, vertical line coming up from the bottom of the graph roughly left of center. The line does not reach all the way to the top.
Spectrum of an unmodulated sinewave (tone). The sample rate is 1 MHz, and the signal is a complex sinusoid set to -100 kHz frequency.

Let's talk about power measurements for a moment. For this post, let's assume that all magnitude values are volts (V), and power measurements are watts (W). This particular spectral display shows the power of signals over frequency. Power is the square of the magnitude. Another way to think of it is that the magnitude is the same as the RMS (root-mean-square) value, while power is just the "mean-square" value. If we zoom in on the peak of the sinusoid, we can see that the magnitude of the sinusoid is -1.8054 dBW. (Again, it's only dBW because we're assuming all magnitudes are volts, which means power will be watts.) That power level (-1.8054 dBW) corresponds to a magnitude of roughly 812 mV. The Signal Source amplitude is set to 2.3 V.

Why the discrepancy? As stated earlier, two problems: scalloping loss and processing gain (which is more like "processing loss"). Let's talk about the processing "gain" (again, really a loss) first. This refers to the attenuation of the signal at the ends of the time record due to the windowing.

Graph showing two overlaid sinusoids, one in blue and one in red. The individual cycles are so close in time that they are difficult to discern.
A time record of a complex sinusoid. This particular time record shows 8192 samples.
Graph of two overlaid sinusoids, one in blue and one in red. The cycles of the sinusoid are so close together that it is difficult to see the individual cycles. The sinudoids are a zero amplitude at each end, and grow in amplitude as the signal gets to the center of the graph.
Windowed time record of a complex sinusoid. Note how the sinusoid has zero amplitude at each end, and rises towards the center. These values at each end lead to a lower overall power level. This is called the "processing gain" (once again, actually a loss) of the window.

The processing "gain" and scalloping loss of a window can be calculated. The values for most of the windows used in Gnu Radio are tabulated below.

WindowProcessing Gain Value (dB)Scalloping Loss (dB)
Uniform (aka Rectangular)03.92
Hanning-6.021.42
Hamming-5.351.75
Blackman (approx)-7.541.10
4-Term Minimum Blackman-harris-8.910.83
Nuttall4b-8.980.81
Stanford Research Flattop ("Flat-top" in Gnu Radio)-13.320.0156

The default window in the QT GUI Frequency Sink is the 4-term Blackman-harris. It has a processing gain of -8.91 dB. We can start by adding this gain back to the signal. So our -1.8054 becomes -1.8054 - (-8.91) = -7.1046 dBW. Our measurement is now 5.13 W, meaning our voltage measurement is 2.27 V. We're now off by less than 2%. The remaining power is due to scalloping loss. We could also account for that, but it would require a lot more calculation. Instead, when making accurate amplitude measurements spectrally, it's much easier to use one of the flattop windows. The one included in Gnu Radio Companion is the SRI (Stanford Research) flattop. It has more processing loss, but it has very little scalloping loss.

Switching the frequency sink window to "Flat-top", we get the following spectrum:

Graph showing a roughly triangular waveform coming up from the bottom. A small cursor in the shape of a plus sign rests at the top of the triangle, with text next to it.
Zoomed in spectral display of a sinusoid using a SRI flattop (aka "Flat-top") window. The peak is measured to be -6.0968 dBW.

This particular window has a processing gain of -13.32 dB, meaning that the actual power measurement is -6.0968 - (-13.32) = 7.2232 dBW. This corresponds to a linear power measurement of 5.276 W, which is off by 13.8 mW, or a difference of only 0.26% of the actual value. As stated, using this window for actual amplitude measurements makes things much easier.

Measuring Power of Noise

Noise is inherently noncoherent. It does not have an absolute, constant amplitude. Its amplitude can only be expressed statistically. Gaussian noise will have a certain average value and standard deviation. The standard deviation is equivalent to the RMS value (volts), while the square of the standard deviation, the variance, is equivalent to the "mean-square" value (watts). Because of this, there's another two issues (in combination with those mentioned for coherent signals discussed above) when measuring noise spectrally:

  1. Different processing gain: The loss for noncoherent energy due to the processing gain of the window will be different than the loss due to coherent signals. For example, the loss for a coherent signal due to a Blackman-harris window is 8.91 dB; the loss for noncoherent signal for the same window is 5.88 dB.
  2. Type of averaging: When attempting to measure the amplitude of a signal spectrally, many times you will invoke averaging. You can either average before the frequency bin powers are set to a logarithmic scale, or average afterwards. You will get different results depending on which one you do. Note that, generally, it doesn't matter if the averaging is exponential or block. It only matters where you place the averaging with respect to the calculation of the logarithmic scale (aka "decibels").

Both of these problems mean that, on the same spectrum, coherent and noncoherent energy will measure differently. To demonstrate this, I've modified the flowgraph to add a noise source.

Block diagram with three rows of blocks. The top row has blocks which are not connected. The middle row has four blocks connected one to the next horizontally. The bottom row is a single block, which is also connected by a line to the third block in the middle row.
Flowgraph that combines a sinusoid and noise into one spectrum. The sinusoid has a power level of 5.29 (2.32), while the noise power level is 0.0225 (0.152).
Graph showing a thin, noisy horizontal line about 1/3 of the way from the bottom. Just left of center is a thin, vertical line extending up from the noisy line almost to the top of the graph.
Spectrum of the sum of noise and a sinusoid. The levels of both the noise and sinusoid are affected by the windowing, but they are affected differently. The display has been set to "High" averaging using a "Flat-top" (SRI flattop) window. This averaging is an exponential averaging.

As the processing gain for noncoherent energy is different from coherent energy, we need to calculate the noncoherent processing gain for each window. Here's the same list as above, but tabulated with the noncoherent processing gain values.

WindowNoncoherent Processing Gain Value (dB)
Uniform (aka Rectangular)0
Hanning-4.260
Hamming-4.008
Blackman (approx)-5.1627
4-Term Minimum Blackman-harris-5.884
Nuttall4b-5.9205
Stanford Research Flattop ("Flat-top")-7.5593

The input noise power level is 22.5 mW (0.0225 = 0.152). That power is distributed equally across all of the bins of the FFT. It's white Gaussian noise, after all. There are 2048 bins, so each bin should see 0.0225/2048 = 10.986 µW. That corresponds to a decibel level of -49.6 dB. Note that the measured noise level in the display above is roughly -60. That's a difference of roughly 10 dB from what we just calculated. The reasons for the difference are:

So, adding both the windowing loss and the averaging loss gets us to -49.9 dB. We're within 0.3 dB of the actual value. Pretty good days work, if you ask me.

How do we get an even more precise value? We need more averaging. We're at the limits of what the QT GUI Frequency Sink can do. We need to create our own spectral display with averaging. The following flowgraph recreates the QT GUI Frequency Sink performance, but with the ability to do many more averages.

Block diagram with four rows of blocks. The top row consists of five blocks not connected to anything. The second row consists of six blocks connected left to right. The third row is a single block connected to the third block of the second row. The bottom row consists of five blocks connected left to right.
Flowgraph to create a spectral display with an adjustable number of averages. For this particular flowgraph, I've set the averages to 10000.

This gives us the following figures. The first is the initial display (once it has stabilized), while the second is a zoomed-in view of the noise floor.

Graph showing a thin, noisy horizontal line about 1/3 of the way from the bottom. Just left of center is a thin, vertical line extending up from the noisy line almost to the top of the graph.
Spectrum using the high (10000) averages. Note that the variance of the noise floor is much lower (the line is much flatter) than the spectrum shown above.
A graph showing a noisy, horizontal line extending from left to right just above the center of the graph.
Zoomed-in view of the noise level. The marker roughly measures the level of the noise at -59.66 dB.

Using this more precise value of the noise (-59.66 dB) and adding in the processing gain and averaging offset, the measured value is now -49.6 dB, almost precisely the actual value.

Note how the averaging is performed in the flowgraph. The power levels are first converted to decibels, then the averaging occurs. What happens if we swap these around (average then convert to decibels)?

Block diagram with four rows of blocks. The top row consists of five blocks not connected to anything. The second row consists of six blocks connected left to right. The third row is a single block connected to the third block of the second row. The bottom row consists of five blocks connected left to right.
Flowgraph to create an averaged spectrum, but with the averaging done on a linear scale before being converted to a logarithmic (decibel) scale. This is the same as the above flowgraph, except the "Log10" and "Moving Average" blocks have been swapped around.
Graph showing a thin, noisy horizontal line about 1/3 of the way from the bottom. Just left of center is a thin, vertical line extending up from the noisy line almost to the top of the graph.
This is similar to the output of the flowgraph above, except note that the noise level is higher than it was in the displays from above. The level is 2.5 dB higher due to the different averaging method. The level is roughly -57.1 dB.

With this modified averaging method (averaging on linear power values, then converting to decibels), we've gained 2.5 dB on the noise levels. This means that we only need to add back the loss due to the windowing, 7.56 dB, to get to -49.54 dB, which is a little high, but off by less than 0.1 dB.

Note that the sinuoid power level is unchanged at -6.096 dB, just as it was measured originally. Again, this averaging method only affects noncoherent energy. What this means is that, when measuring energy spectrally, you have to truly understand whether what you're measuring is coherent or noncoherent.

Hence my statement in my last post: measure in the time-domain. Much easier. Much more fool-proof.

Here's a Random Fact...