コード例 #1
0
    def test_00(self):
        expected_result = (
            0x00, 0x11, 0x22, 0x33,
            0x44, 0x55, 0x66, 0x77,
            0x88, 0x99, 0xaa, 0xbb,
            0xcc, 0xdd, 0xee, 0xff)

        # Filter taps to expand the data to oversample by 8
        # Just using a RRC for some basic filter shape
        taps = gr.firdes.root_raised_cosine(8, 8, 1.0, 0.5, 21)
        
        src = gr.vector_source_b(expected_result)
        frame = digital.simple_framer(4)
        unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST)
        expand = gr.interp_fir_filter_fff(8, taps)
        b2f = gr.char_to_float()
        mult2 = gr.multiply_const_ff(2)
        sub1 = gr.add_const_ff(-1)
        op = digital.simple_correlator(4)
        dst = gr.vector_sink_b()
        self.tb.connect(src, frame, unpack, b2f, mult2, sub1, expand)
        self.tb.connect(expand, op, dst)
        self.tb.run()
        result_data = dst.data()

        self.assertEqual(expected_result, result_data)
コード例 #2
0
ファイル: ec3k.py プロジェクト: asdil12/ec3k
	def _setup_top_block(self):

		self.tb = gr.top_block()

		samp_rate = 96000
		oversample = 10
		center_freq = 868.280e6

		# Radio receiver, initial downsampling
		args = str("nchan=1 rtl=%s,buffers=16,offset_tune=1" % self.device)
		osmosdr_source = osmosdr.source_c(args=args)
		osmosdr_source.set_sample_rate(samp_rate*oversample)
		osmosdr_source.set_center_freq(center_freq, 0)
		osmosdr_source.set_freq_corr(0, 0)
		osmosdr_source.set_gain_mode(1, 0)
		osmosdr_source.set_gain(0, 0)

		low_pass_filter = gr.fir_filter_ccf(oversample, 
				firdes.low_pass(1, samp_rate*oversample, 90e3, 8e3, firdes.WIN_HAMMING, 6.76))

		self.tb.connect((osmosdr_source, 0), (low_pass_filter, 0))

		# Squelch
		self.noise_probe = gr.probe_avg_mag_sqrd_c(0, 1.0/samp_rate/1e2)
		self.squelch = gr.simple_squelch_cc(self.noise_level, 1)

		noise_probe_thread = threading.Thread(target=self._noise_probe_thread)
		noise_probe_thread.start()
		self.threads.append(noise_probe_thread)

		self.tb.connect((low_pass_filter, 0), (self.noise_probe, 0))
		self.tb.connect((low_pass_filter, 0), (self.squelch, 0))

		# FM demodulation
		quadrature_demod = gr.quadrature_demod_cf(1)

		self.tb.connect((self.squelch, 0), (quadrature_demod, 0))

		# Binary slicing, transformation into capture-compatible format

		add_offset = gr.add_const_vff((-1e-3, ))

		binary_slicer = digital.binary_slicer_fb()

		char_to_float = gr.char_to_float(1, 1)

		multiply_const = gr.multiply_const_vff((255, ))

		float_to_uchar = gr.float_to_uchar()

		pipe_sink = gr.file_sink(gr.sizeof_char*1, self.pipe)
		pipe_sink.set_unbuffered(False)

		self.tb.connect((quadrature_demod, 0), (add_offset, 0))
		self.tb.connect((add_offset, 0), (binary_slicer, 0))
		self.tb.connect((binary_slicer, 0), (char_to_float, 0))
		self.tb.connect((char_to_float, 0), (multiply_const, 0))
		self.tb.connect((multiply_const, 0), (float_to_uchar, 0))
		self.tb.connect((float_to_uchar, 0), (pipe_sink, 0))
コード例 #3
0
ファイル: gr_tools.py プロジェクト: luwangg/gr-ofdm-1
    def __init__(self, block):
        vlen = determine_streamsize(block)
        gr.hier_block2.__init__(self, "char_to_float_stream",
                                gr.io_signature(0, 0, 0),
                                gr.io_signature(1, 1, gr.sizeof_float * vlen))

        cvt = gr.char_to_float(vlen)
        self.connect(block, cvt, self)
コード例 #4
0
ファイル: gr_tools.py プロジェクト: WindyCitySDR/gr-ofdm
 def __init__( self, block ):
   vlen = determine_streamsize( block )
   gr.hier_block2.__init__( self,
       "char_to_float_stream",
       gr.io_signature(0,0,0),
       gr.io_signature( 1, 1, gr.sizeof_float * vlen ) )
   
 
   cvt = gr.char_to_float( vlen )
   self.connect( block, cvt, self )
コード例 #5
0
ファイル: top_block.py プロジェクト: manasdas17/PWR
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Top Block")
        _icon_path = "/home/pfb/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
        self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

        ##################################################
        # Variables
        ##################################################
        self.samp_rate = samp_rate = 32000

        ##################################################
        # Blocks
        ##################################################
        self.gr_char_to_float_0 = gr.char_to_float()
        self.gr_scrambler_bb_0 = gr.scrambler_bb(0x8A, 0x7F, 7)
        self.gr_throttle_0 = gr.throttle(gr.sizeof_char * 1, samp_rate)
        self.gr_vector_source_x_0 = gr.vector_source_b((0, 0, 0), True, 1)
        self.wxgui_fftsink2_0 = fftsink2.fft_sink_f(
            self.GetWin(),
            baseband_freq=0,
            y_per_div=10,
            y_divs=10,
            ref_level=50,
            ref_scale=2.0,
            sample_rate=samp_rate,
            fft_size=1024,
            fft_rate=30,
            average=False,
            avg_alpha=None,
            title="FFT Plot",
            peak_hold=False,
        )
        self.Add(self.wxgui_fftsink2_0.win)
        self.wxgui_scopesink2_0 = scopesink2.scope_sink_f(
            self.GetWin(),
            title="Scope Plot",
            sample_rate=samp_rate,
            v_scale=1,
            v_offset=0,
            t_scale=0005,
            ac_couple=False,
            xy_mode=False,
            num_inputs=1,
        )
        self.Add(self.wxgui_scopesink2_0.win)

        ##################################################
        # Connections
        ##################################################
        self.connect((self.gr_scrambler_bb_0, 0), (self.gr_char_to_float_0, 0))
        self.connect((self.gr_char_to_float_0, 0), (self.wxgui_fftsink2_0, 0))
        self.connect((self.gr_vector_source_x_0, 0), (self.gr_throttle_0, 0))
        self.connect((self.gr_throttle_0, 0), (self.gr_scrambler_bb_0, 0))
        self.connect((self.gr_char_to_float_0, 0),
                     (self.wxgui_scopesink2_0, 0))
コード例 #6
0
ファイル: top_block.py プロジェクト: Exadios/PWR
	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="Top Block")
		_icon_path = "/home/pfb/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

		##################################################
		# Variables
		##################################################
		self.samp_rate = samp_rate = 32000

		##################################################
		# Blocks
		##################################################
		self.gr_char_to_float_0 = gr.char_to_float()
		self.gr_scrambler_bb_0 = gr.scrambler_bb(0x8A, 0x7F, 7)
		self.gr_throttle_0 = gr.throttle(gr.sizeof_char*1, samp_rate)
		self.gr_vector_source_x_0 = gr.vector_source_b((0, 0, 0), True, 1)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_f(
			self.GetWin(),
			baseband_freq=0,
			y_per_div=10,
			y_divs=10,
			ref_level=50,
			ref_scale=2.0,
			sample_rate=samp_rate,
			fft_size=1024,
			fft_rate=30,
			average=False,
			avg_alpha=None,
			title="FFT Plot",
			peak_hold=False,
		)
		self.Add(self.wxgui_fftsink2_0.win)
		self.wxgui_scopesink2_0 = scopesink2.scope_sink_f(
			self.GetWin(),
			title="Scope Plot",
			sample_rate=samp_rate,
			v_scale=1,
			v_offset=0,
			t_scale=0005,
			ac_couple=False,
			xy_mode=False,
			num_inputs=1,
		)
		self.Add(self.wxgui_scopesink2_0.win)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_scrambler_bb_0, 0), (self.gr_char_to_float_0, 0))
		self.connect((self.gr_char_to_float_0, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_vector_source_x_0, 0), (self.gr_throttle_0, 0))
		self.connect((self.gr_throttle_0, 0), (self.gr_scrambler_bb_0, 0))
		self.connect((self.gr_char_to_float_0, 0), (self.wxgui_scopesink2_0, 0))
コード例 #7
0
  def setup_ber_measurement(self):
    """
    Setup bit error rate measurement blocks. Using the decoded ID, a reference
    source identical to that in the transmitter reproduces the sent data. A
    measurement block compares the demodulated stream and the reference. It
    counts the bit errors within the given window (specified at the command
    line).
    Access the BER value via get_ber().
    """
    if self.measuring_ber():
      return

    if(self._options.coding):
        decoding = self._data_decoder
    else:
        demod = self._data_demodulator

    config = station_configuration()


    ## Data Reference Source
    dref_src = self._data_reference_source = ber_reference_source(self._options)
    self.connect(self.id_dec,(dref_src,0))
    self.connect(self.bitcount_src,(dref_src,1))
    

    ## BER Measuring Tool
    ber_mst = self._ber_measuring_tool = ber_measurement(int(config.ber_window))
    if(self._options.coding):
        self.connect(decoding,ber_mst)
    else:
        self.connect(demod,ber_mst)
    self.connect(dref_src,(ber_mst,1))
    
    self._measuring_ber = True


    if self._options.enable_ber2:
      ber2 = ofdm.bit_position_dependent_ber( "BER2_" + strftime("%Y%m%d%H%M%S",gmtime()) )
      if(self._options.coding):
        self.connect( decoding, ( ber2, 1 ) )
      else:
        self.connect( demod, ( ber2, 1 ) )
      self.connect( dref_src, ( ber2, 0 ) )
      self.connect( bc_src, ( ber2, 2 ) )

    if self._options.log:
      log_to_file(self, ber_mst, "data/ber_out.float")
      data_f = gr.char_to_float()
      self.connect(dref_src,data_f)
      log_to_file(self, data_f, "data/dataref_out.float")
コード例 #8
0
ファイル: qa_ecc_ccsds_27.py プロジェクト: GREO/GNU-Radio
    def xtest_ccsds_27 (self):
        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
	expected = (0, 0, 0, 0, 1, 2, 3, 4, 5, 6)
        src = gr.vector_source_b(src_data)
	enc = gr.encode_ccsds_27_bb()
	b2f = gr.char_to_float()
	add = gr.add_const_ff(-0.5)
	mul = gr.multiply_const_ff(2.0)
	dec = gr.decode_ccsds_27_fb()
	dst = gr.vector_sink_b()
	self.tb.connect(src, enc, b2f, add, mul, dec, dst)
	self.tb.run()
	dst_data = dst.data()
        self.assertEqual(expected, dst_data)
コード例 #9
0
 def xtest_ccsds_27(self):
     src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
     expected = (0, 0, 0, 0, 1, 2, 3, 4, 5, 6)
     src = gr.vector_source_b(src_data)
     enc = gr.encode_ccsds_27_bb()
     b2f = gr.char_to_float()
     add = gr.add_const_ff(-0.5)
     mul = gr.multiply_const_ff(2.0)
     dec = gr.decode_ccsds_27_fb()
     dst = gr.vector_sink_b()
     self.tb.connect(src, enc, b2f, add, mul, dec, dst)
     self.tb.run()
     dst_data = dst.data()
     self.assertEqual(expected, dst_data)
コード例 #10
0
  def setup_ber_measurement(self):
    """
    Setup bit error rate measurement blocks. Using the decoded ID, a reference
    source identical to that in the transmitter reproduces the sent data. A
    measurement block compares the demodulated stream and the reference. It
    counts the bit errors within the given window (specified at the command
    line).
    Access the BER value via get_ber().
    """
    if self.measuring_ber():
      return

    if(self._options.coding):
        decoding = self._data_decoder
    else:
        demod = self._data_demodulator

    config = station_configuration()


    ## Data Reference Source
    dref_src = self._data_reference_source = ber_reference_source(self._options)
    self.connect(self.id_dec,(dref_src,0))
    self.connect(self.bitcount_src,(dref_src,1))

    ## BER Measuring Tool
    ber_mst = self._ber_measuring_tool = ber_measurement(int(config.ber_window))
    if(self._options.coding):
        self.connect(decoding,ber_mst)
    else:
        self.connect(demod,ber_mst)
    self.connect(dref_src,(ber_mst,1))

    self._measuring_ber = True

    if self._options.enable_ber2:
      ber2 = ofdm.bit_position_dependent_ber( "BER2_" + strftime("%Y%m%d%H%M%S",gmtime()) )
      if(self._options.coding):
        self.connect( decoding, ( ber2, 1 ) )
      else:
        self.connect( demod, ( ber2, 1 ) )
      self.connect( dref_src, ( ber2, 0 ) )
      self.connect( bc_src, ( ber2, 2 ) )

    if self._options.log:
      log_to_file(self, ber_mst, "data/ber_out.float")
      data_f = gr.char_to_float()
      self.connect(dref_src,data_f)
      log_to_file(self, data_f, "data/dataref_out.float")
コード例 #11
0
ファイル: gr_tools.py プロジェクト: WindyCitySDR/gr-ofdm
def log_to_file(hb,block,filename,mag=False,char_to_float=False):
  streamsize = determine_streamsize(block)
  
  if mag:
    vlen = streamsize/gr.sizeof_gr_complex
    gr_mag = gr.complex_to_mag(vlen)
    hb.connect( block, gr_mag )
    log_to_file( hb, gr_mag, filename )
  elif char_to_float:
    vlen = streamsize/gr.sizeof_char
    ctf = gr.char_to_float( vlen )
    hb.connect( block, ctf )
    log_to_file( hb, ctf, filename )
  else:
    file_log = blocks.file_sink(streamsize,filename)
    hb.connect(block,file_log)
コード例 #12
0
ファイル: gr_tools.py プロジェクト: luwangg/gr-ofdm-1
def log_to_file(hb, block, filename, mag=False, char_to_float=False):
    streamsize = determine_streamsize(block)

    if mag:
        vlen = streamsize / gr.sizeof_gr_complex
        gr_mag = gr.complex_to_mag(vlen)
        hb.connect(block, gr_mag)
        log_to_file(hb, gr_mag, filename)
    elif char_to_float:
        vlen = streamsize / gr.sizeof_char
        ctf = gr.char_to_float(vlen)
        hb.connect(block, ctf)
        log_to_file(hb, ctf, filename)
    else:
        file_log = blocks.file_sink(streamsize, filename)
        hb.connect(block, file_log)
コード例 #13
0
ファイル: ofdm_tx.py プロジェクト: ljxangus/ofdm
    def __init__(self, options):
        gr.top_block.__init__(self)

        if options.tx_freq is not None:
            u = uhd_transmitter(options.args, options.bandwidth,
                                options.tx_freq, options.tx_gain, options.spec,
                                options.antenna, options.external,
                                options.verbose)
        elif options.outfile is not None:
            u = gr.file_sink(gr.sizeof_gr_complex, options.outfile)
        else:
            raise SystemExit("--freq or --outfile must be specified\n")

        if options.infile is not None:
            tx = gr.file_source(gr.sizeof_gr_complex,
                                options.infile,
                                repeat=options.repeat)
        else:
            tx = ofdm_rxtx.TX(options)
            data_tones = tx.params.data_tones
            if options.char > 0:
                # read char from file
                data = gr.stream_to_vector(gr.sizeof_float, data_tones * 2)
                # NOTE: we use repeat, assuming the file is long enough or properly aligned
                self.connect(
                    gr.file_source(gr.sizeof_char, options.txdata,
                                   repeat=True), gr.char_to_float(),
                    gr.multiply_const_ff(options.char * (2**-0.5) / 128.0),
                    data)
            else:
                data = ofdm_rxtx.make_data(data_tones, options.size,
                                           options.txdata)
                if options.log:
                    self.connect(
                        data,
                        gr.file_sink(data_tones * gr.sizeof_gr_complex,
                                     'tx-data.dat'))

            self.connect(data, tx)
            self.sender = ofdm_rxtx.sender_thread(tx, options)

        if options.amp != 1:
            amp = gr.multiply_const_cc(options.amp)
            self.connect(tx, amp, u)
        else:
            self.connect(tx, u)
コード例 #14
0
  def __init__( self, vlen, frame_length, no_frames,
                no_preambles, bits_per_subc, bitdata_per_frame ):
    gr.hier_block2.__init__( self,
          "ofdm_ber_estimator",
          gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ),
          gr.io_signature(0,0,0) )

    bpsubc = [0] * ( vlen * no_preambles )
    assert( len( bits_per_subc ) == vlen )
    bpsubc.extend( bits_per_subc )


    bits_per_frame = sum( bpsubc ) * ( frame_length - no_preambles )

    bm_update_trigger = [0] * frame_length
    for i in range( no_preambles + 1 ):
      bm_update_trigger[i] = 1

    bm_update_trigger = gr.vector_source_b( bm_update_trigger, True )

    demapper = ofdm.generic_demapper_vcb( vlen )
    bitmap_src = gr.vector_source_b( bpsubc, True, vlen )

    data_ref_src = gr.vector_source_b( bitdata_per_frame, True )

    compare = gr.xor_bb()
    bitstream_c2f = gr.char_to_float()
    acc_biterr = ofdm.accumulator_ff()

    window_length = bits_per_frame * no_frames
    self.N = window_length
    dst = limit_stream_get_last_item( acc_biterr, window_length )


    self.connect( self, demapper, compare, bitstream_c2f, acc_biterr, dst )
    self.connect( bitmap_src, ( demapper, 1 ) )
    self.connect( bm_update_trigger, ( demapper, 2 ) )
    self.connect( data_ref_src, ( compare, 1 ) )

    self.vector_sources = [ bm_update_trigger, bitmap_src ]
    self.acc = acc_biterr
    self.data_ref_src = data_ref_src
    self.compare = compare
    self.dst = dst
コード例 #15
0
ファイル: ofdm_tx.py プロジェクト: UpYou/ofdm
  def __init__(self, options):
    gr.top_block.__init__(self)

    if options.tx_freq is not None:
      u = uhd_transmitter(options.args,
                          options.bandwidth,
                          options.tx_freq, options.tx_gain,
                          options.spec, options.antenna,
                          options.external, options.verbose)
    elif options.outfile is not None:
      u = gr.file_sink(gr.sizeof_gr_complex, options.outfile)
    else:
      raise SystemExit("--freq or --outfile must be specified\n")

    if options.infile is not None:
      tx = gr.file_source(gr.sizeof_gr_complex, options.infile, repeat = options.repeat)
    else:
      tx = ofdm_rxtx.TX(options)
      data_tones = tx.params.data_tones
      if options.char > 0:
        # read char from file
        data = gr.stream_to_vector(gr.sizeof_float, data_tones * 2)
        # NOTE: we use repeat, assuming the file is long enough or properly aligned
        self.connect(gr.file_source(gr.sizeof_char, options.txdata, repeat=True),
                     gr.char_to_float(),
                     gr.multiply_const_ff(options.char * (2**-0.5) / 128.0),
                     data)
      else:
        data = ofdm_rxtx.make_data(data_tones, options.size, options.txdata)
        if options.log:
          self.connect(data, gr.file_sink(data_tones * gr.sizeof_gr_complex, 'tx-data.dat'))

      self.connect(data, tx)
      self.sender = ofdm_rxtx.sender_thread(tx, options)

    if options.amp != 1:
      amp = gr.multiply_const_cc(options.amp)
      self.connect(tx, amp, u)
    else:
      self.connect(tx, u)
コード例 #16
0
    def __init__(self, frame, panel, vbox, argv):
        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)

        parser = OptionParser(option_class=eng_option)
        parser.add_option("-T",
                          "--tx-subdev-spec",
                          type="subdev",
                          default=None,
                          help="select USRP Tx side A or B")
        parser.add_option("-f",
                          "--freq",
                          type="eng_float",
                          default=107.2e6,
                          help="set Tx frequency to FREQ [required]",
                          metavar="FREQ")
        parser.add_option("--wavfile",
                          type="string",
                          default=None,
                          help="open .wav audio file FILE")
        parser.add_option("--xml",
                          type="string",
                          default="rds_data.xml",
                          help="open .xml RDS data FILE")
        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        usrp_interp = 500
        self.u = usrp.sink_c(0, usrp_interp)
        print "USRP Serial: ", self.u.serial_number()
        usrp_rate = self.u.dac_rate() / usrp_interp  # 256 kS/s

        # determine the daughterboard subdevice we're using
        if options.tx_subdev_spec is None:
            options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
        self.u.set_mux(
            usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec))
        self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec)
        print "Using d'board", self.subdev.side_and_name()

        # set max Tx gain, tune frequency and enable transmitter
        gain = self.subdev.gain_range()[1]
        self.subdev.set_gain(gain)
        print "Gain set to", gain
        if self.u.tune(self.subdev.which(), self.subdev, options.freq):
            print "Tuned to", options.freq / 1e6, "MHz"
        else:
            sys.exit(1)
        self.subdev.set_enable(True)

        # open wav file containing floats in the [-1, 1] range, repeat
        if options.wavfile is None:
            print "Please provide a wavfile to transmit! Exiting\n"
            sys.exit(1)
        self.src = gr.wavfile_source(options.wavfile, True)
        nchans = self.src.channels()
        sample_rate = self.src.sample_rate()
        bits_per_sample = self.src.bits_per_sample()
        print nchans, "channels,", sample_rate, "samples/sec,", \
         bits_per_sample, "bits/sample"

        # resample to usrp rate
        self.resample_left = blks2.rational_resampler_fff(
            usrp_rate, sample_rate)
        self.resample_right = blks2.rational_resampler_fff(
            usrp_rate, sample_rate)
        self.connect((self.src, 0), self.resample_left)
        self.connect((self.src, 1), self.resample_right)

        # create L+R (mono) and L-R (stereo)
        self.audio_lpr = gr.add_ff()
        self.audio_lmr = gr.sub_ff()
        self.connect(self.resample_left, (self.audio_lpr, 0))
        self.connect(self.resample_left, (self.audio_lmr, 0))
        self.connect(self.resample_right, (self.audio_lpr, 1))
        self.connect(self.resample_right, (self.audio_lmr, 1))

        # low-pass filter for L+R
        audio_lpr_taps = gr.firdes.low_pass(
            0.5,  # gain
            usrp_rate,  # sampling rate
            15e3,  # passband cutoff
            1e3,  # transition width
            gr.firdes.WIN_HAMMING)
        self.audio_lpr_filter = gr.fir_filter_fff(1, audio_lpr_taps)
        self.connect(self.audio_lpr, self.audio_lpr_filter)

        # create pilot tone at 19 kHz
        self.pilot = gr.sig_source_f(
            usrp_rate,  # sampling rate
            gr.GR_SIN_WAVE,  # waveform
            19e3,  # frequency
            5e-2)  # amplitude

        # upconvert L-R to 38 kHz and band-pass
        self.mix_stereo = gr.multiply_ff()
        audio_lmr_taps = gr.firdes.band_pass(
            80,  # gain
            usrp_rate,  # sampling rate
            38e3 - 15e3,  # low cutoff
            38e3 + 15e3,  # high cutoff
            1e3,  # transition width
            gr.firdes.WIN_HAMMING)
        self.audio_lmr_filter = gr.fir_filter_fff(1, audio_lmr_taps)
        self.connect(self.audio_lmr, (self.mix_stereo, 0))
        self.connect(self.pilot, (self.mix_stereo, 1))
        self.connect(self.pilot, (self.mix_stereo, 2))
        self.connect(self.mix_stereo, self.audio_lmr_filter)

        # create RDS bitstream
        # diff-encode, manchester-emcode, NRZ
        # enforce the 1187.5bps rate
        # pulse shaping filter (matched with receiver)
        # mix with 57kHz carrier (equivalent to BPSK)
        self.rds_enc = rds.data_encoder('rds_data.xml')
        self.diff_enc = gr.diff_encoder_bb(2)
        self.manchester1 = gr.map_bb([1, 2])
        self.manchester2 = gr.unpack_k_bits_bb(2)
        self.nrz = gr.map_bb([-1, 1])
        self.c2f = gr.char_to_float()
        self.rate_enforcer = rds.rate_enforcer(usrp_rate)
        pulse_shaping_taps = gr.firdes.low_pass(
            1,  # gain
            usrp_rate,  # sampling rate
            1.5e3,  # passband cutoff
            2e3,  # transition width
            gr.firdes.WIN_HAMMING)
        self.pulse_shaping = gr.fir_filter_fff(1, pulse_shaping_taps)
        self.bpsk_mod = gr.multiply_ff()
        self.connect (self.rds_enc, self.diff_enc, self.manchester1, \
         self.manchester2, self.nrz, self.c2f)
        self.connect(self.c2f, (self.rate_enforcer, 0))
        self.connect(self.pilot, (self.rate_enforcer, 1))
        self.connect(self.rate_enforcer, (self.bpsk_mod, 0))
        self.connect(self.pilot, (self.bpsk_mod, 1))
        self.connect(self.pilot, (self.bpsk_mod, 2))
        self.connect(self.pilot, (self.bpsk_mod, 3))

        # RDS band-pass filter
        rds_filter_taps = gr.firdes.band_pass(
            50,  # gain
            usrp_rate,  # sampling rate
            57e3 - 3e3,  # low cutoff
            57e3 + 3e3,  # high cutoff
            1e3,  # transition width
            gr.firdes.WIN_HAMMING)
        self.rds_filter = gr.fir_filter_fff(1, rds_filter_taps)
        self.connect(self.bpsk_mod, self.rds_filter)

        # mix L+R, pilot, L-R and RDS
        self.mixer = gr.add_ff()
        self.connect(self.audio_lpr_filter, (self.mixer, 0))
        self.connect(self.pilot, (self.mixer, 1))
        self.connect(self.audio_lmr_filter, (self.mixer, 2))
        self.connect(self.rds_filter, (self.mixer, 3))

        # fm modulation, gain & TX
        max_dev = 75e3
        k = 2 * math.pi * max_dev / usrp_rate  # modulator sensitivity
        self.modulator = gr.frequency_modulator_fc(k)
        self.gain = gr.multiply_const_cc(5e3)
        self.connect(self.mixer, self.modulator, self.gain, self.u)

        # plot an FFT to verify we are sending what we want
        if 1:
            self.fft = fftsink2.fft_sink_f(panel,
                                           title="Pre FM modulation",
                                           fft_size=512 * 4,
                                           sample_rate=usrp_rate,
                                           y_per_div=20,
                                           ref_level=-20)
            self.connect(self.mixer, self.fft)
            vbox.Add(self.fft.win, 1, wx.EXPAND)
        if 0:
            self.scope = scopesink2.scope_sink_f(panel,
                                                 title="RDS encoder output",
                                                 sample_rate=usrp_rate)
            self.connect(self.rds_enc, self.scope)
            vbox.Add(self.scope.win, 1, wx.EXPAND)
