aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Morman <jmorman@perspectalabs.com>2019-12-04 11:05:55 -0500
committerMichael Dickens <michael.dickens@ettus.com>2020-01-26 16:48:40 -0500
commitbe6647a101077e7fa471ed3a186da1b01025952b (patch)
treeb627f750455ad3df08c2ce2e91f1a0927d5562a1
parentgr-digital: fix undefined behaviour (diff)
downloadgnuradio-be6647a101077e7fa471ed3a186da1b01025952b.tar.xz
gnuradio-be6647a101077e7fa471ed3a186da1b01025952b.zip
digital: add filter response truncation to generic mod
The generic mod implementation is a convenience hier block to modulate bits to symbols and apply an RRC filter. One downside is the output is delayed by the length of the RRC filter (which is specified inside the block). This adds an option to truncate the output according to the length of the filter response such that the start of output is aligned to the first symbol. Fixes #2920
-rw-r--r--gr-digital/grc/digital_constellation_modulator.block.yml11
-rw-r--r--gr-digital/python/digital/generic_mod_demod.py20
2 files changed, 26 insertions, 5 deletions
diff --git a/gr-digital/grc/digital_constellation_modulator.block.yml b/gr-digital/grc/digital_constellation_modulator.block.yml
index 7e509113b..ffbce01b4 100644
--- a/gr-digital/grc/digital_constellation_modulator.block.yml
+++ b/gr-digital/grc/digital_constellation_modulator.block.yml
@@ -34,7 +34,13 @@ parameters:
options: ['True', 'False']
option_labels: ['On', 'Off']
hide: ${ ('part' if str(log) == 'False' else 'none') }
-
+- id: truncate
+ label: Truncate Filter Transient
+ dtype: bool
+ default: 'False'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: ${ ('part' if str(truncate) == 'False' else 'none') }
inputs:
- domain: stream
dtype: byte
@@ -53,6 +59,7 @@ templates:
pre_diff_code=True,
excess_bw=${excess_bw},
verbose=${verbose},
- log=${log})
+ log=${log},
+ truncate=${truncate})
file_format: 1
diff --git a/gr-digital/python/digital/generic_mod_demod.py b/gr-digital/python/digital/generic_mod_demod.py
index 2a0d2c44c..bd0c84924 100644
--- a/gr-digital/python/digital/generic_mod_demod.py
+++ b/gr-digital/python/digital/generic_mod_demod.py
@@ -41,6 +41,7 @@ _def_samples_per_symbol = 2
_def_excess_bw = 0.35
_def_verbose = False
_def_log = False
+_def_truncate = False
# Frequency correction
_def_freq_bw = 2*math.pi/100.0
@@ -93,6 +94,7 @@ class generic_mod(gr.hier_block2):
excess_bw: Root-raised cosine filter excess bandwidth (float)
verbose: Print information about modulator? (boolean)
log: Log modulation data to files? (boolean)
+ truncate: Truncate the modulated output to account for the RRC filter response (boolean)
"""
def __init__(self, constellation,
@@ -101,7 +103,8 @@ class generic_mod(gr.hier_block2):
pre_diff_code=True,
excess_bw=_def_excess_bw,
verbose=_def_verbose,
- log=_def_log):
+ log=_def_log,
+ truncate=_def_truncate):
gr.hier_block2.__init__(self, "generic_mod",
gr.io_signature(1, 1, gr.sizeof_char), # Input signature
@@ -133,7 +136,8 @@ class generic_mod(gr.hier_block2):
# pulse shaping filter
nfilts = 32
- ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each
+ ntaps_per_filt = 11
+ ntaps = nfilts * ntaps_per_filt * int(self._samples_per_symbol) # make nfilts filters of ntaps each
self.rrc_taps = filter.firdes.root_raised_cosine(
nfilts, # gain
nfilts, # sampling rate based on 32 filters in resampler
@@ -143,13 +147,23 @@ class generic_mod(gr.hier_block2):
self.rrc_filter = filter.pfb_arb_resampler_ccf(self._samples_per_symbol,
self.rrc_taps)
+ # Remove the filter transient at the beginning of the transmission
+ if truncate:
+ fsps = float(self._samples_per_symbol)
+ len_filt_delay = (ntaps_per_filt*fsps*fsps-fsps)/2.0 # Length of delay through rrc filter
+ self.skiphead = blocks.skiphead(gr.sizeof_gr_complex*1, len_filt_delay)
+
# Connect
self._blocks = [self, self.bytes2chunks]
if self.pre_diff_code:
self._blocks.append(self.symbol_mapper)
if differential:
self._blocks.append(self.diffenc)
- self._blocks += [self.chunks2symbols, self.rrc_filter, self]
+ self._blocks += [self.chunks2symbols, self.rrc_filter]
+
+ if truncate:
+ self._blocks.append(self.skiphead)
+ self._blocks.append(self)
self.connect(*self._blocks)
if verbose: