diff options
author | Tom Rondeau | 2011-10-12 22:42:55 -0400 |
---|---|---|
committer | Tom Rondeau | 2011-10-12 22:42:55 -0400 |
commit | d53109a88522d243bf684ffe1a9aad2801c52f07 (patch) | |
tree | 683f27b18e62048063b186676eddc466c845d29b | |
parent | d47f0aeab7343fb033352e2ddb787c1dc95d660d (diff) | |
download | gnuradio-d53109a88522d243bf684ffe1a9aad2801c52f07.tar.gz gnuradio-d53109a88522d243bf684ffe1a9aad2801c52f07.tar.bz2 gnuradio-d53109a88522d243bf684ffe1a9aad2801c52f07.zip |
digital: OFDM using new psk and qam modules for constellations. Also, psk2->psk updated in all files and examples.
-rw-r--r-- | gr-digital/grc/digital_psk_mod.xml | 2 | ||||
-rw-r--r-- | gr-digital/python/Makefile.am | 1 | ||||
-rw-r--r-- | gr-digital/python/__init__.py | 4 | ||||
-rw-r--r-- | gr-digital/python/ofdm.py | 14 | ||||
-rw-r--r-- | gr-digital/python/psk.py | 174 | ||||
-rw-r--r-- | gr-digital/python/psk2.py | 122 | ||||
-rwxr-xr-x | gr-digital/python/qa_clock_recovery_mm.py | 2 | ||||
-rwxr-xr-x | gr-digital/python/qa_constellation.py | 4 | ||||
-rwxr-xr-x | gr-digital/python/qa_costas_loop_cc.py | 4 | ||||
-rwxr-xr-x | gr-digital/python/qa_mpsk_receiver.py | 2 | ||||
-rw-r--r-- | gr-digital/python/qam.py | 4 |
11 files changed, 123 insertions, 210 deletions
diff --git a/gr-digital/grc/digital_psk_mod.xml b/gr-digital/grc/digital_psk_mod.xml index 34ed42c97..cafcf4e50 100644 --- a/gr-digital/grc/digital_psk_mod.xml +++ b/gr-digital/grc/digital_psk_mod.xml @@ -30,7 +30,7 @@ <name>PSK Mod</name> <key>digital_psk_mod</key> <import>from gnuradio import digital</import> - <make>digital.psk2.psk_mod( + <make>digital.psk.psk_mod( constellation_points=$constellation_points, mod_code=$mod_code, differential=$differential, diff --git a/gr-digital/python/Makefile.am b/gr-digital/python/Makefile.am index 9c7d557ca..d8c332ff8 100644 --- a/gr-digital/python/Makefile.am +++ b/gr-digital/python/Makefile.am @@ -64,7 +64,6 @@ digital_PYTHON = \ packet_utils.py \ pkt.py \ psk.py \ - psk2.py \ qam.py \ qpsk.py endif diff --git a/gr-digital/python/__init__.py b/gr-digital/python/__init__.py index 56523f955..7e7832481 100644 --- a/gr-digital/python/__init__.py +++ b/gr-digital/python/__init__.py @@ -26,10 +26,10 @@ utilities, and examples for doing digital modulation and demodulation. # The presence of this file turns this directory into a Python package from digital_swig import * -from psk2 import * +from psk import * +from qam import * from bpsk import * from qpsk import * -from qam import * from gmsk import * from cpm import * from pkt import * diff --git a/gr-digital/python/ofdm.py b/gr-digital/python/ofdm.py index c7654f0de..9f57920ef 100644 --- a/gr-digital/python/ofdm.py +++ b/gr-digital/python/ofdm.py @@ -89,10 +89,13 @@ class ofdm_mod(gr.hier_block2): if self._modulation == "qpsk": rot = (0.707+0.707j) + # FIXME: pass the constellation objects instead of just the points if(self._modulation.find("psk") >= 0): - rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) + constel = psk.psk_constellation(arity) + rotated_const = map(lambda pt: pt * rot, constel.points()) elif(self._modulation.find("qam") >= 0): - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + constel = qam.qam_constellation(arity) + rotated_const = map(lambda pt: pt * rot, constel.points()) #print rotated_const self._pkt_input = digital_swig.ofdm_mapper_bcv(rotated_const, msgq_limit, @@ -226,10 +229,13 @@ class ofdm_demod(gr.hier_block2): if self._modulation == "qpsk": rot = (0.707+0.707j) + # FIXME: pass the constellation objects instead of just the points if(self._modulation.find("psk") >= 0): - rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) + constel = psk.psk_constellation(arity) + rotated_const = map(lambda pt: pt * rot, constel.points()) elif(self._modulation.find("qam") >= 0): - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) + constel = qam.qam_constellation(arity) + rotated_const = map(lambda pt: pt * rot, constel.points()) #print rotated_const phgain = 0.25 diff --git a/gr-digital/python/psk.py b/gr-digital/python/psk.py index acedf3b69..82781e63b 100644 --- a/gr-digital/python/psk.py +++ b/gr-digital/python/psk.py @@ -1,5 +1,5 @@ # -# Copyright 2005,2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -19,76 +19,104 @@ # Boston, MA 02110-1301, USA. # -from math import pi, sqrt, log10 -import math, cmath - -# The following algorithm generates Gray coded constellations for M-PSK for M=[2,4,8] -def make_gray_constellation(m): - # number of bits/symbol (log2(M)) - k = int(log10(m) / log10(2.0)) - - coeff = 1 - const_map = [] - bits = [0]*3 - for i in range(m): - # get a vector of the k bits to use in this mapping - bits[3-k:3] = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(k)] - - theta = -(2*bits[0]-1)*(2*pi/m)*(bits[0]+abs(bits[1]-bits[2])+2*bits[1]) - re = math.cos(theta) - im = math.sin(theta) - const_map.append(complex(re, im)) # plug it into the constellation +""" +PSK modulation and demodulation. +""" + +from math import pi, log +from cmath import exp + +import digital_swig +import modulation_utils2 +from utils import mod_codes, gray_code +from generic_mod_demod import generic_mod, generic_demod + +# Default number of points in constellation. +_def_constellation_points = 4 +# 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) - # return the constellation; by default, it is normalized - return const_map - -# This makes a constellation that increments around the unit circle -def make_constellation(m): - return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)] - -# Common definition of constellations for Tx and Rx -constellation = { - 2 : make_constellation(2), # BPSK - 4 : make_constellation(4), # QPSK - 8 : make_constellation(8) # 8PSK - } - -gray_constellation = { - 2 : make_gray_constellation(2), # BPSK - 4 : make_gray_constellation(4), # QPSK - 8 : make_gray_constellation(8) # 8PSK - } - -# ----------------------- -# Do Gray code -# ----------------------- -# binary to gray coding -- constellation does Gray coding -binary_to_gray = { - 2 : range(2), - 4 : [0,1,3,2], - 8 : [0, 1, 3, 2, 7, 6, 4, 5] - } - -# gray to binary -gray_to_binary = { - 2 : range(2), - 4 : [0,1,3,2], - 8 : [0, 1, 3, 2, 6, 7, 5, 4] - } - -# ----------------------- -# Don't Gray code -# ----------------------- -# identity mapping -binary_to_ungray = { - 2 : range(2), - 4 : range(4), - 8 : range(8) - } - -# identity mapping -ungray_to_binary = { - 2 : range(2), - 4 : range(4), - 8 : range(8) - } +# ///////////////////////////////////////////////////////////////////////////// +# PSK constellation +# ///////////////////////////////////////////////////////////////////////////// + +def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code): + """ + Creates a PSK constellation object. + """ + k = log(m) / log(2.0) + 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)] + 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 = digital_swig.constellation_psk(points, pre_diff_code, m) + return constellation + +# ///////////////////////////////////////////////////////////////////////////// +# PSK modulator +# ///////////////////////////////////////////////////////////////////////////// + +class psk_mod(generic_mod): + + def __init__(self, constellation_points=_def_constellation_points, + mod_code=_def_mod_code, + *args, **kwargs): + + """ + Hierarchical block for RRC-filtered PSK modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + See generic_mod block for list of parameters. + """ + + constellation = psk_constellation(constellation_points, mod_code) + super(psk_mod, self).__init__(constellation, *args, **kwargs) + +# ///////////////////////////////////////////////////////////////////////////// +# PSK demodulator +# +# ///////////////////////////////////////////////////////////////////////////// + +class psk_demod(generic_demod): + + def __init__(self, constellation_points=_def_constellation_points, + mod_code=_def_mod_code, + *args, **kwargs): + + """ + Hierarchical block for RRC-filtered PSK modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + See generic_demod block for list of parameters. + """ + + constellation = psk_constellation(constellation_points, mod_code) + super(psk_demod, self).__init__(constellation, *args, **kwargs) + +# +# Add these to the mod/demod registry +# +modulation_utils2.add_type_1_mod('psk', psk_mod) +modulation_utils2.add_type_1_demod('psk', psk_demod) +modulation_utils2.add_type_1_constellation('psk', psk_constellation) diff --git a/gr-digital/python/psk2.py b/gr-digital/python/psk2.py deleted file mode 100644 index 82781e63b..000000000 --- a/gr-digital/python/psk2.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright 2005,2006,2011 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -""" -PSK modulation and demodulation. -""" - -from math import pi, log -from cmath import exp - -import digital_swig -import modulation_utils2 -from utils import mod_codes, gray_code -from generic_mod_demod import generic_mod, generic_demod - -# Default number of points in constellation. -_def_constellation_points = 4 -# 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, mod_code=_def_mod_code): - """ - Creates a PSK constellation object. - """ - k = log(m) / log(2.0) - 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)] - 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 = digital_swig.constellation_psk(points, pre_diff_code, m) - return constellation - -# ///////////////////////////////////////////////////////////////////////////// -# PSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class psk_mod(generic_mod): - - def __init__(self, constellation_points=_def_constellation_points, - mod_code=_def_mod_code, - *args, **kwargs): - - """ - Hierarchical block for RRC-filtered PSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - See generic_mod block for list of parameters. - """ - - constellation = psk_constellation(constellation_points, mod_code) - super(psk_mod, self).__init__(constellation, *args, **kwargs) - -# ///////////////////////////////////////////////////////////////////////////// -# PSK demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class psk_demod(generic_demod): - - def __init__(self, constellation_points=_def_constellation_points, - mod_code=_def_mod_code, - *args, **kwargs): - - """ - Hierarchical block for RRC-filtered PSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - See generic_demod block for list of parameters. - """ - - constellation = psk_constellation(constellation_points, mod_code) - super(psk_demod, self).__init__(constellation, *args, **kwargs) - -# -# Add these to the mod/demod registry -# -modulation_utils2.add_type_1_mod('psk', psk_mod) -modulation_utils2.add_type_1_demod('psk', psk_demod) -modulation_utils2.add_type_1_constellation('psk', psk_constellation) diff --git a/gr-digital/python/qa_clock_recovery_mm.py b/gr-digital/python/qa_clock_recovery_mm.py index 5ef86eda0..f4c345b03 100755 --- a/gr-digital/python/qa_clock_recovery_mm.py +++ b/gr-digital/python/qa_clock_recovery_mm.py @@ -21,7 +21,7 @@ # from gnuradio import gr, gr_unittest -import digital_swig, psk2 +import digital_swig import random, cmath class test_clock_recovery_mm(gr_unittest.TestCase): diff --git a/gr-digital/python/qa_constellation.py b/gr-digital/python/qa_constellation.py index 264ff7de6..b17d2a0fc 100755 --- a/gr-digital/python/qa_constellation.py +++ b/gr-digital/python/qa_constellation.py @@ -28,7 +28,7 @@ from utils import mod_codes import digital_swig # import from local folder -import psk2 +import psk import qam tested_mod_codes = (mod_codes.NO_CODE, mod_codes.GRAY_CODE) @@ -65,7 +65,7 @@ def threed_constell(): return digital_swig.constellation_calcdist(points, [], rot_sym, dim) tested_constellation_info = ( - (psk2.psk_constellation, + (psk.psk_constellation, {'m': (2, 4, 8, 16, 32, 64), 'mod_code': tested_mod_codes, }, True, None), diff --git a/gr-digital/python/qa_costas_loop_cc.py b/gr-digital/python/qa_costas_loop_cc.py index 124159dba..75fdbc2f8 100755 --- a/gr-digital/python/qa_costas_loop_cc.py +++ b/gr-digital/python/qa_costas_loop_cc.py @@ -21,7 +21,7 @@ # from gnuradio import gr, gr_unittest -import digital_swig, psk2 +import digital_swig, psk import random, cmath class test_costas_loop_cc(gr_unittest.TestCase): @@ -125,7 +125,7 @@ class test_costas_loop_cc(gr_unittest.TestCase): self.test = digital_swig.costas_loop_cc(natfreq, order) rot = cmath.exp(-cmath.pi/8.0j) # rotate to match Costas rotation - const = psk2.psk_constellation(order) + const = psk.psk_constellation(order) data = [random.randint(0,7) for i in xrange(100)] data = [2*rot*const.points()[d] for d in data] diff --git a/gr-digital/python/qa_mpsk_receiver.py b/gr-digital/python/qa_mpsk_receiver.py index 6531e59f7..e1f16ee67 100755 --- a/gr-digital/python/qa_mpsk_receiver.py +++ b/gr-digital/python/qa_mpsk_receiver.py @@ -21,7 +21,7 @@ # from gnuradio import gr, gr_unittest -import digital_swig, psk2 +import digital_swig import random, cmath class test_mpsk_receiver(gr_unittest.TestCase): diff --git a/gr-digital/python/qam.py b/gr-digital/python/qam.py index a5a2e6c2c..2a7e51495 100644 --- a/gr-digital/python/qam.py +++ b/gr-digital/python/qam.py @@ -30,6 +30,7 @@ from generic_mod_demod import generic_mod, generic_demod from utils.gray_code import gray_code from utils import mod_codes import modulation_utils2 +import digital_swig # Default number of points in constellation. _def_constellation_points = 16 @@ -164,7 +165,8 @@ def qam_constellation(constellation_points=_def_constellation_points, # 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, 4, side, side, width, width) + constellation = digital_swig.constellation_rect(points, pre_diff_code, 4, + side, side, width, width) return constellation # ///////////////////////////////////////////////////////////////////////////// |