# Denoising effect in GnuRadio OFDM Serializer block

Why does the OFDM serializer has such a strong denoising effect in the flow graph below ? Is that normal ?

The upper constellation is AFTER the OFDM serializer block and the lower is BEFORE the OFDM serializer block.

Here is the OFDM documentation : http://gnuradio.org/doc/doxygen/page_ofdm.html

It does not help to explain why the serializer block has such a strong denoising effect, any idea why this denoising happens ?

Here is the flowgraph (in .grc format): http://pastebin.com/raw/PTY0Q0Ty

Further inspection indicates that the serializer block only does remove non data carriers. It just probably so happens that anything that is non data is super noisy, and data carriers are not noisy at all, but I still wonder how is this possible.

• Further inspection shows indicates that the serializer block only does remove non data carriers. It just probably so happens that anything that is non data is super noisy, and data carriers are not noisy at all, but I still wonder how is this possible. May 12, 2016 at 9:07

Further inspection shows indicates that the serializer block only does remove non data carriers. It just probably so happens that anything that is non data is super noisy, and data carriers are not noisy at all, but I still wonder how is this possible.

The magic that happens here is in the actual equalizer used in the frame equalizer block. If you'd scroll up in the GRC¹, you'd probably see the payload equalizer object block, holding a "simpledfe" equalizer.

Now, simpledfe stands for simple data feed-back equalizer. It's actually pretty well-documented, but somehow the documentation tool broke and the HTML documentation doesn't actually contain any of the explanation given in the source code.

So, here's a source code excerpt with the docs:

/* \brief Simple decision feedback equalizer for OFDM.
* \ingroup ofdm_blk
* \ingroup equalizers_blk
*
* \details
* Equalizes an OFDM signal symbol by symbol using knowledge of the
* complex modulations symbols.
* For every symbol, the following steps are performed:
* - On every sub-carrier, decode the modulation symbol
* - Use the difference between the decoded symbol and the received symbol
*   to update the channel state on this carrier
* - Whenever a pilot symbol is found, it uses the known pilot symbol to
*   update the channel state.
*
* This equalizer makes a lot of assumptions:
* - The initial channel state is good enough to decode the first
*   symbol without error (unless the first symbol only consists of pilot
*   tones)
* - The channel changes only very slowly, such that the channel state
*   from one symbol is enough to decode the next
* - SNR low enough that equalization will always suffice to correctly
*   decode a symbol
* If these assumptions are not met, the most common error is that the
* channel state is estimated incorrectly during equalization; after that,
* all subsequent symbols will be completely wrong.
*
* Note that the equalized symbols are *exact points* on the constellation.
* This means soft information of the modulation symbols is lost after the
* equalization, which is suboptimal for channel codes that use soft decision.
*
*/

Hm, but what about unoccupied carriers?

Now, looking at the implementation in ofdm_equalizer_simpledfe we see:

void
ofdm_equalizer_simpledfe::equalize(gr_complex *frame,
int n_sym,
const std::vector<gr_complex> &initial_taps,
const std::vector<tag_t> &tags)
{
[…]

gr_complex sym_eq, sym_est;

for (int i = 0; i < n_sym; i++) {
for (int k = 0; k < d_fft_len; k++) {
if (!d_occupied_carriers[k]) {
continue;
}
[…]

In other words: those are left untouched from the original FFT.

Now, a typical direct conversion OFDM system will leave the DC carrier unoccupied – that containing the leakage of the receiver LO. That is typically a relatively powerful FFT bin, shouldn't vary much in magnitude, and its phase should depend on the point in time the DFT was taken, and that's the frame start time as determined by the Schmidl&Cox sync. That would be my explanation of the $|\cdot|\approx 50$ constellation points, and the rest might very well be the unequalized noise in original amplitude, especially since we're looking at a constellation sink that shows 1024 constellation points at once – so we'll see some outliers in noise power.

¹ It's often impossible to fit a whole GRC flow graph on the screen. It's therefore really handy that there's the "save screen capture button" in the toolbar and the menu!

• Many thanks for the detailed answer Marcus ! May 12, 2016 at 12:50