10#ifndef INCLUDED_DVBS2RX_CONSTELLATIONS_H
11#define INCLUDED_DVBS2RX_CONSTELLATIONS_H
15#include <gnuradio/gr_complex.h>
16#include <volk/volk_alloc.hh>
30 volk::vector<int8_t> d_aux_8i_buffer;
31 volk::vector<gr_complex> d_aux_32fc_buffer;
41 float _estimate_snr(
const gr_complex* in_syms,
42 const gr_complex* ref_syms,
46 gr_complex norm_sq_ref_fc = 0;
47 volk_32fc_x2_conjugate_dot_prod_32fc(&norm_sq_ref_fc, ref_syms, ref_syms, n_syms);
50 gr_complex* p_aux_buffer = d_aux_32fc_buffer.data();
51 volk_32f_x2_subtract_32f(
reinterpret_cast<float*
>(p_aux_buffer),
52 reinterpret_cast<const float*
>(in_syms),
53 reinterpret_cast<const float*
>(ref_syms),
55 gr_complex norm_sq_noise_fc = 0;
56 volk_32fc_x2_conjugate_dot_prod_32fc(
57 &norm_sq_noise_fc, p_aux_buffer, p_aux_buffer, n_syms);
59 float norm_sq_ref_f = norm_sq_ref_fc.real();
60 float norm_sq_noise_f = norm_sq_noise_fc.real();
61 if (norm_sq_noise_f == 0)
62 norm_sq_noise_f = 1e-12;
64 return norm_sq_ref_f / norm_sq_noise_f;
72 : d_volk_generic(getenv(
"VOLK_GENERIC") != nullptr),
116 void map(gr_complex* out_buf,
117 const int8_t* in_bits,
119 bool inv_convention =
false)
122 throw std::invalid_argument(
"Number of bits must be even");
127 float* out_buf_32f =
reinterpret_cast<float*
>(out_buf);
128 volk_8i_s32f_convert_32f(out_buf_32f, in_bits, div_scalar, n_bits);
139#if VOLK_VERSION <= 30000
140 if (d_volk_generic) {
141 for (
unsigned int i = 0; i < n_bits; i++)
142 out_buf_32f[i] += offset;
144 volk_32f_s32f_add_32f(out_buf_32f, out_buf_32f, offset, n_bits);
147 volk_32f_s32f_add_32f(out_buf_32f, out_buf_32f, offset, n_bits);
157 void map(gr_complex* out_buf,
158 const volk::vector<int8_t>& in_bits,
159 bool inv_convention =
false)
161 map(out_buf, in_bits.data(), in_bits.size(), inv_convention);
171 void slice(gr_complex* out_buf,
const gr_complex* in_buf,
unsigned int n_syms)
178 volk_32f_binary_slicer_8i(
179 d_aux_8i_buffer.data(),
reinterpret_cast<const float*
>(in_buf), n_syms * 2);
180 map(out_buf, d_aux_8i_buffer.data(), n_syms * 2,
true);
188 void slice(gr_complex* out_buf,
const volk::vector<gr_complex>& in_syms)
190 slice(out_buf, in_syms.data(), in_syms.size());
209 demap_soft(int8_t* out_buf,
const gr_complex* in_buf,
unsigned int n_syms,
float N0)
211 float scalar = 2 * M_SQRT2 / N0;
212 volk_32f_s32f_convert_8i(
213 out_buf,
reinterpret_cast<const float*
>(in_buf), scalar, n_syms * 2);
222 void demap_soft(int8_t* out_buf,
const volk::vector<gr_complex>& in_syms,
float N0)
224 demap_soft(out_buf, in_syms.data(), in_syms.size(), N0);
242 slice(d_aux_32fc_buffer.data(), in_syms, n_syms);
243 return _estimate_snr(in_syms, d_aux_32fc_buffer.data(), n_syms);
268 estimate_snr(
const gr_complex* in_syms,
const int8_t* ref_llrs,
unsigned int n_syms)
276 gr_complex* p_ref_syms = d_aux_32fc_buffer.data();
277 volk_8i_s32f_convert_32f(
278 reinterpret_cast<float*
>(p_ref_syms), ref_llrs, 1.0, n_syms * 2);
279 slice(p_ref_syms, p_ref_syms, n_syms);
280 return _estimate_snr(in_syms, p_ref_syms, n_syms);
289 const volk::vector<int8_t>& ref_llrs)
291 if (in_syms.size() * 2 != ref_llrs.size())
292 throw std::invalid_argument(
"Input symbols and LLRs must have matching size");
293 return estimate_snr(in_syms.data(), ref_llrs.data(), in_syms.size());
QPSK Constellation.
Definition qpsk.h:27
float estimate_snr(const gr_complex *in_syms, const int8_t *ref_llrs, unsigned int n_syms)
Estimate the linear SNR based on input QPSK symbols and reference LLRs.
Definition qpsk.h:268
float estimate_snr(const gr_complex *in_syms, unsigned int n_syms)
Estimate the linear SNR of input QPSK symbols.
Definition qpsk.h:240
void slice(gr_complex *out_buf, const volk::vector< gr_complex > &in_syms)
Definition qpsk.h:188
float estimate_snr(const volk::vector< gr_complex > &in_syms, const volk::vector< int8_t > &ref_llrs)
Definition qpsk.h:288
void demap_soft(int8_t *out_buf, const gr_complex *in_buf, unsigned int n_syms, float N0)
Soft-demap noisy input QPSK symbols into quantized LLRs.
Definition qpsk.h:209
~QpskConstellation()
Destroy the Qpsk Constellation object.
Definition qpsk.h:81
void demap_soft(int8_t *out_buf, const volk::vector< gr_complex > &in_syms, float N0)
Definition qpsk.h:222
float estimate_snr(const volk::vector< gr_complex > &in_syms)
Definition qpsk.h:250
void map(gr_complex *out_buf, const int8_t *in_bits, unsigned int n_bits, bool inv_convention=false)
Map input bits to QPSK symbols.
Definition qpsk.h:116
QpskConstellation()
Construct a new Qpsk Constellation object.
Definition qpsk.h:71
void slice(gr_complex *out_buf, const gr_complex *in_buf, unsigned int n_syms)
Slice noisy input QPSK symbols to the closest constellation points.
Definition qpsk.h:171
void map(gr_complex *out_buf, const volk::vector< int8_t > &in_bits, bool inv_convention=false)
Definition qpsk.h:157
#define FRAME_SIZE_NORMAL
Definition dvb_defines.h:37
Fixed-length double-ended queue with contiguous volk-aligned elements.
Definition gr_bch.h:22
#define SQRT2_2
Definition pl_defs.h:34
#define MAX_XFECFRAME_LEN
Definition pl_defs.h:27