summaryrefslogtreecommitdiff
path: root/gr-digital
diff options
context:
space:
mode:
authorEduardo Sánchez Muñoz <esm@eduardosm.net>2020-12-18 12:30:26 +0100
committerMarcus Müller <marcus@hostalia.de>2020-12-18 13:54:10 +0100
commit947800c52f2fcb2b149cfd2809148afcfdb8b79a (patch)
treeffc11b527f2f95606da621185a8e4c8c5d048ff7 /gr-digital
parent00fd051dff4a73081c40f4ccfc3b4ac8c62d74f1 (diff)
Allow to choose whether to normalize constellation average magnitude, average power or to not normalize at all.
Signed-off-by: Eduardo Sánchez Muñoz <esm@eduardosm.net>
Diffstat (limited to 'gr-digital')
-rw-r--r--gr-digital/grc/digital_constellation.block.yml9
-rw-r--r--gr-digital/include/gnuradio/digital/constellation.h42
-rw-r--r--gr-digital/lib/constellation.cc60
-rw-r--r--gr-digital/python/digital/bindings/constellation_python.cc17
4 files changed, 92 insertions, 36 deletions
diff --git a/gr-digital/grc/digital_constellation.block.yml b/gr-digital/grc/digital_constellation.block.yml
index 7a1f4654c0..943b578d80 100644
--- a/gr-digital/grc/digital_constellation.block.yml
+++ b/gr-digital/grc/digital_constellation.block.yml
@@ -29,6 +29,13 @@ parameters:
dtype: int
default: '1'
hide: ${ ( 'none' if str(type) == "calcdist" else 'all') }
+- id: normalization
+ label: Normalization Type
+ dtype: int
+ default: digital.constellation.AMPLITUDE_NORMALIZATION
+ options: [digital.constellation.NO_NORMALIZATION, digital.constellation.POWER_NORMALIZATION, digital.constellation.AMPLITUDE_NORMALIZATION]
+ option_labels: [None, Power, Amplitude]
+ hide: ${ ( 'none' if str(type) == "calcdist" else 'all') }
- id: precision
label: Soft Decisions Precision
dtype: int
@@ -39,7 +46,7 @@ parameters:
dtype: raw
default: None
hide: ${ ('part' if str(soft_dec_lut) == 'None' else 'none') }
-value: ${ digital.constellation_calcdist(const_points, sym_map, rot_sym, dims) if (str(type) == "calcdist") else getattr(digital,'constellation_'+str(type))() }
+value: ${ digital.constellation_calcdist(const_points, sym_map, rot_sym, dims, normalization) if (str(type) == "calcdist") else getattr(digital,'constellation_'+str(type))() }
templates:
diff --git a/gr-digital/include/gnuradio/digital/constellation.h b/gr-digital/include/gnuradio/digital/constellation.h
index a8fffe111e..ebe37088b7 100644
--- a/gr-digital/include/gnuradio/digital/constellation.h
+++ b/gr-digital/include/gnuradio/digital/constellation.h
@@ -49,11 +49,17 @@ typedef std::shared_ptr<constellation> constellation_sptr;
class DIGITAL_API constellation : public std::enable_shared_from_this<constellation>
{
public:
+ enum normalization_t {
+ NO_NORMALIZATION,
+ POWER_NORMALIZATION,
+ AMPLITUDE_NORMALIZATION,
+ };
+
constellation(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- bool normalize_points = true);
+ normalization_t normalization = AMPLITUDE_NORMALIZATION);
constellation();
virtual ~constellation();
@@ -233,15 +239,17 @@ public:
* \param pre_diff_code List of alphabet symbols (before applying any differential
* coding) (order of list matches constell)
* \param rotational_symmetry Number of rotations around unit circle that have the
- * same representation. \param dimensionality Number of dimensions to the
- * constellation. \param normalize_points Normalize constellation points to
- * mean(abs(points))=1 (default is true)
+ * same representation.
+ * \param dimensionality Number of dimensions to the constellation.
+ * \param normalization Use AMPLITUDE_NORMALIZATION to normalize points to
+ * mean(abs(points))=1 (default), POWER_NORMALIZATION to normalize points
+ * to mean(abs(points)^2)=1 or NO_NORMALIZATION to keep the original amplitude.
*/
static sptr make(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- bool normalize_points = true);
+ normalization_t normalization = AMPLITUDE_NORMALIZATION);
unsigned int decision_maker(const gr_complex* sample) override;
// void calc_metric(gr_complex *sample, float *metric, trellis_metric_type_t type);
@@ -253,7 +261,7 @@ protected:
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- bool nomalize_points = true);
+ normalization_t normalization = AMPLITUDE_NORMALIZATION);
};
@@ -286,7 +294,8 @@ public:
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- unsigned int n_sectors);
+ unsigned int n_sectors,
+ normalization_t normalization = AMPLITUDE_NORMALIZATION);
~constellation_sector() override;
@@ -339,13 +348,15 @@ public:
* \param width_imag_sectors width of each imag sector to calculate decision
* boundaries.
*/
- static constellation_rect::sptr make(std::vector<gr_complex> constell,
- std::vector<int> pre_diff_code,
- unsigned int rotational_symmetry,
- unsigned int real_sectors,
- unsigned int imag_sectors,
- float width_real_sectors,
- float width_imag_sectors);
+ static constellation_rect::sptr
+ make(std::vector<gr_complex> constell,
+ std::vector<int> pre_diff_code,
+ unsigned int rotational_symmetry,
+ unsigned int real_sectors,
+ unsigned int imag_sectors,
+ float width_real_sectors,
+ float width_imag_sectors,
+ normalization_t normalization = AMPLITUDE_NORMALIZATION);
~constellation_rect() override;
protected:
@@ -355,7 +366,8 @@ protected:
unsigned int real_sectors,
unsigned int imag_sectors,
float width_real_sectors,
- float width_imag_sectors);
+ float width_imag_sectors,
+ normalization_t normalization = AMPLITUDE_NORMALIZATION);
unsigned int get_sector(const gr_complex* sample) override;
gr_complex calc_sector_center(unsigned int sector);
diff --git a/gr-digital/lib/constellation.cc b/gr-digital/lib/constellation.cc
index 0aff0aaecc..e9d3239503 100644
--- a/gr-digital/lib/constellation.cc
+++ b/gr-digital/lib/constellation.cc
@@ -32,7 +32,7 @@ constellation::constellation(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- bool normalize_points)
+ normalization_t normalization)
: d_constellation(constell),
d_pre_diff_code(pre_diff_code),
d_rotational_symmetry(rotational_symmetry),
@@ -46,18 +46,39 @@ constellation::constellation(std::vector<gr_complex> constell,
d_lut_scale(0)
{
unsigned int constsize = d_constellation.size();
- if (normalize_points) {
+ float summed_mag = 0;
+ switch (normalization) {
+ case NO_NORMALIZATION:
+ break;
+
+ case POWER_NORMALIZATION:
+ // Scale constellation points so that average power is 1.
+ for (unsigned int i = 0; i < constsize; i++) {
+ gr_complex c = d_constellation[i];
+ summed_mag += std::norm(c);
+ }
+ d_scalefactor = constsize / sqrt(summed_mag);
+ for (unsigned int i = 0; i < constsize; i++) {
+ d_constellation[i] = d_constellation[i] * d_scalefactor;
+ }
+ break;
+
+ case AMPLITUDE_NORMALIZATION:
// Scale constellation points so that average magnitude is 1.
- float summed_mag = 0;
for (unsigned int i = 0; i < constsize; i++) {
gr_complex c = d_constellation[i];
- summed_mag += sqrt(c.real() * c.real() + c.imag() * c.imag());
+ summed_mag += std::abs(c);
}
d_scalefactor = constsize / summed_mag;
for (unsigned int i = 0; i < constsize; i++) {
d_constellation[i] = d_constellation[i] * d_scalefactor;
}
+ break;
+
+ default:
+ throw std::runtime_error("Invalid constellation normalization type.");
}
+
if (pre_diff_code.empty())
d_apply_pre_diff_code = false;
else if (pre_diff_code.size() != constsize)
@@ -370,19 +391,19 @@ constellation_calcdist::make(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- bool normalize_points)
+ normalization_t normalization)
{
return constellation_calcdist::sptr(new constellation_calcdist(
- constell, pre_diff_code, rotational_symmetry, dimensionality, normalize_points));
+ constell, pre_diff_code, rotational_symmetry, dimensionality, normalization));
}
constellation_calcdist::constellation_calcdist(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- bool normalize_points)
+ normalization_t normalization)
: constellation(
- constell, pre_diff_code, rotational_symmetry, dimensionality, normalize_points)
+ constell, pre_diff_code, rotational_symmetry, dimensionality, normalization)
{
}
@@ -401,8 +422,10 @@ constellation_sector::constellation_sector(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
unsigned int dimensionality,
- unsigned int n_sectors)
- : constellation(constell, pre_diff_code, rotational_symmetry, dimensionality),
+ unsigned int n_sectors,
+ normalization_t normalization)
+ : constellation(
+ constell, pre_diff_code, rotational_symmetry, dimensionality, normalization),
n_sectors(n_sectors)
{
}
@@ -435,7 +458,8 @@ constellation_rect::sptr constellation_rect::make(std::vector<gr_complex> conste
unsigned int real_sectors,
unsigned int imag_sectors,
float width_real_sectors,
- float width_imag_sectors)
+ float width_imag_sectors,
+ normalization_t normalization)
{
return constellation_rect::sptr(new constellation_rect(constell,
pre_diff_code,
@@ -443,7 +467,8 @@ constellation_rect::sptr constellation_rect::make(std::vector<gr_complex> conste
real_sectors,
imag_sectors,
width_real_sectors,
- width_imag_sectors));
+ width_imag_sectors,
+ normalization));
}
constellation_rect::constellation_rect(std::vector<gr_complex> constell,
@@ -452,9 +477,14 @@ constellation_rect::constellation_rect(std::vector<gr_complex> constell,
unsigned int real_sectors,
unsigned int imag_sectors,
float width_real_sectors,
- float width_imag_sectors)
- : constellation_sector(
- constell, pre_diff_code, rotational_symmetry, 1, real_sectors * imag_sectors),
+ float width_imag_sectors,
+ normalization_t normalization)
+ : constellation_sector(constell,
+ pre_diff_code,
+ rotational_symmetry,
+ 1,
+ real_sectors * imag_sectors,
+ normalization),
n_real_sectors(real_sectors),
n_imag_sectors(imag_sectors),
d_width_real_sectors(width_real_sectors),
diff --git a/gr-digital/python/digital/bindings/constellation_python.cc b/gr-digital/python/digital/bindings/constellation_python.cc
index 77a252c42c..8944e666c9 100644
--- a/gr-digital/python/digital/bindings/constellation_python.cc
+++ b/gr-digital/python/digital/bindings/constellation_python.cc
@@ -14,7 +14,7 @@
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(constellation.h) */
-/* BINDTOOL_HEADER_FILE_HASH(5f7cb544c3d7104e228f713f28b385ee) */
+/* BINDTOOL_HEADER_FILE_HASH(7830b0b770b8e3ae0fa213f34ead29b7) */
/***********************************************************************************/
#include <pybind11/complex.h>
@@ -43,17 +43,23 @@ void bind_constellation(py::module& m)
using constellation_8psk_natural = ::gr::digital::constellation_8psk_natural;
using constellation_16qam = ::gr::digital::constellation_16qam;
+ py::class_<constellation, std::shared_ptr<constellation>> constellation_class(
+ m, "constellation", D(constellation));
- py::class_<constellation, std::shared_ptr<constellation>>(
- m, "constellation", D(constellation))
+ py::enum_<constellation::normalization_t>(constellation_class, "normalization")
+ .value("NO_NORMALIZATION", constellation::NO_NORMALIZATION)
+ .value("POWER_NORMALIZATION", constellation::POWER_NORMALIZATION)
+ .value("AMPLITUDE_NORMALIZATION", constellation::AMPLITUDE_NORMALIZATION)
+ .export_values();
+ constellation_class
// .def(py::init<std::vector<std::complex<float>,
// std::allocator<std::complex<float> > >,std::vector<int, std::allocator<int>
// >,unsigned int,unsigned int,bool>(), py::arg("constell"),
// py::arg("pre_diff_code"),
// py::arg("rotational_symmetry"),
// py::arg("dimensionality"),
- // py::arg("normalize_points") = true,
+ // py::arg("normalization") = constellation::AMPLITUDE_NORMALIZATION,
// D(constellation,constellation,0)
// )
// .def(py::init<>(),D(constellation,constellation,1))
@@ -212,7 +218,7 @@ void bind_constellation(py::module& m)
py::arg("pre_diff_code"),
py::arg("rotational_symmetry"),
py::arg("dimensionality"),
- py::arg("normalize_points") = true,
+ py::arg("normalization") = constellation::AMPLITUDE_NORMALIZATION,
D(constellation_calcdist, make))
@@ -264,6 +270,7 @@ void bind_constellation(py::module& m)
py::arg("imag_sectors"),
py::arg("width_real_sectors"),
py::arg("width_imag_sectors"),
+ py::arg("normalization") = constellation::AMPLITUDE_NORMALIZATION,
D(constellation_rect, make))