コード例 #17
0
ファイル: usrp_rx_lrit.py プロジェクト: jinjoh/SDR
	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="USRP LRIT Receiver")

		##################################################
		# Variables
		##################################################
		self.config_filename = config_filename = "usrp_rx_lrit.cfg"
		self._saved_decim_config = ConfigParser.ConfigParser()
		self._saved_decim_config.read(config_filename)
		try: saved_decim = self._saved_decim_config.getint("main", "decim")
		except: saved_decim = 160
		self.saved_decim = saved_decim
		self.decim = decim = saved_decim
		self.symbol_rate = symbol_rate = 293e3
		self._saved_gain_mu_config = ConfigParser.ConfigParser()
		self._saved_gain_mu_config.read(config_filename)
		try: saved_gain_mu = self._saved_gain_mu_config.getfloat("main", "gain_mu")
		except: saved_gain_mu = 0.005
		self.saved_gain_mu = saved_gain_mu
		self._saved_gain_config = ConfigParser.ConfigParser()
		self._saved_gain_config.read(config_filename)
		try: saved_gain = self._saved_gain_config.getfloat("main", "gain")
		except: saved_gain = 33
		self.saved_gain = saved_gain
		self._saved_freq_config = ConfigParser.ConfigParser()
		self._saved_freq_config.read(config_filename)
		try: saved_freq = self._saved_freq_config.getfloat("main", "freq")
		except: saved_freq = 137e6
		self.saved_freq = saved_freq
		self._saved_costas_alpha_config = ConfigParser.ConfigParser()
		self._saved_costas_alpha_config.read(config_filename)
		try: saved_costas_alpha = self._saved_costas_alpha_config.getfloat("main", "costas_alpha")
		except: saved_costas_alpha = 0.005
		self.saved_costas_alpha = saved_costas_alpha
		self.samp_rate = samp_rate = 64e6/decim
		self.sps = sps = samp_rate/symbol_rate
		self.gain_mu = gain_mu = saved_gain_mu
		self.gain = gain = saved_gain
		self.freq = freq = saved_freq
		self.costas_alpha = costas_alpha = saved_costas_alpha

		##################################################
		# Notebooks
		##################################################
		self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
		self.displays.AddPage(grc_wxgui.Panel(self.displays), "USRP RX")
		self.displays.AddPage(grc_wxgui.Panel(self.displays), "Costas Output")
		self.GridAdd(self.displays, 2, 0, 1, 3)

		##################################################
		# Controls
		##################################################
		self._decim_text_box = forms.text_box(
			parent=self.GetWin(),
			value=self.decim,
			callback=self.set_decim,
			label="Decim",
			converter=forms.int_converter(),
		)
		self.GridAdd(self._decim_text_box, 0, 0, 1, 1)
		_gain_mu_sizer = wx.BoxSizer(wx.VERTICAL)
		self._gain_mu_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_gain_mu_sizer,
			value=self.gain_mu,
			callback=self.set_gain_mu,
			label="Gain Mu",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._gain_mu_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_gain_mu_sizer,
			value=self.gain_mu,
			callback=self.set_gain_mu,
			minimum=0,
			maximum=0.5,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_gain_mu_sizer, 1, 1, 1, 1)
		_gain_sizer = wx.BoxSizer(wx.VERTICAL)
		self._gain_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_gain_sizer,
			value=self.gain,
			callback=self.set_gain,
			label="Gain",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._gain_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_gain_sizer,
			value=self.gain,
			callback=self.set_gain,
			minimum=0,
			maximum=115,
			num_steps=115,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_gain_sizer, 0, 1, 1, 1)
		_freq_sizer = wx.BoxSizer(wx.VERTICAL)
		self._freq_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_freq_sizer,
			value=self.freq,
			callback=self.set_freq,
			label="Frequency",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._freq_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_freq_sizer,
			value=self.freq,
			callback=self.set_freq,
			minimum=135e6,
			maximum=139e6,
			num_steps=400,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_freq_sizer, 0, 2, 1, 1)
		_costas_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
		self._costas_alpha_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_costas_alpha_sizer,
			value=self.costas_alpha,
			callback=self.set_costas_alpha,
			label="Costas Alpha",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._costas_alpha_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_costas_alpha_sizer,
			value=self.costas_alpha,
			callback=self.set_costas_alpha,
			minimum=0,
			maximum=0.5,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_costas_alpha_sizer, 1, 0, 1, 1)

		##################################################
		# Blocks
		##################################################
		self.gr_add_const_vxx_0 = gr.add_const_vff((48.0, ))
		self.gr_agc_xx_0 = gr.agc_cc(1e-6, 1.0, 1.0/32767.0, 1.0)
		self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
		self.gr_char_to_float_0 = gr.char_to_float()
		self.gr_complex_to_real_0 = gr.complex_to_real(1)
		self.gr_file_sink_0 = gr.file_sink(gr.sizeof_char*1, "bits.dat")
		self.gr_file_source_0 = gr.file_source(gr.sizeof_gr_complex*1, "lrit.dat", False)
		self.gr_float_to_char_0 = gr.float_to_char()
		self.gr_mpsk_receiver_cc_0 = gr.mpsk_receiver_cc(2, 0, costas_alpha, costas_alpha*costas_alpha/4.0, -0.05, 0.05, 0.5, gain_mu, sps, gain_mu*gain_mu/4.0, 0.05)
		self.gr_probe_mpsk_snr_c_0 = grc_blks2.probe_mpsk_snr_c(
			type='snr',
			alpha=0.0001,
			probe_rate=10,
		)
		self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex*1, samp_rate)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
			self.displays.GetPage(0).GetWin(),
			baseband_freq=freq,
			y_per_div=10,
			y_divs=10,
			ref_level=50,
			sample_rate=samp_rate,
			fft_size=1024,
			fft_rate=30,
			average=False,
			avg_alpha=None,
			title="Spectrum",
			peak_hold=False,
		)
		self.displays.GetPage(0).GridAdd(self.wxgui_fftsink2_0.win, 0, 0, 1, 1)
		self.wxgui_numbersink2_0 = numbersink2.number_sink_f(
			self.displays.GetPage(1).GetWin(),
			unit="dB",
			minval=0,
			maxval=30,
			factor=1.0,
			decimal_places=1,
			ref_level=0,
			sample_rate=10,
			number_rate=10,
			average=False,
			avg_alpha=None,
			label="SNR",
			peak_hold=False,
			show_gauge=True,
		)
		self.displays.GetPage(1).GridAdd(self.wxgui_numbersink2_0.win, 2, 0, 1, 1)
		self.wxgui_scopesink2_0 = scopesink2.scope_sink_c(
			self.displays.GetPage(0).GetWin(),
			title="Waveform",
			sample_rate=samp_rate,
			v_scale=0.5,
			t_scale=20.0/samp_rate,
			ac_couple=False,
			xy_mode=True,
			num_inputs=1,
		)
		self.displays.GetPage(0).GridAdd(self.wxgui_scopesink2_0.win, 1, 0, 1, 1)
		self.wxgui_scopesink2_1 = scopesink2.scope_sink_c(
			self.displays.GetPage(1).GetWin(),
			title="Scope Plot",
			sample_rate=samp_rate,
			v_scale=0.4,
			t_scale=20.0/samp_rate,
			ac_couple=False,
			xy_mode=True,
			num_inputs=1,
		)
		self.displays.GetPage(1).GridAdd(self.wxgui_scopesink2_1.win, 0, 0, 1, 1)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_agc_xx_0, 0), (self.wxgui_scopesink2_0, 0))
		self.connect((self.gr_file_source_0, 0), (self.gr_throttle_0, 0))
		self.connect((self.gr_throttle_0, 0), (self.gr_agc_xx_0, 0))
		self.connect((self.gr_probe_mpsk_snr_c_0, 0), (self.wxgui_numbersink2_0, 0))
		self.connect((self.gr_mpsk_receiver_cc_0, 0), (self.gr_probe_mpsk_snr_c_0, 0))
		self.connect((self.gr_agc_xx_0, 0), (self.gr_mpsk_receiver_cc_0, 0))
		self.connect((self.gr_mpsk_receiver_cc_0, 0), (self.wxgui_scopesink2_1, 0))
		self.connect((self.gr_agc_xx_0, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_mpsk_receiver_cc_0, 0), (self.gr_complex_to_real_0, 0))
		self.connect((self.gr_complex_to_real_0, 0), (self.gr_binary_slicer_fb_0, 0))
		self.connect((self.gr_binary_slicer_fb_0, 0), (self.gr_char_to_float_0, 0))
		self.connect((self.gr_char_to_float_0, 0), (self.gr_add_const_vxx_0, 0))
		self.connect((self.gr_add_const_vxx_0, 0), (self.gr_float_to_char_0, 0))
		self.connect((self.gr_float_to_char_0, 0), (self.gr_file_sink_0, 0))
コード例 #18
0
ファイル: sync_watcher.py プロジェクト: extrasyllmit/extrasy
    def __init__(self, pkt_size=32032):
        gr.hier_block2.__init__(
            self,
            "Sync Watcher",
            gr.io_signature(1, 1, gr.sizeof_char * 1),
            gr.io_signature(0, 0, 0),
        )

        ##################################################
        # Variables
        ##################################################
        crc_size = 32
        # size of crc, in bits
        preamble_size = 16
        access_code_size = 64
        # size of packet, including crc, but not including preamble or access_code
        # This is (probably) the number of bits left in the packet once an access_code flag is seen
        # TODO: verify timing of access_code flag with respect to the rest of the packet
        self.pkt_size = pkt_size  #use to be: 4000*8 + crc_size

        # number of bits we're interested in from the input byte stream
        self.significant_bits = 2

        ##################################################
        # Blocks
        ##################################################

        # unpack bits takes one byte in and splits it into k bytes out.
        # bit 0 from input is placed in bit 0 of output byte 0
        # bit 1 from input is placed in bit 0 of output byte 1
        # ... and so on up to k
        self.unpack_bits = gr.unpack_k_bits_bb(self.significant_bits)

        # deinterleave splits single stream of bytes at rate of N bytes/sec into two separate
        # streams of bytes, each at a rate of N/2 bytes/sec
        self.deinterleave = gr.deinterleave(gr.sizeof_char * 1)

        self.char_to_float = gr.char_to_float(1)

        # Setup the downcounter that will raise the flag for max iterations upon high input
        self.downcounter = digital_ll.downcounter(self.pkt_size)

        # Null sinks 1 and 2 for tieing off lose ends
        self.null_sink_1 = gr.null_sink(gr.sizeof_char * 1)
        self.null_sink_2 = gr.null_sink(gr.sizeof_float * 1)

        #self.file_sink = gr.file_sink(gr.sizeof_short * 1, "/home/interlaken/a/cr22845/SDR/generalized-sdr-comms/demos/csma_month2/flag_out.dat")

        ##################################################
        # Connections
        ##################################################
        # unpack byte with bit 0 = data bit and bit 1 = flag bit into two bytes, byte 0 has bit
        # 0 = data bit and byte 1 has bit 0 = flag bit
        self.connect((self, 0), (self.unpack_bits, 0))

        # deinterleave to get two streams. One byte stream has only data bits, on stream has only
        # flag bits
        self.connect((self.unpack_bits, 0), (self.deinterleave, 0))

        # send data bytes to null
        self.connect((self.deinterleave, 1), (self.null_sink_1, 0))

        # convert flag bytes to floats for use with downcounter
        self.connect((self.deinterleave, 0), (self.char_to_float, 0))

        # connect the float output to the downcounter block
        self.connect((self.char_to_float, 0), (self.downcounter, 0))

        # finally tie it off with a null sink
        self.connect((self.downcounter, 0), (self.null_sink_2, 0))
コード例 #19
0
ファイル: psk_simu.py プロジェクト: dinart/psk_simu
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Communication System Graphical Analyzer (LAPS/UFCG)")
        
        ##################################################
        # Default Variables
        ##################################################
        self.sps = 2
        self.snr = 20
        self.symbol_rate = 140000
        self.mod_type = "DBPSK"
        self.view = 1
        self.band= 200
        self.excess_bw=0.35
        self.fading_flag = False 
        self.fdts = -8
        self.fading_state_rx = False
        
        ##################################################
        # Blocks Definition
        ##################################################
        
        #A bit stream of 1's is generated at the source, scrambled,
        #modulated and sent to the input of an AWGN channel.
        #random.seed(42)
        #self.source = gr.vector_source_b([random.randint(0, 2) for i in range(0,10^8)], True)
        self.source = gr.vector_source_b((1,), True, 1)
        self.thottle = gr.throttle(gr.sizeof_char,10e5)
        self.scrambler = gr.scrambler_bb(0x40801, 0x92F72, 20) #Taxa de simbolos constante
        self.pack = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST)
        self.modulator = utils.mods[self.mod_type](self.sps,excess_bw=self.excess_bw)
        self.channel = utils.channel(1/10.0**(self.snr/10.0),self.band,self.symbol_rate,self.sps)
        
        #The noisy signal is demodulated, descrambled and the BER
        #is estimated by the ber_estim block using the receiver
        #density of 0 bits.
        self.demodulator = utils.demods[self.mod_type](self.sps,excess_bw=self.excess_bw)     
        self.descrambler = gr.descrambler_bb(0x40801, 0x92F72, 20)
        self.char2float = gr.char_to_float()
        self.mov_average = gr.moving_average_ff(524288, 1/524288., 10000)
        self.ber = utils.ber_estim()
        #self.ber = utils.ber_estim_simple(3)

        
        ##################################################
        # GUI Elements Definition
        ##################################################
        
        #Defines an adds FFT Window to GUI
        self.fft = fftsink.fft_sink_c(self.GetWin(), sample_rate=self.symbol_rate*self.sps, baseband_freq=5e6)
        self.GridAdd(self.fft.win, 0,3,4,3)
        self.ctr= gr.complex_to_real(1)
        
        #Defines and adds SNR slider to GUI
        _snr_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._snr_text_box = forms.text_box(parent=self.GetWin(),
            sizer=_snr_sizer, value=self.snr, callback=self.callback_snr,
            label=" SNR (dB)", converter=forms.float_converter(),
            proportion=0)
        self._snr_slider = forms.slider(parent=self.GetWin(),
            sizer=_snr_sizer, value=self.snr, callback=self.callback_snr,
            minimum=0, maximum=20, style=wx.RA_HORIZONTAL, proportion=1)
        self.GridAdd(_snr_sizer, 4, 3, 1, 3)
        
        #Defines and adds bandwidth slider to GUI
        band_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.band_text_box = forms.text_box(parent=self.GetWin(),
            sizer=band_sizer, value=self.band, callback=self.callback_band,
            label="Bandwidth (kHz)", converter=forms.float_converter(),
            proportion=0)
        self.band_slider = forms.slider(parent=self.GetWin(),
            sizer=band_sizer, value=self.band, callback=self.callback_band,
            minimum=30, maximum=200, style=wx.RA_HORIZONTAL, proportion=1)
        self.GridAdd(band_sizer, 5, 3, 1, 3)
        
        #Defines and adds Rayleigh GUI elements
        
        fading_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.fading_text_box = forms.text_box(parent=self.GetWin(),
            sizer=fading_sizer, value=self.fdts, callback=self.callback_fading,
            label='Fading/log(FdTs)', converter=forms.float_converter(),
            proportion=0)
        self.fading_slider = forms.slider(parent=self.GetWin(),
            sizer=fading_sizer, value=self.fdts, callback=self.callback_fading,
            minimum=-8, maximum=-2, style=wx.RA_HORIZONTAL, proportion=1)
        self.GridAdd(fading_sizer, 6, 3, 1, 3)
        
        #Defines and adds modulation type chooser to GUI
        self._mod_type_chooser = forms.radio_buttons(parent=self.GetWin(),
            value=self.mod_type, callback=self.set_mod_type,
            label="Modulation", choices=["DBPSK", "DQPSK", "D8PSK"],
            labels=["DBPSK", "DQPSK", "D8PSK"], style=wx.RA_HORIZONTAL)
        self.GridAdd(self._mod_type_chooser, 7, 4, 1, 2)

        
        #Defines and adds signal source chooser
        self.sig_src_chooser = forms.radio_buttons(parent=self.GetWin(),
            value=self.view, callback=self.callback_view,
            label="Signal Source", choices=[0,1],
            labels=["Transmitter","Receiver"], style=wx.RA_VERTICAL)
        self.GridAdd(self.sig_src_chooser, 7,3,1,1)
        
        
        #Definition of the of constellation window and attachment to the GUI
        self.constel = constsink.const_sink_c(self.GetWin(),
            title="RX Constellation Plot",  sample_rate=self.symbol_rate,
            const_size=256, mod=self.mod_type)
        self.GridAdd(self.constel.win,0,0,8,3)
        
        
        #Definition of the constellation sink window and attachment to the GUI
        self.number_sink = bersink.number_sink_f(self.GetWin(),
            sample_rate=self.symbol_rate)
        self.GridAdd(self.number_sink.win,8,0,1,6)
        
        ##################################################
        # Blocks Connections
        ##################################################
        
        #The necessary block connections to the system work as described above.
        self.connect(self.source, self.scrambler , self.thottle, self.pack)
        #self.connect(self.source , self.thottle, self.pack)
        self.connect(self.pack, self.modulator, self.channel, self.demodulator)
        self.connect(self.channel, self.fft)
        self.connect(self.demodulator.diffdec, self.constel)
        self.connect(self.demodulator, self.descrambler, self.char2float, self.mov_average)
        self.connect(self.mov_average, self.ber, self.number_sink)
コード例 #20
0
  def publish_rx_performance_measure(self):
    if self._rx_performance_measure_initialized():
      return

    self.rx_performance_measure_initialized = True

    config = station_configuration()
    vlen = config.data_subcarriers
    vlen_sinr_sc = config.subcarriers

#    self.rx_per_sink = rpsink = rpsink_dummy()

    self.setup_ber_measurement()
    self.setup_snr_measurement()
    self.setup_snr_measurement_2()

    ber_mst = self._ber_measuring_tool
    if self._options.sinr_est:
        sinr_mst = self._sinr_measurement
        sinr_mst_2 = self._sinr_measurement_2
    else:
        snr_mst = self._snr_measurement
        snr_mst_2 = self._snr_measurement_2

    # 1. frame id

    # 2. channel transfer function
    ctf = self.filter_ctf()
    ctf_2 = self.filter_ctf_2()
    
    self.zmq_probe_ctf = zeromq.pub_sink(gr.sizeof_float,config.data_subcarriers, "tcp://*:5559")
    self.zmq_probe_ctf_2 = zeromq.pub_sink(gr.sizeof_float,config.data_subcarriers, "tcp://*:5558")
    self.connect(ctf, blocks.keep_one_in_n(gr.sizeof_float*config.data_subcarriers,20) ,self.zmq_probe_ctf)
    self.connect(ctf_2, blocks.keep_one_in_n(gr.sizeof_float*config.data_subcarriers,20) ,self.zmq_probe_ctf_2)
    
    # 3. BER
    ### FIXME HACK


    print "Normal BER measurement"


    trig_src = dynamic_trigger_ib(False)
    self.connect(self.bitcount_src,trig_src)

    ber_sampler = vector_sampler(gr.sizeof_float,1)
    self.connect(ber_mst,(ber_sampler,0))
    self.connect(trig_src,(ber_sampler,1))
      
    if self._options.log:
          trig_src_float = gr.char_to_float()
          self.connect(trig_src,trig_src_float)
          log_to_file(self, trig_src_float , 'data/dynamic_trigger_out.float')


    if self._options.sinr_est is False:
          self.zmq_probe_ber = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5556")
          self.connect(ber_sampler,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_ber)

          self.zmq_probe_snr = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5555")
          self.connect(snr_mst,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_snr)
          
          self.zmq_probe_snr_2 = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5554")
          self.connect(snr_mst_2,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_snr_2)
コード例 #21
0
    def __init__(self):
        gr.top_block.__init__(self, "Simple QAM Simulation")
        Qt.QWidget.__init__(self)
        self.setWindowTitle("Simple QAM Simulation")
        self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
        self.top_scroll_layout = Qt.QVBoxLayout()
        self.setLayout(self.top_scroll_layout)
        self.top_scroll = Qt.QScrollArea()
        self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
        self.top_scroll_layout.addWidget(self.top_scroll)
        self.top_scroll.setWidgetResizable(True)
        self.top_widget = Qt.QWidget()
        self.top_scroll.setWidget(self.top_widget)
        self.top_layout = Qt.QVBoxLayout(self.top_widget)
        self.top_grid_layout = Qt.QGridLayout()
        self.top_layout.addLayout(self.top_grid_layout)

        ##################################################
        # Variables
        ##################################################
        self.constellation_cardinality = constellation_cardinality = 16
        self.const_object = const_object = constellations()['qam'](
            constellation_cardinality)
        self.snr_db = snr_db = 20
        self.constellation = constellation = const_object.points()
        self.sps = sps = 8
        self.samp_rate = samp_rate = 250000
        self.noise_amp = noise_amp = sqrt((10**(-snr_db / 10.)) / 2.)
        self.constellation_power = constellation_power = sqrt(
            sum([abs(i)**2
                 for i in constellation]) / constellation_cardinality)

        ##################################################
        # Blocks
        ##################################################
        self.tabid_0 = Qt.QTabWidget()
        self.tabid_0_widget_0 = Qt.QWidget()
        self.tabid_0_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_0_widget_0)
        self.tabid_0_grid_layout_0 = Qt.QGridLayout()
        self.tabid_0_layout_0.addLayout(self.tabid_0_grid_layout_0)
        self.tabid_0.addTab(self.tabid_0_widget_0, "TX")
        self.tabid_0_widget_1 = Qt.QWidget()
        self.tabid_0_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_0_widget_1)
        self.tabid_0_grid_layout_1 = Qt.QGridLayout()
        self.tabid_0_layout_1.addLayout(self.tabid_0_grid_layout_1)
        self.tabid_0.addTab(self.tabid_0_widget_1, "CHANNEL")
        self.tabid_0_widget_2 = Qt.QWidget()
        self.tabid_0_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_0_widget_2)
        self.tabid_0_grid_layout_2 = Qt.QGridLayout()
        self.tabid_0_layout_2.addLayout(self.tabid_0_grid_layout_2)
        self.tabid_0.addTab(self.tabid_0_widget_2, "RX")
        self.top_grid_layout.addWidget(self.tabid_0, 30, 0, 10, 100)
        self.tabid_2 = Qt.QTabWidget()
        self.tabid_2_widget_0 = Qt.QWidget()
        self.tabid_2_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_2_widget_0)
        self.tabid_2_grid_layout_0 = Qt.QGridLayout()
        self.tabid_2_layout_0.addLayout(self.tabid_2_grid_layout_0)
        self.tabid_2.addTab(self.tabid_2_widget_0, "symbol-based")
        self.tabid_2_widget_1 = Qt.QWidget()
        self.tabid_2_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_2_widget_1)
        self.tabid_2_grid_layout_1 = Qt.QGridLayout()
        self.tabid_2_layout_1.addLayout(self.tabid_2_grid_layout_1)
        self.tabid_2.addTab(self.tabid_2_widget_1, "bit-based")
        self.tabid_2_widget_2 = Qt.QWidget()
        self.tabid_2_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_2_widget_2)
        self.tabid_2_grid_layout_2 = Qt.QGridLayout()
        self.tabid_2_layout_2.addLayout(self.tabid_2_grid_layout_2)
        self.tabid_2.addTab(self.tabid_2_widget_2, "BER")
        self.tabid_0_layout_2.addWidget(self.tabid_2)
        self.tabid_1 = Qt.QTabWidget()
        self.tabid_1_widget_0 = Qt.QWidget()
        self.tabid_1_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_1_widget_0)
        self.tabid_1_grid_layout_0 = Qt.QGridLayout()
        self.tabid_1_layout_0.addLayout(self.tabid_1_grid_layout_0)
        self.tabid_1.addTab(self.tabid_1_widget_0, "bit-based")
        self.tabid_1_widget_1 = Qt.QWidget()
        self.tabid_1_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_1_widget_1)
        self.tabid_1_grid_layout_1 = Qt.QGridLayout()
        self.tabid_1_layout_1.addLayout(self.tabid_1_grid_layout_1)
        self.tabid_1.addTab(self.tabid_1_widget_1, "scrambled")
        self.tabid_1_widget_2 = Qt.QWidget()
        self.tabid_1_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom,
                                              self.tabid_1_widget_2)
        self.tabid_1_grid_layout_2 = Qt.QGridLayout()
        self.tabid_1_layout_2.addLayout(self.tabid_1_grid_layout_2)
        self.tabid_1.addTab(self.tabid_1_widget_2, "symbol-based")
        self.tabid_0_grid_layout_0.addWidget(self.tabid_1, 0, 0, 10, 10)
        self.qtgui_time_sink_x_0 = qtgui.time_sink_f(
            1024,  #size
            samp_rate,  #bw
            "QT GUI Plot",  #name
            1  #number of inputs
        )
        self._qtgui_time_sink_x_0_win = sip.wrapinstance(
            self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget)
        self.tabid_2_layout_2.addWidget(self._qtgui_time_sink_x_0_win)
        self.qtgui_sink_x_0_1_0_0 = qtgui.sink_f(
            1024,  #fftsize
            firdes.WIN_BLACKMAN_hARRIS,  #wintype
            0,  #fc
            samp_rate,  #bw
            "QT GUI Plot",  #name
            False,  #plotfreq
            False,  #plotwaterfall
            True,  #plottime
            True,  #plotconst
        )
        self._qtgui_sink_x_0_1_0_0_win = sip.wrapinstance(
            self.qtgui_sink_x_0_1_0_0.pyqwidget(), Qt.QWidget)
        self.tabid_1_layout_0.addWidget(self._qtgui_sink_x_0_1_0_0_win)
        self.qtgui_sink_x_0_1_0 = qtgui.sink_f(
            1024,  #fftsize
            firdes.WIN_BLACKMAN_hARRIS,  #wintype
            0,  #fc
            samp_rate,  #bw
            "QT GUI Plot",  #name
            True,  #plotfreq
            False,  #plotwaterfall
            True,  #plottime
            True,  #plotconst
        )
        self._qtgui_sink_x_0_1_0_win = sip.wrapinstance(
            self.qtgui_sink_x_0_1_0.pyqwidget(), Qt.QWidget)
        self.tabid_1_layout_1.addWidget(self._qtgui_sink_x_0_1_0_win)
        self.qtgui_sink_x_0_1 = qtgui.sink_c(
            1024,  #fftsize
            firdes.WIN_BLACKMAN_hARRIS,  #wintype
            0,  #fc
            samp_rate,  #bw
            "QT GUI Plot",  #name
            False,  #plotfreq
            False,  #plotwaterfall
            True,  #plottime
            True,  #plotconst
        )
        self._qtgui_sink_x_0_1_win = sip.wrapinstance(
            self.qtgui_sink_x_0_1.pyqwidget(), Qt.QWidget)
        self.tabid_1_layout_2.addWidget(self._qtgui_sink_x_0_1_win)
        self.qtgui_sink_x_0_0_0_0 = qtgui.sink_c(
            1024,  #fftsize
            firdes.WIN_BLACKMAN_hARRIS,  #wintype
            0,  #fc
            samp_rate,  #bw
            "QT GUI Plot",  #name
            True,  #plotfreq
            False,  #plotwaterfall
            True,  #plottime
            True,  #plotconst
        )
        self._qtgui_sink_x_0_0_0_0_win = sip.wrapinstance(
            self.qtgui_sink_x_0_0_0_0.pyqwidget(), Qt.QWidget)
        self.tabid_2_layout_0.addWidget(self._qtgui_sink_x_0_0_0_0_win)
        self.qtgui_sink_x_0_0_0 = qtgui.sink_f(
            1024,  #fftsize
            firdes.WIN_BLACKMAN_hARRIS,  #wintype
            0,  #fc
            samp_rate,  #bw
            "QT GUI Plot",  #name
            False,  #plotfreq
            False,  #plotwaterfall
            True,  #plottime
            True,  #plotconst
        )
        self._qtgui_sink_x_0_0_0_win = sip.wrapinstance(
            self.qtgui_sink_x_0_0_0.pyqwidget(), Qt.QWidget)
        self.tabid_2_layout_1.addWidget(self._qtgui_sink_x_0_0_0_win)
        self.qtgui_sink_x_0_0 = qtgui.sink_c(
            1024,  #fftsize
            firdes.WIN_BLACKMAN_hARRIS,  #wintype
            0,  #fc
            samp_rate,  #bw
            "QT GUI Plot",  #name
            True,  #plotfreq
            False,  #plotwaterfall
            True,  #plottime
            False,  #plotconst
        )
        self._qtgui_sink_x_0_0_win = sip.wrapinstance(
            self.qtgui_sink_x_0_0.pyqwidget(), Qt.QWidget)
        self.tabid_0_layout_1.addWidget(self._qtgui_sink_x_0_0_win)
        self.gr_vector_source_x_0_0 = gr.vector_source_b(([1, 0]), True, 1)
        self.gr_vector_source_x_0 = gr.vector_source_b(([1, 0]), True, 1)
        self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(
            int(log2(constellation_cardinality)))
        self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex * 1, samp_rate)
        self.gr_pack_k_bits_bb_0 = gr.pack_k_bits_bb(
            int(log2(constellation_cardinality)))
        self.gr_null_sink_0 = gr.null_sink(gr.sizeof_char * 1)
        self.gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, noise_amp,
                                                     0)
        self.gr_nlog10_ff_0 = gr.nlog10_ff(1, 1, 0)
        self.gr_multiply_const_vxx_0_0 = gr.multiply_const_vcc(
            (1. / constellation_power, ))
        self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc(
            (constellation_power, ))
        self.gr_file_sink_0_1_0 = gr.file_sink(gr.sizeof_gr_complex * 1,
                                               "rx_sym.32fc")
        self.gr_file_sink_0_1_0.set_unbuffered(False)
        self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_gr_complex * 1,
                                             "tx_sym.32fc")
        self.gr_file_sink_0_1.set_unbuffered(False)
        self.gr_file_sink_0_0 = gr.file_sink(gr.sizeof_char * 1, "rx.8b")
        self.gr_file_sink_0_0.set_unbuffered(False)
        self.gr_file_sink_0 = gr.file_sink(gr.sizeof_char * 1, "tx.8b")
        self.gr_file_sink_0.set_unbuffered(False)
        self.gr_descrambler_bb_0 = gr.descrambler_bb(0xe4001, 0x7ffff, 19)
        self.gr_char_to_float_1_0 = gr.char_to_float(1, 1)
        self.gr_char_to_float_1 = gr.char_to_float(1, 1)
        self.gr_char_to_float_0 = gr.char_to_float(1, 1)
        self.gr_add_xx_0 = gr.add_vcc(1)
        self.digital_scrambler_bb_0 = digital.scrambler_bb(
            0xe4001, 0x7fffF, 19)
        self.digital_constellation_receiver_cb_0 = digital.constellation_receiver_cb(
            const_object.base(), 6.28 / 100, -0.25, +0.25)
        self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bc(
            (constellation), 1)
        self.blks2_error_rate_0 = grc_blks2.error_rate(
            type='BER',
            win_size=samp_rate,
            bits_per_symbol=1,
        )

        ##################################################
        # Connections
        ##################################################
        self.connect((self.gr_vector_source_x_0, 0),
                     (self.digital_scrambler_bb_0, 0))
        self.connect((self.digital_scrambler_bb_0, 0),
                     (self.gr_pack_k_bits_bb_0, 0))
        self.connect((self.gr_pack_k_bits_bb_0, 0),
                     (self.digital_chunks_to_symbols_xx_0, 0))
        self.connect((self.digital_constellation_receiver_cb_0, 0),
                     (self.gr_file_sink_0_0, 0))
        self.connect((self.digital_constellation_receiver_cb_0, 0),
                     (self.gr_unpack_k_bits_bb_0, 0))
        self.connect((self.gr_unpack_k_bits_bb_0, 0),
                     (self.gr_descrambler_bb_0, 0))
        self.connect((self.gr_descrambler_bb_0, 0), (self.gr_null_sink_0, 0))
        self.connect((self.gr_multiply_const_vxx_0, 0),
                     (self.digital_constellation_receiver_cb_0, 0))
        self.connect((self.gr_descrambler_bb_0, 0),
                     (self.gr_char_to_float_0, 0))
        self.connect((self.gr_char_to_float_0, 0),
                     (self.qtgui_sink_x_0_0_0, 0))
        self.connect((self.gr_add_xx_0, 0), (self.gr_throttle_0, 0))
        self.connect((self.gr_noise_source_x_0, 0), (self.gr_add_xx_0, 1))
        self.connect((self.digital_chunks_to_symbols_xx_0, 0),
                     (self.gr_multiply_const_vxx_0_0, 0))
        self.connect((self.gr_multiply_const_vxx_0_0, 0),
                     (self.gr_file_sink_0_1, 0))
        self.connect((self.gr_multiply_const_vxx_0_0, 0),
                     (self.qtgui_sink_x_0_1, 0))
        self.connect((self.gr_char_to_float_1, 0),
                     (self.qtgui_sink_x_0_1_0, 0))
        self.connect((self.gr_pack_k_bits_bb_0, 0),
                     (self.gr_char_to_float_1, 0))
        self.connect((self.gr_pack_k_bits_bb_0, 0), (self.gr_file_sink_0, 0))
        self.connect((self.gr_char_to_float_1_0, 0),
                     (self.qtgui_sink_x_0_1_0_0, 0))
        self.connect((self.gr_vector_source_x_0, 0),
                     (self.gr_char_to_float_1_0, 0))
        self.connect((self.gr_multiply_const_vxx_0_0, 0),
                     (self.gr_add_xx_0, 0))
        self.connect((self.gr_add_xx_0, 0), (self.qtgui_sink_x_0_0, 0))
        self.connect((self.gr_throttle_0, 0),
                     (self.gr_multiply_const_vxx_0, 0))
        self.connect((self.gr_throttle_0, 0), (self.gr_file_sink_0_1_0, 0))
        self.connect((self.gr_throttle_0, 0), (self.qtgui_sink_x_0_0_0_0, 0))
        self.connect((self.gr_nlog10_ff_0, 0), (self.qtgui_time_sink_x_0, 0))
        self.connect((self.blks2_error_rate_0, 0), (self.gr_nlog10_ff_0, 0))
        self.connect((self.gr_vector_source_x_0_0, 0),
                     (self.blks2_error_rate_0, 0))
        self.connect((self.gr_descrambler_bb_0, 0),
                     (self.blks2_error_rate_0, 1))
