GNU Radio's DVBS2RX Package
pi2_bpsk.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright (c) 2021 Igor Freire.
4 *
5 * This file is part of gr-dvbs2rx.
6 *
7 * SPDX-License-Identifier: GPL-3.0-or-later
8 */
9
10#ifndef INCLUDED_DVBS2RX_PI2_BPSK_H
11#define INCLUDED_DVBS2RX_PI2_BPSK_H
12
14#include <gnuradio/gr_complex.h>
15#include <cstdint>
16
17namespace gr {
18namespace dvbs2rx {
19
20/**
21 * @brief Map N bits from the PLHEADER into pi/2 BPSK symbols.
22 */
23DVBS2RX_API void map_bpsk(uint64_t code, gr_complex* out, unsigned int N);
24
25/**
26 * @brief Coherently demap N pi/2 BPSK symbols from the PLHEADER into bits.
27 * @param in (const gr_complex *) Incoming pi/2 BPSK symbols.
28 * @param N (unsigned int) Number of pi/2 BPSK symbols to demap.
29 * @return Demapped bits packed on a bit-level big-endian uint64_t.
30 * @note N must be <= 64.
31 */
32DVBS2RX_API uint64_t demap_bpsk(const gr_complex* in, unsigned int N);
33
34/**
35 * @brief Differentially demap N pi/2 BPSK symbols from the PSLC into bits.
36 *
37 * The differential (non-coherent) demapping is an interesting alternative in
38 * the presence of significant frequency offset. However, it is designed to work
39 * with the PLSC symbols and may not work with an arbitrary pi/2 BPSK
40 * sequence. It assumes the first pi/2 BPSK symbol pointed by argument *in lies
41 * at an odd index and corresponds to the last SOF symbol. Correspondingly, it
42 * assumes the second symbol in the input array represents an even PLHEADER
43 * index and encodes the first PLSC symbol. Do not use this function to demap
44 * any arbitrary pi/2 BPSK sequence. For that, use "demap_bpsk" (i.e., the
45 * coherent demapping) instead.
46 *
47 * @param in (const gr_complex *) Pointer to the array of pi/2 BPSK symbols,
48 * starting from the last SOF symbol and followed by the PLSC symbols.
49 * @param N (unsigned int) Number of pi/2 BPSK symbols to demap.
50 *
51 * @return Demapped bits corresponding to symbols in[1] to in[N] (i.e., the N
52 * symbols past the first input symbol in[0]). The result is packed on a
53 * bit-level big-endian uint64_t.
54 *
55 * @note N must be <= 64, and the complex input array must hold at least N+1
56 * pi/2 BPSK symbols, starting from an odd-indexed symbol.
57 */
58DVBS2RX_API uint64_t demap_bpsk_diff(const gr_complex* in, unsigned int N);
59
60/**
61 * @brief Derotate N complex-valued pi/2 BPSK into regular real BPSK symbols
62 *
63 * Converts a sequence of complex-valued pi/2 BPSK symbols with values
64 * originating from the +-0.707 +-j*0.707 constellation points into the
65 * corresponding sequence of ordinary real-valued BPSK symbols around +-1. If
66 * the input pi/2 BPSK symbols are noisy, the resulting real-valued BPSK symbols
67 * are naturally noisy too and deviate from the nominal +-1 values.
68 *
69 * This derotation effectively produces the "soft decisions" corresponding to
70 * the received pi/2 BPSK symbols. Taking an even index for the demonstration,
71 * note the constellation symbols are either exp(jpi/4) or exp(-j3pi/4). Hence,
72 * the log-likelihood ratio between the received complex symbol r representing
73 * bit=0 versus bit=1 is as follows:
74 *
75 * LLR(r) = (-||r - exp(jpi/4)||^2 + ||r - exp(-j3pi/4)||^2) / N0
76 *
77 * Now, let's say r can be expressed as " exp(jpi/4) * r' ", where r' is the
78 * derotated versions of r, namely " r' = r*exp(-jpi/4) ". In this case, it
79 * follows that:
80 *
81 * LLR(r) = (-||exp(jpi/4)*(r' - 1)||^2 + ||exp(jpi/4)(r' + 1)||^2) / N0,
82 *
83 * given that exp(jpi/4) = -exp(-j3pi/4).
84 *
85 * Since ||exp(jpi/4)||^2 = 1, it can be factored out of the Euclidean norm
86 * terms, which yields:
87 *
88 * LLR(r) = (-||r' - 1||^2 + ||r' + 1||^2) / N0.
89 *
90 * Besides, note that:
91 *
92 * ||r' - 1||^2 = ||r'||^2 -2*real(<r', 1>) + ||1||^2
93 * ||r' + 1||^2 = ||r'||^2 +2*real(<r', 1>) + ||1||^2
94 *
95 * Hence, the LLR can be expressed as:
96 *
97 * LLR(r) = 4 * real(<r', 1>) / N0,
98 * = 4 * real(r') / N0.
99 *
100 * In other words, the LLR is given by the real part of the de-rotated symbol
101 * r', scaled by 4/N0. Furthermore, the scaling factor 4/N0 is only useful for a
102 * maximum a posteriori (MAP) decoder, when the constellation symbols are not
103 * equiprobable. In contrast, for maximum likelihood (ML) decoding, when the
104 * symbols are equiprobable, the scaling factor can be ignored, as the threshold
105 * for decision is zero (i.e., bit=0 when LLR(r) > 0 and bit=1 otherwise). Thus,
106 * ultimately, the "soft decisions" are given by real(r'), which is equal to:
107 *
108 * - real(r * exp(-jpi/4)), on even indexes;
109 * - real(r * exp(-j3pi/4)), on odd indexes.
110 *
111 * Note the term soft decision is loosely taken here as a sufficient statistic
112 * indicating the likelihood of a particular bit, which can be used by a
113 * maximum-likelihood decoder. The particular bit-by-bit soft decision that this
114 * function produces is one proportional to the LLR, but not exactly equal to
115 * the LLR (as it does not need to be). Furthermore, using the terminology from
116 * textbooks such as Forney's (Section 6.5.2), the returned value real(r') can
117 * be used to derive both the hard decision "sign(real(r'))" and the reliability
118 * weight associated with this decision given by "abs(real(r'))".
119 *
120 * In the end, what matters the most is the soft decision format expected by the
121 * coding scheme's decoder. Here, we assume the decoder expects real(r'), as
122 * this function is meant to feed soft decisions into the Reed-Muller decoder
123 * (see the implementation of reed_muller::decode on reed_muller.cc). Hence,
124 * this function first derotates each complex input symbol r[k] to produce
125 * r'[k]. Then, it returns real(r'[k]) for all k on the output buffer.
126 *
127 * @param in (const gr_complex *) Input complex pi/2 BPSK symbols.
128 * @param out (float *) Output real-valued BPSK symbols.
129 * @param N (unsigned int) Number of pi/2 BPSK symbols to derotate.
130 */
131DVBS2RX_API void derotate_bpsk(const gr_complex* in, float* out, unsigned int N);
132
133} // namespace dvbs2rx
134} // namespace gr
135
136#endif /* INCLUDED_DVBS2RX_PI2_BPSK_H */
#define DVBS2RX_API
Definition include/gnuradio/dvbs2rx/api.h:19
DVBS2RX_API void derotate_bpsk(const gr_complex *in, float *out, unsigned int N)
Derotate N complex-valued pi/2 BPSK into regular real BPSK symbols.
DVBS2RX_API uint64_t demap_bpsk(const gr_complex *in, unsigned int N)
Coherently demap N pi/2 BPSK symbols from the PLHEADER into bits.
DVBS2RX_API uint64_t demap_bpsk_diff(const gr_complex *in, unsigned int N)
Differentially demap N pi/2 BPSK symbols from the PSLC into bits.
DVBS2RX_API void map_bpsk(uint64_t code, gr_complex *out, unsigned int N)
Map N bits from the PLHEADER into pi/2 BPSK symbols.
Fixed-length double-ended queue with contiguous volk-aligned elements.
Definition gr_bch.h:22