diff options
Diffstat (limited to 'gr-digital/python/generic_mod_demod.py')
-rw-r--r-- | gr-digital/python/generic_mod_demod.py | 217 |
1 files changed, 120 insertions, 97 deletions
diff --git a/gr-digital/python/generic_mod_demod.py b/gr-digital/python/generic_mod_demod.py index a6c4f3445a..b812fe1c37 100644 --- a/gr-digital/python/generic_mod_demod.py +++ b/gr-digital/python/generic_mod_demod.py @@ -31,6 +31,21 @@ from utils import mod_codes import digital_swig as digital import math +try: + from gnuradio import blocks +except ImportError: + import blocks_swig as blocks + +try: + from gnuradio import filter +except ImportError: + import filter_swig as filter + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + # default values (used in __init__ and add_options) _def_samples_per_symbol = 2 _def_excess_bw = 0.35 @@ -74,42 +89,40 @@ def add_common_options(parser): # ///////////////////////////////////////////////////////////////////////////// class generic_mod(gr.hier_block2): + """ + Hierarchical block for RRC-filtered differential generic modulation. + + The input is a byte stream (unsigned char) and the + output is the complex modulated signal at baseband. + + Args: + constellation: determines the modulation type (gnuradio.digital.digital_constellation) + samples_per_symbol: samples per baud >= 2 (float) + differential: whether to use differential encoding (boolean) + pre_diff_code: whether to use apply a pre-differential mapping (boolean) + excess_bw: Root-raised cosine filter excess bandwidth (float) + verbose: Print information about modulator? (boolean) + log: Log modulation data to files? (boolean) + """ def __init__(self, constellation, - samples_per_symbol=_def_samples_per_symbol, differential=_def_differential, + samples_per_symbol=_def_samples_per_symbol, + pre_diff_code=True, excess_bw=_def_excess_bw, - gray_coded=True, verbose=_def_verbose, log=_def_log): - """ - Hierarchical block for RRC-filtered differential generic modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param constellation: determines the modulation type - @type constellation: gnuradio.digital.gr_constellation - @param samples_per_symbol: samples per baud >= 2 - @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? - @type log: bool - """ gr.hier_block2.__init__(self, "generic_mod", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - self._constellation = constellation.base() + self._constellation = constellation self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._differential = differential + # Only apply a predifferential coding if the constellation also supports it. + self.pre_diff_code = pre_diff_code and self._constellation.apply_pre_diff_code() if self._samples_per_symbol < 2: raise TypeError, ("sbp must be >= 2, is %f" % self._samples_per_symbol) @@ -118,9 +131,9 @@ class generic_mod(gr.hier_block2): # turn bytes into k-bit vectors self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) + blocks.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - if gray_coded == True: + if self.pre_diff_code: self.symbol_mapper = digital.map_bb(self._constellation.pre_diff_code()) if differential: @@ -131,23 +144,23 @@ 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 - self.rrc_taps = gr.firdes.root_raised_cosine( + self.rrc_taps = filter.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.pfb_arb_resampler_ccf(self._samples_per_symbol, - self.rrc_taps) + self.rrc_filter = filter.pfb_arb_resampler_ccf(self._samples_per_symbol, + self.rrc_taps) # Connect - blocks = [self, self.bytes2chunks] - if gray_coded == True: - blocks.append(self.symbol_mapper) + self._blocks = [self, self.bytes2chunks] + if self.pre_diff_code: + self._blocks.append(self.symbol_mapper) if differential: - blocks.append(self.diffenc) - blocks += [self.chunks2symbols, self.rrc_filter, self] - self.connect(*blocks) + self._blocks.append(self.diffenc) + self._blocks += [self.chunks2symbols, self.rrc_filter, self] + self.connect(*self._blocks) if verbose: self._print_verbage() @@ -185,17 +198,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.8b")) - if self._constellation.apply_pre_diff_code(): + blocks.file_sink(gr.sizeof_char, "tx_bytes2chunks.8b")) + if self.pre_diff_code: self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.8b")) + blocks.file_sink(gr.sizeof_char, "tx_symbol_mapper.8b")) if self._differential: self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.8b")) + blocks.file_sink(gr.sizeof_char, "tx_diffenc.8b")) self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.32fc")) + blocks.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.32fc")) self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.32fc")) + blocks.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.32fc")) # ///////////////////////////////////////////////////////////////////////////// @@ -206,48 +219,41 @@ class generic_mod(gr.hier_block2): # ///////////////////////////////////////////////////////////////////////////// class generic_demod(gr.hier_block2): + """ + Hierarchical block for RRC-filtered differential generic demodulation. + + The input is the complex modulated signal at baseband. + The output is a stream of bits packed 1 bit per byte (LSB) + + Args: + constellation: determines the modulation type (gnuradio.digital.digital_constellation) + samples_per_symbol: samples per baud >= 2 (float) + differential: whether to use differential encoding (boolean) + pre_diff_code: whether to use apply a pre-differential mapping (boolean) + excess_bw: Root-raised cosine filter excess bandwidth (float) + freq_bw: loop filter lock-in bandwidth (float) + timing_bw: timing recovery loop lock-in bandwidth (float) + phase_bw: phase recovery loop bandwidth (float) + verbose: Print information about modulator? (boolean) + log: Log modulation data to files? (boolean) + """ def __init__(self, constellation, - samples_per_symbol=_def_samples_per_symbol, differential=_def_differential, + samples_per_symbol=_def_samples_per_symbol, + pre_diff_code=True, excess_bw=_def_excess_bw, - gray_coded=True, freq_bw=_def_freq_bw, timing_bw=_def_timing_bw, phase_bw=_def_phase_bw, verbose=_def_verbose, log=_def_log): - """ - Hierarchical block for RRC-filtered differential generic demodulation. - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param constellation: determines the modulation type - @type constellation: gnuradio.digital.gr_constellation - @param samples_per_symbol: samples per symbol >= 2 - @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 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? - @type debug: bool - """ gr.hier_block2.__init__(self, "generic_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - self._constellation = constellation.base() + self._constellation = constellation self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._phase_bw = phase_bw @@ -259,13 +265,16 @@ class generic_demod(gr.hier_block2): if self._samples_per_symbol < 2: raise TypeError, ("sbp must be >= 2, is %d" % self._samples_per_symbol) + # Only apply a predifferential coding if the constellation also supports it. + self.pre_diff_code = pre_diff_code and self._constellation.apply_pre_diff_code() + 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) + self.agc = analog.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) # Frequency correction fll_ntaps = 55 @@ -273,8 +282,8 @@ class generic_demod(gr.hier_block2): fll_ntaps, self._freq_bw) # symbol timing recovery with RRC data filter - taps = gr.firdes.root_raised_cosine(nfilts, nfilts*self._samples_per_symbol, - 1.0, self._excess_bw, ntaps) + taps = filter.firdes.root_raised_cosine(nfilts, nfilts*self._samples_per_symbol, + 1.0, self._excess_bw, ntaps) self.time_recov = digital.pfb_clock_sync_ccf(self._samples_per_symbol, self._timing_bw, taps, nfilts, nfilts//2, self._timing_max_dev) @@ -282,19 +291,19 @@ class generic_demod(gr.hier_block2): fmin = -0.25 fmax = 0.25 self.receiver = digital.constellation_receiver_cb( - self._constellation, self._phase_bw, + self._constellation.base(), self._phase_bw, fmin, fmax) # Do differential decoding based on phase change of symbols if differential: self.diffdec = digital.diff_decoder_bb(arity) - if gray_coded: + if self.pre_diff_code: self.symbol_mapper = digital.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()) + self.unpack = blocks.unpack_k_bits_bb(self.bits_per_symbol()) if verbose: self._print_verbage() @@ -303,14 +312,14 @@ class generic_demod(gr.hier_block2): self._setup_logging() # Connect and Initialize base class - blocks = [self, self.agc, self.freq_recov, - self.time_recov, self.receiver] + self._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(): - blocks.append(self.symbol_mapper) - blocks += [self.unpack, self] - self.connect(*blocks) + self._blocks.append(self.diffdec) + if self.pre_diff_code: + self._blocks.append(self.symbol_mapper) + self._blocks += [self.unpack, self] + self.connect(*self._blocks) def samples_per_symbol(self): return self._samples_per_symbol @@ -329,39 +338,39 @@ class generic_demod(gr.hier_block2): def _setup_logging(self): print "Modulation logging turned on." self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.32fc")) + blocks.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.32fc")) + blocks.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.32f")) + blocks.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.32f")) + blocks.file_sink(gr.sizeof_float, "rx_freq_recov_phase.32f")) self.connect((self.freq_recov, 3), - gr.file_sink(gr.sizeof_float, "rx_freq_recov_error.32f")) + blocks.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.32fc")) + blocks.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.32f")) + blocks.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.32f")) + blocks.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.32f")) + blocks.file_sink(gr.sizeof_float, "rx_time_recov_phase.32f")) self.connect((self.receiver, 0), - gr.file_sink(gr.sizeof_char, "rx_receiver.8b")) + blocks.file_sink(gr.sizeof_char, "rx_receiver.8b")) self.connect((self.receiver, 1), - gr.file_sink(gr.sizeof_float, "rx_receiver_error.32f")) + blocks.file_sink(gr.sizeof_float, "rx_receiver_error.32f")) self.connect((self.receiver, 2), - gr.file_sink(gr.sizeof_float, "rx_receiver_phase.32f")) + blocks.file_sink(gr.sizeof_float, "rx_receiver_phase.32f")) self.connect((self.receiver, 3), - gr.file_sink(gr.sizeof_float, "rx_receiver_freq.32f")) + blocks.file_sink(gr.sizeof_float, "rx_receiver_freq.32f")) if self._differential: self.connect(self.diffdec, - gr.file_sink(gr.sizeof_char, "rx_diffdec.8b")) - if self._constellation.apply_pre_diff_code(): + blocks.file_sink(gr.sizeof_char, "rx_diffdec.8b")) + if self.pre_diff_code: self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.8b")) + blocks.file_sink(gr.sizeof_char, "rx_symbol_mapper.8b")) self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.8b")) + blocks.file_sink(gr.sizeof_char, "rx_unpack.8b")) def add_options(parser): """ @@ -385,3 +394,17 @@ class generic_demod(gr.hier_block2): return extract_kwargs_from_options_for_class(cls, options) extract_kwargs_from_options=classmethod(extract_kwargs_from_options) +shared_demod_args = """ samples_per_symbol: samples per baud >= 2 (float) + excess_bw: Root-raised cosine filter excess bandwidth (float) + freq_bw: loop filter lock-in bandwidth (float) + timing_bw: timing recovery loop lock-in bandwidth (float) + phase_bw: phase recovery loop bandwidth (float) + verbose: Print information about modulator? (boolean) + log: Log modulation data to files? (boolean) +""" + +shared_mod_args = """ samples_per_symbol: samples per baud >= 2 (float) + excess_bw: Root-raised cosine filter excess bandwidth (float) + verbose: Print information about modulator? (boolean) + log: Log modulation data to files? (boolean) +""" |