コード例 #22
0
ファイル: volk_types.py プロジェクト: FOSSEE-Manipal/gnuradio
def char_to_float(N):
    op = gr.char_to_float()
    tb = helper(N, op, gr.sizeof_char, gr.sizeof_float, 1, 1)
    return tb
コード例 #23
0
ファイル: ofdm_rx.py プロジェクト: UpYou/ofdm
  def __init__(self, options):
    gr.top_block.__init__(self)

    if options.rx_freq is not None:
      u = uhd_receiver(options.args,
                       options.bandwidth,
                       options.rx_freq, options.rx_gain,
                       options.spec, options.antenna,
                       options.verbose)
    elif options.infile is not None:
      u = gr.file_source(gr.sizeof_gr_complex, options.infile)
    else:
      import sys
      sys.stderr.write("--freq or --infile must be specified\n")
      raise SystemExit

    self.scope = None

    if options.outfile is not None:
      rx = gr.file_sink(gr.sizeof_gr_complex, options.outfile)
    else:
      rx = ofdm_rxtx.RX(options)
      data_tones = rx.params.data_tones
      if options.rxdata is not None:
        if options.rxdata == '.':
          import scope
          # scope it out
          rxs = gr.vector_to_stream(gr.sizeof_gr_complex, data_tones)
          self.connect(rx, rxs)
          self.scope = scope.scope(self, rxs, 'Frame SNR', isComplex=True)
        else:
          if options.char > 0:
            # rail and scale
            self.connect(rx,
                         gr.vector_to_stream(gr.sizeof_float, data_tones * 2),
                         gr.multiply_const_ff(128.0 * (2**0.5)/ options.char),
                         gr.rail_ff(-128.0, 127.0),
                         gr.float_to_char(),
                         gr.file_sink(gr.sizeof_char, options.rxdata))
          else:
            self.connect(rx, gr.file_sink(data_tones * gr.sizeof_gr_complex, options.rxdata))

      if options.snrdata is not None:
        # select one of the snr modes
        snr = ofdm_rxtx.SNR(rx.params.data_tones, options.size, mode=options.snrmode)
        if options.char > 0:
          # NOTE: we use repeat, assuming the file is long enough or properly aligned
          data = gr.stream_to_vector(gr.sizeof_float, data_tones * 2)
          self.connect(gr.file_source(gr.sizeof_char, options.txdata, repeat=True),
                      gr.char_to_float(),
                      gr.multiply_const_ff(options.char * (2**-0.5) / 128.0),
                      data)
        else:
          data = ofdm_rxtx.make_data(rx.params.data_tones, options.size, options.txdata)
        self.connect(rx, (snr,0))
        self.connect(data, (snr,1))
        if options.snrdata == '-':
          # print it out
          msgq = gr.msg_queue(16)
          self.connect(snr, gr.message_sink(gr.sizeof_float, msgq, True))
          self.watcher = ofdm_rxtx.queue_watcher(msgq)
        elif options.snrdata == '.':
          import scope
          # scope it out
          self.scope = scope.scope(self, snr, 'Frame SNR')
        else:
          self.connect(snr, gr.file_sink(gr.sizeof_float, options.snrdata))
      else:
        pass
        #self.connect(rx, gr.null_sink(symbol_size)) # XXX do we still need this?

    self.connect(u, rx)
コード例 #24
0
    def setUp (self):
        self.tb = gr.top_block ()
        
        # Read in successfully decoded live data from Matlab
        linf=open('/home/demel/exchange/matlab_d.txt')
        lintu=range(120)
        for i in lintu:
            lintu[i]=float(linf.readline())
        #print lintu
        # source for live data
        self.srcl = gr.vector_source_f(lintu,False,120)
        
        # Read in .txt file with example MIB encoded + CRC checksum
        inf=open('/home/demel/exchange/crc.txt')
        self.intu=range(40)
        for i in self.intu:
            self.intu[i]=float(inf.readline())
                
        #inf=open('/home/demel/exchange/matlab_d.txt')
        #intu=range(120)
    	#for i in range(120):
    	#	intu[i]=float(inf.readline())
        
        # Source and conversions
        self.src  = gr.vector_source_f(self.intu,False,40)
        self.conv = gr.float_to_char(40,1)

        # Resize vector with repetition of last part
        # Vector to stream for encoder
        my_map1=range(46)
        for i in range(40):
            my_map1[i+6]=i
        for i in range(6):
            my_map1[i]=i+40
        self.map1 = lte.vector_resize_vbvb(my_map1,40,46)
        self.vtos = gr.vector_to_stream(1*gr.sizeof_char,46)
        
        # Encoding of input data
        self.fsm  = trellis.fsm(1,3,[91,121,117])
        self.enc  = trellis.encoder_bb(self.fsm,0)
        # unpack packed bits from encoder
        self.unp  = gr.unpack_k_bits_bb(3)
        # stream to vector
        self.stov = gr.stream_to_vector(1*gr.sizeof_char,138)
        # Remove first part which contains tail-biting init stuff
        map2 = range(120)
        for i in map2:
            map2[i]= i+18
        self.map2 = lte.vector_resize_vbvb(map2,138,120)
        # conversion from char to float to match input of decoder
        self.conv2= gr.char_to_float(120,1)
        
        
        ###############################################
        # From here on only "receiver side" processing
        ###############################################
        
        # like QPSK demodulation: NRZ coding.
        vec2=range(120)
        for i in vec2:
            vec2[i]=float(-2.0)
        self.mult = gr.multiply_const_vff(vec2)
        vec=range(120)
        for i in vec:
            vec[i]=1
        self.add  = gr.add_const_vff(vec)
        
        # this is the actual unit under test
        self.vit = lte.viterbi_vfvb()
        
        # Sinks
        self.snk = gr.vector_sink_b(40)
        self.snk2 = gr.vector_sink_f(120)
        
        # connecting blocks
        self.tb.connect(self.src,self.conv,self.map1,self.vtos,self.enc,self.unp)
        self.tb.connect(self.unp,self.stov,self.map2,self.conv2)
        self.tb.connect(self.conv2,self.mult,self.add)
        self.tb.connect(self.srcl,self.vit,self.snk)
        self.tb.connect(self.add,self.snk2)
コード例 #25
0
ファイル: ofdm_receiver.py プロジェクト: luwangg/gr-ofdm-1
    def __init__(self, fft_length, block_length, frame_data_part, block_header,
                 options):
        gr.hier_block2.__init__(
            self, "ofdm_receiver", gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature2(2, 2, gr.sizeof_gr_complex * fft_length,
                             gr.sizeof_char))

        frame_length = frame_data_part + block_header.no_pilotsyms
        cp_length = block_length - fft_length

        self.input = gr.kludge_copy(gr.sizeof_gr_complex)
        self.connect(self, self.input)

        self.blocks_out = (self, 0)
        self.frame_trigger_out = (self, 1)
        self.snr_out = (self, 2)

        if options.log:
            log_to_file(self, self.input, "data/receiver_input.compl")

        # peak detector: thresholds low, high
        #self._pd_thres_lo = 0.09
        #self._pd_thres_hi = 0.1
        self._pd_thres = 0.2
        self._pd_lookahead = fft_length / 2  # empirically chosen

        #########################
        # coarse timing offset estimator
        #    self.tm = schmidl.modified_timing_metric(fft_length,[1]*(fft_length))
        self.tm = schmidl.recursive_timing_metric(fft_length)
        self.connect(self.input, self.tm)
        assert (hasattr(block_header, 'sc_preamble_pos'))
        assert (block_header.sc_preamble_pos == 0
                )  # TODO: relax this restriction

        if options.filter_timingmetric:
            timingmetric_shift = -2  #int(-cp_length * 0.8)
            tmfilter = gr.fir_filter_fff(1, [1. / cp_length] * cp_length)
            self.connect(self.tm, tmfilter)
            self.timing_metric = tmfilter
            print "Filtering timing metric, experimental"
        else:
            self.timing_metric = self.tm
            timingmetric_shift = int(-cp_length / 4)

        if options.log:
            log_to_file(self, self.timing_metric, "data/tm.float")

        # peak detection
        #threshold = gr.threshold_ff(self._pd_thres_lo,self._pd_thres_hi,0)
        #muted_tm = gr.multiply_ff()
        peak_detector = peak_detector_02_fb(self._pd_lookahead, self._pd_thres)
        #self.connect(self.timing_metric, threshold, (muted_tm,0))
        #self.connect(self.timing_metric, (muted_tm,1))
        #self.connect(muted_tm, peak_detector)
        self.connect(self.timing_metric, peak_detector)

        if options.log:
            pd_float = gr.char_to_float()
            self.connect(peak_detector, pd_float)
            log_to_file(self, pd_float, "data/peakdetector.float")

        if options.no_timesync:
            terminate_stream(self, peak_detector)
            trigger = [0] * (frame_length * block_length)
            trigger[block_length - 1] = 1
            peak_detector = blocks.vector_source_b(trigger, True)
            print "Bypassing timing synchronisation"

        # TODO: refine detected peaks with 90% average method as proposed
        # from Schmidl & Cox:
        # Starting from peak, find first points to the left and right whose
        # value is less than or equal 90% of the peak value. New trigger point
        # is average of both

        # Frequency Offset Estimation
        # Used: Algorithm as proposed from Morelli & Mengali
        # Idea: Use periodic preamble, correlate identical parts, determine
        # phase offset. This phase offset is a function of the frequency offset.

        assert (hasattr(block_header, 'mm_preamble_pos'))

        foe = morelli_foe(fft_length, block_header.mm_periodic_parts)
        self.connect(self.input, (foe, 0))

        if block_header.mm_preamble_pos > 0:
            delayed_trigger = gr.delay(
                gr.sizeof_char, block_header.mm_preamble_pos * block_length)
            self.connect(peak_detector, delayed_trigger, (foe, 1))
        else:
            self.connect(peak_detector, (foe, 1))

        self.freq_offset = foe

        if options.log:
            log_to_file(self, self.freq_offset, "data/freqoff_out.float")

        if options.average_freqoff:
            #avg_foe = gr.single_pole_iir_filter_ff( 0.1 )
            avg_foe = ofdm.lms_fir_ff(20, 1e-3)
            self.connect(self.freq_offset, avg_foe)
            self.freq_offset = avg_foe
            #log_to_file( self, avg_foe, "data/freqoff_out_avg.float" )
            print "EXPERIMENTAL!!! Filtering frequency offset estimate"

        if options.no_freqsync:
            terminate_stream(self, self.freq_offset)
            self.freq_offset = blocks.vector_source_f([0.0], True)
            print "Bypassing frequency offset estimator, offset=0.0"

        # TODO: dynamic solution
        frametrig_seq = concatenate([[1], [0] * (frame_length - 1)])
        self.time_sync = peak_detector
        self.frame_trigger = blocks.vector_source_b(frametrig_seq, True)
        self.connect(self.frame_trigger, self.frame_trigger_out)

        ##########################
        # symbol extraction and processing
        #  First, we extract the whole ofdm block, then we divide this block into
        #  several ofdm symbols. This asserts that all symbols belonging to the
        #  same ofdm block will be a consecutive order.
        #  extract ofdm symbols
        #  compensate frequency offset

        # TODO: use PLL and update/reset signals
        delayed_timesync = gr.delay(gr.sizeof_char,
                                    (frame_length - 1) * block_length +
                                    timingmetric_shift)
        self.connect(self.time_sync, delayed_timesync)

        self.block_sampler = vector_sampler(gr.sizeof_gr_complex,
                                            block_length * frame_length)
        self.discard_cp = vector_mask(block_length, cp_length, fft_length, [])

        if options.use_dpll:
            dpll = gr.dpll_bb(frame_length * block_length, .01)
            self.connect(delayed_timesync, dpll)

            if options.log:
                dpll_f = gr.char_to_float()
                delayed_timesync_f = gr.char_to_float()
                self.connect(dpll, dpll_f)
                self.connect(delayed_timesync, delayed_timesync_f)
                log_to_file(self, dpll_f, "data/dpll.float")
                log_to_file(self, delayed_timesync_f, "data/dpll_in.float")

            delayed_timesync = dpll
            print "Using DPLL, EXPERIMENTAL!!!!!"

        self.connect(self.input, self.block_sampler)
        self.connect(delayed_timesync, (self.block_sampler, 1))

        if options.log:
            log_to_file(self, self.block_sampler,
                        "data/block_sampler_out.compl")

        # TODO: dynamic solution
        self.ofdm_symbols = blocks.vector_to_stream(
            gr.sizeof_gr_complex * block_length, frame_length)
        self.connect(self.block_sampler, self.ofdm_symbols, self.discard_cp)

        if options.log:
            log_to_file(self, self.discard_cp, "data/discard_cp_out.compl")
            dcp_fft = gr.fft_vcc(fft_length, True, [], True)
            self.connect(self.discard_cp, dcp_fft)
            log_to_file(self, dcp_fft, "data/discard_cp_fft.compl")

        # reset phase accumulator inside freq_shift on every block start
        # setup output connection

        freq_shift = frequency_shift_vcc(fft_length, -1.0 / fft_length,
                                         cp_length)

        self.connect(self.discard_cp, (freq_shift, 0))
        self.connect(self.freq_offset, (freq_shift, 1))
        self.connect(self.frame_trigger, (freq_shift, 2))
        self.connect(freq_shift, self.blocks_out)

        if options.log:
            log_to_file(self, freq_shift, "data/freqshift_out.compl")

        if options.no_freqshift:
            terminate_stream(self, freq_shift)
            freq_shift = self.discard_cp
            print "Bypassing frequency shift block"
コード例 #26
0
ファイル: usrp_rds_tx.py プロジェクト: quentinmit/gr-rds
    def __init__(self, frame, panel, vbox, argv):
        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)

        parser = OptionParser(option_class=eng_option)
        parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, help="select USRP Tx side A or B")
        parser.add_option(
            "-f",
            "--freq",
            type="eng_float",
            default=107.2e6,
            help="set Tx frequency to FREQ [required]",
            metavar="FREQ",
        )
        parser.add_option("--wavfile", type="string", default=None, help="open .wav audio file FILE")
        parser.add_option("--xml", type="string", default="rds_data.xml", help="open .xml RDS data FILE")
        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        usrp_interp = 500
        self.u = usrp.sink_c(0, usrp_interp)
        print "USRP Serial: ", self.u.serial_number()
        usrp_rate = self.u.dac_rate() / usrp_interp  # 256 kS/s

        # determine the daughterboard subdevice we're using
        if options.tx_subdev_spec is None:
            options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
        self.u.set_mux(usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec))
        self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec)
        print "Using d'board", self.subdev.side_and_name()

        # set max Tx gain, tune frequency and enable transmitter
        gain = self.subdev.gain_range()[1]
        self.subdev.set_gain(gain)
        print "Gain set to", gain
        if self.u.tune(self.subdev.which(), self.subdev, options.freq):
            print "Tuned to", options.freq / 1e6, "MHz"
        else:
            sys.exit(1)
        self.subdev.set_enable(True)

        # open wav file containing floats in the [-1, 1] range, repeat
        if options.wavfile is None:
            print "Please provide a wavfile to transmit! Exiting\n"
            sys.exit(1)
        self.src = gr.wavfile_source(options.wavfile, True)
        nchans = self.src.channels()
        sample_rate = self.src.sample_rate()
        bits_per_sample = self.src.bits_per_sample()
        print nchans, "channels,", sample_rate, "samples/sec,", bits_per_sample, "bits/sample"

        # resample to usrp rate
        self.resample_left = blks2.rational_resampler_fff(usrp_rate, sample_rate)
        self.resample_right = blks2.rational_resampler_fff(usrp_rate, sample_rate)
        self.connect((self.src, 0), self.resample_left)
        self.connect((self.src, 1), self.resample_right)

        # create L+R (mono) and L-R (stereo)
        self.audio_lpr = gr.add_ff()
        self.audio_lmr = gr.sub_ff()
        self.connect(self.resample_left, (self.audio_lpr, 0))
        self.connect(self.resample_left, (self.audio_lmr, 0))
        self.connect(self.resample_right, (self.audio_lpr, 1))
        self.connect(self.resample_right, (self.audio_lmr, 1))

        # low-pass filter for L+R
        audio_lpr_taps = gr.firdes.low_pass(
            0.5,  # gain
            usrp_rate,  # sampling rate
            15e3,  # passband cutoff
            1e3,  # transition width
            gr.firdes.WIN_HAMMING,
        )
        self.audio_lpr_filter = gr.fir_filter_fff(1, audio_lpr_taps)
        self.connect(self.audio_lpr, self.audio_lpr_filter)

        # create pilot tone at 19 kHz
        self.pilot = gr.sig_source_f(
            usrp_rate, gr.GR_SIN_WAVE, 19e3, 5e-2  # sampling rate  # waveform  # frequency
        )  # amplitude

        # upconvert L-R to 38 kHz and band-pass
        self.mix_stereo = gr.multiply_ff()
        audio_lmr_taps = gr.firdes.band_pass(
            80,  # gain
            usrp_rate,  # sampling rate
            38e3 - 15e3,  # low cutoff
            38e3 + 15e3,  # high cutoff
            1e3,  # transition width
            gr.firdes.WIN_HAMMING,
        )
        self.audio_lmr_filter = gr.fir_filter_fff(1, audio_lmr_taps)
        self.connect(self.audio_lmr, (self.mix_stereo, 0))
        self.connect(self.pilot, (self.mix_stereo, 1))
        self.connect(self.pilot, (self.mix_stereo, 2))
        self.connect(self.mix_stereo, self.audio_lmr_filter)

        # create RDS bitstream
        # diff-encode, manchester-emcode, NRZ
        # enforce the 1187.5bps rate
        # pulse shaping filter (matched with receiver)
        # mix with 57kHz carrier (equivalent to BPSK)
        self.rds_enc = rds.data_encoder("rds_data.xml")
        self.diff_enc = gr.diff_encoder_bb(2)
        self.manchester1 = gr.map_bb([1, 2])
        self.manchester2 = gr.unpack_k_bits_bb(2)
        self.nrz = gr.map_bb([-1, 1])
        self.c2f = gr.char_to_float()
        self.rate_enforcer = rds.rate_enforcer(usrp_rate)
        pulse_shaping_taps = gr.firdes.low_pass(
            1,  # gain
            usrp_rate,  # sampling rate
            1.5e3,  # passband cutoff
            2e3,  # transition width
            gr.firdes.WIN_HAMMING,
        )
        self.pulse_shaping = gr.fir_filter_fff(1, pulse_shaping_taps)
        self.bpsk_mod = gr.multiply_ff()
        self.connect(self.rds_enc, self.diff_enc, self.manchester1, self.manchester2, self.nrz, self.c2f)
        self.connect(self.c2f, (self.rate_enforcer, 0))
        self.connect(self.pilot, (self.rate_enforcer, 1))
        self.connect(self.rate_enforcer, (self.bpsk_mod, 0))
        self.connect(self.pilot, (self.bpsk_mod, 1))
        self.connect(self.pilot, (self.bpsk_mod, 2))
        self.connect(self.pilot, (self.bpsk_mod, 3))

        # RDS band-pass filter
        rds_filter_taps = gr.firdes.band_pass(
            50,  # gain
            usrp_rate,  # sampling rate
            57e3 - 3e3,  # low cutoff
            57e3 + 3e3,  # high cutoff
            1e3,  # transition width
            gr.firdes.WIN_HAMMING,
        )
        self.rds_filter = gr.fir_filter_fff(1, rds_filter_taps)
        self.connect(self.bpsk_mod, self.rds_filter)

        # mix L+R, pilot, L-R and RDS
        self.mixer = gr.add_ff()
        self.connect(self.audio_lpr_filter, (self.mixer, 0))
        self.connect(self.pilot, (self.mixer, 1))
        self.connect(self.audio_lmr_filter, (self.mixer, 2))
        self.connect(self.rds_filter, (self.mixer, 3))

        # fm modulation, gain & TX
        max_dev = 75e3
        k = 2 * math.pi * max_dev / usrp_rate  # modulator sensitivity
        self.modulator = gr.frequency_modulator_fc(k)
        self.gain = gr.multiply_const_cc(5e3)
        self.connect(self.mixer, self.modulator, self.gain, self.u)

        # plot an FFT to verify we are sending what we want
        if 1:
            self.fft = fftsink2.fft_sink_f(
                panel, title="Pre FM modulation", fft_size=512 * 4, sample_rate=usrp_rate, y_per_div=20, ref_level=-20
            )
            self.connect(self.mixer, self.fft)
            vbox.Add(self.fft.win, 1, wx.EXPAND)
        if 0:
            self.scope = scopesink2.scope_sink_f(panel, title="RDS encoder output", sample_rate=usrp_rate)
            self.connect(self.rds_enc, self.scope)
            vbox.Add(self.scope.win, 1, wx.EXPAND)
