summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation.cc36
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation.h33
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation.i43
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/generic_mod_demod.py32
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/psk2.py35
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/qam.py31
-rw-r--r--gnuradio-core/src/python/gnuradio/utils/Makefile.am1
-rw-r--r--gnuradio-core/src/python/gnuradio/utils/gray_code.py6
-rw-r--r--gnuradio-core/src/python/gnuradio/utils/mod_codes.py11
9 files changed, 142 insertions, 86 deletions
diff --git a/gnuradio-core/src/lib/general/gr_constellation.cc b/gnuradio-core/src/lib/general/gr_constellation.cc
index 8f5624668..e3b4c14e7 100644
--- a/gnuradio-core/src/lib/general/gr_constellation.cc
+++ b/gnuradio-core/src/lib/general/gr_constellation.cc
@@ -35,19 +35,27 @@
#define SQRT_TWO 0.707107
gr_constellation_sptr
-gr_make_constellation(std::vector<gr_complex> constellation)
+gr_make_constellation(std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code)
{
- return gr_constellation_sptr(new gr_constellation (constellation));
+ return gr_constellation_sptr(new gr_constellation (constellation, pre_diff_code));
}
// Base Constellation Class
-gr_constellation::gr_constellation (std::vector<gr_complex> constellation) :
- d_constellation(constellation)
+gr_constellation::gr_constellation (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code) :
+ d_constellation(constellation),
+ d_pre_diff_code(pre_diff_code)
{
+ if (pre_diff_code.size() == 0)
+ d_apply_pre_diff_code = false;
+ else if (pre_diff_code.size() != constellation.size())
+ throw std::runtime_error ("The constellation and pre-diff code must be of the same length.");
+ else
+ d_apply_pre_diff_code = true;
}
-gr_constellation::gr_constellation ()
+gr_constellation::gr_constellation () :
+ d_apply_pre_diff_code(false)
{
}
@@ -119,8 +127,9 @@ void gr_constellation::calc_hard_symbol_metric(gr_complex sample, float *metric)
}
gr_constellation_sector::gr_constellation_sector (std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int n_sectors) :
- gr_constellation(constellation),
+ gr_constellation(constellation, pre_diff_code),
n_sectors(n_sectors)
{
}
@@ -141,16 +150,18 @@ void gr_constellation_sector::find_sector_values () {
gr_constellation_rect_sptr
gr_make_constellation_rect(std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int real_sectors, unsigned int imag_sectors,
float width_real_sectors, float width_imag_sectors)
{
- return gr_constellation_rect_sptr(new gr_constellation_rect (constellation, real_sectors, imag_sectors, width_real_sectors, width_imag_sectors));
+ return gr_constellation_rect_sptr(new gr_constellation_rect (constellation, pre_diff_code, real_sectors, imag_sectors, width_real_sectors, width_imag_sectors));
}
gr_constellation_rect::gr_constellation_rect (std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int real_sectors, unsigned int imag_sectors,
float width_real_sectors, float width_imag_sectors) :
- gr_constellation_sector(constellation, real_sectors * imag_sectors),
+ gr_constellation_sector(constellation, pre_diff_code, real_sectors * imag_sectors),
n_real_sectors(real_sectors), n_imag_sectors(imag_sectors),
d_width_real_sectors(width_real_sectors), d_width_imag_sectors(width_imag_sectors)
{
@@ -184,14 +195,17 @@ unsigned int gr_constellation_rect::calc_sector_value (unsigned int sector) {
gr_constellation_psk_sptr
-gr_make_constellation_psk(std::vector<gr_complex> constellation, unsigned int n_sectors)
+gr_make_constellation_psk(std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
+ unsigned int n_sectors)
{
- return gr_constellation_psk_sptr(new gr_constellation_psk (constellation, n_sectors));
+ return gr_constellation_psk_sptr(new gr_constellation_psk (constellation, pre_diff_code, n_sectors));
}
gr_constellation_psk::gr_constellation_psk (std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int n_sectors) :
- gr_constellation_sector(constellation, n_sectors)
+ gr_constellation_sector(constellation, pre_diff_code, n_sectors)
{
find_sector_values();
}
diff --git a/gnuradio-core/src/lib/general/gr_constellation.h b/gnuradio-core/src/lib/general/gr_constellation.h
index 6908f43f1..440e32e57 100644
--- a/gnuradio-core/src/lib/general/gr_constellation.h
+++ b/gnuradio-core/src/lib/general/gr_constellation.h
@@ -40,17 +40,21 @@ typedef boost::shared_ptr<gr_constellation> gr_constellation_sptr;
// public constructor
gr_constellation_sptr
- gr_make_constellation (std::vector<gr_complex> constellation);
+gr_make_constellation (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code);
class gr_constellation : public boost::enable_shared_from_this<gr_constellation>
{
public:
- gr_constellation (std::vector<gr_complex> constellation);
+ gr_constellation (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code);
gr_constellation ();
//! Returns the set of points in this constellation.
std::vector<gr_complex> points() { return d_constellation;}
+ //! Whether to apply an encoding before doing differential encoding. (e.g. gray coding)
+ bool apply_pre_diff_code() { return d_apply_pre_diff_code;}
+ //! Returns the encoding to apply before differential encoding.
+ std::vector<unsigned int> pre_diff_code() { return d_pre_diff_code;}
//! Returns the constellation point that matches best.
//! Also calculates the phase error.
@@ -77,6 +81,8 @@ class gr_constellation : public boost::enable_shared_from_this<gr_constellation>
protected:
std::vector<gr_complex> d_constellation;
+ std::vector<unsigned int> d_pre_diff_code;
+ bool d_apply_pre_diff_code;
private:
friend gr_constellation_sptr
@@ -97,6 +103,7 @@ class gr_constellation_sector : public gr_constellation
public:
gr_constellation_sector (std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int n_sectors);
unsigned int decision_maker (gr_complex sample);
@@ -133,15 +140,17 @@ typedef boost::shared_ptr<gr_constellation_rect> gr_constellation_rect_sptr;
// public constructor
gr_constellation_rect_sptr
-gr_make_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors,
+gr_make_constellation_rect (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code,
+ unsigned int real_sectors, unsigned int imag_sectors,
float width_real_sectors, float width_imag_sectors);
class gr_constellation_rect : public gr_constellation_sector
{
public:
- gr_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors,
- float width_real_sectors, float width_imag_sectors);
+ gr_constellation_rect (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code,
+ unsigned int real_sectors, unsigned int imag_sectors,
+ float width_real_sectors, float width_imag_sectors);
protected:
@@ -157,8 +166,9 @@ class gr_constellation_rect : public gr_constellation_sector
float d_width_imag_sectors;
friend gr_constellation_rect_sptr
- gr_make_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors,
- float width_real_sectors, float width_imag_sectors);
+ gr_make_constellation_rect (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code,
+ unsigned int real_sectors, unsigned int imag_sectors,
+ float width_real_sectors, float width_imag_sectors);
};
@@ -177,13 +187,15 @@ typedef boost::shared_ptr<gr_constellation_psk> gr_constellation_psk_sptr;
// public constructor
gr_constellation_psk_sptr
-gr_make_constellation_psk (std::vector<gr_complex> constellation, unsigned int n_sectors);
+gr_make_constellation_psk (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code,
+ unsigned int n_sectors);
class gr_constellation_psk : public gr_constellation_sector
{
public:
- gr_constellation_psk (std::vector<gr_complex> constellation, unsigned int n_sectors);
+ gr_constellation_psk (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code,
+ unsigned int n_sectors);
protected:
@@ -194,7 +206,8 @@ class gr_constellation_psk : public gr_constellation_sector
private:
friend gr_constellation_psk_sptr
- gr_make_constellation_psk (std::vector<gr_complex> constellation, unsigned int n_sectors);
+ gr_make_constellation_psk (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code,
+ unsigned int n_sectors);
};
diff --git a/gnuradio-core/src/lib/general/gr_constellation.i b/gnuradio-core/src/lib/general/gr_constellation.i
index d00c62f90..762289c57 100644
--- a/gnuradio-core/src/lib/general/gr_constellation.i
+++ b/gnuradio-core/src/lib/general/gr_constellation.i
@@ -30,17 +30,26 @@ class gr_constellation;
typedef boost::shared_ptr<gr_constellation> gr_constellation_sptr;
%template(gr_constellation_sptr) boost::shared_ptr<gr_constellation>;
%rename(constellation) gr_make_constellation;
-gr_constellation_sptr gr_make_constellation(std::vector<gr_complex> constellation);
+gr_constellation_sptr gr_make_constellation(std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code);
%ignore gr_constellation;
class gr_constellation
{
public:
- gr_constellation (std::vector<gr_complex> constellation);
+ gr_constellation (std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code);
std::vector<gr_complex> points();
unsigned int decision_maker (gr_complex sample);
unsigned int bits_per_symbol ();
+ unsigned int arity ();
gr_constellation_sptr base ();
+ bool apply_pre_diff_code();
+ std::vector<unsigned int> pre_diff_code();
+};
+
+class gr_constellation_sector: public gr_constellation
+{
};
class gr_constellation_rect;
@@ -48,20 +57,18 @@ typedef boost::shared_ptr<gr_constellation_rect> gr_constellation_rect_sptr;
%template(gr_constellation_rect_sptr) boost::shared_ptr<gr_constellation_rect>;
%rename(constellation_rect) gr_make_constellation_rect;
gr_constellation_rect_sptr gr_make_constellation_rect(std::vector<gr_complex> constellation,
- unsigned int real_sectors, unsigned int imag_sectors,
- float width_real_sectors, float width_imag_sectors);
+ std::vector<unsigned int> pre_diff_code,
+ unsigned int real_sectors, unsigned int imag_sectors,
+ float width_real_sectors, float width_imag_sectors);
%ignore gr_constellation_rect;
class gr_constellation_rect : public gr_constellation_sector
{
public:
gr_constellation_rect (std::vector<gr_complex> constellation,
- unsigned int real_sectors, unsigned int imag_sectors,
- float width_real_sectors, float width_imag_sectors);
- std::vector<gr_complex> points ();
- unsigned int decision_maker (gr_complex sample);
- unsigned int bits_per_symbol ();
- gr_constellation_sptr base ();
+ std::vector<unsigned int> pre_diff_code,
+ unsigned int real_sectors, unsigned int imag_sectors,
+ float width_real_sectors, float width_imag_sectors);
};
class gr_constellation_psk;
@@ -69,18 +76,16 @@ typedef boost::shared_ptr<gr_constellation_psk> gr_constellation_psk_sptr;
%template(gr_constellation_psk_sptr) boost::shared_ptr<gr_constellation_psk>;
%rename(constellation_psk) gr_make_constellation_psk;
gr_constellation_psk_sptr gr_make_constellation_psk(std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int n_sectors);
%ignore gr_constellation_psk;
class gr_constellation_psk : public gr_constellation_sector
{
public:
- gr_constellation_psk (std::vector<gr_complex> constellation,
+ gr_constellation_psk (std::vector<gr_complex> constellation,
+ std::vector<unsigned int> pre_diff_code,
unsigned int n_sectors);
- std::vector<gr_complex> points ();
- unsigned int decision_maker (gr_complex sample);
- unsigned int bits_per_symbol ();
- gr_constellation_sptr base ();
};
class gr_constellation_bpsk;
@@ -94,10 +99,6 @@ class gr_constellation_bpsk : public gr_constellation
{
public:
gr_constellation_bpsk ();
- std::vector<gr_complex> points();
- unsigned int decision_maker (gr_complex sample);
- unsigned int bits_per_symbol ();
- gr_constellation_sptr base ();
};
class gr_constellation_qpsk;
@@ -111,9 +112,5 @@ class gr_constellation_qpsk : public gr_constellation
{
public:
gr_constellation_qpsk ();
- std::vector<gr_complex> points();
- unsigned int decision_maker (gr_complex sample);
- unsigned int bits_per_symbol ();
- gr_constellation_sptr base ();
};
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/generic_mod_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/generic_mod_demod.py
index 933de9113..b88ff72a0 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/generic_mod_demod.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/generic_mod_demod.py
@@ -27,7 +27,7 @@ Generic modulation and demodulation.
from gnuradio import gr
from gnuradio.modulation_utils2 import extract_kwargs_from_options_for_class
-from gnuradio.utils.gray_code import gray_code, inverse_gray_code
+from gnuradio.utils import mod_codes
# default values (used in __init__ and add_options)
_def_samples_per_symbol = 2
@@ -47,7 +47,6 @@ _def_phase_alpha = 0.1
_def_constellation_points = 16
# Whether differential coding is used.
_def_differential = True
-_def_gray_coded = True
def add_common_options(parser):
"""
@@ -59,10 +58,10 @@ def add_common_options(parser):
help="use differential encoding [default=%default]")
parser.add_option("", "--not-differential", action="store_false", dest="differential",
help="do not use differential encoding [default=%default]")
- parser.add_option("", "--gray-coded", action="store_true", dest="gray_coded", default=True,
- help="use gray code [default=%default]")
- parser.add_option("", "--not-gray-coded", action="store_false", dest="gray_coded",
- help="do not use gray code [default=%default]")
+ parser.add_option("", "--mod-code", type="choice", choices=mod_codes.codes,
+ default=mod_codes.NO_CODE,
+ help="Select modulation code from: %s [default=%%default]"
+ % (', '.join(mod_codes.codes),))
parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw,
help="set RRC excess bandwith factor [default=%default]")
@@ -75,7 +74,6 @@ class generic_mod(gr.hier_block2):
def __init__(self, constellation,
differential=_def_differential,
- gray_coded=_def_gray_coded,
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
verbose=_def_verbose,
@@ -106,7 +104,6 @@ class generic_mod(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
self._differential = differential
- self._gray_coded = gray_coded
if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2:
raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol)
@@ -119,8 +116,8 @@ class generic_mod(gr.hier_block2):
self.bytes2chunks = \
gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
- if gray_coded:
- self.symbol_mapper = gr.map_bb(gray_code(arity))
+ if self._constellation.apply_pre_diff_code():
+ self.symbol_mapper = gr.map_bb(self._constellation.pre_diff_code())
if differential:
self.diffenc = gr.diff_encoder_bb(arity)
@@ -140,7 +137,7 @@ class generic_mod(gr.hier_block2):
# Connect
blocks = [self, self.bytes2chunks]
- if gray_coded:
+ if self._constellation.apply_pre_diff_code():
blocks.append(self.symbol_mapper)
if differential:
blocks.append(self.diffenc)
@@ -184,7 +181,7 @@ class generic_mod(gr.hier_block2):
print "Modulation logging turned on."
self.connect(self.bytes2chunks,
gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat"))
- if self._gray_coded:
+ if self._constellation.apply_pre_diff_code():
self.connect(self.symbol_mapper,
gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.dat"))
if self._differential:
@@ -208,7 +205,6 @@ class generic_demod(gr.hier_block2):
def __init__(self, constellation,
samples_per_symbol=_def_samples_per_symbol,
differential=_def_differential,
- gray_coded=_def_gray_coded,
excess_bw=_def_excess_bw,
freq_alpha=_def_freq_alpha,
timing_alpha=_def_timing_alpha,
@@ -256,7 +252,6 @@ class generic_demod(gr.hier_block2):
self._timing_beta = _def_timing_beta
self._timing_max_dev=timing_max_dev
self._differential = differential
- self._gray_coded = gray_coded
if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2:
raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol)
@@ -296,8 +291,9 @@ class generic_demod(gr.hier_block2):
if differential:
self.diffdec = gr.diff_decoder_bb(arity)
- if gray_coded:
- self.symbol_mapper = gr.map_bb(inverse_gray_code(arity))
+ if self._constellation.apply_pre_diff_code():
+ self.symbol_mapper = gr.map_bb(
+ mod_codes.invert_code(self._constellation.pre_diff_code()))
# unpack the k bit vector into a stream of bits
self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol())
@@ -312,7 +308,7 @@ class generic_demod(gr.hier_block2):
blocks = [self, self.agc, self.freq_recov, self.time_recov, self.receiver]
if differential:
blocks.append(self.diffdec)
- if gray_coded:
+ if self._constellation.apply_pre_diff_code():
blocks.append(self.symbol_mapper)
blocks += [self.unpack, self]
self.connect(*blocks)
@@ -365,7 +361,7 @@ class generic_demod(gr.hier_block2):
if self._differential:
self.connect(self.diffdec,
gr.file_sink(gr.sizeof_char, "rx_diffdec.dat"))
- if self._gray_coded:
+ if self._constellation.apply_pre_diff_code():
self.connect(self.symbol_mapper,
gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat"))
self.connect(self.unpack,
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/psk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/psk2.py
index 4fd2c77fe..95f25e75a 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/psk2.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/psk2.py
@@ -28,17 +28,32 @@ from cmath import exp
from gnuradio import gr, modulation_utils2
from gnuradio.blks2impl.generic_mod_demod import generic_mod, generic_demod
+from gnuradio.utils import mod_codes, gray_code
# Default number of points in constellation.
_def_constellation_points = 4
-# Whether differential coding is used.
-_def_differential = True
-
+# The default encoding (e.g. gray-code, set-partition)
+_def_mod_code = mod_codes.GRAY_CODE
+
+def create_encodings(mod_code, arity):
+ post_diff_code = None
+ if mod_code not in mod_codes.codes:
+ raise ValueError('That modulation code does not exist.')
+ if mod_code == mod_codes.GRAY_CODE:
+ pre_diff_code = gray_code.gray_code(arity)
+ elif mod_code == mod_codes.SET_PARTITION_CODE:
+ pre_diff_code = set_partition_code.set_partition_code(arity)
+ elif mod_code == mod_codes.NO_CODE:
+ pre_diff_code = []
+ else:
+ raise ValueError('That modulation code is not implemented for this constellation.')
+ return (pre_diff_code, post_diff_code)
+
# /////////////////////////////////////////////////////////////////////////////
# PSK constellation
# /////////////////////////////////////////////////////////////////////////////
-def psk_constellation(m=_def_constellation_points):
+def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code):
"""
Creates a PSK constellation object.
"""
@@ -46,7 +61,11 @@ def psk_constellation(m=_def_constellation_points):
if (k != int(k)):
raise StandardError('Number of constellation points must be a power of two.')
points = [exp(2*pi*(0+1j)*i/m) for i in range(0,m)]
- constellation = gr.constellation_psk(points, m)
+ pre_diff_code, post_diff_code = create_encodings(mod_code, m)
+ if post_diff_code is not None:
+ inverse_post_diff_code = mod_codes.invert_code(post_diff_code)
+ points = [points[x] for x in inverse_post_diff_code]
+ constellation = gr.constellation_psk(points, pre_diff_code, m)
return constellation
# /////////////////////////////////////////////////////////////////////////////
@@ -56,6 +75,7 @@ def psk_constellation(m=_def_constellation_points):
class psk_mod(generic_mod):
def __init__(self, constellation_points=_def_constellation_points,
+ mod_code=_def_mod_code,
*args, **kwargs):
"""
@@ -67,7 +87,7 @@ class psk_mod(generic_mod):
See generic_mod block for list of parameters.
"""
- constellation = psk_constellation(constellation_points)
+ constellation = psk_constellation(constellation_points, mod_code)
super(psk_mod, self).__init__(constellation, *args, **kwargs)
# /////////////////////////////////////////////////////////////////////////////
@@ -78,6 +98,7 @@ class psk_mod(generic_mod):
class psk_demod(generic_demod):
def __init__(self, constellation_points=_def_constellation_points,
+ mod_code=_def_mod_code,
*args, **kwargs):
"""
@@ -89,7 +110,7 @@ class psk_demod(generic_demod):
See generic_demod block for list of parameters.
"""
- constellation = psk_constellation(constellation_points)
+ constellation = psk_constellation(constellation_points, mod_code)
super(psk_demod, self).__init__(constellation, *args, **kwargs)
#
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam.py
index 20ca6ee89..143f6e108 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/qam.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/qam.py
@@ -28,6 +28,7 @@ from math import pi, sqrt, log
from gnuradio import gr, modulation_utils2
from gnuradio.blks2impl.generic_mod_demod import generic_mod, generic_demod
from gnuradio.utils.gray_code import gray_code
+from gnuradio.utils import mod_codes
# Default number of points in constellation.
_def_constellation_points = 16
@@ -35,7 +36,7 @@ _def_constellation_points = 16
_def_differential = True
# Whether gray coding is used. If differential is True then gray
# coding is used within but not between each quadrant.
-_def_gray_coded = True
+_def_mod_code = mod_codes.NO_CODE
def is_power_of_four(x):
v = log(x)/log(4)
@@ -52,7 +53,7 @@ def get_bits(x, n, k):
# Remove all bits bigger than n+k-1
return v % pow(2, k)
-def make_differential_constellation(m, gray_coded=_def_gray_coded):
+def make_differential_constellation(m, gray_coded):
"""
Create a constellation with m possible symbols where m must be
a power of 4.
@@ -111,7 +112,7 @@ def make_differential_constellation(m, gray_coded=_def_gray_coded):
return const_map
-def make_not_differential_constellation(m, gray_coded=_def_gray_coded):
+def make_not_differential_constellation(m, gray_coded):
side = pow(m, 0.5)
if (not isinstance(m, int) or m < 4 or not is_power_of_four(m)):
raise ValueError("m must be a power of 4 integer.")
@@ -145,17 +146,26 @@ def make_not_differential_constellation(m, gray_coded=_def_gray_coded):
def qam_constellation(constellation_points=_def_constellation_points,
differential=_def_differential,
- gray_coded=_def_gray_coded,):
+ mod_code=_def_mod_code):
"""
Creates a QAM constellation object.
"""
+ if mod_code == mod_codes.GRAY_CODE:
+ gray_coded = True
+ elif mod_code == mod_codes.NO_CODE:
+ gray_coded = False
+ else:
+ raise ValueError("Mod code is not implemented for QAM")
if differential:
points = make_differential_constellation(constellation_points, gray_coded)
else:
points = make_not_differential_constellation(constellation_points, gray_coded)
side = int(sqrt(constellation_points))
width = 2.0/(side-1)
- constellation = gr.constellation_rect(points, side, side, width, width)
+ # No pre-diff code
+ # Should add one so that we can gray-code the quadrant bits too.
+ pre_diff_code = []
+ constellation = gr.constellation_rect(points, pre_diff_code, side, side, width, width)
return constellation
# /////////////////////////////////////////////////////////////////////////////
@@ -166,7 +176,7 @@ class qam_mod(generic_mod):
def __init__(self, constellation_points=_def_constellation_points,
differential=_def_differential,
- gray_coded=_def_gray_coded,
+ mod_code=_def_mod_code,
*args, **kwargs):
"""
@@ -178,11 +188,11 @@ class qam_mod(generic_mod):
See generic_mod block for list of parameters.
"""
- constellation = qam_constellation(constellation_points, differential, gray_coded)
+ constellation = qam_constellation(constellation_points, differential, mod_code)
# We take care of the gray coding in the constellation generation so it doesn't
# need to be done in the block.
super(qam_mod, self).__init__(constellation, differential=differential,
- gray_coded=False, *args, **kwargs)
+ *args, **kwargs)
# /////////////////////////////////////////////////////////////////////////////
# QAM demodulator
@@ -193,7 +203,7 @@ class qam_demod(generic_demod):
def __init__(self, constellation_points=_def_constellation_points,
differential=_def_differential,
- gray_coded=_def_gray_coded,
+ mod_code=_def_mod_code,
*args, **kwargs):
"""
@@ -204,11 +214,10 @@ class qam_demod(generic_demod):
See generic_demod block for list of parameters.
"""
- constellation = qam_constellation(constellation_points, differential, gray_coded)
+ constellation = qam_constellation(constellation_points, differential, mod_code)
# We take care of the gray coding in the constellation generation so it doesn't
# need to be done in the block.
super(qam_demod, self).__init__(constellation, differential=differential,
- gray_coded=False,
*args, **kwargs)
#
diff --git a/gnuradio-core/src/python/gnuradio/utils/Makefile.am b/gnuradio-core/src/python/gnuradio/utils/Makefile.am
index 4c8e46891..c0ac613b9 100644
--- a/gnuradio-core/src/python/gnuradio/utils/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/utils/Makefile.am
@@ -30,6 +30,7 @@ TESTS = \
nobase_utilspython_PYTHON = \
__init__.py \
gray_code.py \
+ mod_codes.py \
doxyxml/__init__.py \
doxyxml/base.py \
doxyxml/doxyindex.py \
diff --git a/gnuradio-core/src/python/gnuradio/utils/gray_code.py b/gnuradio-core/src/python/gnuradio/utils/gray_code.py
index 7d3e0fcb8..70cb9d7e2 100644
--- a/gnuradio-core/src/python/gnuradio/utils/gray_code.py
+++ b/gnuradio-core/src/python/gnuradio/utils/gray_code.py
@@ -43,9 +43,3 @@ _gray_code_generator = GrayCodeGenerator()
gray_code = _gray_code_generator.get_gray_code
-def inverse_gray_code(length):
- gc = enumerate(gray_code(length))
- igc = [(b, a) for (a, b) in gc]
- igc.sort()
- return [a for (b, a) in igc]
-
diff --git a/gnuradio-core/src/python/gnuradio/utils/mod_codes.py b/gnuradio-core/src/python/gnuradio/utils/mod_codes.py
new file mode 100644
index 000000000..db3dc252d
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/utils/mod_codes.py
@@ -0,0 +1,11 @@
+GRAY_CODE = 'gray'
+SET_PARTITION_CODE = 'set-partition'
+NO_CODE = 'none'
+
+codes = (GRAY_CODE, SET_PARTITION_CODE, NO_CODE)
+
+def invert_code(code):
+ c = enumerate(code)
+ ic = [(b, a) for (a, b) in c]
+ ic.sort()
+ return [a for (b, a) in ic]