summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/python
diff options
context:
space:
mode:
authorBen Reynwar2011-02-09 14:19:40 -0700
committerBen Reynwar2011-02-09 14:19:40 -0700
commite4df34e785651787930b2b2fcd4c9fbdeac5d8fc (patch)
tree1a363fd74dbb184e2d78d6d278d7c4a27195b808 /gnuradio-core/src/python
parent765c9f6e947d6dd765d1f33f3d4668f0c69486ee (diff)
downloadgnuradio-e4df34e785651787930b2b2fcd4c9fbdeac5d8fc.tar.gz
gnuradio-e4df34e785651787930b2b2fcd4c9fbdeac5d8fc.tar.bz2
gnuradio-e4df34e785651787930b2b2fcd4c9fbdeac5d8fc.zip
Changed constellation objects so that codings besides gray code can be used.
Diffstat (limited to 'gnuradio-core/src/python')
-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
6 files changed, 74 insertions, 42 deletions
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]