コード例 #27
0
ファイル: psk_simu.py プロジェクト: zhouhiking/psk_simu
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(
            self, title="Communication System Graphical Analyzer (LAPS/UFCG)")

        ##################################################
        # Default Variables
        ##################################################
        self.sps = 2
        self.snr = 20
        self.symbol_rate = 140000
        self.mod_type = "DBPSK"
        self.view = 1
        self.band = 200
        self.excess_bw = 0.35
        self.fading_flag = False
        self.fdts = -8
        self.fading_state_rx = False

        ##################################################
        # Blocks Definition
        ##################################################

        #A bit stream of 1's is generated at the source, scrambled,
        #modulated and sent to the input of an AWGN channel.
        #random.seed(42)
        #self.source = gr.vector_source_b([random.randint(0, 2) for i in range(0,10^8)], True)
        self.source = gr.vector_source_b((1, ), True, 1)
        self.thottle = gr.throttle(gr.sizeof_char, 10e5)
        self.scrambler = gr.scrambler_bb(0x40801, 0x92F72,
                                         20)  #Taxa de simbolos constante
        self.pack = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST)
        self.modulator = utils.mods[self.mod_type](self.sps,
                                                   excess_bw=self.excess_bw)
        self.channel = utils.channel(1 / 10.0**(self.snr / 10.0), self.band,
                                     self.symbol_rate, self.sps)

        #The noisy signal is demodulated, descrambled and the BER
        #is estimated by the ber_estim block using the receiver
        #density of 0 bits.
        self.demodulator = utils.demods[self.mod_type](
            self.sps, excess_bw=self.excess_bw)
        self.descrambler = gr.descrambler_bb(0x40801, 0x92F72, 20)
        self.char2float = gr.char_to_float()
        self.mov_average = gr.moving_average_ff(524288, 1 / 524288., 10000)
        self.ber = utils.ber_estim()
        #self.ber = utils.ber_estim_simple(3)

        ##################################################
        # GUI Elements Definition
        ##################################################

        #Defines an adds FFT Window to GUI
        self.fft = fftsink.fft_sink_c(self.GetWin(),
                                      sample_rate=self.symbol_rate * self.sps,
                                      baseband_freq=5e6)
        self.GridAdd(self.fft.win, 0, 3, 4, 3)
        self.ctr = gr.complex_to_real(1)

        #Defines and adds SNR slider to GUI
        _snr_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._snr_text_box = forms.text_box(parent=self.GetWin(),
                                            sizer=_snr_sizer,
                                            value=self.snr,
                                            callback=self.callback_snr,
                                            label=" SNR (dB)",
                                            converter=forms.float_converter(),
                                            proportion=0)
        self._snr_slider = forms.slider(parent=self.GetWin(),
                                        sizer=_snr_sizer,
                                        value=self.snr,
                                        callback=self.callback_snr,
                                        minimum=0,
                                        maximum=20,
                                        style=wx.RA_HORIZONTAL,
                                        proportion=1)
        self.GridAdd(_snr_sizer, 4, 3, 1, 3)

        #Defines and adds bandwidth slider to GUI
        band_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.band_text_box = forms.text_box(parent=self.GetWin(),
                                            sizer=band_sizer,
                                            value=self.band,
                                            callback=self.callback_band,
                                            label="Bandwidth (kHz)",
                                            converter=forms.float_converter(),
                                            proportion=0)
        self.band_slider = forms.slider(parent=self.GetWin(),
                                        sizer=band_sizer,
                                        value=self.band,
                                        callback=self.callback_band,
                                        minimum=30,
                                        maximum=200,
                                        style=wx.RA_HORIZONTAL,
                                        proportion=1)
        self.GridAdd(band_sizer, 5, 3, 1, 3)

        #Defines and adds Rayleigh GUI elements

        fading_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.fading_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=fading_sizer,
            value=self.fdts,
            callback=self.callback_fading,
            label='Fading/log(FdTs)',
            converter=forms.float_converter(),
            proportion=0)
        self.fading_slider = forms.slider(parent=self.GetWin(),
                                          sizer=fading_sizer,
                                          value=self.fdts,
                                          callback=self.callback_fading,
                                          minimum=-8,
                                          maximum=-2,
                                          style=wx.RA_HORIZONTAL,
                                          proportion=1)
        self.GridAdd(fading_sizer, 6, 3, 1, 3)

        #Defines and adds modulation type chooser to GUI
        self._mod_type_chooser = forms.radio_buttons(
            parent=self.GetWin(),
            value=self.mod_type,
            callback=self.set_mod_type,
            label="Modulation",
            choices=["DBPSK", "DQPSK", "D8PSK"],
            labels=["DBPSK", "DQPSK", "D8PSK"],
            style=wx.RA_HORIZONTAL)
        self.GridAdd(self._mod_type_chooser, 7, 4, 1, 2)

        #Defines and adds signal source chooser
        self.sig_src_chooser = forms.radio_buttons(
            parent=self.GetWin(),
            value=self.view,
            callback=self.callback_view,
            label="Signal Source",
            choices=[0, 1],
            labels=["Transmitter", "Receiver"],
            style=wx.RA_VERTICAL)
        self.GridAdd(self.sig_src_chooser, 7, 3, 1, 1)

        #Definition of the of constellation window and attachment to the GUI
        self.constel = constsink.const_sink_c(self.GetWin(),
                                              title="RX Constellation Plot",
                                              sample_rate=self.symbol_rate,
                                              const_size=256,
                                              mod=self.mod_type)
        self.GridAdd(self.constel.win, 0, 0, 8, 3)

        #Definition of the constellation sink window and attachment to the GUI
        self.number_sink = bersink.number_sink_f(self.GetWin(),
                                                 sample_rate=self.symbol_rate)
        self.GridAdd(self.number_sink.win, 8, 0, 1, 6)

        ##################################################
        # Blocks Connections
        ##################################################

        #The necessary block connections to the system work as described above.
        self.connect(self.source, self.scrambler, self.thottle, self.pack)
        #self.connect(self.source , self.thottle, self.pack)
        self.connect(self.pack, self.modulator, self.channel, self.demodulator)
        self.connect(self.channel, self.fft)
        self.connect(self.demodulator.diffdec, self.constel)
        self.connect(self.demodulator, self.descrambler, self.char2float,
                     self.mov_average)
        self.connect(self.mov_average, self.ber, self.number_sink)
コード例 #28
0
ファイル: rds_tx.py プロジェクト: Crazybond/gr-rds
	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="Rds Tx")
		_icon_path = "/home/azimout/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

		##################################################
		# Variables
		##################################################
		self.usrp_interp = usrp_interp = 500
		self.dac_rate = dac_rate = 128e6
		self.wav_rate = wav_rate = 44100
		self.usrp_rate = usrp_rate = int(dac_rate/usrp_interp)
		self.fm_max_dev = fm_max_dev = 120e3

		##################################################
		# Blocks
		##################################################
		self.band_pass_filter_0 = gr.interp_fir_filter_fff(1, firdes.band_pass(
			1, usrp_rate, 54e3, 60e3, 3e3, firdes.WIN_HAMMING, 6.76))
		self.band_pass_filter_1 = gr.interp_fir_filter_fff(1, firdes.band_pass(
			1, usrp_rate, 23e3, 53e3, 2e3, firdes.WIN_HAMMING, 6.76))
		self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff(
			interpolation=usrp_rate,
			decimation=wav_rate,
			taps=None,
			fractional_bw=None,
		)
		self.blks2_rational_resampler_xxx_1_0 = blks2.rational_resampler_fff(
			interpolation=usrp_rate,
			decimation=wav_rate,
			taps=None,
			fractional_bw=None,
		)
		self.gr_add_xx_0 = gr.add_vff(1)
		self.gr_add_xx_1 = gr.add_vff(1)
		self.gr_char_to_float_0 = gr.char_to_float()
		self.gr_diff_encoder_bb_0 = gr.diff_encoder_bb(2)
		self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2*math.pi*fm_max_dev/usrp_rate)
		self.gr_map_bb_0 = gr.map_bb(([-1,1]))
		self.gr_map_bb_1 = gr.map_bb(([1,2]))
		self.gr_multiply_xx_0 = gr.multiply_vff(1)
		self.gr_multiply_xx_1 = gr.multiply_vff(1)
		self.gr_rds_data_encoder_0 = rds.data_encoder("/media/dimitris/mywork/gr/dimitris/rds/trunk/src/test/rds_data.xml")
		self.gr_rds_rate_enforcer_0 = rds.rate_enforcer(256000)
		self.gr_sig_source_x_0 = gr.sig_source_f(usrp_rate, gr.GR_COS_WAVE, 19e3, 0.3, 0)
		self.gr_sub_xx_0 = gr.sub_ff(1)
		self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(2)
		self.gr_wavfile_source_0 = gr.wavfile_source("/media/dimitris/mywork/gr/dimitris/rds/trunk/src/python/limmenso_stereo.wav", True)
		self.low_pass_filter_0 = gr.interp_fir_filter_fff(1, firdes.low_pass(
			1, usrp_rate, 1.5e3, 2e3, firdes.WIN_HAMMING, 6.76))
		self.low_pass_filter_0_0 = gr.interp_fir_filter_fff(1, firdes.low_pass(
			1, usrp_rate, 15e3, 2e3, firdes.WIN_HAMMING, 6.76))
		self.usrp_simple_sink_x_0 = grc_usrp.simple_sink_c(which=0, side="A")
		self.usrp_simple_sink_x_0.set_interp_rate(500)
		self.usrp_simple_sink_x_0.set_frequency(107.2e6, verbose=True)
		self.usrp_simple_sink_x_0.set_gain(0)
		self.usrp_simple_sink_x_0.set_enable(True)
		self.usrp_simple_sink_x_0.set_auto_tr(True)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_f(
			self.GetWin(),
			baseband_freq=0,
			y_per_div=20,
			y_divs=10,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=usrp_rate,
			fft_size=1024,
			fft_rate=30,
			average=False,
			avg_alpha=None,
			title="FFT Plot",
			peak_hold=False,
		)
		self.Add(self.wxgui_fftsink2_0.win)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_rds_rate_enforcer_0, 1))
		self.connect((self.gr_char_to_float_0, 0), (self.gr_rds_rate_enforcer_0, 0))
		self.connect((self.gr_map_bb_0, 0), (self.gr_char_to_float_0, 0))
		self.connect((self.gr_frequency_modulator_fc_0, 0), (self.usrp_simple_sink_x_0, 0))
		self.connect((self.gr_add_xx_1, 0), (self.gr_frequency_modulator_fc_0, 0))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_add_xx_1, 1))
		self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_1, 2))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 1))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 0))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 3))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 2))
		self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.gr_add_xx_0, 1))
		self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_add_xx_0, 0))
		self.connect((self.blks2_rational_resampler_xxx_1_0, 0), (self.gr_sub_xx_0, 1))
		self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_sub_xx_0, 0))
		self.connect((self.gr_wavfile_source_0, 1), (self.blks2_rational_resampler_xxx_1_0, 0))
		self.connect((self.gr_wavfile_source_0, 0), (self.blks2_rational_resampler_xxx_1, 0))
		self.connect((self.gr_rds_data_encoder_0, 0), (self.gr_diff_encoder_bb_0, 0))
		self.connect((self.gr_diff_encoder_bb_0, 0), (self.gr_map_bb_1, 0))
		self.connect((self.gr_map_bb_1, 0), (self.gr_unpack_k_bits_bb_0, 0))
		self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_map_bb_0, 0))
		self.connect((self.gr_rds_rate_enforcer_0, 0), (self.low_pass_filter_0, 0))
		self.connect((self.low_pass_filter_0, 0), (self.gr_multiply_xx_0, 0))
		self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0))
		self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 0))
		self.connect((self.gr_multiply_xx_1, 0), (self.band_pass_filter_1, 0))
		self.connect((self.band_pass_filter_1, 0), (self.gr_add_xx_1, 3))
		self.connect((self.gr_add_xx_1, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 1))
		self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0_0, 0))
		self.connect((self.low_pass_filter_0_0, 0), (self.gr_add_xx_1, 2))
コード例 #29
0
ファイル: ofdm_receiver.py プロジェクト: extrasyllmit/extrasy
    def __init__(self,
                 fft_length,
                 cp_length,
                 occupied_tones,
                 snr,
                 ks,
                 vcsthresh,
                 vcsbackoff,
                 logging=False,
                 use_coding=0):
        """
	Hierarchical block for receiving OFDM symbols.

	The input is the complex modulated signal at baseband.
        Synchronized packets are sent back to the demodulator.

        @param fft_length: total number of subcarriers
        @type  fft_length: int
        @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length)
        @type  cp_length: int
        @param occupied_tones: number of subcarriers used for data
        @type  occupied_tones: int
        @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer
        @type  snr: float
        @param ks: known symbols used as preambles to each packet
        @type  ks: list of lists
        @param logging: turn file logging on or off
        @type  logging: bool
	"""

        gr.hier_block2.__init__(
            self,
            "ofdm_receiver",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature3(3, 3, gr.sizeof_gr_complex * occupied_tones,
                             gr.sizeof_char,
                             gr.sizeof_float))  # Output signature

        bw = (float(occupied_tones) / float(fft_length)) / 2.0
        tb = bw * 0.08
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            1.0,  # sampling rate
            bw + tb,  # midpoint of trans. band
            tb,  # width of trans. band
            gr.firdes.WIN_HAMMING)  # filter type
        self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)

        win = [1 for i in range(fft_length)]

        zeros_on_left = int(math.ceil((fft_length - occupied_tones) / 2.0))
        ks0 = fft_length * [
            0,
        ]
        ks0[zeros_on_left:zeros_on_left + occupied_tones] = ks[0]

        ks0 = fft.ifftshift(ks0)
        ks0time = fft.ifft(ks0)
        # ADD SCALING FACTOR
        ks0time = ks0time.tolist()

        SYNC = "pn"
        if SYNC == "ml":
            nco_sensitivity = -1.0 / fft_length  # correct for fine frequency
            self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, ks0time,
                                          logging)
        elif SYNC == "pn":
            nco_sensitivity = -2.0 / fft_length  # correct for fine frequency
            self.ofdm_sync = digital_ll.ofdm_sync_pn(fft_length, cp_length,
                                                     vcsthresh, logging)
        elif SYNC == "pnac":
            nco_sensitivity = -2.0 / fft_length  # correct for fine frequency
            self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time,
                                            logging)
        # for testing only; do not user over the air
        # remove filter and filter delay for this
        elif SYNC == "fixed":
            self.chan_filt = gr.multiply_const_cc(1.0)
            nsymbols = 18  # enter the number of symbols per packet
            freq_offset = 0.0  # if you use a frequency offset, enter it here
            nco_sensitivity = -2.0 / fft_length  # correct for fine frequency
            self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, nsymbols,
                                             freq_offset, logging)

        # Set up blocks

        self.nco = gr.frequency_modulator_fc(
            nco_sensitivity
        )  # generate a signal proportional to frequency error of sync block
        self.sigmix = gr.multiply_cc()
        self.sampler = digital_swig.ofdm_sampler(fft_length,
                                                 fft_length + cp_length)
        self.fft_demod = gr.fft_vcc(fft_length, True, win, True)

        if vcsbackoff:
            preamble_sense_time = vcsbackoff
        else:
            if use_coding:
                preamble_sense_time = fft_length * 50
            else:
                preamble_sense_time = fft_length * 25
        #preamble_sense_taps = [1.0 for i in range(preamble_sense_time)]
        #self.preamble_sense_avg = gr.fir_filter_fff(1,preamble_sense_taps)
        self.preamble_sense_avg = digital_ll.downcounter(preamble_sense_time)
        self.char2float = gr.char_to_float()

        #self.ofdm_frame_acq = digital_swig.ofdm_frame_acquisition(occupied_tones,
        #                                                          fft_length,
        #                                                          cp_length, ks[0])
        print 'Using newest ofdm frame acquisition function'
        self.ofdm_frame_acq = digital_ll.digital_ll_ofdm_frame_acquisition(
            occupied_tones, fft_length, cp_length, ks[0])

        self.connect(self, self.chan_filt)  # filter the input channel
        self.connect(self.chan_filt,
                     self.ofdm_sync)  # into the synchronization alg.
        self.connect(
            (self.ofdm_sync, 0), self.nco,
            (self.sigmix,
             1))  # use sync freq. offset output to derotate input signal
        self.connect(self.chan_filt,
                     (self.sigmix, 0))  # signal to be derotated
        self.connect(
            self.sigmix,
            (self.sampler, 0))  # sample off timing signal detected in sync alg
        self.connect((self.ofdm_sync, 1),
                     (self.sampler, 1))  # timing signal to sample at

        self.connect((self.sampler, 0),
                     self.fft_demod)  # send derotated sampled signal to FFT
        self.connect(
            self.fft_demod,
            (self.ofdm_frame_acq, 0))  # find frame start and equalize signal
        self.connect((self.sampler, 1),
                     (self.ofdm_frame_acq,
                      1))  # send timing signal to signal frame start

        self.connect((self.ofdm_sync, 1), self.char2float
                     )  # the timing signal held high by filter for some time
        self.connect(self.char2float, self.preamble_sense_avg)
        self.connect(self.preamble_sense_avg,
                     (self, 2))  # virtual carrier sense signal

        self.connect((self.ofdm_frame_acq, 0),
                     (self, 0))  # finished with fine/coarse freq correction,
        self.connect((self.ofdm_frame_acq, 1),
                     (self, 1))  # frame and symbol timing, and equalization

        if logging:
            self.connect(
                self.chan_filt,
                gr.file_sink(gr.sizeof_gr_complex,
                             "ofdm_receiver-chan_filt_c.dat"))
            self.connect(
                self.fft_demod,
                gr.file_sink(gr.sizeof_gr_complex * fft_length,
                             "ofdm_receiver-fft_out_c.dat"))
            self.connect(
                self.ofdm_frame_acq,
                gr.file_sink(gr.sizeof_gr_complex * occupied_tones,
                             "ofdm_receiver-frame_acq_c.dat"))
            self.connect((self.ofdm_frame_acq, 1),
                         gr.file_sink(1, "ofdm_receiver-found_corr_b.dat"))
            self.connect(
                self.sampler,
                gr.file_sink(gr.sizeof_gr_complex * fft_length,
                             "ofdm_receiver-sampler_c.dat"))
            self.connect(
                self.sigmix,
                gr.file_sink(gr.sizeof_gr_complex,
                             "ofdm_receiver-sigmix_c.dat"))
            self.connect(
                self.nco,
                gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
            self.connect(
                self.preamble_sense_avg,
                gr.file_sink(gr.sizeof_float, "ofdm_receiver-vcs.dat"))
コード例 #30
0
ファイル: ofdm_receiver.py プロジェクト: WindyCitySDR/gr-ofdm
  def __init__(self, fft_length, block_length, frame_data_part, block_header,
               options):
    gr.hier_block2.__init__(self, "ofdm_receiver",
        gr.io_signature (1,1,gr.sizeof_gr_complex),
        gr.io_signature2(2,2,gr.sizeof_gr_complex*fft_length,
                             gr.sizeof_char))

    
    frame_length = frame_data_part + block_header.no_pilotsyms
    cp_length = block_length-fft_length
    
    

    self.input=gr.kludge_copy(gr.sizeof_gr_complex)
    self.connect(self, self.input)
    
    self.blocks_out = (self,0)
    self.frame_trigger_out = (self,1)
    self.snr_out = (self,2)


    if options.log:
      log_to_file(self, self.input, "data/receiver_input.compl")



    # peak detector: thresholds low, high
    #self._pd_thres_lo = 0.09
    #self._pd_thres_hi = 0.1
    self._pd_thres = 0.2
    self._pd_lookahead = fft_length / 2 # empirically chosen
    
    

    #########################
    # coarse timing offset estimator
#    self.tm = schmidl.modified_timing_metric(fft_length,[1]*(fft_length))
    self.tm = schmidl.recursive_timing_metric(fft_length)
    self.connect(self.input,self.tm)
    assert(hasattr(block_header, 'sc_preamble_pos'))
    assert(block_header.sc_preamble_pos == 0) # TODO: relax this restriction
    
    if options.filter_timingmetric:
      timingmetric_shift = -2 #int(-cp_length * 0.8)
      tmfilter = gr.fir_filter_fff(1, [1./cp_length]*cp_length)
      self.connect( self.tm, tmfilter )
      self.timing_metric = tmfilter
      print "Filtering timing metric, experimental"
    else:
      self.timing_metric = self.tm
      timingmetric_shift = int(-cp_length/4)
    
    if options.log:
      log_to_file(self, self.timing_metric, "data/tm.float")
        


    # peak detection
    #threshold = gr.threshold_ff(self._pd_thres_lo,self._pd_thres_hi,0)
    #muted_tm = gr.multiply_ff()
    peak_detector = peak_detector_02_fb(self._pd_lookahead, self._pd_thres)
    #self.connect(self.timing_metric, threshold, (muted_tm,0))
    #self.connect(self.timing_metric, (muted_tm,1))
    #self.connect(muted_tm, peak_detector)
    self.connect(self.timing_metric, peak_detector)

    if options.log:
      pd_float = gr.char_to_float()
      self.connect(peak_detector,pd_float)
      log_to_file(self, pd_float, "data/peakdetector.float")
      
    if options.no_timesync:
      terminate_stream( self, peak_detector )
      trigger = [0]*(frame_length*block_length)
      trigger[ block_length-1 ] = 1
      peak_detector = blocks.vector_source_b( trigger, True )
      print "Bypassing timing synchronisation"
    
    
    # TODO: refine detected peaks with 90% average method as proposed
    # from Schmidl & Cox:
    # Starting from peak, find first points to the left and right whose
    # value is less than or equal 90% of the peak value. New trigger point
    # is average of both
    
    
    
    
    
    # Frequency Offset Estimation
    # Used: Algorithm as proposed from Morelli & Mengali
    # Idea: Use periodic preamble, correlate identical parts, determine
    # phase offset. This phase offset is a function of the frequency offset.
    
    assert(hasattr(block_header, 'mm_preamble_pos'))

    foe = morelli_foe(fft_length,block_header.mm_periodic_parts)
    self.connect(self.input,(foe,0))
    
    if block_header.mm_preamble_pos > 0:
      delayed_trigger = gr.delay(gr.sizeof_char,
                                 block_header.mm_preamble_pos*block_length)
      self.connect(peak_detector,delayed_trigger,(foe,1))
    else:
      self.connect(peak_detector,(foe,1))
    
    self.freq_offset = foe

    if options.log:
      log_to_file(self, self.freq_offset, "data/freqoff_out.float")
      
      
    if options.average_freqoff:
      #avg_foe = gr.single_pole_iir_filter_ff( 0.1 )
      avg_foe = ofdm.lms_fir_ff( 20, 1e-3 )
      self.connect( self.freq_offset, avg_foe )
      self.freq_offset = avg_foe
      #log_to_file( self, avg_foe, "data/freqoff_out_avg.float" )
      print "EXPERIMENTAL!!! Filtering frequency offset estimate"
      
    
    if options.no_freqsync:
      terminate_stream( self, self.freq_offset )
      self.freq_offset = blocks.vector_source_f( [0.0], True )
      print "Bypassing frequency offset estimator, offset=0.0"
      
    
    # TODO: dynamic solution
    frametrig_seq = concatenate([[1],[0]*(frame_length-1)])
    self.time_sync = peak_detector
    self.frame_trigger = blocks.vector_source_b(frametrig_seq,True)
    self.connect(self.frame_trigger, self.frame_trigger_out)
    




    ##########################
    # symbol extraction and processing
    #  First, we extract the whole ofdm block, then we divide this block into
    #  several ofdm symbols. This asserts that all symbols belonging to the
    #  same ofdm block will be a consecutive order.
    #  extract ofdm symbols
    #  compensate frequency offset

    # TODO: use PLL and update/reset signals
    delayed_timesync = gr.delay(gr.sizeof_char,
                                (frame_length-1)*block_length+timingmetric_shift)
    self.connect( self.time_sync, delayed_timesync )
    
    self.block_sampler = vector_sampler(gr.sizeof_gr_complex,block_length*frame_length)
    self.discard_cp = vector_mask(block_length,cp_length,fft_length,[])

    
    if options.use_dpll:
      dpll = gr.dpll_bb( frame_length * block_length , .01 )
      self.connect( delayed_timesync, dpll )
      
      if options.log:
        dpll_f = gr.char_to_float()
        delayed_timesync_f = gr.char_to_float()
        self.connect( dpll, dpll_f )
        self.connect( delayed_timesync, delayed_timesync_f )
        log_to_file( self, dpll_f, "data/dpll.float" )
        log_to_file( self, delayed_timesync_f, "data/dpll_in.float" )
        
      delayed_timesync = dpll
      print "Using DPLL, EXPERIMENTAL!!!!!"

    self.connect(self.input,self.block_sampler)
    self.connect(delayed_timesync,(self.block_sampler,1))
    
    if options.log:
      log_to_file(self, self.block_sampler, "data/block_sampler_out.compl")



    # TODO: dynamic solution
    self.ofdm_symbols = blocks.vector_to_stream(gr.sizeof_gr_complex*block_length,
                                            frame_length)
    self.connect(self.block_sampler,self.ofdm_symbols,self.discard_cp)

    if options.log:
      log_to_file(self, self.discard_cp, "data/discard_cp_out.compl")
      dcp_fft = gr.fft_vcc(fft_length, True, [], True)
      self.connect(self.discard_cp,dcp_fft)
      log_to_file(self, dcp_fft, "data/discard_cp_fft.compl")


    # reset phase accumulator inside freq_shift on every block start
    # setup output connection


    freq_shift = frequency_shift_vcc(fft_length, -1.0/fft_length, cp_length)

    self.connect(self.discard_cp,(freq_shift,0))
    self.connect(self.freq_offset,(freq_shift,1))
    self.connect(self.frame_trigger,(freq_shift,2))
    self.connect(freq_shift, self.blocks_out)
    
    if options.log:
      log_to_file(self, freq_shift, "data/freqshift_out.compl")
      
    if options.no_freqshift:
      terminate_stream( self, freq_shift )
      freq_shift = self.discard_cp
      print "Bypassing frequency shift block"
コード例 #31
0
ファイル: ofdm_rx.py プロジェクト: ljxangus/ofdm
    def __init__(self, options):
        gr.top_block.__init__(self)

        if options.rx_freq is not None:
            u = uhd_receiver(options.args, options.bandwidth, options.rx_freq,
                             options.rx_gain, options.spec, options.antenna,
                             options.verbose)
        elif options.infile is not None:
            u = gr.file_source(gr.sizeof_gr_complex, options.infile)
        else:
            import sys
            sys.stderr.write("--freq or --infile must be specified\n")
            raise SystemExit

        self.scope = None

        if options.outfile is not None:
            rx = gr.file_sink(gr.sizeof_gr_complex, options.outfile)
        else:
            rx = ofdm_rxtx.RX(options)
            data_tones = rx.params.data_tones
            if options.rxdata is not None:
                if options.rxdata == '.':
                    import scope
                    # scope it out
                    rxs = gr.vector_to_stream(gr.sizeof_gr_complex, data_tones)
                    self.connect(rx, rxs)
                    self.scope = scope.scope(self,
                                             rxs,
                                             'Frame SNR',
                                             isComplex=True)
                else:
                    if options.char > 0:
                        # rail and scale
                        self.connect(
                            rx,
                            gr.vector_to_stream(gr.sizeof_float,
                                                data_tones * 2),
                            gr.multiply_const_ff(128.0 * (2**0.5) /
                                                 options.char),
                            gr.rail_ff(-128.0, 127.0), gr.float_to_char(),
                            gr.file_sink(gr.sizeof_char, options.rxdata))
                    else:
                        self.connect(
                            rx,
                            gr.file_sink(data_tones * gr.sizeof_gr_complex,
                                         options.rxdata))

            if options.snrdata is not None:
                # select one of the snr modes
                snr = ofdm_rxtx.SNR(rx.params.data_tones,
                                    options.size,
                                    mode=options.snrmode)
                if options.char > 0:
                    # NOTE: we use repeat, assuming the file is long enough or properly aligned
                    data = gr.stream_to_vector(gr.sizeof_float, data_tones * 2)
                    self.connect(
                        gr.file_source(gr.sizeof_char,
                                       options.txdata,
                                       repeat=True), gr.char_to_float(),
                        gr.multiply_const_ff(options.char * (2**-0.5) / 128.0),
                        data)
                else:
                    data = ofdm_rxtx.make_data(rx.params.data_tones,
                                               options.size, options.txdata)
                self.connect(rx, (snr, 0))
                self.connect(data, (snr, 1))
                if options.snrdata == '-':
                    # print it out
                    msgq = gr.msg_queue(16)
                    self.connect(snr,
                                 gr.message_sink(gr.sizeof_float, msgq, True))
                    self.watcher = ofdm_rxtx.queue_watcher(msgq)
                elif options.snrdata == '.':
                    import scope
                    # scope it out
                    self.scope = scope.scope(self, snr, 'Frame SNR')
                else:
                    self.connect(
                        snr, gr.file_sink(gr.sizeof_float, options.snrdata))
            else:
                pass
                #self.connect(rx, gr.null_sink(symbol_size)) # XXX do we still need this?

        self.connect(u, rx)
コード例 #32
0
ファイル: ofdm_receiver.py プロジェクト: RabbitNick/extrasy
    def __init__(self, fft_length, cp_length, occupied_tones, snr, ks, vcsthresh, vcsbackoff, logging=False, use_coding=0):
        """
	Hierarchical block for receiving OFDM symbols.

	The input is the complex modulated signal at baseband.
        Synchronized packets are sent back to the demodulator.

        @param fft_length: total number of subcarriers
        @type  fft_length: int
        @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length)
        @type  cp_length: int
        @param occupied_tones: number of subcarriers used for data
        @type  occupied_tones: int
        @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer
        @type  snr: float
        @param ks: known symbols used as preambles to each packet
        @type  ks: list of lists
        @param logging: turn file logging on or off
        @type  logging: bool
	"""

	gr.hier_block2.__init__(self, "ofdm_receiver",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature3(3, 3, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char, gr.sizeof_float)) # Output signature
        
        bw = (float(occupied_tones) / float(fft_length)) / 2.0
        tb = bw*0.08
        chan_coeffs = gr.firdes.low_pass (1.0,                     # gain
                                          1.0,                     # sampling rate
                                          bw+tb,                   # midpoint of trans. band
                                          tb,                      # width of trans. band
                                          gr.firdes.WIN_HAMMING)   # filter type
        self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)
        
        win = [1 for i in range(fft_length)]

        zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0))
        ks0 = fft_length*[0,]
        ks0[zeros_on_left : zeros_on_left + occupied_tones] = ks[0]
        
        ks0 = fft.ifftshift(ks0)
        ks0time = fft.ifft(ks0)
        # ADD SCALING FACTOR
        ks0time = ks0time.tolist()

        SYNC = "pn"
        if SYNC == "ml":
            nco_sensitivity = -1.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_ml(fft_length,
                                          cp_length,
                                          snr,
                                          ks0time,
                                          logging)
        elif SYNC == "pn":
            nco_sensitivity = -2.0/fft_length   # correct for fine frequency
            self.ofdm_sync = digital_ll.ofdm_sync_pn(fft_length,
                                          cp_length,
                                          vcsthresh,
                                          logging)
        elif SYNC == "pnac":
            nco_sensitivity = -2.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_pnac(fft_length,
                                            cp_length,
                                            ks0time,
                                            logging)
        # for testing only; do not user over the air
        # remove filter and filter delay for this
        elif SYNC == "fixed":
            self.chan_filt = gr.multiply_const_cc(1.0) 
            nsymbols = 18      # enter the number of symbols per packet
            freq_offset = 0.0  # if you use a frequency offset, enter it here
            nco_sensitivity = -2.0/fft_length   # correct for fine frequency
            self.ofdm_sync = ofdm_sync_fixed(fft_length,
                                             cp_length,
                                             nsymbols,
                                             freq_offset,
                                             logging)

        # Set up blocks

        self.nco = gr.frequency_modulator_fc(nco_sensitivity)         # generate a signal proportional to frequency error of sync block
        self.sigmix = gr.multiply_cc()
        self.sampler = digital_swig.ofdm_sampler(fft_length, fft_length+cp_length)
        self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
        
        if vcsbackoff:
            preamble_sense_time = vcsbackoff
        else:
            if use_coding:
                preamble_sense_time = fft_length*50
            else:
                preamble_sense_time = fft_length*25
        #preamble_sense_taps = [1.0 for i in range(preamble_sense_time)]
        #self.preamble_sense_avg = gr.fir_filter_fff(1,preamble_sense_taps)
        self.preamble_sense_avg = digital_ll.downcounter(preamble_sense_time)
        self.char2float = gr.char_to_float()
        
        #self.ofdm_frame_acq = digital_swig.ofdm_frame_acquisition(occupied_tones,
        #                                                          fft_length,
        #                                                          cp_length, ks[0])
        print 'Using newest ofdm frame acquisition function'
        self.ofdm_frame_acq = digital_ll.digital_ll_ofdm_frame_acquisition(occupied_tones, fft_length, cp_length, ks[0])

        self.connect(self, self.chan_filt)                            # filter the input channel
        self.connect(self.chan_filt, self.ofdm_sync)                  # into the synchronization alg.
        self.connect((self.ofdm_sync,0), self.nco, (self.sigmix,1))   # use sync freq. offset output to derotate input signal
        self.connect(self.chan_filt, (self.sigmix,0))                 # signal to be derotated
        self.connect(self.sigmix, (self.sampler,0))                   # sample off timing signal detected in sync alg
        self.connect((self.ofdm_sync,1), (self.sampler,1))            # timing signal to sample at

        self.connect((self.sampler,0), self.fft_demod)                # send derotated sampled signal to FFT
        self.connect(self.fft_demod, (self.ofdm_frame_acq,0))         # find frame start and equalize signal
        self.connect((self.sampler,1), (self.ofdm_frame_acq,1))       # send timing signal to signal frame start
        
        self.connect((self.ofdm_sync,1), self.char2float)             # the timing signal held high by filter for some time
        self.connect(self.char2float, self.preamble_sense_avg)
        self.connect(self.preamble_sense_avg, (self,2))               # virtual carrier sense signal
        
        self.connect((self.ofdm_frame_acq,0), (self,0))               # finished with fine/coarse freq correction,
        self.connect((self.ofdm_frame_acq,1), (self,1))               # frame and symbol timing, and equalization

        if logging:
            self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat"))
            self.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-fft_out_c.dat"))
            self.connect(self.ofdm_frame_acq,
                         gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_receiver-frame_acq_c.dat"))
            self.connect((self.ofdm_frame_acq,1), gr.file_sink(1, "ofdm_receiver-found_corr_b.dat"))
            self.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-sampler_c.dat"))
            self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-sigmix_c.dat"))
            self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
            self.connect(self.preamble_sense_avg, gr.file_sink(gr.sizeof_float, "ofdm_receiver-vcs.dat"))
コード例 #33
0
def char_to_float(N):
    op = gr.char_to_float()
    tb = helper(N, op, gr.sizeof_char, gr.sizeof_float, 1, 1)
    return tb
コード例 #34
0
ファイル: top_block.py プロジェクト: eroen/radiokom
	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="Top Block")
		_icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

		##################################################
		# Variables
		##################################################
		self.tunefreq = tunefreq = 0
		self.samp_rate = samp_rate = 1000000

		##################################################
		# Notebooks
		##################################################
		self.n0 = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
		self.n0.AddPage(grc_wxgui.Panel(self.n0), "t1")
		self.n0.AddPage(grc_wxgui.Panel(self.n0), "t2")
		self.n0.AddPage(grc_wxgui.Panel(self.n0), "t3")
		self.Add(self.n0)

		##################################################
		# Controls
		##################################################
		_tunefreq_sizer = wx.BoxSizer(wx.VERTICAL)
		self._tunefreq_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_tunefreq_sizer,
			value=self.tunefreq,
			callback=self.set_tunefreq,
			label="tunefreq",
			converter=forms.int_converter(),
			proportion=0,
		)
		self._tunefreq_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_tunefreq_sizer,
			value=self.tunefreq,
			callback=self.set_tunefreq,
			minimum=-100,
			maximum=100,
			num_steps=200,
			style=wx.SL_HORIZONTAL,
			cast=int,
			proportion=1,
		)
		self.Add(_tunefreq_sizer)

		##################################################
		# Blocks
		##################################################
		self.blks2_dxpsk_demod_0 = blks2.dbpsk_demod(
			samples_per_symbol=2,
			excess_bw=0.35,
			costas_alpha=0.175,
			gain_mu=0.175,
			mu=0.5,
			omega_relative_limit=0.005,
			gray_code=True,
			verbose=False,
			log=False,
		)
		self.blks2_dxpsk_mod_0 = blks2.dbpsk_mod(
			samples_per_symbol=4,
			excess_bw=0.35,
			gray_code=True,
			verbose=False,
			log=False,
		)
		self.blks2_packet_decoder_0 = grc_blks2.packet_demod_f(grc_blks2.packet_decoder(
				access_code="",
				threshold=-1,
				callback=lambda ok, payload: self.blks2_packet_decoder_0.recv_pkt(ok, payload),
			),
		)
		self.blks2_packet_encoder_0 = grc_blks2.packet_mod_f(grc_blks2.packet_encoder(
				samples_per_symbol=2,
				bits_per_symbol=1,
				access_code="",
				pad_for_usrp=False,
			),
			payload_length=0,
		)
		self.gr_char_to_float_1 = gr.char_to_float()
		self.gr_sig_source_x_0 = gr.sig_source_f(samp_rate/2/2, gr.GR_SAW_WAVE, 1000, 127, 0)
		self.gr_throttle_0 = gr.throttle(gr.sizeof_char*1, samp_rate/2)
		self.gr_throttle_0_0 = gr.throttle(gr.sizeof_char*1, samp_rate/2)
		self.gr_throttle_2 = gr.throttle(gr.sizeof_float*1, samp_rate/4/4)
		self.gr_throttle_2_0 = gr.throttle(gr.sizeof_float*1, samp_rate/4/4)
		self.wxgui_constellationsink2_1 = constsink_gl.const_sink_c(
			self.GetWin(),
			title="Constellation Plot",
			sample_rate=samp_rate/2*2*8,
			frame_rate=5,
			const_size=2048,
			M=4,
			theta=0,
			alpha=0.005,
			fmax=0.06,
			mu=0.5,
			gain_mu=0.005,
			symbol_rate=samp_rate/2*2*8/4,
			omega_limit=0.005,
		)
		self.Add(self.wxgui_constellationsink2_1.win)
		self.wxgui_scopesink2_1 = scopesink2.scope_sink_f(
			self.n0.GetPage(1).GetWin(),
			title="Scope Plot",
			sample_rate=samp_rate/2/2,
			v_scale=0,
			v_offset=0,
			t_scale=0,
			ac_couple=False,
			xy_mode=False,
			num_inputs=1,
		)
		self.n0.GetPage(1).Add(self.wxgui_scopesink2_1.win)
		self.wxgui_scopesink2_2 = scopesink2.scope_sink_f(
			self.n0.GetPage(0).GetWin(),
			title="Scope Plot",
			sample_rate=samp_rate,
			v_scale=0,
			v_offset=0,
			t_scale=0,
			ac_couple=False,
			xy_mode=False,
			num_inputs=1,
		)
		self.n0.GetPage(0).Add(self.wxgui_scopesink2_2.win)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_throttle_0, 0), (self.blks2_dxpsk_mod_0, 0))
		self.connect((self.blks2_dxpsk_demod_0, 0), (self.gr_throttle_0_0, 0))
		self.connect((self.blks2_packet_encoder_0, 0), (self.gr_throttle_0, 0))
		self.connect((self.gr_throttle_0_0, 0), (self.blks2_packet_decoder_0, 0))
		self.connect((self.blks2_packet_decoder_0, 0), (self.gr_throttle_2, 0))
		self.connect((self.gr_throttle_2, 0), (self.wxgui_scopesink2_1, 0))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_throttle_2_0, 0))
		self.connect((self.gr_throttle_2_0, 0), (self.blks2_packet_encoder_0, 0))
		self.connect((self.blks2_dxpsk_mod_0, 0), (self.blks2_dxpsk_demod_0, 0))
		self.connect((self.gr_throttle_0, 0), (self.gr_char_to_float_1, 0))
		self.connect((self.gr_char_to_float_1, 0), (self.wxgui_scopesink2_2, 0))
		self.connect((self.blks2_dxpsk_mod_0, 0), (self.wxgui_constellationsink2_1, 0))
