summaryrefslogtreecommitdiff
path: root/gr-digital/python/generic_mod_demod.py
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/python/generic_mod_demod.py')
-rw-r--r--gr-digital/python/generic_mod_demod.py194
1 files changed, 92 insertions, 102 deletions
diff --git a/gr-digital/python/generic_mod_demod.py b/gr-digital/python/generic_mod_demod.py
index f8051db0a..dc69fc0b5 100644
--- a/gr-digital/python/generic_mod_demod.py
+++ b/gr-digital/python/generic_mod_demod.py
@@ -27,9 +27,9 @@ Generic modulation and demodulation.
from gnuradio import gr
from modulation_utils2 import extract_kwargs_from_options_for_class
-#from gnuradio.digital.utils import mod_codes
from utils import mod_codes
import digital_swig
+import math
# default values (used in __init__ and add_options)
_def_samples_per_symbol = 2
@@ -38,28 +38,29 @@ _def_verbose = False
_def_log = False
# Frequency correction
-_def_freq_alpha = 0.010
+_def_freq_bw = 2*math.pi/100.0
# Symbol timing recovery
-_def_timing_alpha = 0.100
-_def_timing_beta = 0.010
+_def_timing_bw = 2*math.pi/100.0
_def_timing_max_dev = 1.5
# Fine frequency / Phase correction
-_def_phase_alpha = 0.1
+_def_phase_bw = 2*math.pi/100.0
# Number of points in constellation
_def_constellation_points = 16
# Whether differential coding is used.
-_def_differential = True
+_def_differential = False
def add_common_options(parser):
"""
Sets options common to both modulator and demodulator.
"""
parser.add_option("-p", "--constellation-points", type="int", default=_def_constellation_points,
- help="set the number of constellation points (must be a power of 2 (power of 4 for QAM) [default=%default]")
- parser.add_option("", "--differential", action="store_true", dest="differential", default=True,
+ help="set the number of constellation points (must be a power of 2 for psk, power of 4 for QAM) [default=%default]")
+ parser.add_option("", "--non-differential", action="store_false",
+ dest="differential",
+ help="do not use differential encoding [default=False]")
+ parser.add_option("", "--differential", action="store_true",
+ dest="differential", default=True,
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("", "--mod-code", type="choice", choices=mod_codes.codes,
default=mod_codes.NO_CODE,
help="Select modulation code from: %s [default=%%default]"
@@ -78,6 +79,7 @@ class generic_mod(gr.hier_block2):
differential=_def_differential,
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
+ gray_coded=True,
verbose=_def_verbose,
log=_def_log):
"""
@@ -89,9 +91,11 @@ class generic_mod(gr.hier_block2):
@param constellation: determines the modulation type
@type constellation: gnuradio.digital.gr_constellation
@param samples_per_symbol: samples per baud >= 2
- @type samples_per_symbol: integer
+ @type samples_per_symbol: float
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
+ @param gray_coded: turn gray coding on/off
+ @type gray_coded: bool
@param verbose: Print information about modulator?
@type verbose: bool
@param log: Log modulation data to files?
@@ -106,19 +110,17 @@ class generic_mod(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
self._differential = differential
-
- 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)
-
- ntaps = 11 * self._samples_per_symbol
+ if self._samples_per_symbol < 2:
+ raise TypeError, ("sbp must be >= 2, is %f" % self._samples_per_symbol)
+
arity = pow(2,self.bits_per_symbol())
# turn bytes into k-bit vectors
self.bytes2chunks = \
gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
- if self._constellation.apply_pre_diff_code():
+ if gray_coded == True:
self.symbol_mapper = gr.map_bb(self._constellation.pre_diff_code())
if differential:
@@ -127,19 +129,20 @@ class generic_mod(gr.hier_block2):
self.chunks2symbols = gr.chunks_to_symbols_bc(self._constellation.points())
# pulse shaping filter
- self.rrc_taps = gr.firdes.root_raised_cosine(
- self._samples_per_symbol, # gain (samples_per_symbol since we're
- # interpolating by samples_per_symbol)
- self._samples_per_symbol, # sampling rate
- 1.0, # symbol rate
- self._excess_bw, # excess bandwidth (roll-off factor)
+ nfilts = 32
+ ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each
+ self.rrc_taps = gr.firdes.root_raised_cosine(
+ nfilts, # gain
+ nfilts, # sampling rate based on 32 filters in resampler
+ 1.0, # symbol rate
+ self._excess_bw, # excess bandwidth (roll-off factor)
ntaps)
- self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol,
+ self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol,
self.rrc_taps)
# Connect
blocks = [self, self.bytes2chunks]
- if self._constellation.apply_pre_diff_code():
+ if gray_coded == True:
blocks.append(self.symbol_mapper)
if differential:
blocks.append(self.diffenc)
@@ -182,17 +185,17 @@ class generic_mod(gr.hier_block2):
def _setup_logging(self):
print "Modulation logging turned on."
self.connect(self.bytes2chunks,
- gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat"))
+ gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.8b"))
if self._constellation.apply_pre_diff_code():
self.connect(self.symbol_mapper,
- gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.dat"))
+ gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.8b"))
if self._differential:
self.connect(self.diffenc,
- gr.file_sink(gr.sizeof_char, "tx_diffenc.dat"))
+ gr.file_sink(gr.sizeof_char, "tx_diffenc.8b"))
self.connect(self.chunks2symbols,
- gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat"))
+ gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.32fc"))
self.connect(self.rrc_filter,
- gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat"))
+ gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.32fc"))
# /////////////////////////////////////////////////////////////////////////////
@@ -208,10 +211,10 @@ class generic_demod(gr.hier_block2):
samples_per_symbol=_def_samples_per_symbol,
differential=_def_differential,
excess_bw=_def_excess_bw,
- freq_alpha=_def_freq_alpha,
- timing_alpha=_def_timing_alpha,
- timing_max_dev=_def_timing_max_dev,
- phase_alpha=_def_phase_alpha,
+ gray_coded=True,
+ freq_bw=_def_freq_bw,
+ timing_bw=_def_timing_bw,
+ phase_bw=_def_phase_bw,
verbose=_def_verbose,
log=_def_log):
"""
@@ -226,14 +229,14 @@ class generic_demod(gr.hier_block2):
@type samples_per_symbol: float
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
- @param freq_alpha: loop filter gain for frequency recovery
- @type freq_alpha: float
- @param timing_alpha: loop alpha gain for timing recovery
- @type timing_alpha: float
- @param timing_max_dev: timing loop maximum rate deviations
- @type timing_max_dev: float
- @param phase_alpha: loop filter gain in phase loop
- @type phase_alphas: float
+ @param gray_coded: turn gray coding on/off
+ @type gray_coded: bool
+ @param freq_bw: loop filter lock-in bandwidth
+ @type freq_bw: float
+ @param timing_bw: timing recovery loop lock-in bandwidth
+ @type timing_bw: float
+ @param phase_bw: phase recovery loop bandwidth
+ @type phase_bw: float
@param verbose: Print information about modulator?
@type verbose: bool
@param debug: Print modualtion data to files?
@@ -247,53 +250,46 @@ class generic_demod(gr.hier_block2):
self._constellation = constellation.base()
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
- self._phase_alpha = phase_alpha
- self._freq_alpha = freq_alpha
- self._freq_beta = 0.10*self._freq_alpha
- self._timing_alpha = timing_alpha
- self._timing_beta = _def_timing_beta
- self._timing_max_dev=timing_max_dev
+ self._phase_bw = phase_bw
+ self._freq_bw = freq_bw
+ self._timing_bw = timing_bw
+ self._timing_max_dev= _def_timing_max_dev
self._differential = differential
- 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)
+ if self._samples_per_symbol < 2:
+ raise TypeError, ("sbp must be >= 2, is %d" % self._samples_per_symbol)
arity = pow(2,self.bits_per_symbol())
+ nfilts = 32
+ ntaps = 11 * int(self._samples_per_symbol*nfilts)
+
# Automatic gain control
self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
# Frequency correction
- self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
- 11*int(self._samples_per_symbol),
- self._freq_alpha, self._freq_beta)
+ fll_ntaps = 55
+ self.freq_recov = digital_swig.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
+ fll_ntaps, self._freq_bw)
# symbol timing recovery with RRC data filter
- nfilts = 32
- ntaps = 11 * int(self._samples_per_symbol*nfilts)
- taps = gr.firdes.root_raised_cosine(nfilts, nfilts,
- 1.0/float(self._samples_per_symbol),
- self._excess_bw, ntaps)
+ taps = gr.firdes.root_raised_cosine(nfilts, nfilts*self._samples_per_symbol,
+ 1.0, self._excess_bw, ntaps)
self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
- self._timing_alpha,
- taps, nfilts, nfilts/2, self._timing_max_dev)
- self.time_recov.set_beta(self._timing_beta)
+ self._timing_bw, taps,
+ nfilts, nfilts//2, self._timing_max_dev)
- #self._phase_beta = 0.25 * self._phase_alpha * self._phase_alpha
- self._phase_beta = 0.25 * self._phase_alpha * self._phase_alpha
fmin = -0.25
fmax = 0.25
-
self.receiver = digital_swig.constellation_receiver_cb(
- self._constellation,
- self._phase_alpha, self._phase_beta,
+ self._constellation, self._phase_bw,
fmin, fmax)
-
+
# Do differential decoding based on phase change of symbols
if differential:
self.diffdec = gr.diff_decoder_bb(arity)
- if self._constellation.apply_pre_diff_code():
+ if gray_coded:
self.symbol_mapper = gr.map_bb(
mod_codes.invert_code(self._constellation.pre_diff_code()))
@@ -305,9 +301,10 @@ class generic_demod(gr.hier_block2):
if log:
self._setup_logging()
-
+
# Connect and Initialize base class
- blocks = [self, self.agc, self.freq_recov, self.time_recov, self.receiver]
+ blocks = [self, self.agc, self.freq_recov,
+ self.time_recov, self.receiver]
if differential:
blocks.append(self.diffdec)
if self._constellation.apply_pre_diff_code():
@@ -325,49 +322,46 @@ class generic_demod(gr.hier_block2):
print "\nDemodulator:"
print "bits per symbol: %d" % self.bits_per_symbol()
print "RRC roll-off factor: %.2f" % self._excess_bw
- print "FLL gain: %.2e" % self._freq_alpha
- print "Timing alpha gain: %.2e" % self._timing_alpha
- print "Timing beta gain: %.2e" % self._timing_beta
- print "Timing max dev: %.2f" % self._timing_max_dev
- print "Phase track alpha: %.2e" % self._phase_alpha
- print "Phase track beta: %.2e" % self._phase_beta
+ print "FLL bandwidth: %.2e" % self._freq_bw
+ print "Timing bandwidth: %.2e" % self._timing_bw
+ print "Phase bandwidth: %.2e" % self._phase_bw
def _setup_logging(self):
print "Modulation logging turned on."
self.connect(self.agc,
- gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
+ gr.file_sink(gr.sizeof_gr_complex, "rx_agc.32fc"))
self.connect((self.freq_recov, 0),
- gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat"))
+ gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.32fc"))
self.connect((self.freq_recov, 1),
- gr.file_sink(gr.sizeof_float, "rx_freq_recov_freq.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_freq_recov_freq.32f"))
self.connect((self.freq_recov, 2),
- gr.file_sink(gr.sizeof_float, "rx_freq_recov_phase.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_freq_recov_phase.32f"))
self.connect((self.freq_recov, 3),
- gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov_error.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_freq_recov_error.32f"))
self.connect((self.time_recov, 0),
- gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat"))
+ gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.32fc"))
self.connect((self.time_recov, 1),
- gr.file_sink(gr.sizeof_float, "rx_time_recov_error.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_time_recov_error.32f"))
self.connect((self.time_recov, 2),
- gr.file_sink(gr.sizeof_float, "rx_time_recov_rate.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_time_recov_rate.32f"))
self.connect((self.time_recov, 3),
- gr.file_sink(gr.sizeof_float, "rx_time_recov_phase.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_time_recov_phase.32f"))
self.connect((self.receiver, 0),
- gr.file_sink(gr.sizeof_char, "rx_receiver.dat"))
+ gr.file_sink(gr.sizeof_char, "rx_receiver.8b"))
self.connect((self.receiver, 1),
- gr.file_sink(gr.sizeof_float, "rx_receiver_error.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_receiver_error.32f"))
self.connect((self.receiver, 2),
- gr.file_sink(gr.sizeof_float, "rx_receiver_phase.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_receiver_phase.32f"))
self.connect((self.receiver, 3),
- gr.file_sink(gr.sizeof_float, "rx_receiver_freq.dat"))
+ gr.file_sink(gr.sizeof_float, "rx_receiver_freq.32f"))
if self._differential:
self.connect(self.diffdec,
- gr.file_sink(gr.sizeof_char, "rx_diffdec.dat"))
+ gr.file_sink(gr.sizeof_char, "rx_diffdec.8b"))
if self._constellation.apply_pre_diff_code():
self.connect(self.symbol_mapper,
- gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat"))
+ gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.8b"))
self.connect(self.unpack,
- gr.file_sink(gr.sizeof_char, "rx_unpack.dat"))
+ gr.file_sink(gr.sizeof_char, "rx_unpack.8b"))
def add_options(parser):
"""
@@ -376,16 +370,12 @@ class generic_demod(gr.hier_block2):
# Add options shared with modulator.
add_common_options(parser)
# Add options specific to demodulator.
- parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
- help="set frequency lock loop alpha gain value [default=%default]")
- parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha,
- help="set phase tracking loop alpha value [default=%default]")
- parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha,
- help="set timing symbol sync loop gain alpha value [default=%default]")
- parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta,
- help="set timing symbol sync loop gain beta value [default=%default]")
- parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev,
- help="set timing symbol sync loop maximum deviation [default=%default]")
+ parser.add_option("", "--freq-bw", type="float", default=_def_freq_bw,
+ help="set frequency lock loop lock-in bandwidth [default=%default]")
+ parser.add_option("", "--phase-bw", type="float", default=_def_phase_bw,
+ help="set phase tracking loop lock-in bandwidth [default=%default]")
+ parser.add_option("", "--timing-bw", type="float", default=_def_timing_bw,
+ help="set timing symbol sync loop gain lock-in bandwidth [default=%default]")
add_options=staticmethod(add_options)
def extract_kwargs_from_options(cls, options):