summaryrefslogtreecommitdiff
path: root/gr-digital/python/digital/cpm.py
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/python/digital/cpm.py')
-rw-r--r--gr-digital/python/digital/cpm.py121
1 files changed, 64 insertions, 57 deletions
diff --git a/gr-digital/python/digital/cpm.py b/gr-digital/python/digital/cpm.py
index 322c3f0bfc..0752f01d66 100644
--- a/gr-digital/python/digital/cpm.py
+++ b/gr-digital/python/digital/cpm.py
@@ -1,37 +1,44 @@
#
-# CPM modulation and demodulation.
+# CPM modulation and demodulation.
#
#
# Copyright 2005-2007,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.
-#
+#
+
+from __future__ import print_function
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import unicode_literals
# See gnuradio-examples/python/digital for examples
+
+from math import pi
+import numpy
+
from gnuradio import gr, filter
from gnuradio import analog
from gnuradio import blocks
-from math import pi
-import numpy
+from . import digital_swig
+from . import modulation_utils
-import digital_swig
-import modulation_utils
# default values (used in __init__ and add_options)
_def_samples_per_symbol = 2
@@ -53,16 +60,16 @@ _def_log = False
class cpm_mod(gr.hier_block2):
"""
Hierarchical block for Continuous Phase modulation.
-
+
The input is a byte stream (unsigned char) representing packed
bits and the output is the complex modulated signal at baseband.
-
+
See Proakis for definition of generic CPM signals:
s(t)=exp(j phi(t))
phi(t)= 2 pi h int_0^t f(t') dt'
f(t)=sum_k a_k g(t-kT)
(normalizing assumption: int_0^infty g(t) dt = 1/2)
-
+
Args:
samples_per_symbol: samples per baud >= 2 (integer)
bits_per_symbol: bits per symbol (integer)
@@ -76,21 +83,21 @@ class cpm_mod(gr.hier_block2):
debug: Print modulation data to files? (boolean)
"""
- def __init__(self,
+ def __init__(self,
samples_per_symbol=_def_samples_per_symbol,
bits_per_symbol=_def_bits_per_symbol,
h_numerator=_def_h_numerator,
h_denominator=_def_h_denominator,
cpm_type=_def_cpm_type,
- bt=_def_bt,
- symbols_per_pulse=_def_symbols_per_pulse,
+ bt=_def_bt,
+ symbols_per_pulse=_def_symbols_per_pulse,
generic_taps=_def_generic_taps,
verbose=_def_verbose,
log=_def_log):
- gr.hier_block2.__init__(self, "cpm_mod",
- gr.io_signature(1, 1, gr.sizeof_char), # Input signature
- gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+ gr.hier_block2.__init__(self, "cpm_mod",
+ gr.io_signature(1, 1, gr.sizeof_char), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
self._samples_per_symbol = samples_per_symbol
self._bits_per_symbol = bits_per_symbol
@@ -99,29 +106,29 @@ class cpm_mod(gr.hier_block2):
self._cpm_type = cpm_type
self._bt=bt
if cpm_type == 0 or cpm_type == 2 or cpm_type == 3: # CPFSK, RC, Generic
- self._symbols_per_pulse = symbols_per_pulse
+ self._symbols_per_pulse = symbols_per_pulse
elif cpm_type == 1: # GMSK
- self._symbols_per_pulse = 4
+ self._symbols_per_pulse = 4
else:
- raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,))
+ raise TypeError("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,))
self._generic_taps=numpy.array(generic_taps)
if samples_per_symbol < 2:
- raise TypeError, ("samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,))
+ raise TypeError("samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,))
self.nsymbols = 2**bits_per_symbol
self.sym_alphabet = numpy.arange(-(self.nsymbols-1),self.nsymbols,2).tolist()
- self.ntaps = int(self._symbols_per_pulse * samples_per_symbol)
- sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol
+ self.ntaps = int(self._symbols_per_pulse * samples_per_symbol)
+ sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol
# Unpack Bytes into bits_per_symbol groups
self.B2s = blocks.packed_to_unpacked_bb(bits_per_symbol,gr.GR_MSB_FIRST)
-
-
- # Turn it into symmetric PAM data.
+
+
+ # Turn it into symmetric PAM data.
self.pam = digital_swig.chunks_to_symbols_bf(self.sym_alphabet,1)
# Generate pulse (sum of taps = samples_per_symbol/2)
@@ -129,72 +136,72 @@ class cpm_mod(gr.hier_block2):
self.taps= (1.0/self._symbols_per_pulse/2,) * self.ntaps
elif cpm_type == 1: # GMSK
gaussian_taps = filter.firdes.gaussian(
- 1.0/2, # gain
+ 1.0 / 2, # gain
samples_per_symbol, # symbol_rate
bt, # bandwidth * symbol time
self.ntaps # number of taps
)
- sqwave = (1,) * samples_per_symbol # rectangular window
- self.taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave))
+ sqwave = (1,) * samples_per_symbol # rectangular window
+ self.taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave))
elif cpm_type == 2: # Raised Cosine
# generalize it for arbitrary roll-off factor
- self.taps = (1-numpy.cos(2*pi*numpy.arange(0,self.ntaps)/samples_per_symbol/self._symbols_per_pulse))/(2*self._symbols_per_pulse)
+ self.taps = (1-numpy.cos(2*pi*numpy.arange(0 / self.ntaps/samples_per_symbol/self._symbols_per_pulse)),(2*self._symbols_per_pulse))
elif cpm_type == 3: # Generic CPM
self.taps = generic_taps
else:
- raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,))
+ raise TypeError("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,))
self.filter = filter.pfb.arb_resampler_fff(samples_per_symbol, self.taps)
- # FM modulation
- self.fmmod = analog.frequency_modulator_fc(sensitivity)
-
+ # FM modulation
+ self.fmmod = analog.frequency_modulator_fc(sensitivity)
+
if verbose:
self._print_verbage()
-
+
if log:
self._setup_logging()
- # Connect
- self.connect(self, self.B2s, self.pam, self.filter, self.fmmod, self)
+ # Connect
+ self.connect(self, self.B2s, self.pam, self.filter, self.fmmod, self)
def samples_per_symbol(self):
return self._samples_per_symbol
-
- def bits_per_symbol(self):
+
+ def bits_per_symbol(self):
return self._bits_per_symbol
-
- def h_numerator(self):
+
+ def h_numerator(self):
return self._h_numerator
- def h_denominator(self):
+ def h_denominator(self):
return self._h_denominator
- def cpm_type(self):
+ def cpm_type(self):
return self._cpm_type
- def bt(self):
+ def bt(self):
return self._bt
- def symbols_per_pulse(self):
+ def symbols_per_pulse(self):
return self._symbols_per_pulse
def _print_verbage(self):
- print "Samples per symbol = %d" % self._samples_per_symbol
- print "Bits per symbol = %d" % self._bits_per_symbol
- print "h = " , self._h_numerator , " / " , self._h_denominator
- print "Symbol alphabet = " , self.sym_alphabet
- print "Symbols per pulse = %d" % self._symbols_per_pulse
- print "taps = " , self.taps
-
- print "CPM type = %d" % self._cpm_type
+ print("Samples per symbol = %d" % self._samples_per_symbol)
+ print("Bits per symbol = %d" % self._bits_per_symbol)
+ print("h = " , self._h_numerator , " / " , self._h_denominator)
+ print("Symbol alphabet = " , self.sym_alphabet)
+ print("Symbols per pulse = %d" % self._symbols_per_pulse)
+ print("taps = " , self.taps)
+
+ print("CPM type = %d" % self._cpm_type)
if self._cpm_type == 1:
- print "Gaussian filter BT = %.2f" % self._bt
+ print("Gaussian filter BT = %.2f" % self._bt)
def _setup_logging(self):
- print "Modulation logging turned on."
+ print("Modulation logging turned on.")
self.connect(self.B2s,
blocks.file_sink(gr.sizeof_float, "symbols.dat"))
self.connect(self.pam,