コード例 #35
0
ファイル: simple_qam.py プロジェクト: Nishtha13/telclass
	def __init__(self):
		gr.top_block.__init__(self, "Simple QAM Simulation")
		Qt.QWidget.__init__(self)
		self.setWindowTitle("Simple QAM Simulation")
		self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
		self.top_scroll_layout = Qt.QVBoxLayout()
		self.setLayout(self.top_scroll_layout)
		self.top_scroll = Qt.QScrollArea()
		self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
		self.top_scroll_layout.addWidget(self.top_scroll)
		self.top_scroll.setWidgetResizable(True)
		self.top_widget = Qt.QWidget()
		self.top_scroll.setWidget(self.top_widget)
		self.top_layout = Qt.QVBoxLayout(self.top_widget)
		self.top_grid_layout = Qt.QGridLayout()
		self.top_layout.addLayout(self.top_grid_layout)


		##################################################
		# Variables
		##################################################
		self.constellation_cardinality = constellation_cardinality = 16
		self.const_object = const_object = constellations()['qam'](constellation_cardinality)
		self.snr_db = snr_db = 20
		self.constellation = constellation = const_object.points()
		self.sps = sps = 8
		self.samp_rate = samp_rate = 250000
		self.noise_amp = noise_amp = sqrt(  (10**(-snr_db/10.))  /2. )
		self.constellation_power = constellation_power = sqrt(sum([abs(i)**2 for i in constellation])/constellation_cardinality)

		##################################################
		# Blocks
		##################################################
		self.tabid_0 = Qt.QTabWidget()
		self.tabid_0_widget_0 = Qt.QWidget()
		self.tabid_0_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_0_widget_0)
		self.tabid_0_grid_layout_0 = Qt.QGridLayout()
		self.tabid_0_layout_0.addLayout(self.tabid_0_grid_layout_0)
		self.tabid_0.addTab(self.tabid_0_widget_0, "TX")
		self.tabid_0_widget_1 = Qt.QWidget()
		self.tabid_0_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_0_widget_1)
		self.tabid_0_grid_layout_1 = Qt.QGridLayout()
		self.tabid_0_layout_1.addLayout(self.tabid_0_grid_layout_1)
		self.tabid_0.addTab(self.tabid_0_widget_1, "CHANNEL")
		self.tabid_0_widget_2 = Qt.QWidget()
		self.tabid_0_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_0_widget_2)
		self.tabid_0_grid_layout_2 = Qt.QGridLayout()
		self.tabid_0_layout_2.addLayout(self.tabid_0_grid_layout_2)
		self.tabid_0.addTab(self.tabid_0_widget_2, "RX")
		self.top_grid_layout.addWidget(self.tabid_0, 30,0,10,100)
		self.tabid_2 = Qt.QTabWidget()
		self.tabid_2_widget_0 = Qt.QWidget()
		self.tabid_2_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_2_widget_0)
		self.tabid_2_grid_layout_0 = Qt.QGridLayout()
		self.tabid_2_layout_0.addLayout(self.tabid_2_grid_layout_0)
		self.tabid_2.addTab(self.tabid_2_widget_0, "symbol-based")
		self.tabid_2_widget_1 = Qt.QWidget()
		self.tabid_2_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_2_widget_1)
		self.tabid_2_grid_layout_1 = Qt.QGridLayout()
		self.tabid_2_layout_1.addLayout(self.tabid_2_grid_layout_1)
		self.tabid_2.addTab(self.tabid_2_widget_1, "bit-based")
		self.tabid_2_widget_2 = Qt.QWidget()
		self.tabid_2_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_2_widget_2)
		self.tabid_2_grid_layout_2 = Qt.QGridLayout()
		self.tabid_2_layout_2.addLayout(self.tabid_2_grid_layout_2)
		self.tabid_2.addTab(self.tabid_2_widget_2, "BER")
		self.tabid_0_layout_2.addWidget(self.tabid_2)
		self.tabid_1 = Qt.QTabWidget()
		self.tabid_1_widget_0 = Qt.QWidget()
		self.tabid_1_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_1_widget_0)
		self.tabid_1_grid_layout_0 = Qt.QGridLayout()
		self.tabid_1_layout_0.addLayout(self.tabid_1_grid_layout_0)
		self.tabid_1.addTab(self.tabid_1_widget_0, "bit-based")
		self.tabid_1_widget_1 = Qt.QWidget()
		self.tabid_1_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_1_widget_1)
		self.tabid_1_grid_layout_1 = Qt.QGridLayout()
		self.tabid_1_layout_1.addLayout(self.tabid_1_grid_layout_1)
		self.tabid_1.addTab(self.tabid_1_widget_1, "scrambled")
		self.tabid_1_widget_2 = Qt.QWidget()
		self.tabid_1_layout_2 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.tabid_1_widget_2)
		self.tabid_1_grid_layout_2 = Qt.QGridLayout()
		self.tabid_1_layout_2.addLayout(self.tabid_1_grid_layout_2)
		self.tabid_1.addTab(self.tabid_1_widget_2, "symbol-based")
		self.tabid_0_grid_layout_0.addWidget(self.tabid_1, 0,0,10,10)
		self.qtgui_time_sink_x_0 = qtgui.time_sink_f(
			1024, #size
			samp_rate, #bw
			"QT GUI Plot", #name
			1 #number of inputs
		)
		self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget)
		self.tabid_2_layout_2.addWidget(self._qtgui_time_sink_x_0_win)
		self.qtgui_sink_x_0_1_0_0 = qtgui.sink_f(
			1024, #fftsize
			firdes.WIN_BLACKMAN_hARRIS, #wintype
			0, #fc
			samp_rate, #bw
			"QT GUI Plot", #name
			False, #plotfreq
			False, #plotwaterfall
			True, #plottime
			True, #plotconst
		)
		self._qtgui_sink_x_0_1_0_0_win = sip.wrapinstance(self.qtgui_sink_x_0_1_0_0.pyqwidget(), Qt.QWidget)
		self.tabid_1_layout_0.addWidget(self._qtgui_sink_x_0_1_0_0_win)
		self.qtgui_sink_x_0_1_0 = qtgui.sink_f(
			1024, #fftsize
			firdes.WIN_BLACKMAN_hARRIS, #wintype
			0, #fc
			samp_rate, #bw
			"QT GUI Plot", #name
			True, #plotfreq
			False, #plotwaterfall
			True, #plottime
			True, #plotconst
		)
		self._qtgui_sink_x_0_1_0_win = sip.wrapinstance(self.qtgui_sink_x_0_1_0.pyqwidget(), Qt.QWidget)
		self.tabid_1_layout_1.addWidget(self._qtgui_sink_x_0_1_0_win)
		self.qtgui_sink_x_0_1 = qtgui.sink_c(
			1024, #fftsize
			firdes.WIN_BLACKMAN_hARRIS, #wintype
			0, #fc
			samp_rate, #bw
			"QT GUI Plot", #name
			False, #plotfreq
			False, #plotwaterfall
			True, #plottime
			True, #plotconst
		)
		self._qtgui_sink_x_0_1_win = sip.wrapinstance(self.qtgui_sink_x_0_1.pyqwidget(), Qt.QWidget)
		self.tabid_1_layout_2.addWidget(self._qtgui_sink_x_0_1_win)
		self.qtgui_sink_x_0_0_0_0 = qtgui.sink_c(
			1024, #fftsize
			firdes.WIN_BLACKMAN_hARRIS, #wintype
			0, #fc
			samp_rate, #bw
			"QT GUI Plot", #name
			True, #plotfreq
			False, #plotwaterfall
			True, #plottime
			True, #plotconst
		)
		self._qtgui_sink_x_0_0_0_0_win = sip.wrapinstance(self.qtgui_sink_x_0_0_0_0.pyqwidget(), Qt.QWidget)
		self.tabid_2_layout_0.addWidget(self._qtgui_sink_x_0_0_0_0_win)
		self.qtgui_sink_x_0_0_0 = qtgui.sink_f(
			1024, #fftsize
			firdes.WIN_BLACKMAN_hARRIS, #wintype
			0, #fc
			samp_rate, #bw
			"QT GUI Plot", #name
			False, #plotfreq
			False, #plotwaterfall
			True, #plottime
			True, #plotconst
		)
		self._qtgui_sink_x_0_0_0_win = sip.wrapinstance(self.qtgui_sink_x_0_0_0.pyqwidget(), Qt.QWidget)
		self.tabid_2_layout_1.addWidget(self._qtgui_sink_x_0_0_0_win)
		self.qtgui_sink_x_0_0 = qtgui.sink_c(
			1024, #fftsize
			firdes.WIN_BLACKMAN_hARRIS, #wintype
			0, #fc
			samp_rate, #bw
			"QT GUI Plot", #name
			True, #plotfreq
			False, #plotwaterfall
			True, #plottime
			False, #plotconst
		)
		self._qtgui_sink_x_0_0_win = sip.wrapinstance(self.qtgui_sink_x_0_0.pyqwidget(), Qt.QWidget)
		self.tabid_0_layout_1.addWidget(self._qtgui_sink_x_0_0_win)
		self.gr_vector_source_x_0_0 = gr.vector_source_b(([1,0]), True, 1)
		self.gr_vector_source_x_0 = gr.vector_source_b(([1,0]), True, 1)
		self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(int(log2(constellation_cardinality)))
		self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex*1, samp_rate)
		self.gr_pack_k_bits_bb_0 = gr.pack_k_bits_bb(int(log2(constellation_cardinality)))
		self.gr_null_sink_0 = gr.null_sink(gr.sizeof_char*1)
		self.gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, noise_amp, 0)
		self.gr_nlog10_ff_0 = gr.nlog10_ff(1, 1, 0)
		self.gr_multiply_const_vxx_0_0 = gr.multiply_const_vcc((1./constellation_power, ))
		self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc((constellation_power, ))
		self.gr_file_sink_0_1_0 = gr.file_sink(gr.sizeof_gr_complex*1, "rx_sym.32fc")
		self.gr_file_sink_0_1_0.set_unbuffered(False)
		self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_gr_complex*1, "tx_sym.32fc")
		self.gr_file_sink_0_1.set_unbuffered(False)
		self.gr_file_sink_0_0 = gr.file_sink(gr.sizeof_char*1, "rx.8b")
		self.gr_file_sink_0_0.set_unbuffered(False)
		self.gr_file_sink_0 = gr.file_sink(gr.sizeof_char*1, "tx.8b")
		self.gr_file_sink_0.set_unbuffered(False)
		self.gr_descrambler_bb_0 = gr.descrambler_bb(0xe4001, 0x7ffff, 19)
		self.gr_char_to_float_1_0 = gr.char_to_float(1, 1)
		self.gr_char_to_float_1 = gr.char_to_float(1, 1)
		self.gr_char_to_float_0 = gr.char_to_float(1, 1)
		self.gr_add_xx_0 = gr.add_vcc(1)
		self.digital_scrambler_bb_0 = digital.scrambler_bb(0xe4001, 0x7fffF, 19)
		self.digital_constellation_receiver_cb_0 = digital.constellation_receiver_cb(const_object.base(), 6.28/100, -0.25, +0.25)
		self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bc((constellation), 1)
		self.blks2_error_rate_0 = grc_blks2.error_rate(
			type='BER',
			win_size=samp_rate,
			bits_per_symbol=1,
		)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_vector_source_x_0, 0), (self.digital_scrambler_bb_0, 0))
		self.connect((self.digital_scrambler_bb_0, 0), (self.gr_pack_k_bits_bb_0, 0))
		self.connect((self.gr_pack_k_bits_bb_0, 0), (self.digital_chunks_to_symbols_xx_0, 0))
		self.connect((self.digital_constellation_receiver_cb_0, 0), (self.gr_file_sink_0_0, 0))
		self.connect((self.digital_constellation_receiver_cb_0, 0), (self.gr_unpack_k_bits_bb_0, 0))
		self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_descrambler_bb_0, 0))
		self.connect((self.gr_descrambler_bb_0, 0), (self.gr_null_sink_0, 0))
		self.connect((self.gr_multiply_const_vxx_0, 0), (self.digital_constellation_receiver_cb_0, 0))
		self.connect((self.gr_descrambler_bb_0, 0), (self.gr_char_to_float_0, 0))
		self.connect((self.gr_char_to_float_0, 0), (self.qtgui_sink_x_0_0_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.gr_throttle_0, 0))
		self.connect((self.gr_noise_source_x_0, 0), (self.gr_add_xx_0, 1))
		self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.gr_multiply_const_vxx_0_0, 0))
		self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.gr_file_sink_0_1, 0))
		self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.qtgui_sink_x_0_1, 0))
		self.connect((self.gr_char_to_float_1, 0), (self.qtgui_sink_x_0_1_0, 0))
		self.connect((self.gr_pack_k_bits_bb_0, 0), (self.gr_char_to_float_1, 0))
		self.connect((self.gr_pack_k_bits_bb_0, 0), (self.gr_file_sink_0, 0))
		self.connect((self.gr_char_to_float_1_0, 0), (self.qtgui_sink_x_0_1_0_0, 0))
		self.connect((self.gr_vector_source_x_0, 0), (self.gr_char_to_float_1_0, 0))
		self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.gr_add_xx_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.qtgui_sink_x_0_0, 0))
		self.connect((self.gr_throttle_0, 0), (self.gr_multiply_const_vxx_0, 0))
		self.connect((self.gr_throttle_0, 0), (self.gr_file_sink_0_1_0, 0))
		self.connect((self.gr_throttle_0, 0), (self.qtgui_sink_x_0_0_0_0, 0))
		self.connect((self.gr_nlog10_ff_0, 0), (self.qtgui_time_sink_x_0, 0))
		self.connect((self.blks2_error_rate_0, 0), (self.gr_nlog10_ff_0, 0))
		self.connect((self.gr_vector_source_x_0_0, 0), (self.blks2_error_rate_0, 0))
		self.connect((self.gr_descrambler_bb_0, 0), (self.blks2_error_rate_0, 1))
コード例 #36
0
    def setUp (self):
        self.tb = gr.top_block ()
        
        # Read in successfully decoded live data from Matlab
        linf=open('/home/demel/exchange/matlab_d.txt')
        lintu=range(120)
        for i in lintu:
            lintu[i]=float(linf.readline())
        #print lintu
        # source for live data
        self.srcl = gr.vector_source_f(lintu,False,120)
        
        # Read in .txt file with example MIB encoded + CRC checksum
        inf=open('/home/demel/exchange/crc.txt')
        self.intu=range(40)
        for i in self.intu:
            self.intu[i]=float(inf.readline())
                
        #inf=open('/home/demel/exchange/matlab_d.txt')
        #intu=range(120)
    	#for i in range(120):
    	#	intu[i]=float(inf.readline())
        
        # Source and conversions
        self.src  = gr.vector_source_f(self.intu,False,40)
        self.conv = gr.float_to_char(40,1)

        # Resize vector with repetition of last part
        # Vector to stream for encoder
        my_map1=range(46)
        for i in range(40):
            my_map1[i+6]=i
        for i in range(6):
            my_map1[i]=i+40
        self.map1 = lte.vector_resize_vbvb(my_map1,40,46)
        self.vtos = gr.vector_to_stream(1*gr.sizeof_char,46)
        
        # Encoding of input data
        self.fsm  = trellis.fsm(1,3,[91,121,117])
        self.enc  = trellis.encoder_bb(self.fsm,0)
        # unpack packed bits from encoder
        self.unp  = gr.unpack_k_bits_bb(3)
        # stream to vector
        self.stov = gr.stream_to_vector(1*gr.sizeof_char,138)
        # Remove first part which contains tail-biting init stuff
        map2 = range(120)
        for i in map2:
            map2[i]= i+18
        self.map2 = lte.vector_resize_vbvb(map2,138,120)
        # conversion from char to float to match input of decoder
        self.conv2= gr.char_to_float(120,1)
        
        
        ###############################################
        # From here on only "receiver side" processing
        ###############################################
        
        # like QPSK demodulation: NRZ coding.
        vec2=range(120)
        for i in vec2:
            vec2[i]=float(-2.0)
        self.mult = gr.multiply_const_vff(vec2)
        vec=range(120)
        for i in vec:
            vec[i]=1
        self.add  = gr.add_const_vff(vec)
        
        # this is the actual unit under test
        self.vit = lte.viterbi_vfvb()
        
        # Sinks
        self.snk = gr.vector_sink_b(40)
        self.snk2 = gr.vector_sink_f(120)
        
        # connecting blocks
        self.tb.connect(self.src,self.conv,self.map1,self.vtos,self.enc,self.unp)
        self.tb.connect(self.unp,self.stov,self.map2,self.conv2)
        self.tb.connect(self.conv2,self.mult,self.add)
        self.tb.connect(self.srcl,self.vit,self.snk)
        self.tb.connect(self.add,self.snk2)
コード例 #37
0
ファイル: transmit_path.py プロジェクト: aixtux/gr-ofdm
    def __init__(self, options):
        gr.hier_block2.__init__(self, "transmit_path",
                                gr.io_signature(0, 0, 0),
                                gr.io_signature(1, 1, gr.sizeof_gr_complex))

        common_options.defaults(options)

        config = self.config = station_configuration()

        config.data_subcarriers = options.subcarriers
        config.cp_length = options.cp_length
        config.frame_data_blocks = options.data_blocks
        config._verbose = options.verbose
        config.fft_length = options.fft_length
        config.dc_null = options.dc_null
        config.training_data = default_block_header(config.data_subcarriers,
                                                    config.fft_length,
                                                    config.dc_null, options)
        config.coding = options.coding
        config.bandwidth = options.bandwidth
        config.gui_frame_rate = options.gui_frame_rate
        config.fbmc = options.fbmc

        config.frame_id_blocks = 1  # FIXME

        # digital rms amplitude sent to USRP
        rms_amp = options.rms_amplitude
        self._options = copy.copy(options)

        config.block_length = config.fft_length + config.cp_length
        config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
        config.frame_length = config.frame_data_part + \
                              config.training_data.no_pilotsyms
        config.subcarriers = config.data_subcarriers + \
                             config.training_data.pilot_subcarriers
        config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null

        # default values if parameters not set
        if rms_amp is None:
            rms_amp = math.sqrt(config.subcarriers)
        config.rms_amplitude = rms_amp

        # check some bounds
        if config.fft_length < config.subcarriers:
            raise SystemError, "Subcarrier number must be less than FFT length"
        if config.fft_length < config.cp_length:
            raise SystemError, "Cyclic prefix length must be less than FFT length"

        ## shortcuts
        blen = config.block_length
        flen = config.frame_length
        dsubc = config.data_subcarriers
        vsubc = config.virtual_subcarriers

        # Adaptive Transmitter Concept
        used_id_bits = config.used_id_bits = 8  #TODO: no constant in source code
        rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits  #BPSK
        if config.data_subcarriers % used_id_bits <> 0:
            raise SystemError, "Data subcarriers need to be multiple of %d" % (
                used_id_bits)

        # adapt OFDM frame rate and GUI display frame rate
        self.keep_frame_n = int(
            1.0 / (config.frame_length *
                   (config.cp_length + config.fft_length) / config.bandwidth) /
            config.gui_frame_rate)

        ## Allocation Control
        self.allocation_src = allocation_src(
            config.data_subcarriers, config.frame_data_blocks, config.coding,
            "tcp://*:3333", "tcp://" + options.rx_hostname + ":3322")
        if options.static_allocation:  #DEBUG
            # how many bits per subcarrier

            if options.coding:
                mode = 1  # Coding mode 1-9
                bitspermode = [0.5, 1, 1.5, 2, 3, 4, 4.5, 5,
                               6]  # Information bits per mode
                modulbitspermode = [1, 2, 2, 4, 4, 6, 6, 6,
                                    8]  # Coding bits per mode
                bitcount_vec = [
                    (int)(config.data_subcarriers * config.frame_data_blocks *
                          bitspermode[mode - 1])
                ]
                modul_bitcount_vec = [
                    config.data_subcarriers * config.frame_data_blocks *
                    modulbitspermode[mode - 1]
                ]
                bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1)
                modul_bitcount_src = blocks.vector_source_i(
                    modul_bitcount_vec, True, 1)
                bitloading = mode
            else:
                bitloading = 1
                bitcount_vec = [
                    config.data_subcarriers * config.frame_data_blocks *
                    bitloading
                ]
                bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1)
                modul_bitcount_src = bitcount_src

            # id's for frames
            id_vec = range(0, 256)
            id_src = blocks.vector_source_s(id_vec, True, 1)
            # bitloading for ID symbol and then once for data symbols
            #bitloading_vec = [1]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2)

            #test_allocation = [bitloading]*(int)(config.data_subcarriers/8)+ [0]*(int)(config.data_subcarriers/4*3) + [bitloading]*(int)(config.data_subcarriers/8)
            #bitloading_vec = [1]*dsubc+[bitloading]*dsubc
            test_allocation = [bitloading] * dsubc
            bitloading_vec = [bitloading] * dsubc + test_allocation
            bitloading_src = blocks.vector_source_b(bitloading_vec, True,
                                                    dsubc)
            # bitcount for frames
            #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading]
            bitcount_vec = [config.frame_data_blocks * sum(test_allocation)]
            bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1)
            # power loading, here same for all symbols
            #power_vec = [1]*(int)(config.data_subcarriers/8)+ [0]*(int)(config.data_subcarriers/4*3) + [1]*(int)(config.data_subcarriers/8)
            power_vec = [1] * config.data_subcarriers
            power_src = blocks.vector_source_f(power_vec, True, dsubc)
            # mux control stream to mux id and data bits
            mux_vec = [0] * dsubc + [1] * bitcount_vec[0]
            mux_ctrl = blocks.vector_source_b(mux_vec, True, 1)
        else:
            id_src = (self.allocation_src, 0)
            bitcount_src = (self.allocation_src, 4)
            bitloading_src = (self.allocation_src, 2)
            power_src = (self.allocation_src, 1)
            if options.coding:
                modul_bitcount_src = (self.allocation_src, 5)
            else:
                modul_bitcount_src = bitcount_src
            mux_ctrl = ofdm.tx_mux_ctrl(dsubc)
            self.connect(modul_bitcount_src, mux_ctrl)

            #Initial allocation
            self.allocation_src.set_allocation([2] * config.data_subcarriers,
                                               [1] * config.data_subcarriers)
            self.allocation_src.set_allocation_scheme(0)
            if options.benchmarking:
                self.allocation_src.set_allocation(
                    [4] * config.data_subcarriers,
                    [1] * config.data_subcarriers)

        if options.lab_special_case:
            self.allocation_src.set_allocation(
                [0] * (config.data_subcarriers / 4) + [2] *
                (config.data_subcarriers / 2) + [0] *
                (config.data_subcarriers / 4), [1] * config.data_subcarriers)

        if options.log:
            log_to_file(self, id_src, "data/id_src.short")
            log_to_file(self, bitcount_src, "data/bitcount_src.int")
            log_to_file(self, bitloading_src, "data/bitloading_src.char")
            log_to_file(self, power_src, "data/power_src.cmplx")

        ## GUI probe output
        zmq_probe_bitloading = zeromq.pub_sink(gr.sizeof_char, dsubc,
                                               "tcp://*:4445")
        # also skip ID symbol bitloading with keep_one_in_n (side effect)
        # factor 2 for bitloading because we have two vectors per frame, one for id symbol and one for all payload/data symbols
        # factor config.frame_data_part for power because there is one vector per ofdm symbol per frame
        self.connect(bitloading_src,
                     blocks.keep_one_in_n(gr.sizeof_char * dsubc, 2 * 40),
                     zmq_probe_bitloading)
        zmq_probe_power = zeromq.pub_sink(gr.sizeof_float, dsubc,
                                          "tcp://*:4444")
        #self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_gr_complex*dsubc,40), blocks.complex_to_real(dsubc), zmq_probe_power)
        self.connect(power_src,
                     blocks.keep_one_in_n(gr.sizeof_float * dsubc, 40),
                     zmq_probe_power)

        ## Workaround to avoid periodic structure
        seed(1)
        whitener_pn = [
            randint(0, 1) for i in range(used_id_bits * rep_id_bits)
        ]

        ## ID Encoder
        id_enc = self._id_encoder = repetition_encoder_sb(
            used_id_bits, rep_id_bits, whitener_pn)
        self.connect(id_src, id_enc)

        if options.log:
            id_enc_f = gr.char_to_float()
            self.connect(id_enc, id_enc_f)
            log_to_file(self, id_enc_f, "data/id_enc_out.float")

        ## Reference Data Source
        ber_ref_src = ber_reference_source(self._options)
        self.connect(id_src, (ber_ref_src, 0))
        self.connect(bitcount_src, (ber_ref_src, 1))

        if options.log:
            log_to_file(self, ber_ref_src, "data/ber_rec_src_tx.char")

        if options.log:
            log_to_file(self, btrig, "data/bitmap_trig.char")

        ## Bitmap Update Trigger for puncturing
        if not options.nopunct:
            bmaptrig_stream_puncturing = [
                1
            ] + [0] * (config.frame_data_blocks / 2 - 1)

            btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b(
                bmaptrig_stream_puncturing, True)
            bmapsrc_stream_puncturing = [1] * dsubc + [2] * dsubc
            bsrc_puncturing = self._bitmap_src_puncturing = blocks.vector_source_b(
                bmapsrc_stream_puncturing, True, dsubc)

        if options.log and options.coding and not options.nopunct:
            log_to_file(self, btrig_puncturing,
                        "data/bitmap_trig_puncturing.char")

        ## Frame Trigger
        ftrig_stream = [1] + [0] * (config.frame_data_part - 1)
        ftrig = self._frame_trigger = blocks.vector_source_b(
            ftrig_stream, True)

        ## Data Multiplexer
        # Input 0: control stream
        # Input 1: encoded ID stream
        # Inputs 2..n: data streams
        dmux = self._data_multiplexer = stream_controlled_mux_b()
        self.connect(mux_ctrl, (dmux, 0))
        self.connect(id_enc, (dmux, 1))

        if options.coding:
            fo = trellis.fsm(1, 2, [91, 121])
            encoder = self._encoder = trellis.encoder_bb(fo, 0)
            unpack = self._unpack = blocks.unpack_k_bits_bb(2)
            self.connect(ber_ref_src, encoder, unpack)

            if options.interleave:
                int_object = trellis.interleaver(2000, 666)
                interlv = trellis.permutation(int_object.K(),
                                              int_object.INTER(), 1,
                                              gr.sizeof_char)

            if not options.nopunct:
                bmaptrig_stream_puncturing = [
                    1
                ] + [0] * (config.frame_data_blocks / 2 - 1)
                btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b(
                    bmaptrig_stream_puncturing, True)
                puncturing = self._puncturing = puncture_bb(
                    config.data_subcarriers)
                self.connect(bitloading_src, (puncturing, 1))
                self.connect(self._bitmap_trigger_puncturing, (puncturing, 2))
                self.connect(unpack, puncturing)
                last_block = puncturing

                if options.interleave:
                    self.connect(last_block, interlv)
                    last_block = interlv

                if options.benchmarking:
                    self.connect(last_block,
                                 blocks.head(gr.sizeof_char, options.N),
                                 (dmux, 2))
                else:
                    self.connect(last_block, (dmux, 2))
            else:
                if options.benchmarking:
                    self.connect(unpack, blocks.head(gr.sizeof_char,
                                                     options.N), (dmux, 2))
                else:
                    self.connect(unpack, (dmux, 2))

        else:
            if options.benchmarking:
                self.connect(ber_ref_src, blocks.head(gr.sizeof_char,
                                                      options.N), (dmux, 2))
            else:
                self.connect(ber_ref_src, (dmux, 2))

        if options.log:
            dmux_f = gr.char_to_float()
            self.connect(dmux, dmux_f)
            log_to_file(self, dmux_f, "data/dmux_out.float")

        ## Modulator
        mod = self._modulator = generic_mapper_bcv(config.data_subcarriers,
                                                   config.coding,
                                                   config.frame_data_part)
        self.connect(dmux, (mod, 0))
        self.connect(bitloading_src, (mod, 1))
        #log_to_file(self, mod, "data/mod_out.compl")

        if options.log:
            log_to_file(self, mod, "data/mod_out.compl")
            modi = blocks.complex_to_imag(config.data_subcarriers)
            modr = blocks.complex_to_real(config.data_subcarriers)
            self.connect(mod, modi)
            self.connect(mod, modr)
            log_to_file(self, modi, "data/mod_imag_out.float")
            log_to_file(self, modr, "data/mod_real_out.float")

        ## Power allocator
        pa = self._power_allocator = multiply_frame_fc(config.frame_data_part,
                                                       config.data_subcarriers)
        self.connect(mod, (pa, 0))
        self.connect(power_src, (pa, 1))

        if options.log:
            log_to_file(self, pa, "data/pa_out.compl")

        # Standard Transmitter Parts

        ## Pilot subcarriers
        psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter()
        self.connect(pa, psubc)

        if options.log:
            log_to_file(self, psubc, "data/psubc_out.compl")

        ## Add virtual subcarriers
        if config.fft_length > config.subcarriers:
            vsubc = self._virtual_subcarrier_extender = \
                    vector_padding_dc_null(config.subcarriers, config.fft_length,config.dc_null)
            self.connect(psubc, vsubc)
        else:
            vsubc = self._virtual_subcarrier_extender = psubc

        if options.log:
            log_to_file(self, vsubc, "data/vsubc_out.compl")

        ## IFFT, no window, block shift
        ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [],
                                               True)
        self.connect(vsubc, ifft)

        if options.log:
            log_to_file(self, ifft, "data/ifft_out.compl")

        ## Pilot blocks (preambles)
        pblocks = self._pilot_block_inserter = pilot_block_inserter(5, False)
        self.connect(ifft, pblocks)

        if options.log:
            log_to_file(self, pblocks, "data/pilot_block_ins_out.compl")

        ## Cyclic Prefix
        cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length,
                                                     config.block_length)
        self.connect(pblocks, cp)

        lastblock = cp

        if options.log:
            log_to_file(self, cp, "data/cp_out.compl")

        #Digital Amplifier for resource allocation
        #if not options.coding:
        rep = blocks.repeat(gr.sizeof_gr_complex,
                            config.frame_length * config.block_length)
        amp = blocks.multiply_cc()
        self.connect(lastblock, (amp, 0))
        self.connect((self.allocation_src, 3), rep, (amp, 1))
        lastblock = amp

        ## Digital Amplifier
        #amp = self._amplifier = gr.multiply_const_cc(1)
        amp = self._amplifier = ofdm.multiply_const_ccf(1.0)
        self.connect(lastblock, amp)
        self.set_rms_amplitude(rms_amp)

        if options.log:
            log_to_file(self, amp, "data/amp_tx_out.compl")

        ## Tx parameters
        bandwidth = options.bandwidth or 2e6
        bits = 8 * config.data_subcarriers * config.frame_data_blocks  # max. QAM256
        samples_per_frame = config.frame_length * config.block_length
        tb = samples_per_frame / bandwidth
        # set dummy carrier frequency if none available due to baseband mode
        if (options.tx_freq is None):
            options.tx_freq = 0.0
        self.tx_parameters = {'carrier_frequency':options.tx_freq/1e9,'fft_size':config.fft_length, 'cp_size':config.cp_length \
                              , 'subcarrier_spacing':options.bandwidth/config.fft_length/1e3 \
                              , 'data_subcarriers':config.data_subcarriers, 'bandwidth':options.bandwidth/1e6 \
                              , 'frame_length':config.frame_length  \
                              , 'symbol_time':(config.cp_length + config.fft_length)/options.bandwidth*1e6, 'max_data_rate':(bits/tb)/1e6}

        ## Setup Output
        self.connect(amp, self)

        # Display some information about the setup
        if config._verbose:
            self._print_verbage()
コード例 #38
0
ファイル: transmit_path2.py プロジェクト: luwangg/gr-ofdm-1
    def __init__(self, options):
        gr.hier_block2.__init__(self, "transmit_path",
                                gr.io_signature(0, 0, 0),
                                gr.io_signature(2, 2, gr.sizeof_gr_complex))

        common_options.defaults(options)

        config = self.config = station_configuration()

        config.data_subcarriers = options.subcarriers
        config.cp_length = options.cp_length
        config.frame_data_blocks = options.data_blocks
        config._verbose = options.verbose
        config.fft_length = options.fft_length
        config.training_data = default_block_header(config.data_subcarriers,
                                                    config.fft_length, options)
        config.tx_station_id = options.station_id
        config.coding = options.coding

        if config.tx_station_id is None:
            raise SystemError, "Station ID not set"

        config.frame_id_blocks = 1  # FIXME

        # digital rms amplitude sent to USRP
        rms_amp = options.rms_amplitude
        self._options = copy.copy(options)

        self.servants = []  # FIXME

        config.block_length = config.fft_length + config.cp_length
        config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
        config.frame_length = config.frame_data_part + \
                              config.training_data.no_pilotsyms
        config.subcarriers = config.data_subcarriers + \
                             config.training_data.pilot_subcarriers
        config.virtual_subcarriers = config.fft_length - config.subcarriers

        # default values if parameters not set
        if rms_amp is None:
            rms_amp = math.sqrt(config.subcarriers)
        config.rms_amplitude = rms_amp

        # check some bounds
        if config.fft_length < config.subcarriers:
            raise SystemError, "Subcarrier number must be less than FFT length"
        if config.fft_length < config.cp_length:
            raise SystemError, "Cyclic prefix length must be less than FFT length"

        ## shortcuts
        blen = config.block_length
        flen = config.frame_length
        dsubc = config.data_subcarriers
        vsubc = config.virtual_subcarriers

        # ------------------------------------------------------------------------ #
        # Adaptive Transmitter Concept

        used_id_bits = config.used_id_bits = 8  #TODO: no constant in source code
        rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits  #BPSK
        if config.data_subcarriers % used_id_bits <> 0:
            raise SystemError, "Data subcarriers need to be multiple of %d" % (
                used_id_bits)

        ## Control Part
        if options.debug:
            self._control = ctrl = static_tx_control(options)
            print "Statix TX Control used"
        else:
            self._control = ctrl = corba_tx_control(options)
            print "CORBA TX Control used"

        id_src = (ctrl, 0)
        mux_src = (ctrl, 1)
        map_src = self._map_src = (ctrl, 2)
        pa_src = (ctrl, 3)

        if options.log:
            id_src_f = gr.short_to_float()
            self.connect(id_src, id_src_f)
            log_to_file(self, id_src_f, "data/id_src_out.float")

            mux_src_f = gr.short_to_float()
            self.connect(mux_src, mux_src_f)
            log_to_file(self, mux_src_f, "data/mux_src_out.float")

            map_src_s = blocks.vector_to_stream(gr.sizeof_char,
                                                config.data_subcarriers)
            map_src_f = gr.char_to_float()
            self.connect(map_src, map_src_s, map_src_f)
            ##log_to_file(self, map_src_f, "data/map_src.float")

            ##log_to_file(self, pa_src, "data/pa_src_out.float")

        ## Workaround to avoid periodic structure
        seed(1)
        whitener_pn = [
            randint(0, 1) for i in range(used_id_bits * rep_id_bits)
        ]

        ## ID Encoder
        id_enc = self._id_encoder = repetition_encoder_sb(
            used_id_bits, rep_id_bits, whitener_pn)
        self.connect(id_src, id_enc)

        if options.log:
            id_enc_f = gr.char_to_float()
            self.connect(id_enc, id_enc_f)
            log_to_file(self, id_enc_f, "data/id_enc_out.float")

        ## Bitmap Update Trigger
        # TODO
        #bmaptrig_stream = concatenate([[1, 2],[0]*(config.frame_data_part-7)])
        bmaptrig_stream = concatenate([[1, 1],
                                       [0] * (config.frame_data_part - 2)])
        print "bmaptrig_stream = ", bmaptrig_stream
        btrig = self._bitmap_trigger = blocks.vector_source_b(
            bmaptrig_stream.tolist(), True)
        if options.log:
            log_to_file(self, btrig, "data/bitmap_trig.char")

        ## Bitmap Update Trigger for puncturing
        # TODO
        if not options.nopunct:
            #bmaptrig_stream_puncturing = concatenate([[1],[0]*(config.frame_data_part-2)])
            bmaptrig_stream_puncturing = concatenate(
                [[1], [0] * (config.frame_data_blocks / 2 - 1)])

            btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b(
                bmaptrig_stream_puncturing.tolist(), True)
            bmapsrc_stream_puncturing = concatenate([[1] * dsubc, [2] * dsubc])
            bsrc_puncturing = self._bitmap_src_puncturing = blocks.vector_source_b(
                bmapsrc_stream_puncturing.tolist(), True, dsubc)

        if options.log and options.coding and not options.nopunct:
            log_to_file(self, btrig_puncturing,
                        "data/bitmap_trig_puncturing.char")

        ## Frame Trigger
        # TODO
        ftrig_stream = concatenate([[1], [0] * (config.frame_data_part - 1)])
        ftrig = self._frame_trigger = blocks.vector_source_b(
            ftrig_stream.tolist(), True)

        ## Data Multiplexer
        # Input 0: control stream
        # Input 1: encoded ID stream
        # Inputs 2..n: data streams
        dmux = self._data_multiplexer = stream_controlled_mux_b()
        self.connect(mux_src, (dmux, 0))
        self.connect(id_enc, (dmux, 1))

        self._data_multiplexer_nextport = 2

        if options.log:
            dmux_f = gr.char_to_float()
            self.connect(dmux, dmux_f)
            log_to_file(self, dmux_f, "data/dmux_out.float")

        ## Modulator
        mod = self._modulator = generic_mapper_bcv(config.data_subcarriers,
                                                   options.coding)

        self.connect(dmux, (mod, 0))
        self.connect(map_src, (mod, 1))
        self.connect(btrig, (mod, 2))

        if options.log:
            log_to_file(self, mod, "data/mod_out.compl")
            modi = gr.complex_to_imag(config.data_subcarriers)
            modr = gr.complex_to_real(config.data_subcarriers)
            self.connect(mod, modi)
            self.connect(mod, modr)
            log_to_file(self, modi, "data/mod_imag_out.float")
            log_to_file(self, modr, "data/mod_real_out.float")

        ## Power allocator
        if options.debug:

            ## static
            pa = self._power_allocator = power_allocator(
                config.data_subcarriers)
            self.connect(mod, (pa, 0))
            self.connect(pa_src, (pa, 1))

        else:

            ## with CORBA control event channel
            ns_ip = ctrl.ns_ip
            ns_port = ctrl.ns_port
            evchan = ctrl.evchan
            pa = self._power_allocator = corba_power_allocator(dsubc, \
                evchan, ns_ip, ns_port, True)

            self.connect(mod, (pa, 0))
            self.connect(id_src, (pa, 1))
            self.connect(ftrig, (pa, 2))

        if options.log:
            log_to_file(self, pa, "data/pa_out.compl")

        ## Pilot subcarriers
        psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter()
        self.connect(pa, psubc)

        pilot_subc = config.training_data.shifted_pilot_tones
        print "pilot_subc", pilot_subc
        stc = stc_encoder(config.subcarriers, config.frame_data_blocks,
                          pilot_subc)

        self.connect(psubc, stc)

        if options.log:
            log_to_file(self, psubc, "data/psubc_out.compl")
            log_to_file(self, psubc_2, "data/psubc2_out.compl")
            log_to_file(self, pa, "data/pa.compl")
            log_to_file(self, (stc, 0), "data/stc_0.compl")
            log_to_file(self, (stc, 1), "data/stc_1.compl")

        ## Add virtual subcarriers
        if config.fft_length > config.subcarriers:
            vsubc = self._virtual_subcarrier_extender = \
                    vector_padding(config.subcarriers, config.fft_length)
            self.connect(stc, vsubc)
            vsubc_2 = self._virtual_subcarrier_extender_2 = \
                    vector_padding(config.subcarriers, config.fft_length)
            self.connect((stc, 1), vsubc_2)
        else:
            vsubc = self._virtual_subcarrier_extender = psubc
            vsubc_2 = self._virtual_subcarrier_extender_2 = psubc_2

        log_to_file(self, psubc, "data/psubc.compl")
        log_to_file(self, stc, "data/stc1.compl")
        log_to_file(self, (stc, 1), "data/stc2.compl")
        if options.log:
            log_to_file(self, vsubc, "data/vsubc_out.compl")
            log_to_file(self, vsubc_2, "data/vsubc2_out.compl")

        ## IFFT, no window, block shift
        ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [],
                                               True)
        self.connect(vsubc, ifft)
        ifft_2 = self._ifft_2 = fft_blocks.fft_vcc(config.fft_length, False,
                                                   [], True)
        self.connect(vsubc_2, ifft_2)

        if options.log:
            log_to_file(self, ifft, "data/ifft_out.compl")
            log_to_file(self, ifft_2, "data/ifft2_out.compl")

        ## Pilot blocks (preambles)
        pblocks = self._pilot_block_inserter = pilot_block_inserter(1, False)
        self.connect(ifft, pblocks)
        pblocks_2 = self._pilot_block_inserter_2 = pilot_block_inserter(
            2, False)
        self.connect(ifft_2, pblocks_2)

        if options.log:
            log_to_file(self, pblocks, "data/pilot_block_ins_out.compl")
            log_to_file(self, pblocks_2, "data/pilot_block_ins2_out.compl")

        ## Cyclic Prefix
        cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length,
                                                     config.block_length)
        self.connect(pblocks, cp)
        cp_2 = self._cyclic_prefixer_2 = cyclic_prefixer(
            config.fft_length, config.block_length)
        self.connect(pblocks_2, cp_2)

        lastblock = cp
        lastblock_2 = cp_2

        if options.log:
            log_to_file(self, cp, "data/cp_out.compl")
            log_to_file(self, cp_2, "data/cp2_out.compl")

        if options.cheat:
            ## Artificial Channel
            # kept to compare with previous system
            achan_ir = concatenate([[1.0], [0.0] * (config.cp_length - 1)])
            achan = self._artificial_channel = gr.fir_filter_ccc(1, achan_ir)
            self.connect(lastblock, achan)
            lastblock = achan
            achan_2 = self._artificial_channel_2 = gr.fir_filter_ccc(
                1, achan_ir)
            self.connect(lastblock_2, achan_2)
            lastblock_2 = achan_2

        ## Digital Amplifier
        amp = self._amplifier = ofdm.multiply_const_ccf(1.0 / math.sqrt(2))
        self.connect(lastblock, amp)
        amp_2 = self._amplifier_2 = ofdm.multiply_const_ccf(1.0 / math.sqrt(2))
        self.connect(lastblock_2, amp_2)
        self.set_rms_amplitude(rms_amp)

        if options.log:
            log_to_file(self, amp, "data/amp_tx_out.compl")
            log_to_file(self, amp_2, "data/amp_tx2_out.compl")

        ## Setup Output
        self.connect(amp, (self, 0))
        self.connect(amp_2, (self, 1))

        # ------------------------------------------------------------------------ #

        # Display some information about the setup
        if config._verbose:
            self._print_verbage()
コード例 #39
0
  def publish_rx_performance_measure(self):
    if self._rx_performance_measure_initialized():
      return

    self.rx_performance_measure_initialized = True

    config = station_configuration()
    vlen = config.data_subcarriers
    vlen_sinr_sc = config.subcarriers

    if self.ideal2 is False:
        self.setup_ber_measurement()
        self.setup_snr_measurement()
        ber_mst = self._ber_measuring_tool
    
    if self._options.sinr_est:
        sinr_mst = self._sinr_measurement
    else:
        if self.ideal2 is False:
            snr_mst = self._snr_measurement

    if self.ideal is False and self.ideal2 is False:
        self.ctf = self.filter_ctf()
        self.zmq_probe_ctf = zeromq.pub_sink(gr.sizeof_float,config.data_subcarriers, "tcp://*:5559")
        self.connect(self.ctf, blocks.keep_one_in_n(gr.sizeof_float*config.data_subcarriers,20) ,self.zmq_probe_ctf)
    else:
        #self.zmq_probe_ctf = zeromq.pub_sink(gr.sizeof_float,config.subcarriers, "tcp://*:5559")
        self.connect(self.ctf,blocks.null_sink(gr.sizeof_float*config.subcarriers))
        #self.rx_per_sink = rpsink = corba_rxinfo_sink("himalaya",config.ns_ip,
#                                    config.ns_port,vlen,config.rx_station_id)



#      print "BER img xfer"
#      self.connect(ber_mst,(rpsink,3))
#      ## no sampling needed
      # 3. SNR

    if self.ideal2 is False:
        print "Normal BER measurement"
    
        trig_src = dynamic_trigger_ib(False)
        self.connect(self.bitcount_src,trig_src)
        
        ber_sampler = vector_sampler(gr.sizeof_float,1)
        self.connect(ber_mst,(ber_sampler,0))
        self.connect(trig_src,(ber_sampler,1))
    else:
        if(self._options.coding):
            demod = self._data_decoder
        else:
            demod = self._data_demodulator
        self.connect(self.bitcount_src,blocks.null_sink(gr.sizeof_int) )
        self.connect(demod,blocks.null_sink(gr.sizeof_char))
    
    
    if self._options.log:
          trig_src_float = gr.char_to_float()
          self.connect(trig_src,trig_src_float)
          log_to_file(self, trig_src_float , 'data/dynamic_trigger_out.float')
    
    
    if self._options.sinr_est is False and self.ideal2 is False:
          self.zmq_probe_ber = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5556")
          self.connect(ber_sampler,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_ber)
    
          if self.ideal2 is False:
              self.zmq_probe_snr = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5555")
              self.connect(snr_mst,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_snr)
コード例 #40
0
ファイル: rds_tx.py プロジェクト: Shmuma/gr-rds
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Rds Tx")
        _icon_path = "/home/azimout/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
        self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

        ##################################################
        # Variables
        ##################################################
        self.usrp_interp = usrp_interp = 500
        self.dac_rate = dac_rate = 128e6
        self.wav_rate = wav_rate = 44100
        self.usrp_rate = usrp_rate = int(dac_rate / usrp_interp)
        self.fm_max_dev = fm_max_dev = 120e3

        ##################################################
        # Blocks
        ##################################################
        self.band_pass_filter_0 = gr.interp_fir_filter_fff(
            1,
            firdes.band_pass(1, usrp_rate, 54e3, 60e3, 3e3, firdes.WIN_HAMMING,
                             6.76))
        self.band_pass_filter_1 = gr.interp_fir_filter_fff(
            1,
            firdes.band_pass(1, usrp_rate, 23e3, 53e3, 2e3, firdes.WIN_HAMMING,
                             6.76))
        self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff(
            interpolation=usrp_rate,
            decimation=wav_rate,
            taps=None,
            fractional_bw=None,
        )
        self.blks2_rational_resampler_xxx_1_0 = blks2.rational_resampler_fff(
            interpolation=usrp_rate,
            decimation=wav_rate,
            taps=None,
            fractional_bw=None,
        )
        self.gr_add_xx_0 = gr.add_vff(1)
        self.gr_add_xx_1 = gr.add_vff(1)
        self.gr_char_to_float_0 = gr.char_to_float()
        self.gr_diff_encoder_bb_0 = gr.diff_encoder_bb(2)
        self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(
            2 * math.pi * fm_max_dev / usrp_rate)
        self.gr_map_bb_0 = gr.map_bb(([-1, 1]))
        self.gr_map_bb_1 = gr.map_bb(([1, 2]))
        self.gr_multiply_xx_0 = gr.multiply_vff(1)
        self.gr_multiply_xx_1 = gr.multiply_vff(1)
        self.gr_rds_data_encoder_0 = rds.data_encoder(
            "/media/dimitris/mywork/gr/dimitris/rds/trunk/src/test/rds_data.xml"
        )
        self.gr_rds_rate_enforcer_0 = rds.rate_enforcer(256000)
        self.gr_sig_source_x_0 = gr.sig_source_f(usrp_rate, gr.GR_COS_WAVE,
                                                 19e3, 0.3, 0)
        self.gr_sub_xx_0 = gr.sub_ff(1)
        self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(2)
        self.gr_wavfile_source_0 = gr.wavfile_source(
            "/media/dimitris/mywork/gr/dimitris/rds/trunk/src/python/limmenso_stereo.wav",
            True)
        self.low_pass_filter_0 = gr.interp_fir_filter_fff(
            1,
            firdes.low_pass(1, usrp_rate, 1.5e3, 2e3, firdes.WIN_HAMMING,
                            6.76))
        self.low_pass_filter_0_0 = gr.interp_fir_filter_fff(
            1,
            firdes.low_pass(1, usrp_rate, 15e3, 2e3, firdes.WIN_HAMMING, 6.76))
        self.usrp_simple_sink_x_0 = grc_usrp.simple_sink_c(which=0, side="A")
        self.usrp_simple_sink_x_0.set_interp_rate(500)
        self.usrp_simple_sink_x_0.set_frequency(107.2e6, verbose=True)
        self.usrp_simple_sink_x_0.set_gain(0)
        self.usrp_simple_sink_x_0.set_enable(True)
        self.usrp_simple_sink_x_0.set_auto_tr(True)
        self.wxgui_fftsink2_0 = fftsink2.fft_sink_f(
            self.GetWin(),
            baseband_freq=0,
            y_per_div=20,
            y_divs=10,
            ref_level=0,
            ref_scale=2.0,
            sample_rate=usrp_rate,
            fft_size=1024,
            fft_rate=30,
            average=False,
            avg_alpha=None,
            title="FFT Plot",
            peak_hold=False,
        )
        self.Add(self.wxgui_fftsink2_0.win)

        ##################################################
        # Connections
        ##################################################
        self.connect((self.gr_sig_source_x_0, 0),
                     (self.gr_rds_rate_enforcer_0, 1))
        self.connect((self.gr_char_to_float_0, 0),
                     (self.gr_rds_rate_enforcer_0, 0))
        self.connect((self.gr_map_bb_0, 0), (self.gr_char_to_float_0, 0))
        self.connect((self.gr_frequency_modulator_fc_0, 0),
                     (self.usrp_simple_sink_x_0, 0))
        self.connect((self.gr_add_xx_1, 0),
                     (self.gr_frequency_modulator_fc_0, 0))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_add_xx_1, 1))
        self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_1, 2))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 1))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_1, 0))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 3))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 2))
        self.connect((self.blks2_rational_resampler_xxx_1_0, 0),
                     (self.gr_add_xx_0, 1))
        self.connect((self.blks2_rational_resampler_xxx_1, 0),
                     (self.gr_add_xx_0, 0))
        self.connect((self.blks2_rational_resampler_xxx_1_0, 0),
                     (self.gr_sub_xx_0, 1))
        self.connect((self.blks2_rational_resampler_xxx_1, 0),
                     (self.gr_sub_xx_0, 0))
        self.connect((self.gr_wavfile_source_0, 1),
                     (self.blks2_rational_resampler_xxx_1_0, 0))
        self.connect((self.gr_wavfile_source_0, 0),
                     (self.blks2_rational_resampler_xxx_1, 0))
        self.connect((self.gr_rds_data_encoder_0, 0),
                     (self.gr_diff_encoder_bb_0, 0))
        self.connect((self.gr_diff_encoder_bb_0, 0), (self.gr_map_bb_1, 0))
        self.connect((self.gr_map_bb_1, 0), (self.gr_unpack_k_bits_bb_0, 0))
        self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_map_bb_0, 0))
        self.connect((self.gr_rds_rate_enforcer_0, 0),
                     (self.low_pass_filter_0, 0))
        self.connect((self.low_pass_filter_0, 0), (self.gr_multiply_xx_0, 0))
        self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0))
        self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 0))
        self.connect((self.gr_multiply_xx_1, 0), (self.band_pass_filter_1, 0))
        self.connect((self.band_pass_filter_1, 0), (self.gr_add_xx_1, 3))
        self.connect((self.gr_add_xx_1, 0), (self.wxgui_fftsink2_0, 0))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 1))
        self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0_0, 0))
        self.connect((self.low_pass_filter_0_0, 0), (self.gr_add_xx_1, 2))
コード例 #41
0
  def __init__(self, options):
    gr.hier_block2.__init__(self, "fbmc_receive_path",
        gr.io_signature(1,1,gr.sizeof_gr_complex),
        gr.io_signature(0,0,0))

    print "This is  FBMC receive path 1x1"

    common_options.defaults(options)

    config = self.config = station_configuration()

    config.data_subcarriers     = dsubc = options.subcarriers
    config.cp_length            = 0
    config.frame_data_blocks    = options.data_blocks
    config._verbose             = options.verbose #TODO: update
    config.fft_length           = options.fft_length
    config.dc_null             = options.dc_null
    config.training_data        = default_block_header(dsubc,
                                          config.fft_length,config.dc_null,options)
    config.coding              = options.coding
    config.ber_window           = options.ber_window

    config.periodic_parts       = 8

    config.frame_id_blocks      = 1 # FIXME

    self._options               = copy.copy(options) #FIXME: do we need this?
    
    config.fbmc                 = options.fbmc

    

    config.block_length = config.fft_length + config.cp_length
    config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
    config.frame_length = config.training_data.fbmc_no_preambles + 2*config.frame_data_part 
    
    config.postpro_frame_length = config.frame_data_part + \
                          config.training_data.no_pilotsyms
    config.subcarriers = dsubc + \
                         config.training_data.pilot_subcarriers
    config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null

    total_subc = config.subcarriers
    


    # check some bounds
    if config.fft_length < config.subcarriers:
      raise SystemError, "Subcarrier number must be less than FFT length"
    if config.fft_length < config.cp_length:
      raise SystemError, "Cyclic prefix length must be less than FFT length"



    #self.input =  gr.kludge_copy(gr.sizeof_gr_complex)
    #self.connect( self, self.input )
    self.input = self
    self.ideal = options.ideal
    self.ideal2 = options.ideal2


    ## Inner receiver

    ## Timing & Frequency Synchronization
    ## Channel estimation + Equalization
    ## Phase Tracking for sampling clock frequency offset correction
    inner_receiver = self.inner_receiver = fbmc_inner_receiver( options, options.log )
    self.connect( self.input, inner_receiver )
    ofdm_blocks = ( inner_receiver, 2 )
    frame_start = ( inner_receiver, 1 )
    disp_ctf = ( inner_receiver, 0 )
    #self.snr_est_preamble = ( inner_receiver, 3 )
    #terminate_stream(self,snr_est_preamble)
    disp_cfo =  ( inner_receiver, 3 )
    
    if self.ideal is False and self.ideal2 is False:
        self.zmq_probe_freqoff = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5557")
        self.connect(disp_cfo, self.zmq_probe_freqoff)
    else:
        self.connect(disp_cfo, blocks.null_sink(gr.sizeof_float))




    # for ID decoder
    used_id_bits = config.used_id_bits = 8 #TODO: constant in source code!
    rep_id_bits = config.rep_id_bits = dsubc/used_id_bits #BPSK
    if options.log:
      print "rep_id_bits %d" % (rep_id_bits)
    if dsubc % used_id_bits <> 0:
      raise SystemError,"Data subcarriers need to be multiple of 10"

    ## Workaround to avoid periodic structure
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]





    ## NOTE!!! BIG HACK!!!
    ## first preamble ain't equalized ....
    ## for Milan's SNR estimator






    ## Outer Receiver

    ## Make new inner receiver compatible with old outer receiver
    ## FIXME: renew outer receiver

    self.ctf = disp_ctf

    #frame_sampler = ofdm_frame_sampler(options)
    frame_sampler = fbmc_frame_sampler(options)

    self.connect( ofdm_blocks, frame_sampler)
    self.connect( frame_start, (frame_sampler,1) )


#
#    ft = [0] * config.frame_length
#    ft[0] = 1
#
#    # The next block ensures that only complete frames find their way into
#    # the old outer receiver. The dynamic frame start trigger is hence
#    # replaced with a static one, fixed to the frame length.
#
#    frame_sampler = ofdm.vector_sampler( gr.sizeof_gr_complex * total_subc,
#                                              config.frame_length )
#    self.symbol_output = blocks.vector_to_stream( gr.sizeof_gr_complex * total_subc,
#                                              config.frame_length )
#    delayed_frame_start = blocks.delay( gr.sizeof_char, config.frame_length - 1 )
#    damn_static_frame_trigger = blocks.vector_source_b( ft, True )
#
#    if options.enable_erasure_decision:
#      frame_gate = vector_sampler(
#        gr.sizeof_gr_complex * total_subc * config.frame_length, 1 )
#      self.connect( ofdm_blocks, frame_sampler, frame_gate,
#                    self.symbol_output )
#    else:
#      self.connect( ofdm_blocks, frame_sampler, self.symbol_output )
#
#    self.connect( frame_start, delayed_frame_start, ( frame_sampler, 1 ) )

    if options.enable_erasure_decision:
      frame_gate = frame_sampler.frame_gate

    self.symbol_output = frame_sampler

    orig_frame_start = frame_start
    frame_start = (frame_sampler,1)
    self.frame_trigger = frame_start
    #terminate_stream(self, self.frame_trigger)








    ## Pilot block filter
    pb_filt = self._pilot_block_filter = fbmc_pilot_block_filter()
    self.connect(self.symbol_output,pb_filt)
    self.connect(self.frame_trigger,(pb_filt,1))

    self.frame_data_trigger = (pb_filt,1)
    
    #self.symbol_output = pb_filt
    

    #if options.log:
      #log_to_file(self, pb_filt, "data/pb_filt_out.compl")


    if config.fbmc:
        pda_in = pb_filt

    else:
        ## Pilot subcarrier filter
        ps_filt = self._pilot_subcarrier_filter = pilot_subcarrier_filter()
        self.connect(self.symbol_output,ps_filt)

        if options.log:
            log_to_file(self, ps_filt, "data/ps_filt_out.compl")
            
        pda_in = ps_filt

    


    ## Workaround to avoid periodic structure
    # for ID decoder
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

    

    if not options.enable_erasure_decision:

      ## ID Block Filter
      # Filter ID block, skip data blocks
      id_bfilt = self._id_block_filter = vector_sampler(
            gr.sizeof_gr_complex * dsubc, 1 )
      if not config.frame_id_blocks == 1:
        raise SystemExit, "# ID Blocks > 1 not supported"

      self.connect(   pda_in     ,   id_bfilt      )
      self.connect( self.frame_data_trigger, ( id_bfilt, 1 ) ) # trigger

      #log_to_file( self, id_bfilt, "data/id_bfilt.compl" )

      ## ID Demapper and Decoder, soft decision
      self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( dsubc,
          used_id_bits, whitener_pn )
      self.connect( id_bfilt, self.id_dec )
      

      print "Using coded BPSK soft decoder for ID detection"


    else: # options.enable_erasure_decision:

      id_bfilt = self._id_block_filter = vector_sampler(
        gr.sizeof_gr_complex * total_subc, config.frame_id_blocks )

      id_bfilt_trig_delay = 0
      for x in range( config.frame_length ):
        if x in config.training_data.pilotsym_pos:
          id_bfilt_trig_delay += 1
        else:
          break
      print "Position of ID block within complete frame: %d" %(id_bfilt_trig_delay)

      assert( id_bfilt_trig_delay > 0 ) # else not supported

      id_bfilt_trig = blocks.delay( gr.sizeof_char, id_bfilt_trig_delay )

      self.connect( ofdm_blocks, id_bfilt )
      self.connect( orig_frame_start, id_bfilt_trig, ( id_bfilt, 1 ) )

      self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( total_subc,
          used_id_bits, whitener_pn, config.training_data.shifted_pilot_tones )
      self.connect( id_bfilt, self.id_dec )

      print "Using coded BPSK soft decoder for ID detection"

      # The threshold block either returns 1.0 if the llr-value from the
      # id decoder is below the threshold, else 0.0. Hence we convert this
      # into chars, 0 and 1, and use it as trigger for the sampler.

      min_llr = ( self.id_dec, 1 )
      erasure_threshold = gr.threshold_ff( 10.0, 10.0, 0 ) # FIXME is it the optimal threshold?
      erasure_dec = gr.float_to_char()
      id_gate = vector_sampler( gr.sizeof_short, 1 )
      ctf_gate = vector_sampler( gr.sizeof_float * total_subc, 1 )


      self.connect( self.id_dec ,       id_gate )
      self.connect( self.ctf,      ctf_gate )

      self.connect( min_llr,       erasure_threshold,  erasure_dec )
      self.connect( erasure_dec, ( frame_gate, 1 ) )
      self.connect( erasure_dec, ( id_gate,    1 ) )
      self.connect( erasure_dec, ( ctf_gate,   1 ) )

      self.id_dec = self._id_decoder = id_gate
      self.ctf = ctf_gate



      print "Erasure decision for IDs is enabled"




    if options.log:
      id_dec_f = gr.short_to_float()
      self.connect(self.id_dec,id_dec_f)
      log_to_file(self, id_dec_f, "data/id_dec_out.float")


    if options.log:
      log_to_file(self, id_bfilt, "data/id_blockfilter_out.compl")


    # TODO: refactor names




    if options.log:
      map_src_f = gr.char_to_float(dsubc)
      self.connect(map_src,map_src_f)
      log_to_file(self, map_src_f, "data/map_src_out.float")

    ## Allocation Control
    if options.static_allocation: #DEBUG
        
        if options.coding:
            mode = 1 # Coding mode 1-9
            bitspermode = [0.5,1,1.5,2,3,4,4.5,5,6] # Information bits per mode
            bitcount_vec = [(int)(config.data_subcarriers*config.frame_data_blocks*bitspermode[mode-1])]
            bitloading = mode
        else:
            bitloading = 1
            bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading]
        #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks]
        self.bitcount_src = blocks.vector_source_i(bitcount_vec,True,1)
        # 0s for ID block, then data
        #bitloading_vec = [0]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2)
        bitloading_vec = [0]*dsubc+[bitloading]*dsubc
        bitloading_src = blocks.vector_source_b(bitloading_vec,True,dsubc)
        power_vec = [1]*config.data_subcarriers
        power_src = blocks.vector_source_f(power_vec,True,dsubc)
    else:
        self.allocation_buffer = ofdm.allocation_buffer(config.data_subcarriers, config.frame_data_blocks, "tcp://"+options.tx_hostname+":3333",config.coding)
        self.bitcount_src = (self.allocation_buffer,0)
        bitloading_src = (self.allocation_buffer,1)
        power_src = (self.allocation_buffer,2)
        self.connect(self.id_dec, self.allocation_buffer)
        if options.benchmarking:
            self.allocation_buffer.set_allocation([4]*config.data_subcarriers,[1]*config.data_subcarriers)

    if options.log:
        log_to_file(self, self.bitcount_src, "data/bitcount_src_rx.int")
        log_to_file(self, bitloading_src, "data/bitloading_src_rx.char")
        log_to_file(self, power_src, "data/power_src_rx.cmplx")
        log_to_file(self, self.id_dec, "data/id_dec_rx.short")

    ## Power Deallocator
    pda = self._power_deallocator = multiply_frame_fc(config.frame_data_part, dsubc)
    self.connect(pda_in,(pda,0))
    self.connect(power_src,(pda,1))

    ## Demodulator
#    if 0:
#          ac_vector = [0.0+0.0j]*208
#          ac_vector[0] = (2*10**(-0.452))
#          ac_vector[3] = (10**(-0.651))
#          ac_vector[7] = (10**(-1.151))
#          csi_vector_inv=abs(numpy.fft.fft(numpy.sqrt(ac_vector)))**2
#          dm_csi = numpy.fft.fftshift(csi_vector_inv) # TODO

    dm_csi = [1]*dsubc # TODO
    dm_csi = blocks.vector_source_f(dm_csi,True)
    ## Depuncturer
    dp_trig = [0]*(config.frame_data_blocks/2)
    dp_trig[0] = 1
    dp_trig = blocks.vector_source_b(dp_trig,True) # TODO



    if(options.coding):
        fo=ofdm.fsm(1,2,[91,121])
        if options.interleave:
            int_object=trellis.interleaver(2000,666)
            deinterlv = trellis.permutation(int_object.K(),int_object.DEINTER(),1,gr.sizeof_float)
        
        demod = self._data_demodulator = generic_softdemapper_vcf(dsubc, config.frame_data_part, config.coding)
        #self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2))
        if(options.ideal):
            self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2))
        else:
            dm_csi_filter = self.dm_csi_filter = filter.single_pole_iir_filter_ff(0.01,dsubc)
            self.connect(self.ctf, self.dm_csi_filter,(demod,2))
            #log_to_file(self, dm_csi_filter, "data/softs_csi.float")
        #self.connect(dm_trig,(demod,3))
    else:
        demod = self._data_demodulator = generic_demapper_vcb(dsubc, config.frame_data_part)
    if options.benchmarking:
        # Do receiver benchmarking until the number of frames x symbols are collected
        self.connect(pda,blocks.head(gr.sizeof_gr_complex*dsubc, options.N*config.frame_data_blocks),demod)
    else:        
        self.connect(pda,demod)
    self.connect(bitloading_src,(demod,1))

    if(options.coding):
        ## Depuncturing
        if not options.nopunct:
            depuncturing = depuncture_ff(dsubc,0)
            frametrigger_bitmap_filter = blocks.vector_source_b([1,0],True)
            self.connect(bitloading_src,(depuncturing,1))
            self.connect(dp_trig,(depuncturing,2))

        ## Decoding
        chunkdivisor = int(numpy.ceil(config.frame_data_blocks/5.0))
        print "Number of chunks at Viterbi decoder: ", chunkdivisor
        decoding = self._data_decoder = ofdm.viterbi_combined_fb(fo,dsubc,-1,-1,2,chunkdivisor,[-1,-1,-1,1,1,-1,1,1],ofdm.TRELLIS_EUCLIDEAN)

        
        if options.log and options.coding:
            log_to_file(self, decoding, "data/decoded.char")
            if not options.nopunct:
                log_to_file(self, depuncturing, "data/vit_in.float")

        if not options.nopunct:
            if options.interleave:
                self.connect(demod,deinterlv,depuncturing,decoding)
            else:
                self.connect(demod,depuncturing,decoding)
        else:
            self.connect(demod,decoding)
        self.connect(self.bitcount_src, multiply_const_ii(1./chunkdivisor), (decoding,1))

    if options.scatterplot or options.scatter_plot_before_phase_tracking:
        if self.ideal2 is False:
            scatter_vec_elem = self._scatter_vec_elem = ofdm.vector_element(dsubc,40)
            scatter_s2v = self._scatter_s2v = blocks.stream_to_vector(gr.sizeof_gr_complex,config.frame_data_blocks)
    
            scatter_id_filt = skip(gr.sizeof_gr_complex*dsubc,config.frame_data_blocks)
            scatter_id_filt.skip_call(0)
            scatter_trig = [0]*config.frame_data_part
            scatter_trig[0] = 1
            scatter_trig = blocks.vector_source_b(scatter_trig,True)
            self.connect(scatter_trig,(scatter_id_filt,1))
            self.connect(scatter_vec_elem,scatter_s2v)
    
            if not options.scatter_plot_before_phase_tracking:
                print "Enabling Scatterplot for data subcarriers"
                self.connect(pda,scatter_id_filt,scatter_vec_elem)
                  # Work on this
                  #scatter_sink = ofdm.scatterplot_sink(dsubc)
                  #self.connect(pda,scatter_sink)
                  #self.connect(map_src,(scatter_sink,1))
                  #self.connect(dm_trig,(scatter_sink,2))
                  #print "Enabled scatterplot gui interface"
                self.zmq_probe_scatter = zeromq.pub_sink(gr.sizeof_gr_complex,config.frame_data_blocks, "tcp://*:5560")
                self.connect(scatter_s2v, blocks.keep_one_in_n(gr.sizeof_gr_complex*config.frame_data_blocks,20), self.zmq_probe_scatter)
            else:
                print "Enabling Scatterplot for data before phase tracking"
                inner_rx = inner_receiver.before_phase_tracking
                #scatter_sink2 = ofdm.scatterplot_sink(dsubc,"phase_tracking")
                op = copy.copy(options)
                op.enable_erasure_decision = False
                new_framesampler = ofdm_frame_sampler(op)
                self.connect( inner_rx, new_framesampler )
                self.connect( orig_frame_start, (new_framesampler,1) )
                new_ps_filter = pilot_subcarrier_filter()
                new_pb_filter = fbmc_pilot_block_filter()
    
                self.connect( (new_framesampler,1), (new_pb_filter,1) )
                self.connect( new_framesampler, new_pb_filter,
                             new_ps_filter, scatter_id_filt, scatter_vec_elem )
    
                #self.connect( new_ps_filter, scatter_sink2 )
                #self.connect( map_src, (scatter_sink2,1))
                #self.connect( dm_trig, (scatter_sink2,2))


    if options.log:
      if(options.coding):
          log_to_file(self, demod, "data/data_stream_out.float")
      else:
          data_f = gr.char_to_float()
          self.connect(demod,data_f)
          log_to_file(self, data_f, "data/data_stream_out.float")



    if options.sfo_feedback:
      used_id_bits = 8
      rep_id_bits = config.data_subcarriers/used_id_bits

      seed(1)
      whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

      id_enc = ofdm.repetition_encoder_sb(used_id_bits,rep_id_bits,whitener_pn)
      self.connect( self.id_dec, id_enc )

      id_mod = ofdm_bpsk_modulator(dsubc)
      self.connect( id_enc, id_mod )

      id_mod_conj = gr.conjugate_cc(dsubc)
      self.connect( id_mod, id_mod_conj )

      id_mult = blocks.multiply_vcc(dsubc)
      self.connect( id_bfilt, ( id_mult,0) )
      self.connect( id_mod_conj, ( id_mult,1) )

#      id_mult_avg = filter.single_pole_iir_filter_cc(0.01,dsubc)
#      self.connect( id_mult, id_mult_avg )

      id_phase = gr.complex_to_arg(dsubc)
      self.connect( id_mult, id_phase )

      log_to_file( self, id_phase, "data/id_phase.float" )

      est=ofdm.LS_estimator_straight_slope(dsubc)
      self.connect(id_phase,est)

      slope=blocks.multiply_const_ff(1e6/2/3.14159265)
      self.connect( (est,0), slope )

      log_to_file( self, slope, "data/slope.float" )
      log_to_file( self, (est,1), "data/offset.float" )

    # ------------------------------------------------------------------------ #




    # Display some information about the setup
    if config._verbose:
      self._print_verbage()

    ## debug logging ##
    if options.log:
#      log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.compl")
#      log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.float",mag=True)


      fftlen = 256
      my_window = window.hamming(fftlen) #.blackmanharris(fftlen)
      rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen)
      rxs_sampler_vect = concatenate([[1],[0]*49])
      rxs_trigger = blocks.vector_source_b(rxs_sampler_vect.tolist(),True)
      rxs_window = blocks.multiply_const_vcc(my_window)
      rxs_spectrum = gr.fft_vcc(fftlen,True,[],True)
      rxs_mag = gr.complex_to_mag(fftlen)
      rxs_avg = filter.single_pole_iir_filter_ff(0.01,fftlen)
      #rxs_logdb = blocks.nlog10_ff(20.0,fftlen,-20*log10(fftlen))
      rxs_logdb = gr.kludge_copy( gr.sizeof_float * fftlen )
      rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,1)
      self.connect(rxs_trigger,(rxs_sampler,1))
      self.connect(self.input,rxs_sampler,rxs_window,
                   rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate)
      log_to_file( self, rxs_decimate_rate, "data/psd_input.float" )


    #output branches
    self.publish_rx_performance_measure()
コード例 #42
0
    def __init__(self, fft_length, cp_length, snr, kstime, logging):
        ''' Maximum Likelihood OFDM synchronizer:
        J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation
        of Time and Frequency Offset in OFDM Systems," IEEE Trans.
        Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997.
        '''

	gr.hier_block2.__init__(self, "ofdm_sync_ml",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature

        self.input = gr.add_const_cc(0)

        SNR = 10.0**(snr/10.0)
        rho = SNR / (SNR + 1.0)
        symbol_length = fft_length + cp_length

        # ML Sync

        # Energy Detection from ML Sync

        self.connect(self, self.input)

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length)
        self.connect(self.input, self.delay)

        # magnitude squared blocks
        self.magsqrd1 = gr.complex_to_mag_squared()
        self.magsqrd2 = gr.complex_to_mag_squared()
        self.adder = gr.add_ff()

        moving_sum_taps = [rho/2 for i in range(cp_length)]
        self.moving_sum_filter = gr.fir_filter_fff(1,moving_sum_taps)
        
        self.connect(self.input,self.magsqrd1)
        self.connect(self.delay,self.magsqrd2)
        self.connect(self.magsqrd1,(self.adder,0))
        self.connect(self.magsqrd2,(self.adder,1))
        self.connect(self.adder,self.moving_sum_filter)
        

        # Correlation from ML Sync
        self.conjg = gr.conjugate_cc();
        self.mixer = gr.multiply_cc();

        movingsum2_taps = [1.0 for i in range(cp_length)]
        self.movingsum2 = gr.fir_filter_ccf(1,movingsum2_taps)
        
        # Correlator data handler
        self.c2mag = gr.complex_to_mag()
        self.angle = gr.complex_to_arg()
        self.connect(self.input,(self.mixer,1))
        self.connect(self.delay,self.conjg,(self.mixer,0))
        self.connect(self.mixer,self.movingsum2,self.c2mag)
        self.connect(self.movingsum2,self.angle)

        # ML Sync output arg, need to find maximum point of this
        self.diff = gr.sub_ff()
        self.connect(self.c2mag,(self.diff,0))
        self.connect(self.moving_sum_filter,(self.diff,1))

        #ML measurements input to sampler block and detect
        self.f2c = gr.float_to_complex()
        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
        self.sample_and_hold = gr.sample_and_hold_ff()

        # use the sync loop values to set the sampler and the NCO
        #     self.diff = theta
        #     self.angle = epsilon
                          
        self.connect(self.diff, self.pk_detect)

        # The DPLL corrects for timing differences between CP correlations
        use_dpll = 0
        if use_dpll:
            self.dpll = gr.dpll_bb(float(symbol_length),0.01)
            self.connect(self.pk_detect, self.dpll)
            self.connect(self.dpll, (self.sample_and_hold,1))
        else:
            self.connect(self.pk_detect, (self.sample_and_hold,1))
            
        self.connect(self.angle, (self.sample_and_hold,0))

        ################################
        # correlate against known symbol
        # This gives us the same timing signal as the PN sync block only on the preamble
        # we don't use the signal generated from the CP correlation because we don't want
        # to readjust the timing in the middle of the packet or we ruin the equalizer settings.
        kstime = [k.conjugate() for k in kstime]
        kstime.reverse()
        self.kscorr = gr.fir_filter_ccc(1, kstime)
        self.corrmag = gr.complex_to_mag_squared()
        self.div = gr.divide_ff()

        # The output signature of the correlation has a few spikes because the rest of the
        # system uses the repeated preamble symbol. It needs to work that generically if 
        # anyone wants to use this against a WiMAX-like signal since it, too, repeats.
        # The output theta of the correlator above is multiplied with this correlation to
        # identify the proper peak and remove other products in this cross-correlation
        self.threshold_factor = 0.1
        self.slice = gr.threshold_ff(self.threshold_factor, self.threshold_factor, 0)
        self.f2b = gr.float_to_char()
        self.b2f = gr.char_to_float()
        self.mul = gr.multiply_ff()
        
        # Normalize the power of the corr output by the energy. This is not really needed
        # and could be removed for performance, but it makes for a cleaner signal.
        # if this is removed, the threshold value needs adjustment.
        self.connect(self.input, self.kscorr, self.corrmag, (self.div,0))
        self.connect(self.moving_sum_filter, (self.div,1))
        
        self.connect(self.div, (self.mul,0))
        self.connect(self.pk_detect, self.b2f, (self.mul,1))
        self.connect(self.mul, self.slice)
        
        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self,0))
        self.connect(self.slice, self.f2b, (self,1))


        if logging:
            self.connect(self.moving_sum_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-energy_f.dat"))
            self.connect(self.diff, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-theta_f.dat"))
            self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-epsilon_f.dat"))
            self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-corrmag_f.dat"))
            self.connect(self.kscorr, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-kscorr_c.dat"))
            self.connect(self.div, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-div_f.dat"))
            self.connect(self.mul, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-mul_f.dat"))
            self.connect(self.slice, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-slice_f.dat"))
            self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-peaks_b.dat"))
            if use_dpll:
                self.connect(self.dpll, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-dpll_b.dat"))

            self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat"))
            self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-input_c.dat"))
コード例 #43
0
ファイル: fbmc_transmit_path.py プロジェクト: rwth-ti/gr-ofdm
    def __init__(self, options):
        gr.hier_block2.__init__(
            self, "fbmc_transmit_path", gr.io_signature(0, 0, 0), gr.io_signature(1, 1, gr.sizeof_gr_complex)
        )

        common_options.defaults(options)

        config = self.config = station_configuration()

        config.data_subcarriers = options.subcarriers
        config.cp_length = 0
        config.frame_data_blocks = options.data_blocks
        config._verbose = options.verbose
        config.fft_length = options.fft_length
        config.dc_null = options.dc_null
        config.training_data = default_block_header(config.data_subcarriers, config.fft_length, config.dc_null, options)
        config.coding = options.coding
        config.fbmc = options.fbmc
        config.adaptive_fbmc = options.adaptive_fbmc

        config.frame_id_blocks = 1  # FIXME

        # digital rms amplitude sent to USRP
        rms_amp = options.rms_amplitude
        self._options = copy.copy(options)

        config.block_length = config.fft_length + config.cp_length
        config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
        config.frame_length = config.training_data.fbmc_no_preambles + 2 * config.frame_data_part
        config.subcarriers = config.data_subcarriers + config.training_data.pilot_subcarriers
        config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null

        # default values if parameters not set
        if rms_amp is None:
            rms_amp = math.sqrt(config.subcarriers)
        config.rms_amplitude = rms_amp

        # check some bounds
        if config.fft_length < config.subcarriers:
            raise SystemError, "Subcarrier number must be less than FFT length"
        if config.fft_length < config.cp_length:
            raise SystemError, "Cyclic prefix length must be less than FFT length"

        ## shortcuts
        blen = config.block_length
        flen = config.frame_length
        dsubc = config.data_subcarriers
        vsubc = config.virtual_subcarriers

        # Adaptive Transmitter Concept

        used_id_bits = config.used_id_bits = 8  # TODO: no constant in source code
        rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits  # BPSK
        if config.data_subcarriers % used_id_bits <> 0:
            raise SystemError, "Data subcarriers need to be multiple of %d" % (used_id_bits)

        ## Allocation Control
        self.allocation_src = allocation_src(
            config.data_subcarriers,
            config.frame_data_blocks,
            config.coding,
            "tcp://*:3333",
            "tcp://" + options.rx_hostname + ":3322",
        )
        if options.static_allocation:  # DEBUG
            # how many bits per subcarrier

            if options.coding:
                mode = 1  # Coding mode 1-9
                bitspermode = [0.5, 1, 1.5, 2, 3, 4, 4.5, 5, 6]  # Information bits per mode
                modulbitspermode = [1, 2, 2, 4, 4, 6, 6, 6, 8]  # Coding bits per mode
                bitcount_vec = [(int)(config.data_subcarriers * config.frame_data_blocks * bitspermode[mode - 1])]
                modul_bitcount_vec = [config.data_subcarriers * config.frame_data_blocks * modulbitspermode[mode - 1]]
                bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1)
                modul_bitcount_src = blocks.vector_source_i(modul_bitcount_vec, True, 1)
                bitloading = mode
            else:
                bitloading = 1
                bitcount_vec = [config.data_subcarriers * config.frame_data_blocks * bitloading]
                bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1)
                modul_bitcount_src = bitcount_src
            # id's for frames
            id_vec = range(0, 256)
            id_src = blocks.vector_source_s(id_vec, True, 1)
            # bitloading for ID symbol and then once for data symbols
            # bitloading_vec = [1]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2)

            test_allocation = (
                [bitloading] * (int)(config.data_subcarriers / 8)
                + [0] * (int)(config.data_subcarriers / 4 * 3)
                + [bitloading] * (int)(config.data_subcarriers / 8)
            )
            # bitloading_vec = [1]*dsubc+[bitloading]*dsubc
            bitloading_vec = [1] * dsubc + test_allocation
            bitloading_src = blocks.vector_source_b(bitloading_vec, True, dsubc)
            # bitcount for frames
            # bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading]
            bitcount_vec = [config.frame_data_blocks * sum(test_allocation)]
            bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1)
            # power loading, here same for all symbols
            power_vec = (
                [1] * (int)(config.data_subcarriers / 8)
                + [0] * (int)(config.data_subcarriers / 4 * 3)
                + [1] * (int)(config.data_subcarriers / 8)
            )
            power_src = blocks.vector_source_f(power_vec, True, dsubc)
            # mux control stream to mux id and data bits
            mux_vec = [0] * dsubc + [1] * bitcount_vec[0]
            mux_ctrl = blocks.vector_source_b(mux_vec, True, 1)
        else:
            id_src = (self.allocation_src, 0)
            bitcount_src = (self.allocation_src, 4)
            bitloading_src = (self.allocation_src, 2)
            power_src = (self.allocation_src, 1)
            if options.coding:
                modul_bitcount_src = (self.allocation_src, 5)
            else:
                modul_bitcount_src = bitcount_src
            mux_ctrl = ofdm.tx_mux_ctrl(dsubc)
            self.connect(modul_bitcount_src, mux_ctrl)
            # Initial allocation
            self.allocation_src.set_allocation([4] * config.data_subcarriers, [1] * config.data_subcarriers)
            if options.benchmarking:
                self.allocation_src.set_allocation([4] * config.data_subcarriers, [1] * config.data_subcarriers)

        if options.lab_special_case:
            self.allocation_src.set_allocation(
                [0] * (config.data_subcarriers / 4)
                + [2] * (config.data_subcarriers / 2)
                + [0] * (config.data_subcarriers / 4),
                [1] * config.data_subcarriers,
            )

        if options.log:
            log_to_file(self, id_src, "data/id_src.short")
            log_to_file(self, bitcount_src, "data/bitcount_src.int")
            log_to_file(self, bitloading_src, "data/bitloading_src.char")
            log_to_file(self, power_src, "data/power_src.cmplx")

        ## GUI probe output
        zmq_probe_bitloading = zeromq.pub_sink(gr.sizeof_char, dsubc, "tcp://*:4445")
        # also skip ID symbol bitloading with keep_one_in_n (side effect)
        # factor 2 for bitloading because we have two vectors per frame, one for id symbol and one for all payload/data symbols
        # factor config.frame_data_part for power because there is one vector per ofdm symbol per frame
        self.connect(bitloading_src, blocks.keep_one_in_n(gr.sizeof_char * dsubc, 2 * 40), zmq_probe_bitloading)
        zmq_probe_power = zeromq.pub_sink(gr.sizeof_float, dsubc, "tcp://*:4444")
        # self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_gr_complex*dsubc,40), blocks.complex_to_real(dsubc), zmq_probe_power)
        self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_float * dsubc, 40), zmq_probe_power)

        ## Workaround to avoid periodic structure
        seed(1)
        whitener_pn = [randint(0, 1) for i in range(used_id_bits * rep_id_bits)]

        ## ID Encoder
        id_enc = self._id_encoder = repetition_encoder_sb(used_id_bits, rep_id_bits, whitener_pn)
        self.connect(id_src, id_enc)

        if options.log:
            id_enc_f = gr.char_to_float()
            self.connect(id_enc, id_enc_f)
            log_to_file(self, id_enc_f, "data/id_enc_out.float")

        ## Reference Data Source
        ber_ref_src = ber_reference_source(self._options)
        self.connect(id_src, (ber_ref_src, 0))
        self.connect(bitcount_src, (ber_ref_src, 1))

        if options.log:
            log_to_file(self, ber_ref_src, "data/ber_rec_src_tx.char")

        if options.log:
            log_to_file(self, btrig, "data/bitmap_trig.char")

        ## Frame Trigger
        ftrig_stream = [1] + [0] * (config.frame_data_part - 1)
        ftrig = self._frame_trigger = blocks.vector_source_b(ftrig_stream, True)

        ## Data Multiplexer
        # Input 0: control stream
        # Input 1: encoded ID stream
        # Inputs 2..n: data streams
        dmux = self._data_multiplexer = stream_controlled_mux_b()
        self.connect(mux_ctrl, (dmux, 0))
        self.connect(id_enc, (dmux, 1))

        if options.coding:
            fo = trellis.fsm(1, 2, [91, 121])
            encoder = self._encoder = trellis.encoder_bb(fo, 0)
            unpack = self._unpack = blocks.unpack_k_bits_bb(2)
            self.connect(ber_ref_src, encoder, unpack)

            if options.interleave:
                int_object = trellis.interleaver(2000, 666)
                interlv = trellis.permutation(int_object.K(), int_object.INTER(), 1, gr.sizeof_char)

            if not options.nopunct:
                bmaptrig_stream_puncturing = [1] + [0] * (config.frame_data_blocks / 2 - 1)
                btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b(
                    bmaptrig_stream_puncturing, True
                )
                puncturing = self._puncturing = puncture_bb(config.data_subcarriers)
                self.connect(bitloading_src, (puncturing, 1))
                self.connect(self._bitmap_trigger_puncturing, (puncturing, 2))
                self.connect(unpack, puncturing)
                last_block = puncturing

                if options.interleave:
                    self.connect(last_block, interlv)
                    last_block = interlv

                if options.benchmarking:
                    self.connect(last_block, blocks.head(gr.sizeof_char, options.N), (dmux, 2))
                else:
                    self.connect(last_block, (dmux, 2))
            else:
                if options.benchmarking:
                    self.connect(unpack, blocks.head(gr.sizeof_char, options.N), (dmux, 2))
                else:
                    self.connect(unpack, (dmux, 2))

        else:
            if options.benchmarking:
                self.connect(ber_ref_src, blocks.head(gr.sizeof_char, options.N), (dmux, 2))
            else:
                self.connect(ber_ref_src, (dmux, 2))

        if options.log:
            dmux_f = gr.char_to_float()
            self.connect(dmux, dmux_f)
            log_to_file(self, dmux_f, "data/dmux_out.float")

        ## Modulator
        mod = self._modulator = generic_mapper_bcv(config.data_subcarriers, config.coding, config.frame_data_part)
        self.connect(dmux, (mod, 0))
        self.connect(bitloading_src, (mod, 1))

        if options.log:
            log_to_file(self, mod, "data/mod_out.compl")
            modi = blocks.complex_to_imag(config.data_subcarriers)
            modr = blocks.complex_to_real(config.data_subcarriers)
            self.connect(mod, modi)
            self.connect(mod, modr)
            log_to_file(self, modi, "data/mod_imag_out.float")
            log_to_file(self, modr, "data/mod_real_out.float")

        ## Power allocator
        pa = self._power_allocator = multiply_frame_fc(config.frame_data_part, config.data_subcarriers)
        self.connect(mod, (pa, 0))
        self.connect(power_src, (pa, 1))

        if options.log:
            log_to_file(self, pa, "data/pa_out.compl")

        if options.fbmc:
            psubc = pa
        else:
            psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter()
            self.connect(pa, psubc)

            if options.log:
                log_to_file(self, psubc, "data/psubc_out.compl")

        subcarriers = config.subcarriers

        # fbmc_pblocks_timing = self._fbmc_timing_pilot_block_inserter = fbmc_timing_pilot_block_inserter(5,False)

        oqam_prep = self._oqam_prep = fbmc_oqam_preprocessing_vcvc(config.subcarriers, 0, 0)
        self.connect(psubc, oqam_prep)

        fbmc_pblocks = self._fbmc_pilot_block_inserter = fbmc_pilot_block_inserter(5, False)
        self.connect(oqam_prep, fbmc_pblocks)
        # log_to_file(self, fbmc_pblocks, "data/fbmc_pblocks_out.compl")
        # fbmc_insert_pream = self._fbmc_insert_pream = fbmc_insert_preamble_vcvc(M, syms_per_frame, preamble)
        # log_to_file(self, oqam_prep, "data/oqam_prep.compl")
        # log_to_file(self, psubc, "data/psubc_out.compl")
        # fbmc_pblocks = fbmc_pblocks_timing
        # log_to_file(self, fbmc_pblocks, "data/fbmc_pblocks_out.compl")

        beta_mult = self._beta_mult = fbmc_beta_multiplier_vcvc(config.subcarriers, 4, 4 * config.fft_length - 1, 0)
        self.connect(fbmc_pblocks, beta_mult)
        log_to_file(self, beta_mult, "data/beta_mult.compl")

        ## Add virtual subcarriers
        if config.fft_length > subcarriers:
            vsubc = self._virtual_subcarrier_extender = vector_padding_dc_null(
                config.subcarriers, config.fft_length, config.dc_null
            )
            self.connect(beta_mult, vsubc)
        else:
            vsubc = self._virtual_subcarrier_extender = beta_mult

        if options.log:
            log_to_file(self, vsubc, "data/vsubc_out.compl")

        ## IFFT, no window, block shift
        ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [], True)
        self.connect(vsubc, ifft)

        if options.log:
            log_to_file(self, ifft, "data/ifft_out.compl")

        # FBMC separate stream + filterbanks
        separate_oqam = self._separate_oqam = fbmc_separate_vcvc(config.fft_length, 2)
        poly_netw_1 = self._poly_netw_1 = fbmc_polyphase_network_vcvc(
            config.fft_length, 4, 4 * config.fft_length - 1, False
        )
        poly_netw_2 = self._poly_netw_2 = fbmc_polyphase_network_vcvc(
            config.fft_length, 4, 4 * config.fft_length - 1, False
        )
        overlap_p2s = self._overlap_p2s = fbmc_overlapping_parallel_to_serial_vcc(config.fft_length)

        self.connect(ifft, (separate_oqam, 0), poly_netw_1)
        self.connect((separate_oqam, 1), poly_netw_2)
        self.connect(poly_netw_1, (overlap_p2s, 0))
        self.connect(poly_netw_2, (overlap_p2s, 1))

        ## Pilot blocks (preambles)
        # pblocks = self._pilot_block_inserter = pilot_block_inserter2(5,False)
        # self.connect( overlap_p2s, blocks.stream_to_vector(gr.sizeof_gr_complex,config.fft_length/2),  pblocks )

        # log_to_file(self, pblocks, "data/fbmc_pilot_block_ins_out.compl")

        if options.log:
            log_to_file(self, pblocks, "data/pilot_block_ins_out.compl")

        ## Cyclic Prefix
        # cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length,
        # config.block_length)

        # cp= blocks.vector_to_stream(gr.sizeof_gr_complex, config.fft_length/2)
        # self.connect(pblocks, cp )
        # self.connect( overlap_p2s,blocks.stream_to_vector(gr.sizeof_gr_complex,config.fft_length/2), cp )

        lastblock = overlap_p2s

        if options.log:
            log_to_file(self, overlap_p2s, "data/overlap_p2s_out.compl")

        # Digital Amplifier for resource allocation
        if config.adaptive_fbmc:
            rep = blocks.repeat(gr.sizeof_gr_complex, config.frame_length * config.block_length)
            amp = blocks.multiply_cc()
            self.connect(lastblock, (amp, 0))
            self.connect((self.allocation_src, 3), rep, (amp, 1))
            lastblock = amp
        else:
            self.connect((self.allocation_src, 3), blocks.null_sink(gr.sizeof_gr_complex))

        ## Digital Amplifier
        # amp = self._amplifier = gr.multiply_const_cc(1)
        amp = self._amplifier = ofdm.multiply_const_ccf(1.0)
        self.connect(lastblock, amp)
        self.set_rms_amplitude(rms_amp)
        # log_to_file(self, amp, "data/amp_tx_out.compl")

        if options.log:
            log_to_file(self, amp, "data/amp_tx_out.compl")

        ## Tx parameters
        bandwidth = options.bandwidth or 2e6
        bits = 8 * config.data_subcarriers * config.frame_data_blocks  # max. QAM256
        samples_per_frame = config.frame_length * config.block_length
        tb = samples_per_frame / bandwidth
        # set dummy carrier frequency if none available due to baseband mode
        if options.tx_freq is None:
            options.tx_freq = 0.0
        self.tx_parameters = {
            "carrier_frequency": options.tx_freq / 1e9,
            "fft_size": config.fft_length,
            "cp_size": config.cp_length,
            "subcarrier_spacing": options.bandwidth / config.fft_length / 1e3,
            "data_subcarriers": config.data_subcarriers,
            "bandwidth": options.bandwidth / 1e6,
            "frame_length": config.frame_length,
            "symbol_time": (config.cp_length + config.fft_length) / options.bandwidth * 1e6,
            "max_data_rate": (bits / tb) / 1e6,
        }

        ## Setup Output
        self.connect(amp, self)

        # Display some information about the setup
        if config._verbose:
            self._print_verbage()
コード例 #44
0
  def __init__(self, options):
    gr.hier_block2.__init__(self, "transmit_path",
        gr.io_signature(0,0,0),
        gr.io_signature(2,2,gr.sizeof_gr_complex))

    common_options.defaults(options)

    config = self.config = station_configuration()

    config.data_subcarriers    = options.subcarriers
    config.cp_length           = options.cp_length
    config.frame_data_blocks   = options.data_blocks
    config._verbose            = options.verbose
    config.fft_length          = options.fft_length
    config.training_data       = default_block_header(config.data_subcarriers,
                                          config.fft_length,options)
    config.tx_station_id       = options.station_id
    config.coding              = options.coding
    

    if config.tx_station_id is None:
      raise SystemError, "Station ID not set"

    config.frame_id_blocks     = 1 # FIXME

    # digital rms amplitude sent to USRP
    rms_amp                    = options.rms_amplitude
    self._options              = copy.copy(options)

    self.servants = [] # FIXME

    config.block_length = config.fft_length + config.cp_length
    config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
    config.frame_length = config.frame_data_part + \
                          config.training_data.no_pilotsyms
    config.subcarriers = config.data_subcarriers + \
                         config.training_data.pilot_subcarriers
    config.virtual_subcarriers = config.fft_length - config.subcarriers

    # default values if parameters not set
    if rms_amp is None:
      rms_amp = math.sqrt(config.subcarriers)
    config.rms_amplitude = rms_amp

    # check some bounds
    if config.fft_length < config.subcarriers:
      raise SystemError, "Subcarrier number must be less than FFT length"
    if config.fft_length < config.cp_length:
      raise SystemError, "Cyclic prefix length must be less than FFT length"

    ## shortcuts
    blen = config.block_length
    flen = config.frame_length
    dsubc = config.data_subcarriers
    vsubc = config.virtual_subcarriers


    # ------------------------------------------------------------------------ #
    # Adaptive Transmitter Concept

    used_id_bits = config.used_id_bits = 8 #TODO: no constant in source code
    rep_id_bits = config.rep_id_bits = config.data_subcarriers/used_id_bits #BPSK
    if config.data_subcarriers % used_id_bits <> 0:
      raise SystemError,"Data subcarriers need to be multiple of %d" % (used_id_bits)


    ## Control Part
    if options.debug:
      self._control = ctrl = static_tx_control(options)
      print "Statix TX Control used"
    else:
      self._control = ctrl = corba_tx_control(options)
      print "CORBA TX Control used"

    id_src = (ctrl,0)
    mux_src = (ctrl,1)
    map_src = self._map_src = (ctrl,2)
    pa_src = (ctrl,3)


    if options.log:
      id_src_f = gr.short_to_float()
      self.connect(id_src,id_src_f)
      log_to_file(self, id_src_f, "data/id_src_out.float")

      mux_src_f = gr.short_to_float()
      self.connect(mux_src,mux_src_f)
      log_to_file(self, mux_src_f, "data/mux_src_out.float")

      map_src_s = blocks.vector_to_stream(gr.sizeof_char,config.data_subcarriers)
      map_src_f = gr.char_to_float()
      self.connect(map_src,map_src_s,map_src_f)
      ##log_to_file(self, map_src_f, "data/map_src.float")

      ##log_to_file(self, pa_src, "data/pa_src_out.float")

    ## Workaround to avoid periodic structure
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

    ## ID Encoder
    id_enc = self._id_encoder = repetition_encoder_sb(used_id_bits,rep_id_bits,whitener_pn)
    self.connect(id_src,id_enc)

    if options.log:
      id_enc_f = gr.char_to_float()
      self.connect(id_enc,id_enc_f)
      log_to_file(self, id_enc_f, "data/id_enc_out.float")

    ## Bitmap Update Trigger
    # TODO
    #bmaptrig_stream = concatenate([[1, 2],[0]*(config.frame_data_part-7)])
    bmaptrig_stream = concatenate([[1, 1],[0]*(config.frame_data_part-2)])
    print"bmaptrig_stream = ",bmaptrig_stream
    btrig = self._bitmap_trigger = blocks.vector_source_b(bmaptrig_stream.tolist(), True)
    if options.log:
      log_to_file(self, btrig, "data/bitmap_trig.char")
      
    ## Bitmap Update Trigger for puncturing
    # TODO
    if not options.nopunct:
        #bmaptrig_stream_puncturing = concatenate([[1],[0]*(config.frame_data_part-2)])
        bmaptrig_stream_puncturing = concatenate([[1],[0]*(config.frame_data_blocks/2-1)])
        
        btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b(bmaptrig_stream_puncturing.tolist(), True)
        bmapsrc_stream_puncturing = concatenate([[1]*dsubc,[2]*dsubc])
        bsrc_puncturing = self._bitmap_src_puncturing = blocks.vector_source_b(bmapsrc_stream_puncturing.tolist(), True, dsubc)
        
    if options.log and options.coding and not options.nopunct:
      log_to_file(self, btrig_puncturing, "data/bitmap_trig_puncturing.char")

    ## Frame Trigger
    # TODO
    ftrig_stream = concatenate([[1],[0]*(config.frame_data_part-1)])
    ftrig = self._frame_trigger = blocks.vector_source_b(ftrig_stream.tolist(),True)

    ## Data Multiplexer
    # Input 0: control stream
    # Input 1: encoded ID stream
    # Inputs 2..n: data streams
    dmux = self._data_multiplexer = stream_controlled_mux_b()
    self.connect(mux_src,(dmux,0))
    self.connect(id_enc,(dmux,1))
                      
    self._data_multiplexer_nextport = 2

    if options.log:
      dmux_f = gr.char_to_float()
      self.connect(dmux,dmux_f)
      log_to_file(self, dmux_f, "data/dmux_out.float")
      
    ## Modulator
    mod = self._modulator = generic_mapper_bcv(config.data_subcarriers,options.coding)



    self.connect(dmux,(mod,0))
    self.connect(map_src,(mod,1))
    self.connect(btrig,(mod,2))
    
    if options.log:
      log_to_file(self, mod, "data/mod_out.compl")
      modi = gr.complex_to_imag(config.data_subcarriers)
      modr = gr.complex_to_real(config.data_subcarriers)
      self.connect(mod,modi)
      self.connect(mod,modr)
      log_to_file(self, modi, "data/mod_imag_out.float")
      log_to_file(self, modr, "data/mod_real_out.float")



    ## Power allocator
    if options.debug:

      ## static
      pa = self._power_allocator = power_allocator(config.data_subcarriers)
      self.connect(mod,(pa,0))
      self.connect(pa_src,(pa,1))

    else:

      ## with CORBA control event channel
      ns_ip = ctrl.ns_ip
      ns_port = ctrl.ns_port
      evchan = ctrl.evchan
      pa = self._power_allocator = corba_power_allocator(dsubc, \
          evchan, ns_ip, ns_port, True)

      self.connect(mod,(pa,0))
      self.connect(id_src,(pa,1))
      self.connect(ftrig,(pa,2))

    if options.log:
      log_to_file(self, pa, "data/pa_out.compl")



    ## Pilot subcarriers
    psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter()
    self.connect( pa ,psubc )
        
    pilot_subc = config.training_data.shifted_pilot_tones;
    print "pilot_subc", pilot_subc
    stc = stc_encoder( config.subcarriers, config.frame_data_blocks,  pilot_subc )
    
    self.connect(psubc, stc)
    
    if options.log:
      log_to_file(self, psubc, "data/psubc_out.compl")
      log_to_file(self, psubc_2, "data/psubc2_out.compl")
      log_to_file(self, pa, "data/pa.compl")
      log_to_file(self, ( stc, 0 ), "data/stc_0.compl")
      log_to_file(self, ( stc, 1 ), "data/stc_1.compl")

    ## Add virtual subcarriers
    if config.fft_length > config.subcarriers:
      vsubc = self._virtual_subcarrier_extender = \
              vector_padding(config.subcarriers, config.fft_length)
      self.connect(stc,vsubc)
      vsubc_2 = self._virtual_subcarrier_extender_2 = \
              vector_padding(config.subcarriers, config.fft_length)
      self.connect((stc,1),vsubc_2)
    else:
      vsubc = self._virtual_subcarrier_extender = psubc
      vsubc_2 = self._virtual_subcarrier_extender_2 = psubc_2
      
    log_to_file(self, psubc, "data/psubc.compl")
    log_to_file(self, stc, "data/stc1.compl")
    log_to_file(self, (stc,1), "data/stc2.compl")
    if options.log:
      log_to_file(self, vsubc, "data/vsubc_out.compl")
      log_to_file(self, vsubc_2, "data/vsubc2_out.compl")

    
    ## IFFT, no window, block shift
    ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length,False,[],True)
    self.connect(vsubc,ifft)
    ifft_2 = self._ifft_2 = fft_blocks.fft_vcc(config.fft_length,False,[],True)
    self.connect(vsubc_2,ifft_2)

    if options.log:
      log_to_file(self, ifft, "data/ifft_out.compl")
      log_to_file(self, ifft_2, "data/ifft2_out.compl")


    ## Pilot blocks (preambles)
    pblocks = self._pilot_block_inserter = pilot_block_inserter(1, False)
    self.connect( ifft, pblocks )
    pblocks_2 = self._pilot_block_inserter_2 = pilot_block_inserter( 2, False)
    self.connect( ifft_2, pblocks_2 )
    
    if options.log:
      log_to_file(self, pblocks, "data/pilot_block_ins_out.compl")
      log_to_file(self, pblocks_2, "data/pilot_block_ins2_out.compl")
    
    ## Cyclic Prefix
    cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length,
                                                 config.block_length)
    self.connect( pblocks, cp )
    cp_2 = self._cyclic_prefixer_2 = cyclic_prefixer(config.fft_length,
                                                 config.block_length)
    self.connect( pblocks_2, cp_2 )
    
    lastblock = cp
    lastblock_2 = cp_2

    
    if options.log:
      log_to_file(self, cp, "data/cp_out.compl")
      log_to_file(self, cp_2, "data/cp2_out.compl")


    if options.cheat:
      ## Artificial Channel
      # kept to compare with previous system
      achan_ir = concatenate([[1.0],[0.0]*(config.cp_length-1)])
      achan = self._artificial_channel = gr.fir_filter_ccc(1,achan_ir)
      self.connect( lastblock, achan )
      lastblock = achan
      achan_2 = self._artificial_channel_2 = gr.fir_filter_ccc(1,achan_ir)
      self.connect( lastblock_2, achan_2 )
      lastblock_2 = achan_2


    ## Digital Amplifier
    amp = self._amplifier = ofdm.multiply_const_ccf( 1.0/math.sqrt(2) )
    self.connect( lastblock, amp )
    amp_2 = self._amplifier_2 = ofdm.multiply_const_ccf( 1.0/math.sqrt(2) )
    self.connect( lastblock_2, amp_2 )
    self.set_rms_amplitude(rms_amp)
    
    if options.log:
      log_to_file(self, amp, "data/amp_tx_out.compl")
      log_to_file(self, amp_2, "data/amp_tx2_out.compl")

    ## Setup Output
    self.connect(amp,(self,0))
    self.connect(amp_2,(self,1))

    # ------------------------------------------------------------------------ #

    # Display some information about the setup
    if config._verbose:
      self._print_verbage()