Advertisement
Guest User

Untitled

a guest
Mar 8th, 2012
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.39 KB | None | 0 0
  1. #
  2. # Copyright 2005,2006,2007,2009,2011 Free Software Foundation, Inc.
  3. #
  4. # This file is part of GNU Radio
  5. #
  6. # GNU Radio is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 3, or (at your option)
  9. # any later version.
  10. #
  11. # GNU Radio is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with GNU Radio; see the file COPYING.  If not, write to
  18. # the Free Software Foundation, Inc., 51 Franklin Street,
  19. # Boston, MA 02110-1301, USA.
  20. #
  21.  
  22. # See gnuradio-examples/python/digital for examples
  23.  
  24. """
  25. Generic modulation and demodulation.
  26. """
  27.  
  28. from gnuradio import gr
  29. from gnuradio.digital.modulation_utils import extract_kwargs_from_options_for_class
  30. from gnuradio.digital.utils import mod_codes
  31. from gnuradio.digital import digital_swig,digital
  32. import math
  33.  
  34. # default values (used in __init__ and add_options)
  35. _def_samples_per_symbol = 2
  36. _def_excess_bw = 0.35
  37. _def_verbose = False
  38. _def_log = False
  39.  
  40. # Frequency correction
  41. _def_freq_bw = 2*math.pi/100.0
  42. # Symbol timing recovery
  43. _def_timing_bw = 2*math.pi/100.0
  44. _def_timing_max_dev = 1.5
  45. # Fine frequency / Phase correction
  46. _def_phase_bw = 2*math.pi/100.0
  47. # Number of points in constellation
  48. _def_constellation_points = 16
  49. # Whether differential coding is used.
  50. _def_differential = False
  51.  
  52. def add_common_options(parser):
  53.     """
  54.    Sets options common to both modulator and demodulator.
  55.    """
  56.     parser.add_option("-p", "--constellation-points", type="int", default=_def_constellation_points,
  57.                       help="set the number of constellation points (must be a power of 2 for psk, power of 4 for QAM) [default=%default]")
  58.     parser.add_option("", "--non-differential", action="store_false",
  59.                       dest="differential",
  60.                       help="do not use differential encoding [default=False]")
  61.     parser.add_option("", "--differential", action="store_true",
  62.                       dest="differential", default=True,
  63.                       help="use differential encoding [default=%default]")
  64.     parser.add_option("", "--mod-code", type="choice", choices=mod_codes.codes,
  65.                       default=mod_codes.NO_CODE,
  66.                       help="Select modulation code from: %s [default=%%default]"
  67.                             % (', '.join(mod_codes.codes),))
  68.     parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw,
  69.                       help="set RRC excess bandwith factor [default=%default]")
  70.    
  71.  
  72. # /////////////////////////////////////////////////////////////////////////////
  73. #                             Generic modulator
  74. # /////////////////////////////////////////////////////////////////////////////
  75.  
  76. class generic_mod(gr.hier_block2):
  77.  
  78.     def __init__(self, constellation,
  79.                  samples_per_symbol=_def_samples_per_symbol,
  80.                  differential=_def_differential,
  81.                  excess_bw=_def_excess_bw,
  82.                  gray_coded=True,
  83.                  verbose=_def_verbose,
  84.                  log=_def_log):
  85.         """
  86.     Hierarchical block for RRC-filtered differential generic modulation.
  87.  
  88.     The input is a byte stream (unsigned char) and the
  89.     output is the complex modulated signal at baseband.
  90.        
  91.     @param constellation: determines the modulation type
  92.     @type constellation: gnuradio.digital.gr_constellation
  93.     @param samples_per_symbol: samples per baud >= 2
  94.     @type samples_per_symbol: float
  95.     @param excess_bw: Root-raised cosine filter excess bandwidth
  96.     @type excess_bw: float
  97.        @param gray_coded: turn gray coding on/off
  98.        @type gray_coded: bool
  99.        @param verbose: Print information about modulator?
  100.        @type verbose: bool
  101.        @param log: Log modulation data to files?
  102.        @type log: bool
  103.     """
  104.  
  105.     gr.hier_block2.__init__(self, "generic_mod",
  106.                 gr.io_signature(1, 1, gr.sizeof_char),       # Input signature
  107.                 gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
  108.  
  109.         self._constellation = constellation.base()
  110.         self._samples_per_symbol = samples_per_symbol
  111.         self._excess_bw = excess_bw
  112.         self._differential = differential
  113.  
  114.         #if self._samples_per_symbol < 2:
  115.             #raise TypeError, ("sbp must be >= 2, is %f" % self._samples_per_symbol)
  116.        
  117.         arity = pow(2,self.bits_per_symbol())
  118.        
  119.         # turn bytes into k-bit vectors
  120.         self.bytes2chunks = \
  121.           gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
  122.  
  123.         if gray_coded == True:
  124.             self.symbol_mapper = gr.map_bb(self._constellation.pre_diff_code())
  125.  
  126.         #if differential:
  127.             #self.diffenc = gr.diff_encoder_bb(arity)
  128.  
  129.         self.chunks2symbols = gr.chunks_to_symbols_bc(self._constellation.points())
  130.     print self._constellation.points()
  131.     #self.constell = digital.digital_constellation(self._constellation.points())
  132.  
  133.         ## pulse shaping filter
  134.         #nfilts = 32
  135.         #ntaps = nfilts * 11 * int(self._samples_per_symbol)    # make nfilts filters of ntaps each
  136.         #self.rrc_taps = gr.firdes.root_raised_cosine(
  137.             #nfilts,          # gain
  138.             #nfilts,          # sampling rate based on 32 filters in resampler
  139.             #1.0,             # symbol rate
  140.             #self._excess_bw, # excess bandwidth (roll-off factor)
  141.             #ntaps)
  142.         #self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol,
  143.                                                    #self.rrc_taps)
  144.  
  145.     # Connect
  146.         blocks = [self, self.bytes2chunks]
  147.         if gray_coded == True:
  148.             blocks.append(self.symbol_mapper)
  149.         #if differential:
  150.             #blocks.append(self.diffenc)
  151.         #blocks += [self.chunks2symbols, self.rrc_filter, self]
  152.     blocks += [self.chunks2symbols, self]
  153.         self.connect(*blocks)
  154.  
  155.         if verbose:
  156.             self._print_verbage()
  157.            
  158.         if log:
  159.             self._setup_logging()
  160.            
  161.  
  162.     def samples_per_symbol(self):
  163.         return self._samples_per_symbol
  164.  
  165.     def bits_per_symbol(self):   # static method that's also callable on an instance
  166.         return self._constellation.bits_per_symbol()
  167.  
  168.     def add_options(parser):
  169.         """
  170.        Adds generic modulation options to the standard parser
  171.        """
  172.         add_common_options(parser)
  173.     add_options=staticmethod(add_options)
  174.  
  175.     def extract_kwargs_from_options(cls, options):
  176.         """
  177.        Given command line options, create dictionary suitable for passing to __init__
  178.        """
  179.         return extract_kwargs_from_options_for_class(cls, options)
  180.     extract_kwargs_from_options=classmethod(extract_kwargs_from_options)
  181.  
  182.  
  183.     def _print_verbage(self):
  184.         print "\nModulator:"
  185.         print "bits per symbol:     %d" % self.bits_per_symbol()
  186.         print "RRC roll-off factor: %.2f" % self._excess_bw
  187.  
  188.     def _setup_logging(self):
  189.         print "Modulation logging turned on."
  190.         self.connect(self.bytes2chunks,
  191.                      gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.8b"))
  192.         if self._constellation.apply_pre_diff_code():
  193.             self.connect(self.symbol_mapper,
  194.                          gr.file_sink(gr.sizeof_char, "tx_symbol_mapper.8b"))
  195.         if self._differential:
  196.             self.connect(self.diffenc,
  197.                          gr.file_sink(gr.sizeof_char, "tx_diffenc.8b"))
  198.         self.connect(self.chunks2symbols,
  199.                      gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.32fc"))
  200.         self.connect(self.rrc_filter,
  201.                      gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.32fc"))
  202.              
  203.  
  204. # /////////////////////////////////////////////////////////////////////////////
  205. #                             Generic demodulator
  206. #
  207. #      Differentially coherent detection of differentially encoded generically
  208. #      modulated signal.
  209. # /////////////////////////////////////////////////////////////////////////////
  210.  
  211. class generic_demod(gr.hier_block2):
  212.  
  213.     def __init__(self, constellation,
  214.                  samples_per_symbol=_def_samples_per_symbol,
  215.                  differential=_def_differential,
  216.                  excess_bw=_def_excess_bw,
  217.                  gray_coded=True,
  218.                  freq_bw=_def_freq_bw,
  219.                  timing_bw=_def_timing_bw,
  220.                  phase_bw=_def_phase_bw,
  221.                  verbose=_def_verbose,
  222.                  log=_def_log):
  223.         """
  224.     Hierarchical block for RRC-filtered differential generic demodulation.
  225.  
  226.     The input is the complex modulated signal at baseband.
  227.     The output is a stream of bits packed 1 bit per byte (LSB)
  228.  
  229.     @param constellation: determines the modulation type
  230.     @type constellation: gnuradio.digital.gr_constellation
  231.     @param samples_per_symbol: samples per symbol >= 2
  232.     @type samples_per_symbol: float
  233.     @param excess_bw: Root-raised cosine filter excess bandwidth
  234.     @type excess_bw: float
  235.        @param gray_coded: turn gray coding on/off
  236.        @type gray_coded: bool
  237.        @param freq_bw: loop filter lock-in bandwidth
  238.        @type freq_bw: float
  239.        @param timing_bw: timing recovery loop lock-in bandwidth
  240.        @type timing_bw: float
  241.        @param phase_bw: phase recovery loop bandwidth
  242.        @type phase_bw: float
  243.        @param verbose: Print information about modulator?
  244.        @type verbose: bool
  245.        @param debug: Print modualtion data to files?
  246.        @type debug: bool
  247.     """
  248.        
  249.     gr.hier_block2.__init__(self, "generic_demod",
  250.                 gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
  251.                 gr.io_signature(1, 1, gr.sizeof_char))       # Output signature
  252.                
  253.         self._constellation = constellation.base()
  254.         self._samples_per_symbol = samples_per_symbol
  255.         self._excess_bw = excess_bw
  256.         self._phase_bw = phase_bw
  257.         self._freq_bw = freq_bw
  258.         self._timing_bw = timing_bw
  259.         self._timing_max_dev= _def_timing_max_dev
  260.         self._differential = differential
  261.  
  262.         #if self._samples_per_symbol < 2:
  263.             #raise TypeError, ("sbp must be >= 2, is %d" % self._samples_per_symbol)
  264.  
  265.         arity = pow(2,self.bits_per_symbol())
  266.  
  267.         #nfilts = 32
  268.         #ntaps = 11 * int(self._samples_per_symbol*nfilts)
  269.  
  270.         # Automatic gain control
  271.         #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
  272.  
  273.         ## Frequency correction
  274.         #fll_ntaps = 55
  275.         #self.freq_recov = digital_swig.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
  276.                                                         #fll_ntaps, self._freq_bw)
  277.  
  278.         # symbol timing recovery with RRC data filter
  279.         #taps = gr.firdes.root_raised_cosine(nfilts, nfilts*self._samples_per_symbol,
  280.                                             #1.0, self._excess_bw, ntaps)
  281.         #self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
  282.                                                 #self._timing_bw, taps,
  283.                                                 #nfilts, nfilts//2, self._timing_max_dev)
  284.  
  285.         fmin = -0.25
  286.         fmax = 0.25
  287.    
  288.         self.receiver = digital_swig.constellation_receiver_cb(
  289.             self._constellation, self._phase_bw,
  290.             fmin, fmax)
  291.    
  292.         self.receiver2 = digital_swig.constellation_decoder_cb(self._constellation)
  293.         print self._constellation
  294.         # Do differential decoding based on phase change of symbols
  295.         #if differential:
  296.             #self.diffdec = gr.diff_decoder_bb(arity)
  297.  
  298.         if gray_coded:
  299.             self.symbol_mapper = gr.map_bb(
  300.                 mod_codes.invert_code(self._constellation.pre_diff_code()))
  301.  
  302.         # unpack the k bit vector into a stream of bits
  303.         self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) #ber mode
  304.     self.unpack2 = gr.unpacked_to_packed_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
  305.  
  306.         #if verbose:
  307.             #self._print_verbage()
  308.  
  309.         #if log:
  310.             #self._setup_logging()
  311.        
  312.         # Connect and Initialize base class
  313.         #blocks = [self, self.agc, self.freq_recov,
  314.                   #self.time_recov, self.receiver]
  315.         blocks = [self, self.receiver2,self.symbol_mapper,self]
  316.         #if differential:
  317.             #blocks.append(self.diffdec)
  318.         #if self._constellation.apply_pre_diff_code():
  319.             #blocks.append(self.symbol_mapper)
  320.         #blocks += [self]
  321.         self.connect(*blocks)
  322.  
  323.     def samples_per_symbol(self):
  324.         return self._samples_per_symbol
  325.  
  326.     def bits_per_symbol(self):   # staticmethod that's also callable on an instance
  327.         return self._constellation.bits_per_symbol()
  328.  
  329.     #def _print_verbage(self):
  330.         #print "\nDemodulator:"
  331.         #print "bits per symbol:     %d"   % self.bits_per_symbol()
  332.         #print "RRC roll-off factor: %.2f" % self._excess_bw
  333.         #print "FLL bandwidth:       %.2e" % self._freq_bw
  334.         #print "Timing bandwidth:    %.2e" % self._timing_bw
  335.         #print "Phase bandwidth:     %.2e" % self._phase_bw
  336.  
  337.     #def _setup_logging(self):
  338.         #print "Modulation logging turned on."
  339.         #self.connect(self.agc,
  340.                      #gr.file_sink(gr.sizeof_gr_complex, "rx_agc.32fc"))
  341.         #self.connect((self.freq_recov, 0),
  342.                      #gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.32fc"))
  343.         #self.connect((self.freq_recov, 1),
  344.                      #gr.file_sink(gr.sizeof_float, "rx_freq_recov_freq.32f"))
  345.         #self.connect((self.freq_recov, 2),
  346.                      #gr.file_sink(gr.sizeof_float, "rx_freq_recov_phase.32f"))
  347.         #self.connect((self.freq_recov, 3),
  348.                      #gr.file_sink(gr.sizeof_float, "rx_freq_recov_error.32f"))
  349.         #self.connect((self.time_recov, 0),
  350.                      #gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.32fc"))
  351.         #self.connect((self.time_recov, 1),
  352.                      #gr.file_sink(gr.sizeof_float, "rx_time_recov_error.32f"))
  353.         #self.connect((self.time_recov, 2),
  354.                      #gr.file_sink(gr.sizeof_float, "rx_time_recov_rate.32f"))
  355.         #self.connect((self.time_recov, 3),
  356.                      #gr.file_sink(gr.sizeof_float, "rx_time_recov_phase.32f"))
  357.         #self.connect((self.receiver, 0),
  358.                      #gr.file_sink(gr.sizeof_char, "rx_receiver.8b"))
  359.         #self.connect((self.receiver, 1),
  360.                      #gr.file_sink(gr.sizeof_float, "rx_receiver_error.32f"))
  361.         #self.connect((self.receiver, 2),
  362.                      #gr.file_sink(gr.sizeof_float, "rx_receiver_phase.32f"))
  363.         #self.connect((self.receiver, 3),
  364.                      #gr.file_sink(gr.sizeof_float, "rx_receiver_freq.32f"))
  365.         #if self._differential:
  366.             #self.connect(self.diffdec,
  367.                          #gr.file_sink(gr.sizeof_char, "rx_diffdec.8b"))
  368.         #if self._constellation.apply_pre_diff_code():
  369.             #self.connect(self.symbol_mapper,
  370.                          #gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.8b"))
  371.         #self.connect(self.unpack,
  372.                      #gr.file_sink(gr.sizeof_char, "rx_unpack.8b"))
  373.        
  374.     #def add_options(parser):
  375.         #"""
  376.         #Adds generic demodulation options to the standard parser
  377.         #"""
  378.         ## Add options shared with modulator.
  379.         #add_common_options(parser)
  380.         ## Add options specific to demodulator.
  381.         #parser.add_option("", "--freq-bw", type="float", default=_def_freq_bw,
  382.                           #help="set frequency lock loop lock-in bandwidth [default=%default]")
  383.         #parser.add_option("", "--phase-bw", type="float", default=_def_phase_bw,
  384.                           #help="set phase tracking loop lock-in bandwidth [default=%default]")
  385.         #parser.add_option("", "--timing-bw", type="float", default=_def_timing_bw,
  386.                           #help="set timing symbol sync loop gain lock-in bandwidth [default=%default]")
  387.     #add_options=staticmethod(add_options)
  388.    
  389.     #def extract_kwargs_from_options(cls, options):
  390.         #"""
  391.         #Given command line options, create dictionary suitable for passing to __init__
  392.         #"""
  393.         #return extract_kwargs_from_options_for_class(cls, options)
  394.     #extract_kwargs_from_options=classmethod(extract_kwargs_from_options)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement