def test_sub_ff_2 (self):
     src1_data = (1,  2, 3, 4, 5)
     src2_data = (8, -3, 4, 8, 2)
     expected_result = (-7, 5, -1, -4, 3)
     op = gr.sub_ff (2)
     self.help_ff ((src1_data, src2_data),
                   expected_result, op, port_prefix='float_in_')
    def __init__(self, *args, **kwargs):
        """
        Hierarchical block for O-QPSK demodulation.

        The input is the complex modulated signal at baseband
        and the output is a stream of bytes.

        @param sps: samples per symbol
        @type sps: integer
        """
        try:
            self.sps = kwargs.pop('sps')
            self.log = kwargs.pop('log')
        except KeyError:
            pass

        gr.hier_block2.__init__(
            self,
            "ieee802_15_4_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input
            gr.io_signature(1, 1, gr.sizeof_float))  # Output

        # Demodulate FM
        sensitivity = (pi / 2) / self.sps
        #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)
        self.fmdemod = gr.quadrature_demod_cf(1)

        # Low pass the output of fmdemod to allow us to remove
        # the DC offset resulting from frequency offset

        alpha = 0.0008 / self.sps
        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        self.connect(self, self.fmdemod)
        self.connect(self.fmdemod, (self.sub, 0))
        self.connect(self.fmdemod, self.freq_offset, (self.sub, 1))

        # recover the clock
        omega = self.sps
        gain_mu = 0.03
        mu = 0.5
        omega_relative_limit = 0.0002
        freq_error = 0.0

        gain_omega = .25 * gain_mu * gain_mu  # critically damped
        self.clock_recovery = digital.clock_recovery_mm_ff(
            omega, gain_omega, mu, gain_mu, omega_relative_limit)

        # Connect
        self.connect(self.sub, self.clock_recovery, self)

        if self.log:
            self.connect(self.fmdemod,
                         gr.file_sink(gr.sizeof_float, 'rx-fmdemod.dat'))
            self.connect(self.freq_offset,
                         gr.file_sink(gr.sizeof_float, 'rx-fo.dat'))
            self.connect(self.sub, gr.file_sink(gr.sizeof_float, 'rx-sub.dat'))
            self.connect(self.clock_recovery,
                         gr.file_sink(gr.sizeof_float, 'rx-recovery.dat'))
Exemple #3
0
 def test_sub_ff_1(self):
     src1_data = (-1.0, 2.25, -3.5, 4, -5)
     expected_result = (1, -2.25, 3.5, -4, 5)
     op = gr.sub_ff(1)
     self.help_ff((src1_data, ),
                  expected_result,
                  op,
                  port_prefix='SINGLE_PORT')
 def test_sub_ff_3 (self):
     src1_data = (1,  2, 3, 4, 5)
     src2_data = (8, -3, 4, 8, 2)
     src3_data = (-8, 3, 4, -8, -2)
     expected_result = (1, 2, -5, 4, 5)
     op = gr.sub_ff (3)
     self.help_ff ((src1_data, src2_data, src3_data),
                   expected_result, op, port_prefix='float_in_')
 def test_sub_ff_4 (self):
     src1_data = (1,  2, 3, 4, 5)
     src2_data = (8, -3, 4, 8, 2)
     src3_data = (-8, 3, 4, -8, -2)
     src4_data = (-1, 2, 3, -4, -5)
     expected_result = (2, 0, -8, 8, 10)
     op = gr.sub_ff (4)
     self.help_ff ((src1_data, src2_data, src3_data, src4_data),
                   expected_result, op, port_prefix='float_in_')
Exemple #6
0
 def test_sub_ff_2(self):
     src1_data = (1, 2, 3, 4, 5)
     src2_data = (8, -3, 4, 8, 2)
     expected_result = (-7, 5, -1, -4, 3)
     op = gr.sub_ff(2)
     self.help_ff((src1_data, src2_data),
                  expected_result,
                  op,
                  port_prefix='float_in_')
Exemple #7
0
 def test_sub_ff_3(self):
     src1_data = (1, 2, 3, 4, 5)
     src2_data = (8, -3, 4, 8, 2)
     src3_data = (-8, 3, 4, -8, -2)
     expected_result = (1, 2, -5, 4, 5)
     op = gr.sub_ff(3)
     self.help_ff((src1_data, src2_data, src3_data),
                  expected_result,
                  op,
                  port_prefix='float_in_')
Exemple #8
0
    def __init__(self):
        gr.hier_block2.__init__(self, "bit_slicer",
                                gr.io_signature(2, 2, gr.sizeof_float),
                                gr.io_signature(1, 1, gr.sizeof_char))
        diff = gr.sub_ff()
        bpsk_slicer = gr.binary_slicer_fb()

        self.connect((self, 1), (diff, 0))
        self.connect((self, 0), (diff, 1))
        self.connect(diff, bpsk_slicer, self)
    def __init__(self, *args, **kwargs):
        """
        Hierarchical block for O-QPSK demodulation.

        The input is the complex modulated signal at baseband
        and the output is a stream of bytes.

        @param sps: samples per symbol
        @type sps: integer
        """
	try:
		self.sps = kwargs.pop('sps')
                self.log = kwargs.pop('log')
	except KeyError:
		pass

	gr.hier_block2.__init__(self, "ieee802_15_4_demod",
				gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input
				gr.io_signature(1, 1, gr.sizeof_float))  # Output

        # Demodulate FM
        sensitivity = (pi / 2) / self.sps
        #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)
        self.fmdemod = gr.quadrature_demod_cf(1)

        # Low pass the output of fmdemod to allow us to remove
        # the DC offset resulting from frequency offset

        alpha = 0.0008/self.sps
        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        self.connect(self, self.fmdemod)
        self.connect(self.fmdemod, (self.sub, 0))
        self.connect(self.fmdemod, self.freq_offset, (self.sub, 1))


        # recover the clock
        omega = self.sps
        gain_mu=0.03
        mu=0.5
        omega_relative_limit=0.0002
        freq_error=0.0

        gain_omega = .25*gain_mu*gain_mu        # critically damped
        self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu,
                                                      omega_relative_limit)

        # Connect
        self.connect(self.sub, self.clock_recovery, self)

        if self.log:
            self.connect(self.fmdemod, gr.file_sink(gr.sizeof_float, 'rx-fmdemod.dat'))
            self.connect(self.freq_offset, gr.file_sink(gr.sizeof_float, 'rx-fo.dat'))
            self.connect(self.sub, gr.file_sink(gr.sizeof_float, 'rx-sub.dat'))
            self.connect(self.clock_recovery, gr.file_sink(gr.sizeof_float, 'rx-recovery.dat'))
    def __init__(self):
        gr.top_block.__init__(self, "FSK Demod Demo")

        # Variables
        self.symbol_rate = symbol_rate = 125e3
        self.samp_rate = samp_rate = symbol_rate
        self.f_center = f_center = 868e6
        self.sps = sps = 2
        self.sensitivity = sensitivity = (pi / 2) / sps
        self.alpha = alpha = 0.0512 / sps
        self.bandwidth = bandwidth = 100e3

        # Blocks
        self.uhd_usrp_source_0 = uhd.usrp_source(
            device_addr="",
            stream_args=uhd.stream_args(
                cpu_format="fc32",
                channels=range(1),
            ),
        )
        self.uhd_usrp_source_0.set_samp_rate(samp_rate)
        self.uhd_usrp_source_0.set_center_freq(f_center, 0)
        self.uhd_usrp_source_0.set_gain(0, 0)
        self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)

        self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity)

        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        self.add = gr.add_ff()
        self.multiply = gr.multiply_ff()
        self.invert = gr.multiply_const_vff((-1, ))

        # recover the clock
        omega = sps
        gain_mu = 0.03
        mu = 0.5
        omega_relative_limit = 0.0002
        freq_error = 0.0
        gain_omega = .25 * gain_mu * gain_mu  # critically damped
        self.clock_recovery = digital.clock_recovery_mm_ff(
            omega, gain_omega, mu, gain_mu, omega_relative_limit)

        self.slice = digital.binary_slicer_fb()
        self.sink = gr.vector_sink_b(1)
        self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log')

        # Connections
        self.connect(self.fm_demod, (self.add, 0))
        self.connect(self.fm_demod, self.freq_offset, (self.add, 1))
        self.connect(self.uhd_usrp_source_0, self.fm_demod)
        self.connect(self.add, self.clock_recovery, self.invert, self.slice,
                     self.file_sink)
        self.connect(self.slice, self.sink)
Exemple #11
0
 def test_sub_ff_4(self):
     src1_data = (1, 2, 3, 4, 5)
     src2_data = (8, -3, 4, 8, 2)
     src3_data = (-8, 3, 4, -8, -2)
     src4_data = (-1, 2, 3, -4, -5)
     expected_result = (2, 0, -8, 8, 10)
     op = gr.sub_ff(4)
     self.help_ff((src1_data, src2_data, src3_data, src4_data),
                  expected_result,
                  op,
                  port_prefix='float_in_')
Exemple #12
0
def main():

	print os.getpid()

	tb = gr.top_block()

        u = gr.file_source(gr.sizeof_float,"/tmp/atsc_pipe_2")

        input_rate = 19.2e6
	IF_freq = 5.75e6


	# 1/2 as wide because we're designing lp filter
	symbol_rate = atsc.ATSC_SYMBOL_RATE/2.
	NTAPS = 279
	tt = gr.firdes.root_raised_cosine (1.0, input_rate, symbol_rate, .115, NTAPS)
  # heterodyne the low pass coefficients up to the specified bandpass
  # center frequency.  Note that when we do this, the filter bandwidth
  # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
  # matches the diagram in the ATSC spec.
	arg = 2. * math.pi * IF_freq / input_rate
	t=[]
	for i in range(len(tt)):
	  t += [tt[i] * 2. * math.cos(arg * i)]
	rrc = gr.fir_filter_fff(1, t)

	fpll = atsc.fpll()

	pilot_freq = IF_freq - 3e6 + 0.31e6
	lower_edge = 6e6 - 0.31e6
	upper_edge = IF_freq - 3e6 + pilot_freq
	transition_width = upper_edge - lower_edge
	lp_coeffs = gr.firdes.low_pass (1.0,
			   input_rate,
			   (lower_edge + upper_edge) * 0.5,
                           transition_width,
                           gr.firdes.WIN_HAMMING);

	lp_filter = gr.fir_filter_fff (1,lp_coeffs)

	alpha = 1e-5
	iir = gr.single_pole_iir_filter_ff(alpha)
	remove_dc = gr.sub_ff()

	out = gr.file_sink(gr.sizeof_float,"/tmp/atsc_pipe_3")
	# out = gr.file_sink(gr.sizeof_float,"/mnt/sata/atsc_data_float")

        tb.connect(u, fpll, lp_filter)
	tb.connect(lp_filter, iir)
	tb.connect(lp_filter, (remove_dc,0))
	tb.connect(iir, (remove_dc,1))
	tb.connect(remove_dc, out)

	tb.run()
	def __init__(self):
		gr.top_block.__init__(self, "FSK Demod Demo")

		# Variables
		self.symbol_rate = symbol_rate = 125e3
		self.samp_rate = samp_rate = symbol_rate
		self.f_center = f_center = 868e6
		self.sps = sps = 2
		self.sensitivity = sensitivity = (pi / 2) / sps
		self.alpha = alpha = 0.0512/sps
		self.bandwidth = bandwidth = 100e3

		# Blocks
		self.uhd_usrp_source_0 = uhd.usrp_source(
			device_addr="",
			stream_args=uhd.stream_args(
				cpu_format="fc32",
				channels=range(1),
			),
		)
		self.uhd_usrp_source_0.set_samp_rate(samp_rate)
		self.uhd_usrp_source_0.set_center_freq(f_center, 0)
		self.uhd_usrp_source_0.set_gain(0, 0)
		self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)

		self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity)
		
		self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
		self.sub = gr.sub_ff()
		self.add = gr.add_ff()
		self.multiply = gr.multiply_ff()
		self.invert = gr.multiply_const_vff((-1, ))

		# recover the clock
		omega = sps
		gain_mu = 0.03
		mu = 0.5
		omega_relative_limit = 0.0002
		freq_error = 0.0
		gain_omega = .25 * gain_mu * gain_mu        # critically damped
		self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit)

		self.slice = digital.binary_slicer_fb()
		self.sink = gr.vector_sink_b(1)
		self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log')

		# Connections
		self.connect(self.fm_demod, (self.add, 0))
		self.connect(self.fm_demod, self.freq_offset, (self.add, 1))
		self.connect(self.uhd_usrp_source_0, self.fm_demod)
		self.connect(self.add, self.clock_recovery, self.invert, self.slice, self.file_sink)
		self.connect(self.slice, self.sink)
Exemple #14
0
    def __init__(self, fg, sps=8, symbol_rate=38400, p_size=13):
        """
        Hierarchical block for FSK demodulation.
    
        The input is the complex modulated signal at baseband
        and the output is a stream of bytes.
        
        @param fg: flow graph
        @type fg: flow graph
        @param sps: samples per symbol
        @type sps: integer
        @param symbol_rate: symbols per second
        @type symbol_rate: float
        @param p_size: packet size
        @type p_size: integer
        """

        # Demodulate FM
        sensitivity = (pi / 2) / sps
        #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)
        self.fmdemod = gr.quadrature_demod_cf(1 / sensitivity)

        # Low pass the output of fmdemod to allow us to remove
        # the DC offset resulting from frequency offset

        alpha = 0.0512 / sps
        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()

        fg.connect(self.fmdemod, (self.sub, 0))
        fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1))

        # recover the clock
        omega = sps
        gain_mu = 0.03
        mu = 0.5
        omega_relative_limit = 0.0002
        freq_error = 0.0

        gain_omega = .25 * gain_mu * gain_mu  # critically damped
        self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu,
                                                      gain_mu,
                                                      omega_relative_limit)

        # Connect
        fg.connect(self.sub, self.clock_recovery)

        #filesink = gr.file_sink(gr.sizeof_float, 'rx_fsk_test.dat')
        #fg.connect(self.clock_recovery, filesink)

        # Initialize base class
        gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery)
Exemple #15
0
	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="RTTY decoder example")

		##################################################
		# Variables
		##################################################
		self.samp_rate = samp_rate = 44100

		##################################################
		# Blocks
		##################################################
		self.wxgui_scopesink2_0 = scopesink2.scope_sink_f(
			self.GetWin(),
			title="Scope Plot",
			sample_rate=samp_rate/40,
			v_scale=1,
			v_offset=0,
			t_scale=25e-3,
			ac_couple=False,
			xy_mode=False,
			num_inputs=1,
			trig_mode=gr.gr_TRIG_MODE_AUTO,
			y_axis_label="Counts",
		)
		self.Add(self.wxgui_scopesink2_0.win)
		self.rtty_decode_ff_0 = rtty.decode_ff(
		  samp_rate=samp_rate/40, 
		  baud_rate=45.45, 
		  polarity=True,
		)
		self.low_pass_filter_0 = gr.fir_filter_fff(40, firdes.low_pass(
			100, samp_rate, 45.45*3, 20, firdes.WIN_HANN, 6.76))
		self.gr_wavfile_source_0 = gr.wavfile_source("/home/nick/Downloads/ksm_rtty.wav", False)
		self.gr_sub_xx_0 = gr.sub_ff(1)
		self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1)
		self.gr_moving_average_xx_0 = gr.moving_average_ff(5000, 1.0/5000, 20000)
		self.gr_hilbert_fc_0 = gr.hilbert_fc(64)
		self.gr_file_sink_0 = gr.file_sink(gr.sizeof_char*1, "/home/nick/Desktop/rtty/test.dat")
		self.gr_file_sink_0.set_unbuffered(False)

		##################################################
		# Connections
		##################################################
		self.connect((self.low_pass_filter_0, 0), (self.gr_moving_average_xx_0, 0))
		self.connect((self.gr_moving_average_xx_0, 0), (self.gr_sub_xx_0, 1))
		self.connect((self.gr_sub_xx_0, 0), (self.wxgui_scopesink2_0, 0))
		self.connect((self.low_pass_filter_0, 0), (self.gr_sub_xx_0, 0))
		self.connect((self.rtty_decode_ff_0, 0), (self.gr_file_sink_0, 0))
		self.connect((self.gr_sub_xx_0, 0), (self.rtty_decode_ff_0, 0))
		self.connect((self.gr_quadrature_demod_cf_0, 0), (self.low_pass_filter_0, 0))
		self.connect((self.gr_hilbert_fc_0, 0), (self.gr_quadrature_demod_cf_0, 0))
		self.connect((self.gr_wavfile_source_0, 0), (self.gr_hilbert_fc_0, 0))
Exemple #16
0
def main():

    print os.getpid()

    tb = gr.top_block()

    u = gr.file_source(gr.sizeof_float, "/tmp/atsc_pipe_2")

    input_rate = 19.2e6
    IF_freq = 5.75e6

    # 1/2 as wide because we're designing lp filter
    symbol_rate = atsc.ATSC_SYMBOL_RATE / 2.
    NTAPS = 279
    tt = gr.firdes.root_raised_cosine(1.0, input_rate, symbol_rate, .115,
                                      NTAPS)
    # heterodyne the low pass coefficients up to the specified bandpass
    # center frequency.  Note that when we do this, the filter bandwidth
    # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
    # matches the diagram in the ATSC spec.
    arg = 2. * math.pi * IF_freq / input_rate
    t = []
    for i in range(len(tt)):
        t += [tt[i] * 2. * math.cos(arg * i)]
    rrc = gr.fir_filter_fff(1, t)

    fpll = atsc.fpll()

    pilot_freq = IF_freq - 3e6 + 0.31e6
    lower_edge = 6e6 - 0.31e6
    upper_edge = IF_freq - 3e6 + pilot_freq
    transition_width = upper_edge - lower_edge
    lp_coeffs = gr.firdes.low_pass(1.0, input_rate,
                                   (lower_edge + upper_edge) * 0.5,
                                   transition_width, gr.firdes.WIN_HAMMING)

    lp_filter = gr.fir_filter_fff(1, lp_coeffs)

    alpha = 1e-5
    iir = gr.single_pole_iir_filter_ff(alpha)
    remove_dc = gr.sub_ff()

    out = gr.file_sink(gr.sizeof_float, "/tmp/atsc_pipe_3")
    # out = gr.file_sink(gr.sizeof_float,"/mnt/sata/atsc_data_float")

    tb.connect(u, fpll, lp_filter)
    tb.connect(lp_filter, iir)
    tb.connect(lp_filter, (remove_dc, 0))
    tb.connect(iir, (remove_dc, 1))
    tb.connect(remove_dc, out)

    tb.run()
Exemple #17
0
    def __init__(self, fg, sps = 8, symbol_rate = 38400, p_size = 13):
        """
        Hierarchical block for FSK demodulation.
    
        The input is the complex modulated signal at baseband
        and the output is a stream of bytes.
        
        @param fg: flow graph
        @type fg: flow graph
        @param sps: samples per symbol
        @type sps: integer
        @param symbol_rate: symbols per second
        @type symbol_rate: float
        @param p_size: packet size
        @type p_size: integer
        """
        
        # Demodulate FM
        sensitivity = (pi / 2) / sps
        #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)
        self.fmdemod = gr.quadrature_demod_cf(1 / sensitivity)

        # Low pass the output of fmdemod to allow us to remove
        # the DC offset resulting from frequency offset

        alpha = 0.0512/sps
        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        
        fg.connect(self.fmdemod, (self.sub, 0))
        fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1))
        
        
        # recover the clock
        omega = sps
        gain_mu=0.03
        mu=0.5
        omega_relative_limit=0.0002
        freq_error=0.0
        
        gain_omega = .25*gain_mu*gain_mu        # critically damped
        self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu,
                                                      omega_relative_limit)
        
        # Connect
        fg.connect(self.sub, self.clock_recovery)
        
        #filesink = gr.file_sink(gr.sizeof_float, 'rx_fsk_test.dat')
        #fg.connect(self.clock_recovery, filesink)
        
        # Initialize base class
        gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery)
	def __init__(self, options):
		gr.hier_block2.__init__(self, "fsk_demod",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature(1, 1, gr.sizeof_char)) # Output signature

		self._syms_per_sec = options.syms_per_sec # ditto
		self._samples_per_second = options.samples_per_second
		self._gain_mu = options.gain_mu # for the clock recovery block
		self._mu = options.mu
		self._omega_relative_limit = options.omega_relative_limit

		self._freqoffset = options.offset

		#first bring that input stream down to a manageable level, let's say 3 samples per bit.
		self._clockrec_oversample = 3

		self._downsampletaps = gr.firdes.low_pass(1, self._samples_per_second, 10000, 1000, firdes.WIN_HANN)

		self._decim = int(self._samples_per_second / (self._syms_per_sec * self._clockrec_oversample))

		print "Demodulator decimation: %i" % (self._decim,)
		self._downsample = gr.freq_xlating_fir_filter_ccf(self._decim, #decimation
														  self._downsampletaps, #taps
														  self._freqoffset, #freq offset
														  self._samples_per_second) #sampling rate

		#using a pll to demod gets you a nice IIR LPF response for free
		self._demod = gr.pll_freqdet_cf(2.0 / self._clockrec_oversample, #gain alpha, rad/samp
										 2*pi/self._clockrec_oversample,  #max freq, rad/samp
										-2*pi/self._clockrec_oversample)  #min freq, rad/samp

		self._sps = float(self._samples_per_second)/self._decim/self._syms_per_sec

		#band edge filter FLL with a low bandwidth is very good
		#at synchronizing to continuous FSK signals
		self._carriertrack = digital.fll_band_edge_cc(self._sps,
													  0.6, #rolloff factor
													  64,  #taps
													  1.0) #loop bandwidth

		print "Samples per symbol: %f" % (self._sps,)
		self._softbits = digital.clock_recovery_mm_ff(self._sps,
												 0.25*self._gain_mu*self._gain_mu, #gain omega, = mu/2 * mu_gain^2
												 self._mu, #mu (decision threshold)
												 self._gain_mu, #mu gain
												 self._omega_relative_limit) #omega relative limit

		self._subtract = gr.sub_ff()

		self._slicer = digital.binary_slicer_fb()

		self.connect(self, self._downsample, self._carriertrack, self._demod, self._softbits, self._slicer, self)
Exemple #19
0
    def __init__(self):
        gr.hier_block2.__init__(self,
                                "bit_slicer",
                                gr.io_signature(2, 2, gr.sizeof_float),
                                gr.io_signature(1, 1, gr.sizeof_char))
        diff = gr.sub_ff()
        bpsk_slicer = gr.binary_slicer_fb()

        self.connect((self, 1), (diff, 0))
        self.connect((self, 0), (diff, 1))
        self.connect(diff,
                     bpsk_slicer,
                     self)
Exemple #20
0
    def __init__(self, audio_rate):
        gr.hier_block2.__init__(
            self,
            "standard_squelch",
            gr.io_signature(1, 1, gr.sizeof_float),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_float))  # Output signature

        self.input_node = gr.add_const_ff(0)  # FIXME kludge

        self.low_iir = gr.iir_filter_ffd((0.0193, 0, -0.0193),
                                         (1, 1.9524, -0.9615))
        self.low_square = gr.multiply_ff()
        self.low_smooth = gr.single_pole_iir_filter_ff(
            1 / (0.01 * audio_rate))  # 100ms time constant

        self.hi_iir = gr.iir_filter_ffd((0.0193, 0, -0.0193),
                                        (1, 1.3597, -0.9615))
        self.hi_square = gr.multiply_ff()
        self.hi_smooth = gr.single_pole_iir_filter_ff(1 / (0.01 * audio_rate))

        self.sub = gr.sub_ff()
        self.add = gr.add_ff()
        self.gate = gr.threshold_ff(0.3, 0.43, 0)
        self.squelch_lpf = gr.single_pole_iir_filter_ff(1 /
                                                        (0.01 * audio_rate))

        self.div = gr.divide_ff()
        self.squelch_mult = gr.multiply_ff()

        self.connect(self, self.input_node)
        self.connect(self.input_node, (self.squelch_mult, 0))

        self.connect(self.input_node, self.low_iir)
        self.connect(self.low_iir, (self.low_square, 0))
        self.connect(self.low_iir, (self.low_square, 1))
        self.connect(self.low_square, self.low_smooth, (self.sub, 0))
        self.connect(self.low_smooth, (self.add, 0))

        self.connect(self.input_node, self.hi_iir)
        self.connect(self.hi_iir, (self.hi_square, 0))
        self.connect(self.hi_iir, (self.hi_square, 1))
        self.connect(self.hi_square, self.hi_smooth, (self.sub, 1))
        self.connect(self.hi_smooth, (self.add, 1))

        self.connect(self.sub, (self.div, 0))
        self.connect(self.add, (self.div, 1))
        self.connect(self.div, self.gate, self.squelch_lpf,
                     (self.squelch_mult, 1))
        self.connect(self.squelch_mult, self)
Exemple #21
0
    def __init__(self, vlen):
        gr.hier_block2.__init__(
            self, "snr_estimator",
            gr.io_signature(2, 2, gr.sizeof_gr_complex * vlen),
            gr.io_signature(1, 1, gr.sizeof_float))

        reference = gr.kludge_copy(gr.sizeof_gr_complex * vlen)
        received = gr.kludge_copy(gr.sizeof_gr_complex * vlen)
        self.connect((self, 0), reference)
        self.connect((self, 1), received)

        received_conjugated = gr.conjugate_cc(vlen)
        self.connect(received, received_conjugated)

        R_innerproduct = gr.multiply_vcc(vlen)
        self.connect(reference, R_innerproduct)
        self.connect(received_conjugated, (R_innerproduct, 1))

        R_sum = vector_sum_vcc(vlen)
        self.connect(R_innerproduct, R_sum)

        R = gr.complex_to_mag_squared()
        self.connect(R_sum, R)

        received_magsqrd = gr.complex_to_mag_squared(vlen)
        reference_magsqrd = gr.complex_to_mag_squared(vlen)
        self.connect(received, received_magsqrd)
        self.connect(reference, reference_magsqrd)

        received_sum = vector_sum_vff(vlen)
        reference_sum = vector_sum_vff(vlen)
        self.connect(received_magsqrd, received_sum)
        self.connect(reference_magsqrd, reference_sum)

        P = gr.multiply_ff()
        self.connect(received_sum, (P, 0))
        self.connect(reference_sum, (P, 1))

        denominator = gr.sub_ff()
        self.connect(P, denominator)
        self.connect(R, (denominator, 1))

        rho_hat = gr.divide_ff()
        self.connect(R, rho_hat)
        self.connect(denominator, (rho_hat, 1))
        self.connect(rho_hat, self)
Exemple #22
0
  def __init__(self,vlen):
    gr.hier_block2.__init__(self,"snr_estimator",
      gr.io_signature(2,2,gr.sizeof_gr_complex*vlen),
      gr.io_signature(1,1,gr.sizeof_float))

    reference = gr.kludge_copy(gr.sizeof_gr_complex*vlen)
    received = gr.kludge_copy(gr.sizeof_gr_complex*vlen)
    self.connect((self,0),reference)
    self.connect((self,1),received)

    received_conjugated = gr.conjugate_cc(vlen)
    self.connect(received,received_conjugated)

    R_innerproduct = gr.multiply_vcc(vlen)
    self.connect(reference,R_innerproduct)
    self.connect(received_conjugated,(R_innerproduct,1))

    R_sum = vector_sum_vcc(vlen)
    self.connect(R_innerproduct,R_sum)

    R = gr.complex_to_mag_squared()
    self.connect(R_sum,R)

    received_magsqrd = gr.complex_to_mag_squared(vlen)
    reference_magsqrd = gr.complex_to_mag_squared(vlen)
    self.connect(received,received_magsqrd)
    self.connect(reference,reference_magsqrd)

    received_sum = vector_sum_vff(vlen)
    reference_sum = vector_sum_vff(vlen)
    self.connect(received_magsqrd,received_sum)
    self.connect(reference_magsqrd,reference_sum)

    P = gr.multiply_ff()
    self.connect(received_sum,(P,0))
    self.connect(reference_sum,(P,1))

    denominator = gr.sub_ff()
    self.connect(P,denominator)
    self.connect(R,(denominator,1))

    rho_hat = gr.divide_ff()
    self.connect(R,rho_hat)
    self.connect(denominator,(rho_hat,1))
    self.connect(rho_hat,self)
Exemple #23
0
	def __init__(self, samp_rate=1600000, samp_per_sym=16, freq_error=-0.0025000):
		gr.hier_block2.__init__(
			self, "Wireless M-Bus Demod",
			gr.io_signature(1, 1, gr.sizeof_gr_complex*1),
			gr.io_signature(1, 1, gr.sizeof_char*1),
		)

		##################################################
		# Parameters
		##################################################
		self.samp_rate = samp_rate
		self.samp_per_sym = samp_per_sym
		self.freq_error = freq_error

		##################################################
		# Variables
		##################################################
		self.cutoff = cutoff = 120e3
		self.chip_rate = chip_rate = samp_rate/samp_per_sym

		##################################################
		# Blocks
		##################################################
		self.low_pass_filter_0 = gr.fir_filter_ccf(1, firdes.low_pass(
			1, samp_rate, cutoff, cutoff/2, firdes.WIN_HAMMING, 6.76))
		self.gr_sub_xx_0 = gr.sub_ff(1)
		self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(0.0512/samp_per_sym, 1)
		self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1)
		self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(samp_per_sym*(1+freq_error), .25 *0.06*0.06*4, 0.5, 0.06*2, 0.002*2)
		self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb()

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0))
		self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_sub_xx_0, 1))
		self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_sub_xx_0, 0))
		self.connect((self.gr_sub_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0))
		self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
		self.connect((self.low_pass_filter_0, 0), (self.gr_quadrature_demod_cf_0, 0))
		self.connect((self.digital_binary_slicer_fb_0, 0), (self, 0))
		self.connect((self, 0), (self.low_pass_filter_0, 0))
    def __init__(self, audio_rate):
	gr.hier_block2.__init__(self, "standard_squelch",
				gr.io_signature(1, 1, gr.sizeof_float), # Input signature
				gr.io_signature(1, 1, gr.sizeof_float)) # Output signature

        self.input_node = gr.add_const_ff(0)          # FIXME kludge

        self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615))
        self.low_square = gr.multiply_ff()
        self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))   # 100ms time constant

        self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615))
        self.hi_square = gr.multiply_ff()
        self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))

        self.sub = gr.sub_ff();
        self.add = gr.add_ff();
        self.gate = gr.threshold_ff(0.3,0.43,0)
        self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))

        self.div = gr.divide_ff()
        self.squelch_mult = gr.multiply_ff()

	self.connect (self, self.input_node)
        self.connect (self.input_node, (self.squelch_mult, 0))

        self.connect (self.input_node,self.low_iir)
        self.connect (self.low_iir,(self.low_square,0))
        self.connect (self.low_iir,(self.low_square,1))
        self.connect (self.low_square,self.low_smooth,(self.sub,0))
        self.connect (self.low_smooth, (self.add,0))

        self.connect (self.input_node,self.hi_iir)
        self.connect (self.hi_iir,(self.hi_square,0))
        self.connect (self.hi_iir,(self.hi_square,1))
        self.connect (self.hi_square,self.hi_smooth,(self.sub,1))
        self.connect (self.hi_smooth, (self.add,1))

        self.connect (self.sub, (self.div, 0))
        self.connect (self.add, (self.div, 1))
        self.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1))
	self.connect (self.squelch_mult, self)
Exemple #25
0
    def __init__(self):
        """
        Hierarchical block for FSK demodulation.
    
        The input is the complex modulated signal at baseband
        and the output is a stream of floats.
        """
        # Initialize base class
        gr.hier_block2.__init__(self, "fsk_demod",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        # Variables
        self.sps = sps = 2
        self.sensitivity = sensitivity = (pi / 2) / sps
        self.alpha = alpha = 0.0512 / sps

        self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity)

        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        self.add = gr.add_ff()
        self.multiply = gr.multiply_ff()
        self.invert = gr.multiply_const_vff((-1, ))

        # recover the clock
        omega = sps
        gain_mu = 0.03
        mu = 0.5
        omega_relative_limit = 0.0002
        freq_error = 0.0
        gain_omega = .25 * gain_mu * gain_mu  # critically damped
        self.clock_recovery = digital.clock_recovery_mm_ff(
            omega, gain_omega, mu, gain_mu, omega_relative_limit)

        self.slice = digital.binary_slicer_fb()

        # Connections
        self.connect(self.fm_demod, (self.add, 0))
        self.connect(self.fm_demod, self.freq_offset, (self.add, 1))
        self.connect(self, self.fm_demod)
        self.connect(self.add, self.clock_recovery, self.invert, self)
Exemple #26
0
 def __init__ ( self, fft_length ):
   gr.hier_block2.__init__(self, "recursive_timing_metric",
       gr.io_signature(1,1,gr.sizeof_gr_complex),
       gr.io_signature(1,1,gr.sizeof_float))
   
   self.input = gr.kludge_copy(gr.sizeof_gr_complex)
   self.connect(self, self.input)
   
   # P(d) = sum(0 to L-1, conj(delayed(r)) * r)
   conj = gr.conjugate_cc()
   mixer = gr.multiply_cc()
   mix_delay = delay(gr.sizeof_gr_complex,fft_length/2+1)
   mix_diff = gr.sub_cc()
   nominator = accumulator_cc()
   inpdelay = delay(gr.sizeof_gr_complex,fft_length/2)
   
   self.connect(self.input, inpdelay, 
                conj, (mixer,0))
   self.connect(self.input, (mixer,1))
   self.connect(mixer,(mix_diff,0))
   self.connect(mixer, mix_delay, (mix_diff,1))
   self.connect(mix_diff,nominator)
   
   rmagsqrd = gr.complex_to_mag_squared()
   rm_delay = delay(gr.sizeof_float,fft_length+1)
   rm_diff = gr.sub_ff()
   denom = accumulator_ff()
   self.connect(self.input,rmagsqrd,rm_diff,gr.multiply_const_ff(0.5),denom)
   self.connect(rmagsqrd,rm_delay,(rm_diff,1))
   
   
   ps = gr.complex_to_mag_squared()
   rs = gr.multiply_ff()
   self.connect(nominator,ps)
   self.connect(denom,rs)
   self.connect(denom,(rs,1))
   
   div = gr.divide_ff()
   self.connect(ps,div)
   self.connect(rs,(div,1))
   
   self.connect(div,self)
Exemple #27
0
	def __init__(self, controller, ac_couple_key, ac_couple, sample_rate_key):
		gr.hier_block2.__init__(
			self,
			"ac_couple",
			gr.io_signature(1, 1, gr.sizeof_float),
			gr.io_signature(1, 1, gr.sizeof_float),
		)
		#blocks
		lpf = gr.single_pole_iir_filter_ff(0.0)
		sub = gr.sub_ff()
		mute = gr.mute_ff()
		#connect
		self.connect(self, sub, self)
		self.connect(self, lpf, mute, (sub, 1))
		#subscribe
		controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x))
		controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(2.0/x))
		#initialize
		controller[ac_couple_key] = ac_couple
		controller[sample_rate_key] = controller[sample_rate_key]
Exemple #28
0
 def __init__(self, controller, ac_couple_key, sample_rate_key):
     gr.hier_block2.__init__(
         self,
         "ac_couple",
         gr.io_signature(1, 1, gr.sizeof_float),
         gr.io_signature(1, 1, gr.sizeof_float),
     )
     #blocks
     lpf = gr.single_pole_iir_filter_ff(0.0)
     sub = gr.sub_ff()
     mute = gr.mute_ff()
     #connect
     self.connect(self, sub, self)
     self.connect(self, lpf, mute, (sub, 1))
     #subscribe
     controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x))
     controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05))
     #initialize
     controller[ac_couple_key] = controller[ac_couple_key]
     controller[sample_rate_key] = controller[sample_rate_key]
Exemple #29
0
    def __init__(self, fft_length):
        gr.hier_block2.__init__(self, "recursive_timing_metric",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

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

        # P(d) = sum(0 to L-1, conj(delayed(r)) * r)
        conj = gr.conjugate_cc()
        mixer = gr.multiply_cc()
        mix_delay = delay(gr.sizeof_gr_complex, fft_length / 2 + 1)
        mix_diff = gr.sub_cc()
        nominator = accumulator_cc()
        inpdelay = delay(gr.sizeof_gr_complex, fft_length / 2)

        self.connect(self.input, inpdelay, conj, (mixer, 0))
        self.connect(self.input, (mixer, 1))
        self.connect(mixer, (mix_diff, 0))
        self.connect(mixer, mix_delay, (mix_diff, 1))
        self.connect(mix_diff, nominator)

        rmagsqrd = gr.complex_to_mag_squared()
        rm_delay = delay(gr.sizeof_float, fft_length + 1)
        rm_diff = gr.sub_ff()
        denom = accumulator_ff()
        self.connect(self.input, rmagsqrd, rm_diff, gr.multiply_const_ff(0.5),
                     denom)
        self.connect(rmagsqrd, rm_delay, (rm_diff, 1))

        ps = gr.complex_to_mag_squared()
        rs = gr.multiply_ff()
        self.connect(nominator, ps)
        self.connect(denom, rs)
        self.connect(denom, (rs, 1))

        div = gr.divide_ff()
        self.connect(ps, div)
        self.connect(rs, (div, 1))

        self.connect(div, self)
Exemple #30
0
    def __init__(self):
        """
        Hierarchical block for FSK demodulation.
    
        The input is the complex modulated signal at baseband
        and the output is a stream of floats.
        """
        # Initialize base class
        gr.hier_block2.__init__(
            self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)
        )

        # Variables
        self.sps = sps = 2
        self.sensitivity = sensitivity = (pi / 2) / sps
        self.alpha = alpha = 0.0512 / sps

        self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity)

        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        self.add = gr.add_ff()
        self.multiply = gr.multiply_ff()
        self.invert = gr.multiply_const_vff((-1,))

        # recover the clock
        omega = sps
        gain_mu = 0.03
        mu = 0.5
        omega_relative_limit = 0.0002
        freq_error = 0.0
        gain_omega = 0.25 * gain_mu * gain_mu  # critically damped
        self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit)

        self.slice = digital.binary_slicer_fb()

        # Connections
        self.connect(self.fm_demod, (self.add, 0))
        self.connect(self.fm_demod, self.freq_offset, (self.add, 1))
        self.connect(self, self.fm_demod)
        self.connect(self.add, self.clock_recovery, self.invert, self)
    def __init__(self, fg, audio_rate):
    
        self.input_node = gr.add_const_ff(0)          # FIXME kludge
        
        self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615))
        self.low_square = gr.multiply_ff()
        self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))   # 100ms time constant

        self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615))
        self.hi_square = gr.multiply_ff()
        self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))

        self.sub = gr.sub_ff();
        self.add = gr.add_ff();
        self.gate = gr.threshold_ff(0.3,0.43,0)
        self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))

        self.div = gr.divide_ff()
        self.squelch_mult = gr.multiply_ff()

        fg.connect (self.input_node, (self.squelch_mult, 0))

        fg.connect (self.input_node,self.low_iir)
        fg.connect (self.low_iir,(self.low_square,0))
        fg.connect (self.low_iir,(self.low_square,1))
        fg.connect (self.low_square,self.low_smooth,(self.sub,0))
        fg.connect (self.low_smooth, (self.add,0))

        fg.connect (self.input_node,self.hi_iir)
        fg.connect (self.hi_iir,(self.hi_square,0))
        fg.connect (self.hi_iir,(self.hi_square,1))
        fg.connect (self.hi_square,self.hi_smooth,(self.sub,1))
        fg.connect (self.hi_smooth, (self.add,1))

        fg.connect (self.sub, (self.div, 0))
        fg.connect (self.add, (self.div, 1))
        fg.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1))

        gr.hier_block.__init__(self, fg, self.input_node, self.squelch_mult)
Exemple #32
0
	def __init__(self, devid="type=b100", rdsfile="rds_fifo", gain=35.0, freq=101.1e6, xmlport=13777, arate=int(48e3), mute=-15.0, ftune=0, ant="J1", subdev="A:0", ahw="pulse", deemph=75.0e-6, prenames='["UWRF","89.3","950","WEVR"]', prefreqs="[88.715e6,89.3e6,950.735e6,106.317e6]", volume=1.0):
		grc_wxgui.top_block_gui.__init__(self, title="Simple FM (Stereo) Receiver")
		_icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

		##################################################
		# Parameters
		##################################################
		self.devid = devid
		self.rdsfile = rdsfile
		self.gain = gain
		self.freq = freq
		self.xmlport = xmlport
		self.arate = arate
		self.mute = mute
		self.ftune = ftune
		self.ant = ant
		self.subdev = subdev
		self.ahw = ahw
		self.deemph = deemph
		self.prenames = prenames
		self.prefreqs = prefreqs
		self.volume = volume

		##################################################
		# Variables
		##################################################
		self.pthresh = pthresh = 350
		self.preselect = preselect = eval(prefreqs)[0]
		self.pilot_level = pilot_level = 0
		self.ifreq = ifreq = freq
		self.stpilotdet = stpilotdet = True if (pilot_level > pthresh) else False
		self.stereo = stereo = True
		self.rf_pwr_lvl = rf_pwr_lvl = 0
		self.cur_freq = cur_freq = simple_fm_helper.freq_select(ifreq,preselect)
		self.vol = vol = volume
		self.variable_static_text_0 = variable_static_text_0 = 10.0*math.log(rf_pwr_lvl+1.0e-11)/math.log(10)
		self.tone_med = tone_med = 5
		self.tone_low = tone_low = 5
		self.tone_high = tone_high = 5
		self.stereo_0 = stereo_0 = stpilotdet
		self.st_enabled = st_enabled = 1 if (stereo == True and pilot_level > pthresh) else 0
		self.squelch_probe = squelch_probe = 0
		self.sq_thresh = sq_thresh = mute
		self.samp_rate = samp_rate = 250e3
		self.rtext_0 = rtext_0 = cur_freq
		self.record = record = False
		self.rdsrate = rdsrate = 25e3
		self.osmo_taps = osmo_taps = firdes.low_pass(1.0,1.00e6,95e3,20e3,firdes.WIN_HAMMING,6.76)
		self.mod_reset = mod_reset = 0
		self.igain = igain = gain
		self.fine = fine = ftune
		self.farate = farate = arate
		self.dm = dm = deemph
		self.discrim_dc = discrim_dc = 0
		self.capture_file = capture_file = "capture.wav"
		self.asrate = asrate = 125e3

		##################################################
		# Blocks
		##################################################
		_sq_thresh_sizer = wx.BoxSizer(wx.VERTICAL)
		self._sq_thresh_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_sq_thresh_sizer,
			value=self.sq_thresh,
			callback=self.set_sq_thresh,
			label="Mute Level",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._sq_thresh_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_sq_thresh_sizer,
			value=self.sq_thresh,
			callback=self.set_sq_thresh,
			minimum=-30.0,
			maximum=-5.0,
			num_steps=40,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_sq_thresh_sizer, 1, 5, 1, 1)
		self.input_power = gr.probe_avg_mag_sqrd_c(sq_thresh, 1.0/(samp_rate/10))
		self.dc_level = gr.probe_signal_f()
		_vol_sizer = wx.BoxSizer(wx.VERTICAL)
		self._vol_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_vol_sizer,
			value=self.vol,
			callback=self.set_vol,
			label="Volume",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._vol_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_vol_sizer,
			value=self.vol,
			callback=self.set_vol,
			minimum=0,
			maximum=11,
			num_steps=110,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_vol_sizer, 0, 3, 1, 1)
		_tone_med_sizer = wx.BoxSizer(wx.VERTICAL)
		self._tone_med_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_tone_med_sizer,
			value=self.tone_med,
			callback=self.set_tone_med,
			label="1Khz-4Khz",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._tone_med_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_tone_med_sizer,
			value=self.tone_med,
			callback=self.set_tone_med,
			minimum=0,
			maximum=10,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_tone_med_sizer, 1, 3, 1, 1)
		_tone_low_sizer = wx.BoxSizer(wx.VERTICAL)
		self._tone_low_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_tone_low_sizer,
			value=self.tone_low,
			callback=self.set_tone_low,
			label="0-1Khz",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._tone_low_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_tone_low_sizer,
			value=self.tone_low,
			callback=self.set_tone_low,
			minimum=0,
			maximum=10,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_tone_low_sizer, 1, 2, 1, 1)
		_tone_high_sizer = wx.BoxSizer(wx.VERTICAL)
		self._tone_high_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_tone_high_sizer,
			value=self.tone_high,
			callback=self.set_tone_high,
			label="4Khz-15Khz",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._tone_high_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_tone_high_sizer,
			value=self.tone_high,
			callback=self.set_tone_high,
			minimum=0,
			maximum=10,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_tone_high_sizer, 1, 4, 1, 1)
		def _squelch_probe_probe():
			while True:
				val = self.input_power.unmuted()
				try: self.set_squelch_probe(val)
				except AttributeError, e: pass
				time.sleep(1.0/(10))
		_squelch_probe_thread = threading.Thread(target=_squelch_probe_probe)
		_squelch_probe_thread.daemon = True
		_squelch_probe_thread.start()
		self._record_check_box = forms.check_box(
			parent=self.GetWin(),
			value=self.record,
			callback=self.set_record,
			label="Record Audio",
			true=True,
			false=False,
		)
		self.GridAdd(self._record_check_box, 2, 2, 1, 1)
		self.pilot_probe = gr.probe_signal_f()
		_fine_sizer = wx.BoxSizer(wx.VERTICAL)
		self._fine_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_fine_sizer,
			value=self.fine,
			callback=self.set_fine,
			label="Fine Tuning",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._fine_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_fine_sizer,
			value=self.fine,
			callback=self.set_fine,
			minimum=-50.0e3,
			maximum=50.e03,
			num_steps=400,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_fine_sizer, 1, 0, 1, 1)
		def _discrim_dc_probe():
			while True:
				val = self.dc_level.level()
				try: self.set_discrim_dc(val)
				except AttributeError, e: pass
				time.sleep(1.0/(2.5))
		_discrim_dc_thread = threading.Thread(target=_discrim_dc_probe)
		_discrim_dc_thread.daemon = True
		_discrim_dc_thread.start()
		self._capture_file_text_box = forms.text_box(
			parent=self.GetWin(),
			value=self.capture_file,
			callback=self.set_capture_file,
			label="Record Filename",
			converter=forms.str_converter(),
		)
		self.GridAdd(self._capture_file_text_box, 2, 0, 1, 2)
		self.Main = self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
		self.Main.AddPage(grc_wxgui.Panel(self.Main), "L/R")
		self.Main.AddPage(grc_wxgui.Panel(self.Main), "FM Demod Spectrum")
		self.Add(self.Main)
		self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c(
			self.GetWin(),
			baseband_freq=0,
			dynamic_range=100,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=samp_rate,
			fft_size=512,
			fft_rate=15,
			average=False,
			avg_alpha=None,
			title="Waterfall Plot",
		)
		self.Add(self.wxgui_waterfallsink2_0.win)
		self.wxgui_scopesink2_0 = scopesink2.scope_sink_f(
			self.Main.GetPage(0).GetWin(),
			title="Audio Channels (L and R)",
			sample_rate=farate,
			v_scale=0,
			v_offset=0,
			t_scale=0,
			ac_couple=False,
			xy_mode=False,
			num_inputs=2,
			trig_mode=gr.gr_TRIG_MODE_AUTO,
			y_axis_label="Rel. Audio Level",
		)
		self.Main.GetPage(0).Add(self.wxgui_scopesink2_0.win)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_f(
			self.Main.GetPage(1).GetWin(),
			baseband_freq=0,
			y_per_div=10,
			y_divs=10,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=asrate,
			fft_size=1024,
			fft_rate=6,
			average=True,
			avg_alpha=0.1,
			title="FM Demod Spectrum",
			peak_hold=False,
		)
		self.Main.GetPage(1).Add(self.wxgui_fftsink2_0.win)
		self._variable_static_text_0_static_text = forms.static_text(
			parent=self.GetWin(),
			value=self.variable_static_text_0,
			callback=self.set_variable_static_text_0,
			label="RF Power ",
			converter=forms.float_converter(formatter=lambda x: "%4.1f" % x),
		)
		self.GridAdd(self._variable_static_text_0_static_text, 0, 2, 1, 1)
		self._stereo_0_check_box = forms.check_box(
			parent=self.GetWin(),
			value=self.stereo_0,
			callback=self.set_stereo_0,
			label="Stereo Detect",
			true=True,
			false=False,
		)
		self.GridAdd(self._stereo_0_check_box, 2, 5, 1, 1)
		self._stereo_check_box = forms.check_box(
			parent=self.GetWin(),
			value=self.stereo,
			callback=self.set_stereo,
			label="Stereo",
			true=True,
			false=False,
		)
		self.GridAdd(self._stereo_check_box, 2, 4, 1, 1)
		self.rtl2832_source_0 = baz.rtl_source_c(defer_creation=True)
		self.rtl2832_source_0.set_verbose(True)
		self.rtl2832_source_0.set_vid(0x0)
		self.rtl2832_source_0.set_pid(0x0)
		self.rtl2832_source_0.set_tuner_name("")
		self.rtl2832_source_0.set_default_timeout(0)
		self.rtl2832_source_0.set_use_buffer(True)
		self.rtl2832_source_0.set_fir_coefficients(([]))
		
		
		
		
		
		if self.rtl2832_source_0.create() == False: raise Exception("Failed to create RTL2832 Source: rtl2832_source_0")
		
		
		self.rtl2832_source_0.set_sample_rate(1.0e6)
		
		self.rtl2832_source_0.set_frequency(cur_freq+200e3)
		
		
		self.rtl2832_source_0.set_auto_gain_mode(False)
		self.rtl2832_source_0.set_relative_gain(True)
		self.rtl2832_source_0.set_gain(gain)
		  
		self._rtext_0_static_text = forms.static_text(
			parent=self.GetWin(),
			value=self.rtext_0,
			callback=self.set_rtext_0,
			label="CURRENT FREQUENCY>>",
			converter=forms.float_converter(),
		)
		self.GridAdd(self._rtext_0_static_text, 0, 1, 1, 1)
		def _rf_pwr_lvl_probe():
			while True:
				val = self.input_power.level()
				try: self.set_rf_pwr_lvl(val)
				except AttributeError, e: pass
				time.sleep(1.0/(2))
		_rf_pwr_lvl_thread = threading.Thread(target=_rf_pwr_lvl_probe)
		_rf_pwr_lvl_thread.daemon = True
		_rf_pwr_lvl_thread.start()
		self._preselect_chooser = forms.radio_buttons(
			parent=self.GetWin(),
			value=self.preselect,
			callback=self.set_preselect,
			label='preselect',
			choices=eval(prefreqs),
			labels=eval(prenames),
			style=wx.RA_HORIZONTAL,
		)
		self.GridAdd(self._preselect_chooser, 0, 4, 1, 1)
		def _pilot_level_probe():
			while True:
				val = self.pilot_probe.level()
				try: self.set_pilot_level(val)
				except AttributeError, e: pass
				time.sleep(1.0/(5))
		_pilot_level_thread = threading.Thread(target=_pilot_level_probe)
		_pilot_level_thread.daemon = True
		_pilot_level_thread.start()
		self.low_pass_filter_3 = gr.fir_filter_fff(1, firdes.low_pass(
			3, asrate/500, 10, 3, firdes.WIN_HAMMING, 6.76))
		self.low_pass_filter_2 = gr.fir_filter_fff(10, firdes.low_pass(
			3, asrate/50, 100, 30, firdes.WIN_HAMMING, 6.76))
		self.low_pass_filter_1 = gr.fir_filter_fff(10, firdes.low_pass(
			3, asrate/5, 1e3, 200, firdes.WIN_HAMMING, 6.76))
		self.low_pass_filter_0 = gr.fir_filter_fff(5, firdes.low_pass(
			3, asrate, 10e3, 2e3, firdes.WIN_HAMMING, 6.76))
		_igain_sizer = wx.BoxSizer(wx.VERTICAL)
		self._igain_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_igain_sizer,
			value=self.igain,
			callback=self.set_igain,
			label="RF Gain",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._igain_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_igain_sizer,
			value=self.igain,
			callback=self.set_igain,
			minimum=0,
			maximum=50,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_igain_sizer, 1, 1, 1, 1)
		_ifreq_sizer = wx.BoxSizer(wx.VERTICAL)
		self._ifreq_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_ifreq_sizer,
			value=self.ifreq,
			callback=self.set_ifreq,
			label="Center Frequency",
			converter=forms.float_converter(),
			proportion=0,
		)
		self._ifreq_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_ifreq_sizer,
			value=self.ifreq,
			callback=self.set_ifreq,
			minimum=88.1e6,
			maximum=108.1e6,
			num_steps=200,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.GridAdd(_ifreq_sizer, 0, 0, 1, 1)
		self.gr_wavfile_sink_0 = gr.wavfile_sink("/dev/null" if record == False else capture_file, 2, int(farate), 16)
		self.gr_sub_xx_0 = gr.sub_ff(1)
		self.gr_single_pole_iir_filter_xx_1 = gr.single_pole_iir_filter_ff(2.5/(asrate/500), 1)
		self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(1.0/(asrate/3), 1)
		self.gr_multiply_xx_1 = gr.multiply_vff(1)
		self.gr_multiply_xx_0_0 = gr.multiply_vff(1)
		self.gr_multiply_xx_0 = gr.multiply_vff(1)
		self.gr_multiply_const_vxx_3 = gr.multiply_const_vff((3.16e3 if st_enabled else 0, ))
		self.gr_multiply_const_vxx_2 = gr.multiply_const_vff((1.0 if st_enabled else 1.414, ))
		self.gr_multiply_const_vxx_1_0 = gr.multiply_const_vff((0 if st_enabled else 1, ))
		self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((0 if squelch_probe == 0 else 1.0, ))
		self.gr_multiply_const_vxx_0_0 = gr.multiply_const_vff((vol*1.5*10.0, ))
		self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((vol*1.5*10.0 if st_enabled else 0, ))
		self.gr_keep_one_in_n_0 = gr.keep_one_in_n(gr.sizeof_float*1, int(asrate/3))
		self.gr_freq_xlating_fir_filter_xxx_0 = gr.freq_xlating_fir_filter_ccc(4, (osmo_taps), 200e3+fine+(-12e3*discrim_dc), 1.0e6)
		self.gr_fractional_interpolator_xx_0_0 = gr.fractional_interpolator_ff(0, asrate/farate)
		self.gr_fractional_interpolator_xx_0 = gr.fractional_interpolator_ff(0, asrate/farate)
		self.gr_fft_filter_xxx_1_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_high/10.0,asrate,3.5e3,15.0e3,5.0e3,firdes.WIN_HAMMING)), 1)
		self.gr_fft_filter_xxx_1_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_med/10.0,asrate,1.0e3,4.0e3,2.0e3,firdes.WIN_HAMMING)), 1)
		self.gr_fft_filter_xxx_1 = gr.fft_filter_fff(1, (firdes.low_pass(tone_low/10.0,asrate,1.2e3,500,firdes.WIN_HAMMING)), 1)
		self.gr_fft_filter_xxx_0_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_high/10.0,asrate,3.5e3,13.5e3,3.5e3,firdes.WIN_HAMMING)), 1)
		self.gr_fft_filter_xxx_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_med/10.0,asrate,1.0e3,4.0e3,2.0e3,firdes.WIN_HAMMING)), 1)
		self.gr_fft_filter_xxx_0 = gr.fft_filter_fff(1, (firdes.low_pass(tone_low/10.0,asrate,1.2e3,500,firdes.WIN_HAMMING)), 1)
		self.gr_divide_xx_0 = gr.divide_ff(1)
		self.gr_agc_xx_1 = gr.agc_cc(1e-2, 0.35, 1.0, 5000)
		self.gr_add_xx_2_0 = gr.add_vff(1)
		self.gr_add_xx_2 = gr.add_vff(1)
		self.gr_add_xx_1 = gr.add_vff(1)
		self.gr_add_xx_0 = gr.add_vff(1)
		self.gr_add_const_vxx_0 = gr.add_const_vff((1.0e-7, ))
		self._dm_chooser = forms.radio_buttons(
			parent=self.GetWin(),
			value=self.dm,
			callback=self.set_dm,
			label="FM Deemphasis",
			choices=[75.0e-6, 50.0e-6],
			labels=["NA", "EU"],
			style=wx.RA_HORIZONTAL,
		)
		self.GridAdd(self._dm_chooser, 0, 5, 1, 1)
		self.blks2_wfm_rcv_0 = blks2.wfm_rcv(
			quad_rate=samp_rate,
			audio_decimation=2,
		)
		self.blks2_fm_deemph_0_0 = blks2.fm_deemph(fs=farate, tau=deemph)
		self.blks2_fm_deemph_0 = blks2.fm_deemph(fs=farate, tau=deemph)
		self.band_pass_filter_2_0 = gr.fir_filter_fff(1, firdes.band_pass(
			20, asrate, 17.5e3, 17.9e3, 250, firdes.WIN_HAMMING, 6.76))
		self.band_pass_filter_2 = gr.fir_filter_fff(1, firdes.band_pass(
			10, asrate, 18.8e3, 19.2e3, 350, firdes.WIN_HAMMING, 6.76))
		self.band_pass_filter_0_0 = gr.fir_filter_fff(1, firdes.band_pass(
			1, asrate, 38e3-(15e3), 38e3+(15e3), 4.0e3, firdes.WIN_HAMMING, 6.76))
		self.audio_sink_0 = audio.sink(int(farate), "" if ahw == "Default" else ahw, True)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_add_xx_1, 0), (self.gr_fractional_interpolator_xx_0, 0))
		self.connect((self.gr_sub_xx_0, 0), (self.gr_fractional_interpolator_xx_0_0, 0))
		self.connect((self.band_pass_filter_0_0, 0), (self.gr_multiply_xx_1, 0))
		self.connect((self.gr_multiply_const_vxx_1_0, 0), (self.gr_add_xx_0, 0))
		self.connect((self.band_pass_filter_2_0, 0), (self.gr_multiply_xx_0, 0))
		self.connect((self.band_pass_filter_2_0, 0), (self.gr_multiply_xx_0, 1))
		self.connect((self.gr_multiply_xx_0_0, 0), (self.gr_divide_xx_0, 0))
		self.connect((self.gr_divide_xx_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0))
		self.connect((self.gr_multiply_xx_0, 0), (self.gr_add_const_vxx_0, 0))
		self.connect((self.gr_add_const_vxx_0, 0), (self.gr_divide_xx_0, 1))
		self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0))
		self.connect((self.gr_keep_one_in_n_0, 0), (self.pilot_probe, 0))
		self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_1, 2))
		self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_0_0, 0))
		self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_add_xx_1, 0))
		self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_sub_xx_0, 0))
		self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_sub_xx_0, 1))
		self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_add_xx_1, 1))
		self.connect((self.gr_fractional_interpolator_xx_0, 0), (self.gr_multiply_const_vxx_0_0, 0))
		self.connect((self.gr_fractional_interpolator_xx_0_0, 0), (self.gr_multiply_const_vxx_0, 0))
		self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_1, 1))
		self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0, 0))
		self.connect((self.gr_fft_filter_xxx_1, 0), (self.gr_add_xx_2, 0))
		self.connect((self.gr_fft_filter_xxx_1_0, 0), (self.gr_add_xx_2, 1))
		self.connect((self.gr_fft_filter_xxx_1_0_0, 0), (self.gr_add_xx_2, 2))
		self.connect((self.gr_add_xx_2, 0), (self.gr_multiply_const_vxx_2, 0))
		self.connect((self.gr_add_xx_2_0, 0), (self.gr_multiply_const_vxx_3, 0))
		self.connect((self.gr_fft_filter_xxx_0, 0), (self.gr_add_xx_2_0, 0))
		self.connect((self.gr_fft_filter_xxx_0_0, 0), (self.gr_add_xx_2_0, 1))
		self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0_0, 0))
		self.connect((self.gr_fft_filter_xxx_0_0_0, 0), (self.gr_add_xx_2_0, 2))
		self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0_0_0, 0))
		self.connect((self.blks2_fm_deemph_0, 0), (self.gr_multiply_const_vxx_1_0, 0))
		self.connect((self.blks2_fm_deemph_0, 0), (self.gr_wavfile_sink_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1_0_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.blks2_fm_deemph_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.audio_sink_0, 1))
		self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_fm_deemph_0_0, 0))
		self.connect((self.blks2_fm_deemph_0_0, 0), (self.gr_add_xx_0, 1))
		self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_0_0, 1))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_2, 0))
		self.connect((self.blks2_fm_deemph_0, 0), (self.audio_sink_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_2_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_0_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.gr_wavfile_sink_0, 1))
		self.connect((self.blks2_fm_deemph_0, 0), (self.wxgui_scopesink2_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.wxgui_scopesink2_0, 1))
		self.connect((self.blks2_wfm_rcv_0, 0), (self.gr_multiply_const_vxx_1, 0))
		self.connect((self.gr_agc_xx_1, 0), (self.blks2_wfm_rcv_0, 0))
		self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.gr_agc_xx_1, 0))
		self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.input_power, 0))
		self.connect((self.blks2_wfm_rcv_0, 0), (self.low_pass_filter_0, 0))
		self.connect((self.low_pass_filter_0, 0), (self.low_pass_filter_1, 0))
		self.connect((self.low_pass_filter_1, 0), (self.low_pass_filter_2, 0))
		self.connect((self.low_pass_filter_2, 0), (self.low_pass_filter_3, 0))
		self.connect((self.gr_single_pole_iir_filter_xx_1, 0), (self.dc_level, 0))
		self.connect((self.low_pass_filter_3, 0), (self.gr_single_pole_iir_filter_xx_1, 0))
		self.connect((self.rtl2832_source_0, 0), (self.gr_freq_xlating_fir_filter_xxx_0, 0))
		self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_waterfallsink2_0, 0))
Exemple #33
0
	def __init__(self, dab_params, rx_params, verbose=False, debug=False):
		"""
		Hierarchical block for OFDM demodulation

		@param dab_params DAB parameter object (dab.parameters.dab_parameters)
		@param rx_params RX parameter object (dab.parameters.receiver_parameters)
		@param debug enables debug output to files
		@param verbose whether to produce verbose messages
		"""

		self.dp = dp = dab_params
		self.rp = rp = rx_params
		self.verbose = verbose

		if self.rp.softbits:
			gr.hier_block2.__init__(self,"ofdm_demod",
						gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature
						gr.io_signature2(2, 2, gr.sizeof_float*self.dp.num_carriers*2, gr.sizeof_char)) # output signature
		else:
			gr.hier_block2.__init__(self,"ofdm_demod",
						gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature
						gr.io_signature2(2, 2, gr.sizeof_char*self.dp.num_carriers/4, gr.sizeof_char)) # output signature

		

		# workaround for a problem that prevents connecting more than one block directly (see trac ticket #161)
		self.input = gr.kludge_copy(gr.sizeof_gr_complex)
		self.connect(self, self.input)
		
		# input filtering
		if self.rp.input_fft_filter: 
			if verbose: print "--> RX filter enabled"
			lowpass_taps = gr.firdes_low_pass(1.0,                     # gain
							  dp.sample_rate,          # sampling rate
							  rp.filt_bw,              # cutoff frequency
							  rp.filt_tb,              # width of transition band
							  gr.firdes.WIN_HAMMING)   # Hamming window
			self.fft_filter = gr.fft_filter_ccc(1, lowpass_taps)
		

		# correct sample rate offset, if enabled
		if self.rp.autocorrect_sample_rate:
			if verbose: print "--> dynamic sample rate correction enabled"
			self.rate_detect_ns = detect_null.detect_null(dp.ns_length, False)
			self.rate_estimator = dab_swig.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length)
			self.rate_prober = gr.probe_signal_f()
			self.connect(self.input, self.rate_detect_ns, self.rate_estimator, self.rate_prober)
			# self.resample = gr.fractional_interpolator_cc(0, 1)
			self.resample = dab_swig.fractional_interpolator_triggered_update_cc(0,1)
			self.connect(self.rate_detect_ns, (self.resample,1))
			self.updater = Timer(0.1,self.update_correction)
			# self.updater = threading.Thread(target=self.update_correction)
			self.run_interpolater_update_thread = True
			self.updater.setDaemon(True)
			self.updater.start()
		else:
			self.run_interpolater_update_thread = False
			if self.rp.sample_rate_correction_factor != 1:
				if verbose: print "--> static sample rate correction enabled"
				self.resample = gr.fractional_interpolator_cc(0, self.rp.sample_rate_correction_factor)

		# timing and fine frequency synchronisation
		self.sync = ofdm_sync_dab2.ofdm_sync_dab(self.dp, self.rp, debug)

		# ofdm symbol sampler
		self.sampler = dab_swig.ofdm_sampler(dp.fft_length, dp.cp_length, dp.symbols_per_frame, rp.cp_gap)
		
		# fft for symbol vectors
		self.fft = gr.fft_vcc(dp.fft_length, True, [], True)

		# coarse frequency synchronisation
		self.cfs = dab_swig.ofdm_coarse_frequency_correct(dp.fft_length, dp.num_carriers, dp.cp_length)

		# diff phasor
		self.phase_diff = dab_swig.diff_phasor_vcc(dp.num_carriers)

		# remove pilot symbol
		self.remove_pilot = dab_swig.ofdm_remove_first_symbol_vcc(dp.num_carriers)

		# magnitude equalisation
		if self.rp.equalize_magnitude:
			if verbose: print "--> magnitude equalization enabled"
			self.equalizer = dab_swig.magnitude_equalizer_vcc(dp.num_carriers, rp.symbols_for_magnitude_equalization)

		# frequency deinterleaving
		self.deinterleave = dab_swig.frequency_interleaver_vcc(dp.frequency_deinterleaving_sequence_array)
		
		# symbol demapping
		self.demapper = dab_swig.qpsk_demapper_vcb(dp.num_carriers)

		#
		# connect everything
		#

		if self.rp.autocorrect_sample_rate or self.rp.sample_rate_correction_factor != 1:
			self.connect(self.input, self.resample)
			self.input2 = self.resample
		else:
			self.input2 = self.input
		if self.rp.input_fft_filter:
			self.connect(self.input2, self.fft_filter, self.sync)
		else:
			self.connect(self.input2, self.sync)

		# data stream
		self.connect((self.sync, 0), (self.sampler, 0), self.fft, (self.cfs, 0), self.phase_diff, (self.remove_pilot,0))
		if self.rp.equalize_magnitude:
			self.connect((self.remove_pilot,0), (self.equalizer,0), self.deinterleave)
		else:
			self.connect((self.remove_pilot,0), self.deinterleave)
		if self.rp.softbits:
			if verbose: print "--> using soft bits"
			self.softbit_interleaver = dab_swig.complex_to_interleaved_float_vcf(self.dp.num_carriers)
			self.connect(self.deinterleave, self.softbit_interleaver, (self,0))
		else:
			self.connect(self.deinterleave, self.demapper, (self,0))

		# control stream
		self.connect((self.sync, 1), (self.sampler, 1), (self.cfs, 1), (self.remove_pilot,1))
		if self.rp.equalize_magnitude:
			self.connect((self.remove_pilot,1), (self.equalizer,1), (self,1))
		else:
			self.connect((self.remove_pilot,1), (self,1))
			
		# calculate an estimate of the SNR
		self.phase_var_decim   = gr.keep_one_in_n(gr.sizeof_gr_complex*self.dp.num_carriers, self.rp.phase_var_estimate_downsample)
		self.phase_var_arg     = gr.complex_to_arg(dp.num_carriers)
		self.phase_var_v2s     = gr.vector_to_stream(gr.sizeof_float, dp.num_carriers)
		self.phase_var_mod     = dab_swig.modulo_ff(pi/2)
		self.phase_var_avg_mod = gr.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) 
		self.phase_var_sub_avg = gr.sub_ff()
		self.phase_var_sqr     = gr.multiply_ff()
		self.phase_var_avg     = gr.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) 
		self.probe_phase_var   = gr.probe_signal_f()
		self.connect((self.remove_pilot,0), self.phase_var_decim, self.phase_var_arg, self.phase_var_v2s, self.phase_var_mod, (self.phase_var_sub_avg,0), (self.phase_var_sqr,0))
		self.connect(self.phase_var_mod, self.phase_var_avg_mod, (self.phase_var_sub_avg,1))
		self.connect(self.phase_var_sub_avg, (self.phase_var_sqr,1))
		self.connect(self.phase_var_sqr, self.phase_var_avg, self.probe_phase_var)

		# measure processing rate
		self.measure_rate = dab_swig.measure_processing_rate(gr.sizeof_gr_complex, 2000000) 
		self.connect(self.input, self.measure_rate)

		# debugging
		if debug:
			self.connect(self.fft, gr.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/ofdm_after_fft.dat"))
			self.connect((self.cfs,0), gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_after_cfs.dat"))
			self.connect(self.phase_diff, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_diff_phasor.dat"))
			self.connect((self.remove_pilot,0), gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_pilot_removed.dat"))
			self.connect((self.remove_pilot,1), gr.file_sink(gr.sizeof_char, "debug/ofdm_after_cfs_trigger.dat"))
			self.connect(self.deinterleave, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_deinterleaved.dat"))
			if self.rp.equalize_magnitude:
				self.connect(self.equalizer, gr.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_equalizer.dat"))
			if self.rp.softbits:
				self.connect(self.softbit_interleaver, gr.file_sink(gr.sizeof_float*dp.num_carriers*2, "debug/softbits.dat"))
Exemple #34
0
    def __init__(self, syms_per_sec, samples_per_sec, gain_mu, mu,
                 omega_relative_limit, freq_offset):
        gr.hier_block2.__init__(
            self,
            "fsk_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_char))  # Output signature

        self._syms_per_sec = syms_per_sec  # ditto
        self._samples_per_second = samples_per_sec
        self._gain_mu = gain_mu  # for the clock recovery block
        self._mu = mu
        self._omega_relative_limit = omega_relative_limit

        self._freqoffset = freq_offset

        self._filtdecim = 1

        #first bring that input stream down to a manageable level, let's say 10 samples per bit. that's 36kS/s.
        self._clockrec_oversample = 10

        self._downsampletaps = firdes.low_pass(1, self._samples_per_second,
                                               10000, 1000, firdes.WIN_HANN)

        self._decim = int(self._samples_per_second /
                          (self._syms_per_sec * self._clockrec_oversample))

        print "Demodulator decimation: %i" % (self._decim, )

        self._downsample = filter.freq_xlating_fir_filter_ccc(
            self._decim,  #decimation
            self._downsampletaps,  #taps
            self._freqoffset,  #freq offset
            self._samples_per_second)  #sampling rate

        #these coeffs were found experimentally
        self._demod = analog.pll_freqdet_cf(
            0.8,  #gain alpha, rad/samp
            0.3,  #gain beta, rad/samp
            6,  #max freq, rad/samp
            -6)  #min freq, rad/samp

        #this pll is low phase gain to track the carrier itself, to cancel out freq error
        #it's a continuous carrier so you don't have to worry too much about it locking fast
        self._carriertrack = analog.pll_freqdet_cf(0.3, 10e-6, 6, -6)

        self._lpfcoeffs = firdes.low_pass(
            1000, self._samples_per_second / self._decim, self._syms_per_sec,
            100, firdes.WIN_HANN)

        self._lpf = filter.fir_filter_fff(
            self._filtdecim,  #decimation
            self._lpfcoeffs)  #coeffs

        print "Samples per symbol: %f" % (float(self._samples_per_second) /
                                          self._decim / self._syms_per_sec, )
        self._softbits = gr.clock_recovery_mm_ff(
            float(self._samples_per_second) / self._decim / self._syms_per_sec,
            0.25 * self._gain_mu *
            self._gain_mu,  #gain omega, = mu/2 * mu_gain^2
            self._mu,  #mu (decision threshold)
            self._gain_mu,  #mu gain
            self._omega_relative_limit)  #omega relative limit

        self._subtract = gr.sub_ff()

        self._slicer = gr.binary_slicer_fb()

        self.connect(self, self._downsample, self._demod, (self._subtract, 0))
        self.connect(self._downsample, self._carriertrack)
        self.connect(self._carriertrack, (self._subtract, 1))
        self.connect(self._subtract, self._lpf, self._softbits, self._slicer,
                     self)
Exemple #35
0
    def __init__(self,
                 frequency,
                 sample_rate,
                 uhd_address="192.168.10.2",
                 trigger=False):

        gr.top_block.__init__(self)

        self.freq = frequency
        self.samp_rate = sample_rate
        self.uhd_addr = uhd_address
        self.gain = 32
        self.trigger = trigger

        self.uhd_src = uhd.single_usrp_source(
            device_addr=self.uhd_addr,
            io_type=uhd.io_type_t.COMPLEX_FLOAT32,
            num_channels=1,
        )

        self.uhd_src.set_samp_rate(self.samp_rate)
        self.uhd_src.set_center_freq(self.freq, 0)
        self.uhd_src.set_gain(self.gain, 0)

        taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60)
        self.chanfilt = gr.fir_filter_ccc(10, taps)
        self.ann0 = gr.annotator_alltoall(100000, gr.sizeof_gr_complex)
        self.tagger = gr.burst_tagger(gr.sizeof_gr_complex)

        # Dummy signaler to collect a burst on known periods
        data = 1000 * [
            0,
        ] + 1000 * [
            1,
        ]
        self.signal = gr.vector_source_s(data, True)

        # Energy detector to get signal burst
        self.c2m = gr.complex_to_mag_squared()
        self.iir = gr.single_pole_iir_filter_ff(0.0001)
        self.sub = gr.sub_ff()
        self.mult = gr.multiply_const_ff(32768)
        self.f2s = gr.float_to_short()
        self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate)

        ##################################################
        # Connections
        ##################################################
        self.connect((self.uhd_src, 0), (self.tagger, 0))
        self.connect((self.tagger, 0), (self.fsnk, 0))

        if self.trigger:
            # Connect a dummy signaler to the burst tagger
            self.connect((self.signal, 0), (self.tagger, 1))

        else:
            # Connect an energy detector signaler to the burst tagger
            self.connect((self.uhd_src, 0), (self.c2m, 0))
            self.connect((self.c2m, 0), (self.sub, 0))
            self.connect((self.c2m, 0), (self.iir, 0))
            self.connect((self.iir, 0), (self.sub, 1))
            self.connect((self.sub, 0), (self.mult, 0))
            self.connect((self.mult, 0), (self.f2s, 0))
            self.connect((self.f2s, 0), (self.tagger, 1))
Exemple #36
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)
    def __init__(self, options):
        """
        Hierarchical block for O-QPSK demodulation.
        
        The input is the complex modulated signal at baseband
        and the output is a stream of bytes.
        
        @param sps: samples per symbol
        @type sps: integer
        """ 
        try:
            #self.sps = kwargs.pop('sps')
            self.sps = 2
        except KeyError:
            pass
        
        gr.hier_block2.__init__(self, "oqpsk_demodulator",
                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input
                gr.io_signature(0, 0, 0))  # Output
        
        # Demodulate FM
        sensitivity = (pi / 2) / self.sps
        #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)
        self.fmdemod = gr.quadrature_demod_cf(1)
        
        # Low pass the output of fmdemod to allow us to remove
        # the DC offset resulting from frequency offset
        
        alpha = 0.0008/self.sps
        self.freq_offset = gr.single_pole_iir_filter_ff(alpha)
        self.sub = gr.sub_ff()
        
        # recover the clock
        omega = self.sps
        gain_mu=0.03
        mu=0.5
        omega_relative_limit=0.0002
        freq_error=0.0
        
        gain_omega = .25*gain_mu*gain_mu        # critically damped
        
        # Descramble BERT sequence.  A channel error will create 3 incorrect bits
        #self._descrambler = gr.descrambler_bb(0x8A, 0x7F, 31) # CCSDS 7-bit descrambler
        
        self.clock_recovery_f = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu,
                                                      omega_relative_limit)
    
        self.gr_float_to_complex = gr.float_to_complex(1)
        
        #Create a vector source reference to calculate BER
        self._vector_source_ref = gr.vector_source_b(([1,]), True, 1)
        #create a comparator 
        self.comparator = howto.compare_vector_cci((1, 1, 1, 1 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), (0,0, 1, 1, 0,0), 5, 0, True)
        
        self._ber = grc_blks2.error_rate(type='BER', 
                                         win_size=1000,
                                         bits_per_symbol=1)
        
        self._slicer = digital.binary_slicer_fb()
        
        
        self.gr_null_sink_f = gr.null_sink(gr.sizeof_float*1)
        
        # Add an SNR probe on the demodulated constellation
        #self._snr_probe = gr.probe_mpsk_snr_c(10.0/symbol_rate)
        self._snr_probe = digital.mpsk_snr_est_cc(0, 10000, 0.001) # 0 at the first mean Simple
        self.gr_null_sink_cc = gr.null_sink(gr.sizeof_gr_complex*1)
        
        self.gr_null_source = gr.null_source(gr.sizeof_float*1)
        
        ###############################
        ###------->                                            -->gr_float_to_complex--->_snr_probe --> gr_null_sink_cc
        ###---->fmdemod -->freq_offset--->sub-->clock_recovery --> _slicer -->_descrambler --> comparator -->_ber--> self.gr_null_sink_f 
        ###'''''''''''''|-->----------------|-->'                      _vector_source_ref-->
        #############################
        # Connect
        
        self.connect(self, self.fmdemod)
        self.connect(self.fmdemod, (self.sub, 0))
        self.connect(self.fmdemod, self.freq_offset, (self.sub, 1))
        
        #self.connect(self.sub, self.clock_recovery_f, self._slicer, self._descrambler, self.comparator, (self._ber, 0))
        self.connect(self.sub, self.clock_recovery_f, self._slicer, self.comparator, (self._ber, 0))
        
#        self.connect(self.clock_recovery_f, (self.gr_float_to_complex, 1))
#        self.connect(self.gr_null_source, (self.gr_float_to_complex, 0))
#    
#        self.connect(self.gr_float_to_complex, self._snr_probe, self.gr_null_sink_cc)
        
        self.connect(self._vector_source_ref, (self._ber,1))
        self.connect(self._ber, self.gr_null_sink_f)
Exemple #38
0
	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))
Exemple #39
0
    def __init__(self, fft_length, cp_length, kstime, logging=False):
        """
        OFDM synchronization using PN Correlation and initial cross-correlation:
        F. Tufvesson, O. Edfors, and M. Faulkner, "Time and Frequency Synchronization for OFDM using
        PN-Sequency Preambles," IEEE Proc. VTC, 1999, pp. 2203-2207.

        This implementation is meant to be a more robust version of the Schmidl and Cox receiver design.
        By correlating against the preamble and using that as the input to the time-delayed correlation,
        this circuit produces a very clean timing signal at the end of the preamble. The timing is 
        more accurate and does not have the problem associated with determining the timing from the
        plateau structure in the Schmidl and Cox.

        This implementation appears to require that the signal is received with a normalized power or signal
        scalling factor to reduce ambiguities intorduced from partial correlation of the cyclic prefix and
        the peak detection. A better peak detection block might fix this.

        Also, the cross-correlation falls apart as the frequency offset gets larger and completely fails
        when an integer offset is introduced. Another thing to look at.
        """

        gr.hier_block2.__init__(
            self,
            "ofdm_sync_pnac",
            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)

        symbol_length = fft_length + cp_length

        # PN Sync with cross-correlation input

        # cross-correlate with the known symbol
        kstime = [k.conjugate() for k in kstime[0:fft_length // 2]]
        kstime.reverse()
        self.crosscorr_filter = gr.fir_filter_ccc(1, kstime)

        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length / 2)

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

        # Create a moving sum filter for the input
        self.mag = gr.complex_to_mag_squared()
        movingsum_taps = (fft_length // 1) * [
            1.0,
        ]
        self.power = gr.fir_filter_fff(1, movingsum_taps)

        # Get magnitude (peaks) and angle (phase/freq error)
        self.c2mag = gr.complex_to_mag_squared()
        self.angle = gr.complex_to_arg()
        self.compare = gr.sub_ff()

        self.sample_and_hold = gr.sample_and_hold_ff()

        #ML measurements input to sampler block and detect
        self.threshold = gr.threshold_ff(
            0, 0, 0)  # threshold detection might need to be tweaked
        self.peaks = gr.float_to_char()

        self.connect(self, self.input)

        # Cross-correlate input signal with known preamble
        self.connect(self.input, self.crosscorr_filter)

        # use the output of the cross-correlation as input time-shifted correlation
        self.connect(self.crosscorr_filter, self.delay)
        self.connect(self.crosscorr_filter, (self.corr, 0))
        self.connect(self.delay, self.conjg)
        self.connect(self.conjg, (self.corr, 1))
        self.connect(self.corr, self.c2mag)
        self.connect(self.corr, self.angle)
        self.connect(self.angle, (self.sample_and_hold, 0))

        # Get the power of the input signal to compare against the correlation
        self.connect(self.crosscorr_filter, self.mag, self.power)

        # Compare the power to the correlator output to determine timing peak
        # When the peak occurs, it peaks above zero, so the thresholder detects this
        self.connect(self.c2mag, (self.compare, 0))
        self.connect(self.power, (self.compare, 1))
        self.connect(self.compare, self.threshold)
        self.connect(self.threshold, self.peaks, (self.sample_and_hold, 1))

        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self, 0))
        self.connect(self.peaks, (self, 1))

        if logging:
            self.connect(
                self.compare,
                gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-compare_f.dat"))
            self.connect(
                self.c2mag,
                gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-theta_f.dat"))
            self.connect(
                self.power,
                gr.file_sink(gr.sizeof_float,
                             "ofdm_sync_pnac-inputpower_f.dat"))
            self.connect(
                self.angle,
                gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-epsilon_f.dat"))
            self.connect(
                self.threshold,
                gr.file_sink(gr.sizeof_float,
                             "ofdm_sync_pnac-threshold_f.dat"))
            self.connect(
                self.peaks,
                gr.file_sink(gr.sizeof_char, "ofdm_sync_pnac-peaks_b.dat"))
            self.connect(
                self.sample_and_hold,
                gr.file_sink(gr.sizeof_float,
                             "ofdm_sync_pnac-sample_and_hold_f.dat"))
            self.connect(
                self.input,
                gr.file_sink(gr.sizeof_gr_complex,
                             "ofdm_sync_pnac-input_c.dat"))
    def __init__(self, fft_length, cp_length, kstime, logging=False):
        """
        OFDM synchronization using PN Correlation and initial cross-correlation:
        F. Tufvesson, O. Edfors, and M. Faulkner, "Time and Frequency Synchronization for OFDM using
        PN-Sequency Preambles," IEEE Proc. VTC, 1999, pp. 2203-2207.

        This implementation is meant to be a more robust version of the Schmidl and Cox receiver design.
        By correlating against the preamble and using that as the input to the time-delayed correlation,
        this circuit produces a very clean timing signal at the end of the preamble. The timing is 
        more accurate and does not have the problem associated with determining the timing from the
        plateau structure in the Schmidl and Cox.

        This implementation appears to require that the signal is received with a normalized power or signal
        scalling factor to reduce ambiguities intorduced from partial correlation of the cyclic prefix and
        the peak detection. A better peak detection block might fix this.

        Also, the cross-correlation falls apart as the frequency offset gets larger and completely fails
        when an integer offset is introduced. Another thing to look at.
        """

	gr.hier_block2.__init__(self, "ofdm_sync_pnac",
				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)

        symbol_length = fft_length + cp_length

        # PN Sync with cross-correlation input

        # cross-correlate with the known symbol
        kstime = [k.conjugate() for k in kstime[0:fft_length//2]]
        kstime.reverse()
        self.crosscorr_filter = filter.fir_filter_ccc(1, kstime)
        
        # Create a delay line
        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)

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

        # Create a moving sum filter for the input
        self.mag = gr.complex_to_mag_squared()
        movingsum_taps = (fft_length//1)*[1.0,]
        self.power = filter.fir_filter_fff(1,movingsum_taps)
     
        # Get magnitude (peaks) and angle (phase/freq error)
        self.c2mag = gr.complex_to_mag_squared()
        self.angle = gr.complex_to_arg()
        self.compare = gr.sub_ff()
        
        self.sample_and_hold = gr.sample_and_hold_ff()

        #ML measurements input to sampler block and detect
        self.threshold = gr.threshold_ff(0,0,0)      # threshold detection might need to be tweaked
        self.peaks = gr.float_to_char()

        self.connect(self, self.input)

        # Cross-correlate input signal with known preamble
        self.connect(self.input, self.crosscorr_filter)

        # use the output of the cross-correlation as input time-shifted correlation
        self.connect(self.crosscorr_filter, self.delay)
        self.connect(self.crosscorr_filter, (self.corr,0))
        self.connect(self.delay, self.conjg)
        self.connect(self.conjg, (self.corr,1))
        self.connect(self.corr, self.c2mag)
        self.connect(self.corr, self.angle)
        self.connect(self.angle, (self.sample_and_hold,0))
        
        # Get the power of the input signal to compare against the correlation
        self.connect(self.crosscorr_filter, self.mag, self.power)

        # Compare the power to the correlator output to determine timing peak
        # When the peak occurs, it peaks above zero, so the thresholder detects this
        self.connect(self.c2mag, (self.compare,0))
        self.connect(self.power, (self.compare,1))
        self.connect(self.compare, self.threshold)
        self.connect(self.threshold, self.peaks, (self.sample_and_hold,1))

        # Set output signals
        #    Output 0: fine frequency correction value
        #    Output 1: timing signal
        self.connect(self.sample_and_hold, (self,0))
        self.connect(self.peaks, (self,1))

        if logging:
            self.connect(self.compare, gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-compare_f.dat"))
            self.connect(self.c2mag, gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-theta_f.dat"))
            self.connect(self.power, gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-inputpower_f.dat"))
            self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-epsilon_f.dat"))
            self.connect(self.threshold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-threshold_f.dat"))
            self.connect(self.peaks, gr.file_sink(gr.sizeof_char, "ofdm_sync_pnac-peaks_b.dat"))
            self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pnac-sample_and_hold_f.dat"))
            self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pnac-input_c.dat"))
Exemple #41
0
def graph (args):

    nargs = len(args)
    if nargs == 2:
	infile = args[0]
        outfile = args[1]
    else:
        raise ValueError('usage: interp.py input_file output_file\n')

    tb = gr.top_block ()

    # Convert to a from shorts to a stream of complex numbers.
    srcf = gr.file_source (gr.sizeof_short,infile)
    s2ss = gr.stream_to_streams(gr.sizeof_short,2)
    s2f1 = gr.short_to_float()
    s2f2 = gr.short_to_float()
    src0 = gr.float_to_complex()
    tb.connect(srcf, s2ss)
    tb.connect((s2ss, 0), s2f1, (src0, 0))
    tb.connect((s2ss, 1), s2f2, (src0, 1))

    # Low pass filter it and increase sample rate by a factor of 3.
    lp_coeffs = gr.firdes.low_pass ( 3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING )
    lp = gr.interp_fir_filter_ccf ( 3, lp_coeffs )
    tb.connect(src0, lp)

    # Upconvert it.
    duc_coeffs = gr.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, gr.firdes.WIN_HAMMING )
    duc = gr.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, 5.75e6, 19.2e6 )
    # Discard the imaginary component.
    c2f = gr.complex_to_float()
    tb.connect(lp, duc, c2f)

    # Frequency Phase Lock Loop
    input_rate = 19.2e6
    IF_freq = 5.75e6
    # 1/2 as wide because we're designing lp filter
    symbol_rate = atsc.ATSC_SYMBOL_RATE/2.
    NTAPS = 279
    tt = gr.firdes.root_raised_cosine (1.0, input_rate, symbol_rate, .115, NTAPS)
    # heterodyne the low pass coefficients up to the specified bandpass
    # center frequency.  Note that when we do this, the filter bandwidth
    # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
    # matches the diagram in the ATSC spec.
    arg = 2. * math.pi * IF_freq / input_rate
    t=[]
    for i in range(len(tt)):
        t += [tt[i] * 2. * math.cos(arg * i)]
    rrc = gr.fir_filter_fff(1, t)

    fpll = atsc.fpll()

    pilot_freq = IF_freq - 3e6 + 0.31e6
    lower_edge = 6e6 - 0.31e6
    upper_edge = IF_freq - 3e6 + pilot_freq
    transition_width = upper_edge - lower_edge
    lp_coeffs = gr.firdes.low_pass (1.0,
                                    input_rate,
                                    (lower_edge + upper_edge) * 0.5,
                                    transition_width,
                                    gr.firdes.WIN_HAMMING);
    
    lp_filter = gr.fir_filter_fff (1,lp_coeffs)
    
    alpha = 1e-5
    iir = gr.single_pole_iir_filter_ff(alpha)
    remove_dc = gr.sub_ff()

    tb.connect(c2f, fpll, lp_filter)
    tb.connect(lp_filter, iir)
    tb.connect(lp_filter, (remove_dc,0))
    tb.connect(iir, (remove_dc,1))
    
    # Bit Timing Loop, Field Sync Checker and Equalizer

    btl = atsc.bit_timing_loop()
    fsc = atsc.fs_checker()
    eq = atsc.equalizer()
    fsd = atsc.field_sync_demux()

    tb.connect(remove_dc, btl)
    tb.connect((btl, 0),(fsc, 0),(eq, 0),(fsd, 0))
    tb.connect((btl, 1),(fsc, 1),(eq, 1),(fsd, 1))

    # Viterbi

    viterbi = atsc.viterbi_decoder()
    deinter = atsc.deinterleaver()
    rs_dec = atsc.rs_decoder()
    derand = atsc.derandomizer()
    depad = atsc.depad()
    dst = gr.file_sink(gr.sizeof_char, outfile)
    tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst)

    dst2 = gr.file_sink(gr.sizeof_gr_complex, "atsc_complex.data")
    tb.connect(src0, dst2)

    tb.run ()
Exemple #42
0
	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="Fm Stereo Tx")

		##################################################
		# Variables
		##################################################
		self.st_gain = st_gain = 10
		self.samp_rate = samp_rate = 195.312e3
		self.pilot_gain = pilot_gain = 80e-3
		self.mpx_rate = mpx_rate = 160e3
		self.Mono_gain = Mono_gain = 300e-3
		self.FM_freq = FM_freq = 96.5e6

		##################################################
		# Blocks
		##################################################
		_st_gain_sizer = wx.BoxSizer(wx.VERTICAL)
		self._st_gain_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_st_gain_sizer,
			value=self.st_gain,
			callback=self.set_st_gain,
			label='st_gain',
			converter=forms.float_converter(),
			proportion=0,
		)
		self._st_gain_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_st_gain_sizer,
			value=self.st_gain,
			callback=self.set_st_gain,
			minimum=0,
			maximum=100,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Add(_st_gain_sizer)
		_pilot_gain_sizer = wx.BoxSizer(wx.VERTICAL)
		self._pilot_gain_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_pilot_gain_sizer,
			value=self.pilot_gain,
			callback=self.set_pilot_gain,
			label='pilot_gain',
			converter=forms.float_converter(),
			proportion=0,
		)
		self._pilot_gain_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_pilot_gain_sizer,
			value=self.pilot_gain,
			callback=self.set_pilot_gain,
			minimum=0,
			maximum=1,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Add(_pilot_gain_sizer)
		self.notebook_0 = self.notebook_0 = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
		self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "FM")
		self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "audio")
		self.Add(self.notebook_0)
		_Mono_gain_sizer = wx.BoxSizer(wx.VERTICAL)
		self._Mono_gain_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_Mono_gain_sizer,
			value=self.Mono_gain,
			callback=self.set_Mono_gain,
			label='Mono_gain',
			converter=forms.float_converter(),
			proportion=0,
		)
		self._Mono_gain_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_Mono_gain_sizer,
			value=self.Mono_gain,
			callback=self.set_Mono_gain,
			minimum=0,
			maximum=1,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Add(_Mono_gain_sizer)
		_FM_freq_sizer = wx.BoxSizer(wx.VERTICAL)
		self._FM_freq_text_box = forms.text_box(
			parent=self.GetWin(),
			sizer=_FM_freq_sizer,
			value=self.FM_freq,
			callback=self.set_FM_freq,
			label='FM_freq',
			converter=forms.float_converter(),
			proportion=0,
		)
		self._FM_freq_slider = forms.slider(
			parent=self.GetWin(),
			sizer=_FM_freq_sizer,
			value=self.FM_freq,
			callback=self.set_FM_freq,
			minimum=88e6,
			maximum=108e6,
			num_steps=100,
			style=wx.SL_HORIZONTAL,
			cast=float,
			proportion=1,
		)
		self.Add(_FM_freq_sizer)
		self.wxgui_fftsink2_1 = fftsink2.fft_sink_f(
			self.notebook_0.GetPage(1).GetWin(),
			baseband_freq=0,
			y_per_div=10,
			y_divs=10,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=samp_rate,
			fft_size=1024,
			fft_rate=15,
			average=False,
			avg_alpha=None,
			title="FFT Plot",
			peak_hold=False,
		)
		self.notebook_0.GetPage(1).Add(self.wxgui_fftsink2_1.win)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
			self.notebook_0.GetPage(0).GetWin(),
			baseband_freq=FM_freq,
			y_per_div=10,
			y_divs=10,
			ref_level=0,
			ref_scale=2.0,
			sample_rate=samp_rate,
			fft_size=1024,
			fft_rate=15,
			average=False,
			avg_alpha=None,
			title="FFT Plot",
			peak_hold=False,
		)
		self.notebook_0.GetPage(0).Add(self.wxgui_fftsink2_0.win)
		self.uhd_usrp_sink_0 = uhd.usrp_sink(
			device_addr="addr=192.168.10.2",
			stream_args=uhd.stream_args(
				cpu_format="fc32",
				channels=range(1),
			),
		)
		self.uhd_usrp_sink_0.set_samp_rate(samp_rate)
		self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0)
		self.uhd_usrp_sink_0.set_gain(0, 0)
		self.uhd_usrp_sink_0.set_antenna("TX/RX", 0)
		self.low_pass_filter_0 = gr.fir_filter_fff(1, firdes.low_pass(
			Mono_gain, mpx_rate, 15000, 2000, firdes.WIN_HAMMING, 6.76))
		self.gr_vector_to_streams_0 = gr.vector_to_streams(gr.sizeof_short*1, 2)
		self.gr_sub_xx_0 = gr.sub_ff(1)
		self.gr_sig_source_x_1 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 19000, pilot_gain, 0)
		self.gr_sig_source_x_0 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 38000, 30e-3, 0)
		self.gr_short_to_float_1 = gr.short_to_float(1, 1)
		self.gr_short_to_float_0 = gr.short_to_float(1, 1)
		self.gr_multiply_xx_0 = gr.multiply_vff(1)
		self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc((32.768e3, ))
		self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((30e-6, ))
		self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((30e-6, ))
		self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(980e-3)
		self.gr_file_source_0 = gr.file_source(gr.sizeof_short*2, "/home/kranthi/Documents/project/FM Transceiver/FM Transmitter/test.raw", True)
		self.gr_add_xx_1 = gr.add_vff(1)
		self.gr_add_xx_0 = gr.add_vff(1)
		self.blks2_rational_resampler_xxx_2 = blks2.rational_resampler_fff(
			interpolation=4,
			decimation=1,
			taps=None,
			fractional_bw=None,
		)
		self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff(
			interpolation=5,
			decimation=1,
			taps=None,
			fractional_bw=None,
		)
		self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff(
			interpolation=5,
			decimation=1,
			taps=None,
			fractional_bw=None,
		)
		self.blks2_fm_preemph_0 = blks2.fm_preemph(fs=mpx_rate, tau=50e-6)
		self.band_pass_filter_0 = gr.fir_filter_fff(1, firdes.band_pass(
			st_gain, mpx_rate, 23000, 53000, 2000, firdes.WIN_HAMMING, 6.76))

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_file_source_0, 0), (self.gr_vector_to_streams_0, 0))
		self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0))
		self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_1, 0))
		self.connect((self.gr_short_to_float_0, 0), (self.gr_multiply_const_vxx_0, 0))
		self.connect((self.gr_short_to_float_1, 0), (self.gr_multiply_const_vxx_1, 0))
		self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_rational_resampler_xxx_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.blks2_rational_resampler_xxx_1, 0))
		self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.gr_add_xx_0, 1))
		self.connect((self.blks2_rational_resampler_xxx_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.blks2_rational_resampler_xxx_1, 0), (self.gr_add_xx_0, 0))
		self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0, 0))
		self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 0))
		self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_0, 1))
		self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0))
		self.connect((self.gr_sig_source_x_1, 0), (self.gr_add_xx_1, 0))
		self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 1))
		self.connect((self.low_pass_filter_0, 0), (self.gr_add_xx_1, 2))
		self.connect((self.gr_add_xx_1, 0), (self.blks2_fm_preemph_0, 0))
		self.connect((self.blks2_fm_preemph_0, 0), (self.blks2_rational_resampler_xxx_2, 0))
		self.connect((self.blks2_rational_resampler_xxx_2, 0), (self.gr_frequency_modulator_fc_0, 0))
		self.connect((self.gr_frequency_modulator_fc_0, 0), (self.gr_multiply_const_vxx_2, 0))
		self.connect((self.gr_multiply_const_vxx_2, 0), (self.uhd_usrp_sink_0, 0))
		self.connect((self.gr_multiply_const_vxx_2, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_fftsink2_1, 0))
Exemple #43
0
	def __init__(self):
		gr.top_block.__init__ (self)

		parser=OptionParser(option_class=eng_option)
		parser.add_option("-H", "--hostname", type="string", default="localhost",
						  help="set hostname of generic sdr")
		parser.add_option("-P", "--portnum", type="int", default=None,
						  help="set portnum of generic sdr")
		parser.add_option("-W", "--wsportnum", type="int", default=None,
						  help="set portnum of audio websocket server")
		parser.add_option("-r", "--sdr_rate", type="eng_float", default=250e3,
						  help="set sample rate of generic sdr")
		parser.add_option("-V", "--volume", type="eng_float", default=None,
						  help="set volume (default is midpoint)")
		parser.add_option("-O", "--audio-output", type="string", default="plughw:0,0",
						  help="pcm device name (default is plughw:0,0)")

		# print help when called with wrong arguments
		(options, args) = parser.parse_args()
		if len(args) != 0:
			parser.print_help()
			sys.exit(1)

		self.vol = options.volume
		if self.vol is None:
			self.vol = 0.1

		# connect to generic SDR
		sdr_rate = options.sdr_rate
		audio_decim = 8
		audio_rate = int(sdr_rate/audio_decim)
		print "audio_rate = ", audio_rate
		self.interleaved_short_to_complex = gr.interleaved_short_to_complex()
		self.char_to_short = gr.char_to_short(1)
		self.sdr_source = grc_blks2.tcp_source(
			itemsize=gr.sizeof_char*1,
			addr=options.hostname,
			port=options.portnum,
			server=False
		)
#		self.sdr_source = gr.file_source(1, 'sdrs_baseband.dat')
#		self.throttle = gr.throttle(1, 500e3)
#		self.connect(self.sdr_source, self.file_sink)
		self.logger = gr.file_sink(1, 'log.out')
		self.connect(self.sdr_source, self.logger)


		# channel filter
		chan_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			80e3,			# passband cutoff
			35e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.chan_filter = gr.fir_filter_ccf(1, chan_filter_coeffs)
#		print "# channel filter:", len(chan_filter_coeffs), "taps"

		# PLL-based WFM demod
		fm_alpha = 0.25 * 250e3 * math.pi / sdr_rate		# 0.767
		fm_beta = fm_alpha * fm_alpha / 4.0			# 0.147
		fm_max_freq = 2.0 * math.pi * 90e3 / sdr_rate		# 2.209
		self.fm_demod = gr.pll_freqdet_cf(
			1.0,				# Loop BW
			fm_max_freq,		# in radians/sample
			-fm_max_freq)
		self.fm_demod.set_alpha(fm_alpha)
		self.fm_demod.set_beta(fm_beta)
		self.connect(self.sdr_source, self.char_to_short)
		self.connect(self.char_to_short, self.interleaved_short_to_complex)
		self.connect(self.interleaved_short_to_complex, self.chan_filter, self.fm_demod)

		# L+R, pilot, L-R, RDS filters
		lpr_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			15e3,			# passband cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.lpr_filter = gr.fir_filter_fff(audio_decim, lpr_filter_coeffs)
		pilot_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			19e3-500,		# low cutoff
			19e3+500,		# high cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.pilot_filter = gr.fir_filter_fff(1, pilot_filter_coeffs)
		dsbsc_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			38e3-15e3/2,	# low cutoff
			38e3+15e3/2,	# high cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.dsbsc_filter = gr.fir_filter_fff(1, dsbsc_filter_coeffs)
		rds_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			57e3-3e3,		# low cutoff
			57e3+3e3,		# high cutoff
			3e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_filter = gr.fir_filter_fff(1, rds_filter_coeffs)
#		print "# lpr filter:", len(lpr_filter_coeffs), "taps"
#		print "# pilot filter:", len(pilot_filter_coeffs), "taps"
#		print "# dsbsc filter:", len(dsbsc_filter_coeffs), "taps"
#		print "# rds filter:", len(rds_filter_coeffs), "taps"
		self.connect(self.fm_demod, self.lpr_filter)
		self.connect(self.fm_demod, self.pilot_filter)
		self.connect(self.fm_demod, self.dsbsc_filter)
		self.connect(self.fm_demod, self.rds_filter)

		# down-convert L-R, RDS
		self.stereo_baseband = gr.multiply_ff()
		self.connect(self.pilot_filter, (self.stereo_baseband, 0))
		self.connect(self.pilot_filter, (self.stereo_baseband, 1))
		self.connect(self.dsbsc_filter, (self.stereo_baseband, 2))
		self.rds_baseband = gr.multiply_ff()
		self.connect(self.pilot_filter, (self.rds_baseband, 0))
		self.connect(self.pilot_filter, (self.rds_baseband, 1))
		self.connect(self.pilot_filter, (self.rds_baseband, 2))
		self.connect(self.rds_filter, (self.rds_baseband, 3))

		# low-pass and downsample L-R
		lmr_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			15e3,			# passband cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.lmr_filter = gr.fir_filter_fff(audio_decim, lmr_filter_coeffs)
		self.connect(self.stereo_baseband, self.lmr_filter)

		# create L, R from L-R, L+R
		self.left = gr.add_ff()
		self.right = gr.sub_ff()
		self.connect(self.lpr_filter, (self.left, 0))
		self.connect(self.lmr_filter, (self.left, 1))
		self.connect(self.lpr_filter, (self.right, 0))
		self.connect(self.lmr_filter, (self.right, 1))

		# volume control, complex2flot, audio sink
		self.volume_control_l = gr.multiply_const_ff(self.vol)
		self.volume_control_r = gr.multiply_const_ff(self.vol)
		output_audio_rate = 48000
		self.resamp_L = blks2.rational_resampler_fff(interpolation=output_audio_rate,decimation=audio_rate,taps=None,fractional_bw=None,)
		self.resamp_R = blks2.rational_resampler_fff(interpolation=output_audio_rate,decimation=audio_rate,taps=None,fractional_bw=None,)
		self.connect(self.left,  self.volume_control_l, self.resamp_L)
		self.connect(self.right, self.volume_control_r, self.resamp_R)
#		self.audio_sink = audio.sink(int(output_audio_rate),
#							options.audio_output, False)
# 		self.connect(self.resamp_L, (self.audio_sink, 0))
#		self.connect(self.resamp_R, (self.audio_sink, 1))
#		self.file_sink1 = gr.file_sink(gr.sizeof_float, 'audioL.dat')
#		self.file_sink2 = gr.file_sink(gr.sizeof_float, 'audioR.dat')
#		self.file_sink3 = gr.file_sink(gr.sizeof_float, 'fmDemod.dat')
#       		self.connect(self.resamp_L, self.file_sink1)
#		self.connect(self.resamp_R, self.file_sink2)
#		self.connect(self.fm_demod, self.file_sink3)

		# Interleave both channels so that we can push over one websocket connection
		self.audio_interleaver = gr.float_to_complex(1)
		self.connect(self.resamp_L, (self.audio_interleaver, 0))
		self.connect(self.resamp_R, (self.audio_interleaver, 1))
		
		self.ws_audio_server = sdrportal.ws_sink_c(True, options.wsportnum, "FLOAT")
		self.connect(self.audio_interleaver, self.ws_audio_server)

		# low-pass the baseband RDS signal at 1.5kHz
		rds_bb_filter_coeffs = gr.firdes.low_pass(
			1,				# gain
			sdr_rate,		# sampling rate
			1.5e3,			# passband cutoff
			2e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_bb_filter = gr.fir_filter_fff(audio_decim, rds_bb_filter_coeffs)
#		print "# rds bb filter:", len(rds_bb_filter_coeffs), "taps"
		self.connect(self.rds_baseband, self.rds_bb_filter)

		# 1187.5bps = 19kHz/16
		self.clock_divider = rds.freq_divider(16)
		rds_clock_taps = gr.firdes.low_pass(
			1,				# gain
			sdr_rate,		# sampling rate
			1.2e3,			# passband cutoff
			1.5e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_clock = gr.fir_filter_fff(audio_decim, rds_clock_taps)
#		print "# rds clock filter:", len(rds_clock_taps), "taps"
		self.connect(self.pilot_filter, self.clock_divider, self.rds_clock)

		# bpsk_demod, diff_decoder, rds_decoder
		self.bpsk_demod = rds.bpsk_demod(audio_rate)
		self.differential_decoder = gr.diff_decoder_bb(2)
		self.msgq = gr.msg_queue()
		self.rds_decoder = rds.data_decoder(self.msgq)
		self.connect(self.rds_bb_filter, (self.bpsk_demod, 0))
		self.connect(self.rds_clock, (self.bpsk_demod, 1))
		self.connect(self.bpsk_demod, self.differential_decoder)
		self.connect(self.differential_decoder, self.rds_decoder)
Exemple #44
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("-R", "--rx-subdev-spec", type="subdev", default=None,
						  help="select USRP Rx side A or B (default=A)")
		parser.add_option("-f", "--freq", type="eng_float", default=91.2e6,
						  help="set frequency to FREQ", metavar="FREQ")
		parser.add_option("-g", "--gain", type="eng_float", default=None,
						  help="set gain in dB")
# FIXME add squelch
		parser.add_option("-s", "--squelch", type="eng_float", default=0,
						  help="set squelch level (default is 0)")
		parser.add_option("-V", "--volume", type="eng_float", default=None,
						  help="set volume (default is midpoint)")
		parser.add_option("-O", "--audio-output", type="string", default="plughw:0,0",
						  help="pcm device name (default is plughw:0,0)")

		# print help when called with wrong arguments
		(options, args) = parser.parse_args()
		if len(args) != 0:
			parser.print_help()
			sys.exit(1)

		# connect to USRP
		usrp_decim = 250
		self.u = usrp.source_c(0, usrp_decim)
		print "USRP Serial:", self.u.serial_number()
		usrp_rate = self.u.adc_rate() / usrp_decim		# 256 kS/s
		print "usrp_rate =", usrp_rate
		audio_decim = 8
		audio_rate = usrp_rate / audio_decim			# 32 kS/s
		print "audio_rate =", audio_rate
		#if options.rx_subdev_spec is None:
		#	options.rx_subdev_spec = usrp.pick_subdev(self.u, dblist)

		self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
		self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
		print "Using d'board", self.subdev.side_and_name()

		# gain, volume, frequency
		self.gain = options.gain
		if options.gain is None:
			g = self.subdev.gain_range()
			self.gain = float(g[0]+g[1])/2
		self.vol = options.volume
		if self.vol is None:
			g = self.volume_range()
			self.vol = float(g[0]+g[1])/2
		self.freq = options.freq
		print "Volume:%r, Gain:%r, Freq:%3.1f MHz" % (self.vol, self.gain, self.freq/1e6)

		# channel filter
		chan_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			usrp_rate,		# sampling rate
			80e3,			# passband cutoff
			35e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.chan_filter = gr.fir_filter_ccf(1, chan_filter_coeffs)
		print "# channel filter:", len(chan_filter_coeffs), "taps"

		# PLL-based WFM demod
		fm_alpha = 0.25 * 250e3 * math.pi / usrp_rate		# 0.767
		fm_beta = fm_alpha * fm_alpha / 4.0					# 0.147
		fm_max_freq = 2.0 * math.pi * 90e3 / usrp_rate		# 2.209
		self.fm_demod = gr.pll_freqdet_cf(
			#fm_alpha,			# phase gain
			#fm_beta,			# freq gain
			1.0,				# Loop BW
			fm_max_freq,		# in radians/sample
			-fm_max_freq)
		self.fm_demod.set_alpha(fm_alpha)
		self.fm_demod.set_beta(fm_beta)
		self.connect(self.u, self.chan_filter, self.fm_demod)

		# L+R, pilot, L-R, RDS filters
		lpr_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			usrp_rate,		# sampling rate
			15e3,			# passband cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.lpr_filter = gr.fir_filter_fff(audio_decim, lpr_filter_coeffs)
		pilot_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			usrp_rate,		# sampling rate
			19e3-500,		# low cutoff
			19e3+500,		# high cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.pilot_filter = gr.fir_filter_fff(1, pilot_filter_coeffs)
		dsbsc_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			usrp_rate,		# sampling rate
			38e3-15e3/2,	# low cutoff
			38e3+15e3/2,	# high cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.dsbsc_filter = gr.fir_filter_fff(1, dsbsc_filter_coeffs)
		rds_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			usrp_rate,		# sampling rate
			57e3-3e3,		# low cutoff
			57e3+3e3,		# high cutoff
			3e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_filter = gr.fir_filter_fff(1, rds_filter_coeffs)
		print "# lpr filter:", len(lpr_filter_coeffs), "taps"
		print "# pilot filter:", len(pilot_filter_coeffs), "taps"
		print "# dsbsc filter:", len(dsbsc_filter_coeffs), "taps"
		print "# rds filter:", len(rds_filter_coeffs), "taps"
		self.connect(self.fm_demod, self.lpr_filter)
		self.connect(self.fm_demod, self.pilot_filter)
		self.connect(self.fm_demod, self.dsbsc_filter)
		self.connect(self.fm_demod, self.rds_filter)

		# down-convert L-R, RDS
		self.stereo_baseband = gr.multiply_ff()
		self.connect(self.pilot_filter, (self.stereo_baseband, 0))
		self.connect(self.pilot_filter, (self.stereo_baseband, 1))
		self.connect(self.dsbsc_filter, (self.stereo_baseband, 2))
		self.rds_baseband = gr.multiply_ff()
		self.connect(self.pilot_filter, (self.rds_baseband, 0))
		self.connect(self.pilot_filter, (self.rds_baseband, 1))
		self.connect(self.pilot_filter, (self.rds_baseband, 2))
		self.connect(self.rds_filter, (self.rds_baseband, 3))

		# low-pass and downsample L-R
		lmr_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			usrp_rate,		# sampling rate
			15e3,			# passband cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.lmr_filter = gr.fir_filter_fff(audio_decim, lmr_filter_coeffs)
		self.connect(self.stereo_baseband, self.lmr_filter)

		# create L, R from L-R, L+R
		self.left = gr.add_ff()
		self.right = gr.sub_ff()
		self.connect(self.lpr_filter, (self.left, 0))
		self.connect(self.lmr_filter, (self.left, 1))
		self.connect(self.lpr_filter, (self.right, 0))
		self.connect(self.lmr_filter, (self.right, 1))

		# volume control, complex2flot, audio sink
		self.volume_control_l = gr.multiply_const_ff(self.vol)
		self.volume_control_r = gr.multiply_const_ff(self.vol)
		output_audio_rate = 48000
		self.audio_sink = audio.sink(int(output_audio_rate),
							options.audio_output, False)
		#self.connect(self.left, self.volume_control_l, (self.audio_sink, 0))
		#self.connect(self.right, self.volume_control_r, (self.audio_sink, 1))
		self.resamp_L = blks2.rational_resampler_fff(interpolation=output_audio_rate,decimation=audio_rate,taps=None,fractional_bw=None,)
		self.resamp_R = blks2.rational_resampler_fff(interpolation=output_audio_rate,decimation=audio_rate,taps=None,fractional_bw=None,)
		self.connect(self.left,  self.volume_control_l, self.resamp_L, (self.audio_sink, 0))
		self.connect(self.right, self.volume_control_r, self.resamp_R, (self.audio_sink, 1))

		# low-pass the baseband RDS signal at 1.5kHz
		rds_bb_filter_coeffs = gr.firdes.low_pass(
			1,				# gain
			usrp_rate,		# sampling rate
			1.5e3,			# passband cutoff
			2e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_bb_filter = gr.fir_filter_fff(audio_decim, rds_bb_filter_coeffs)
		print "# rds bb filter:", len(rds_bb_filter_coeffs), "taps"
		self.connect(self.rds_baseband, self.rds_bb_filter)

		# 1187.5bps = 19kHz/16
		self.clock_divider = rds.freq_divider(16)
		rds_clock_taps = gr.firdes.low_pass(
			1,				# gain
			usrp_rate,		# sampling rate
			1.2e3,			# passband cutoff
			1.5e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_clock = gr.fir_filter_fff(audio_decim, rds_clock_taps)
		print "# rds clock filter:", len(rds_clock_taps), "taps"
		self.connect(self.pilot_filter, self.clock_divider, self.rds_clock)

		# bpsk_demod, diff_decoder, rds_decoder
		self.bpsk_demod = rds.bpsk_demod(audio_rate)
		self.differential_decoder = gr.diff_decoder_bb(2)
		self.msgq = gr.msg_queue()
		self.rds_decoder = rds.data_decoder(self.msgq)
		self.connect(self.rds_bb_filter, (self.bpsk_demod, 0))
		self.connect(self.rds_clock, (self.bpsk_demod, 1))
		self.connect(self.bpsk_demod, self.differential_decoder)
		self.connect(self.differential_decoder, self.rds_decoder)


		self.frame = frame
		self.panel = panel
		self._build_gui(vbox, usrp_rate, audio_rate)
		self.set_gain(self.gain)
		self.set_vol(self.vol)
		if not(self.set_freq(self.freq)):
			self._set_status_msg("Failed to set initial frequency")	
Exemple #45
0
	def __init__(self):
		gr.top_block.__init__ (self)

		parser=OptionParser(option_class=eng_option)
		parser.add_option("-H", "--hostname", type="string", default="localhost",
						  help="set hostname of generic sdr")
		parser.add_option("-P", "--portnum", type="int", default=None,
						  help="set portnum of generic sdr")
		parser.add_option("-r", "--sdr_rate", type="eng_float", default=250e3,
						  help="set sample rate of generic sdr")
		parser.add_option("-V", "--volume", type="eng_float", default=None,
						  help="set volume (default is midpoint)")
		parser.add_option("-O", "--audio-output", type="string", default="plughw:0,0",
						  help="pcm device name (default is plughw:0,0)")

		# print help when called with wrong arguments
		(options, args) = parser.parse_args()
		if len(args) != 0:
			parser.print_help()
			sys.exit(1)

		self.vol = options.volume
		if self.vol is None:
			self.vol = 0.1

		# connect to generic SDR
		sdr_rate = options.sdr_rate
		audio_decim = 8
		audio_rate = int(sdr_rate/audio_decim)
		print "audio_rate = ", audio_rate
		self.interleaved_short_to_complex = gr.interleaved_short_to_complex()
		self.char_to_short = gr.char_to_short(1)
		self.sdr_source = grc_blks2.tcp_source(
			itemsize=gr.sizeof_char*1,
			addr=options.hostname,
			port=options.portnum,
			server=False
		)
#		self.sdr_source = gr.file_source(1, 'sdrs_baseband.dat')
#		self.throttle = gr.throttle(1, 500e3)
#		self.connect(self.sdr_source, self.file_sink)
		self.logger = gr.file_sink(1, 'log.out')
		self.connect(self.sdr_source, self.logger)


		# channel filter
		chan_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			80e3,			# passband cutoff
			35e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.chan_filter = gr.fir_filter_ccf(1, chan_filter_coeffs)
#		print "# channel filter:", len(chan_filter_coeffs), "taps"

		# PLL-based WFM demod
		fm_alpha = 0.25 * 250e3 * math.pi / sdr_rate		# 0.767
		fm_beta = fm_alpha * fm_alpha / 4.0			# 0.147
		fm_max_freq = 2.0 * math.pi * 90e3 / sdr_rate		# 2.209
		self.fm_demod = gr.pll_freqdet_cf(
			1.0,				# Loop BW
			fm_max_freq,		# in radians/sample
			-fm_max_freq)
		self.fm_demod.set_alpha(fm_alpha)
		self.fm_demod.set_beta(fm_beta)
		self.connect(self.sdr_source, self.char_to_short)
		self.connect(self.char_to_short, self.interleaved_short_to_complex)
		self.connect(self.interleaved_short_to_complex, self.chan_filter, self.fm_demod)

		# L+R, pilot, L-R, RDS filters
		lpr_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			15e3,			# passband cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.lpr_filter = gr.fir_filter_fff(audio_decim, lpr_filter_coeffs)
		pilot_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			19e3-500,		# low cutoff
			19e3+500,		# high cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.pilot_filter = gr.fir_filter_fff(1, pilot_filter_coeffs)
		dsbsc_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			38e3-15e3/2,	# low cutoff
			38e3+15e3/2,	# high cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.dsbsc_filter = gr.fir_filter_fff(1, dsbsc_filter_coeffs)
		rds_filter_coeffs = gr.firdes.band_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			57e3-3e3,		# low cutoff
			57e3+3e3,		# high cutoff
			3e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_filter = gr.fir_filter_fff(1, rds_filter_coeffs)
#		print "# lpr filter:", len(lpr_filter_coeffs), "taps"
#		print "# pilot filter:", len(pilot_filter_coeffs), "taps"
#		print "# dsbsc filter:", len(dsbsc_filter_coeffs), "taps"
#		print "# rds filter:", len(rds_filter_coeffs), "taps"
		self.connect(self.fm_demod, self.lpr_filter)
		self.connect(self.fm_demod, self.pilot_filter)
		self.connect(self.fm_demod, self.dsbsc_filter)
		self.connect(self.fm_demod, self.rds_filter)

		# down-convert L-R, RDS
		self.stereo_baseband = gr.multiply_ff()
		self.connect(self.pilot_filter, (self.stereo_baseband, 0))
		self.connect(self.pilot_filter, (self.stereo_baseband, 1))
		self.connect(self.dsbsc_filter, (self.stereo_baseband, 2))
		self.rds_baseband = gr.multiply_ff()
		self.connect(self.pilot_filter, (self.rds_baseband, 0))
		self.connect(self.pilot_filter, (self.rds_baseband, 1))
		self.connect(self.pilot_filter, (self.rds_baseband, 2))
		self.connect(self.rds_filter, (self.rds_baseband, 3))

		# low-pass and downsample L-R
		lmr_filter_coeffs = gr.firdes.low_pass(
			1.0,			# gain
			sdr_rate,		# sampling rate
			15e3,			# passband cutoff
			1e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.lmr_filter = gr.fir_filter_fff(audio_decim, lmr_filter_coeffs)
		self.connect(self.stereo_baseband, self.lmr_filter)

		# create L, R from L-R, L+R
		self.left = gr.add_ff()
		self.right = gr.sub_ff()
		self.connect(self.lpr_filter, (self.left, 0))
		self.connect(self.lmr_filter, (self.left, 1))
		self.connect(self.lpr_filter, (self.right, 0))
		self.connect(self.lmr_filter, (self.right, 1))

		# volume control, complex2flot, audio sink
		self.volume_control_l = gr.multiply_const_ff(self.vol)
		self.volume_control_r = gr.multiply_const_ff(self.vol)
		output_audio_rate = 48000
		self.resamp_L = blks2.rational_resampler_fff(interpolation=output_audio_rate,decimation=audio_rate,taps=None,fractional_bw=None,)
		self.resamp_R = blks2.rational_resampler_fff(interpolation=output_audio_rate,decimation=audio_rate,taps=None,fractional_bw=None,)
		self.connect(self.left,  self.volume_control_l, self.resamp_L)
		self.connect(self.right, self.volume_control_r, self.resamp_R)
#		self.audio_sink = audio.sink(int(output_audio_rate),
#							options.audio_output, False)
# 		self.connect(self.resamp_L, (self.audio_sink, 0))
#		self.connect(self.resamp_R, (self.audio_sink, 1))
		self.file_sink1 = gr.file_sink(gr.sizeof_float, 'audioL.dat')
		self.file_sink2 = gr.file_sink(gr.sizeof_float, 'audioR.dat')
		self.file_sink3 = gr.file_sink(gr.sizeof_float, 'fmDemod.dat')
       		self.connect(self.resamp_L, self.file_sink1)
		self.connect(self.resamp_R, self.file_sink2)
		self.connect(self.fm_demod, self.file_sink3)

		# low-pass the baseband RDS signal at 1.5kHz
		rds_bb_filter_coeffs = gr.firdes.low_pass(
			1,				# gain
			sdr_rate,		# sampling rate
			1.5e3,			# passband cutoff
			2e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_bb_filter = gr.fir_filter_fff(audio_decim, rds_bb_filter_coeffs)
#		print "# rds bb filter:", len(rds_bb_filter_coeffs), "taps"
		self.connect(self.rds_baseband, self.rds_bb_filter)

		# 1187.5bps = 19kHz/16
		self.clock_divider = rds.freq_divider(16)
		rds_clock_taps = gr.firdes.low_pass(
			1,				# gain
			sdr_rate,		# sampling rate
			1.2e3,			# passband cutoff
			1.5e3,			# transition width
			gr.firdes.WIN_HAMMING)
		self.rds_clock = gr.fir_filter_fff(audio_decim, rds_clock_taps)
#		print "# rds clock filter:", len(rds_clock_taps), "taps"
		self.connect(self.pilot_filter, self.clock_divider, self.rds_clock)

		# bpsk_demod, diff_decoder, rds_decoder
		self.bpsk_demod = rds.bpsk_demod(audio_rate)
		self.differential_decoder = gr.diff_decoder_bb(2)
		self.msgq = gr.msg_queue()
		self.rds_decoder = rds.data_decoder(self.msgq)
		self.connect(self.rds_bb_filter, (self.bpsk_demod, 0))
		self.connect(self.rds_clock, (self.bpsk_demod, 1))
		self.connect(self.bpsk_demod, self.differential_decoder)
		self.connect(self.differential_decoder, self.rds_decoder)
Exemple #46
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="",
                          help="read input from FILE")
        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        self.usrp_interp = 200
        self.u = usrp.sink_c(0, self.usrp_interp)
        print "USRP Serial: ", self.u.serial_number()
        self.dac_rate = self.u.dac_rate()  # 128 MS/s
        self.usrp_rate = self.dac_rate / self.usrp_interp  # 640 kS/s
        self.sw_interp = 5
        self.audio_rate = self.usrp_rate / self.sw_interp  # 128 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
        self.subdev.set_gain(self.subdev.gain_range()[1])
        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, "kS/s,", bits_per_sample, "bits/sample"

        # resample to 128kS/s
        if sample_rate == 44100:
            self.resample_left = blks2.rational_resampler_fff(32, 11)
            self.resample_right = blks2.rational_resampler_fff(32, 11)
        elif sample_rate == 48000:
            self.resample_left == blks2.rational_resampler_fff(8, 3)
            self.resample_right == blks2.rational_resampler_fff(8, 3)
        elif sample_rate == 8000:
            self.resample_left == blks2.rational_resampler_fff(16, 1)
            self.resample_right == blks2.rational_resampler_fff(16, 1)
        else:
            print sample_rate, "is an unsupported sample rate"
            sys.exit(1)
        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.3,  # gain
            self.audio_rate,  # sampling rate
            15e3,  # passband cutoff
            2e3,  # transition width
            gr.firdes.WIN_HANN)
        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(
            self.audio_rate,  # sampling freq
            gr.GR_SIN_WAVE,  # waveform
            19e3,  # frequency
            3e-2)  # amplitude

        # create the L-R signal carrier at 38 kHz, high-pass to remove 0Hz tone
        self.stereo_carrier = gr.multiply_ff()
        self.connect(self.pilot, (self.stereo_carrier, 0))
        self.connect(self.pilot, (self.stereo_carrier, 1))
        stereo_carrier_taps = gr.firdes.high_pass(
            1,  # gain
            self.audio_rate,  # sampling rate
            1e4,  # cutoff freq
            2e3,  # transition width
            gr.firdes.WIN_HANN)
        self.stereo_carrier_filter = gr.fir_filter_fff(1, stereo_carrier_taps)
        self.connect(self.stereo_carrier, self.stereo_carrier_filter)

        # upconvert L-R to 23-53 kHz and band-pass
        self.mix_stereo = gr.multiply_ff()
        audio_lmr_taps = gr.firdes.band_pass(
            3e3,  # gain
            self.audio_rate,  # sampling rate
            23e3,  # low cutoff
            53e3,  # high cuttof
            2e3,  # transition width
            gr.firdes.WIN_HANN)
        self.audio_lmr_filter = gr.fir_filter_fff(1, audio_lmr_taps)
        self.connect(self.audio_lmr, (self.mix_stereo, 0))
        self.connect(self.stereo_carrier_filter, (self.mix_stereo, 1))
        self.connect(self.mix_stereo, self.audio_lmr_filter)

        # mix L+R, pilot and L-R
        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))

        # interpolation & pre-emphasis
        interp_taps = gr.firdes.low_pass(
            self.sw_interp,  # gain
            self.audio_rate,  # Fs
            60e3,  # cutoff freq
            5e3,  # transition width
            gr.firdes.WIN_HAMMING)
        self.interpolator = gr.interp_fir_filter_fff(self.sw_interp,
                                                     interp_taps)
        self.pre_emph = blks2.fm_preemph(self.usrp_rate, tau=50e-6)
        self.connect(self.mixer, self.interpolator, self.pre_emph)

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

        # plot an FFT to verify we are sending what we want
        pre_mod = fftsink2.fft_sink_f(panel,
                                      title="Before Interpolation",
                                      fft_size=512,
                                      sample_rate=self.audio_rate,
                                      y_per_div=20,
                                      ref_level=20)
        self.connect(self.mixer, pre_mod)
        vbox.Add(pre_mod.win, 1, wx.EXPAND)
Exemple #47
0
def graph(args):

    nargs = len(args)
    if nargs == 2:
        infile = args[0]
        outfile = args[1]
    else:
        raise ValueError('usage: interp.py input_file output_file\n')

    tb = gr.top_block()

    # Convert to a from shorts to a stream of complex numbers.
    srcf = gr.file_source(gr.sizeof_short, infile)
    s2ss = gr.stream_to_streams(gr.sizeof_short, 2)
    s2f1 = gr.short_to_float()
    s2f2 = gr.short_to_float()
    src0 = gr.float_to_complex()
    tb.connect(srcf, s2ss)
    tb.connect((s2ss, 0), s2f1, (src0, 0))
    tb.connect((s2ss, 1), s2f2, (src0, 1))

    # Low pass filter it and increase sample rate by a factor of 3.
    lp_coeffs = gr.firdes.low_pass(3, 19.2e6, 3.2e6, .5e6,
                                   gr.firdes.WIN_HAMMING)
    lp = gr.interp_fir_filter_ccf(3, lp_coeffs)
    tb.connect(src0, lp)

    # Upconvert it.
    duc_coeffs = gr.firdes.low_pass(1, 19.2e6, 9e6, 1e6, gr.firdes.WIN_HAMMING)
    duc = gr.freq_xlating_fir_filter_ccf(1, duc_coeffs, 5.75e6, 19.2e6)
    # Discard the imaginary component.
    c2f = gr.complex_to_float()
    tb.connect(lp, duc, c2f)

    # Frequency Phase Lock Loop
    input_rate = 19.2e6
    IF_freq = 5.75e6
    # 1/2 as wide because we're designing lp filter
    symbol_rate = atsc.ATSC_SYMBOL_RATE / 2.
    NTAPS = 279
    tt = gr.firdes.root_raised_cosine(1.0, input_rate, symbol_rate, .115,
                                      NTAPS)
    # heterodyne the low pass coefficients up to the specified bandpass
    # center frequency.  Note that when we do this, the filter bandwidth
    # is effectively twice the low pass (2.69 * 2 = 5.38) and hence
    # matches the diagram in the ATSC spec.
    arg = 2. * math.pi * IF_freq / input_rate
    t = []
    for i in range(len(tt)):
        t += [tt[i] * 2. * math.cos(arg * i)]
    rrc = gr.fir_filter_fff(1, t)

    fpll = atsc.fpll()

    pilot_freq = IF_freq - 3e6 + 0.31e6
    lower_edge = 6e6 - 0.31e6
    upper_edge = IF_freq - 3e6 + pilot_freq
    transition_width = upper_edge - lower_edge
    lp_coeffs = gr.firdes.low_pass(1.0, input_rate,
                                   (lower_edge + upper_edge) * 0.5,
                                   transition_width, gr.firdes.WIN_HAMMING)

    lp_filter = gr.fir_filter_fff(1, lp_coeffs)

    alpha = 1e-5
    iir = gr.single_pole_iir_filter_ff(alpha)
    remove_dc = gr.sub_ff()

    tb.connect(c2f, fpll, lp_filter)
    tb.connect(lp_filter, iir)
    tb.connect(lp_filter, (remove_dc, 0))
    tb.connect(iir, (remove_dc, 1))

    # Bit Timing Loop, Field Sync Checker and Equalizer

    btl = atsc.bit_timing_loop()
    fsc = atsc.fs_checker()
    eq = atsc.equalizer()
    fsd = atsc.field_sync_demux()

    tb.connect(remove_dc, btl)
    tb.connect((btl, 0), (fsc, 0), (eq, 0), (fsd, 0))
    tb.connect((btl, 1), (fsc, 1), (eq, 1), (fsd, 1))

    # Viterbi

    viterbi = atsc.viterbi_decoder()
    deinter = atsc.deinterleaver()
    rs_dec = atsc.rs_decoder()
    derand = atsc.derandomizer()
    depad = atsc.depad()
    dst = gr.file_sink(gr.sizeof_char, outfile)
    tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst)

    dst2 = gr.file_sink(gr.sizeof_gr_complex, "atsc_complex.data")
    tb.connect(src0, dst2)

    tb.run()
Exemple #48
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, 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)
Exemple #49
0
    def test_001(self):
        vlen = 256
        subc = 208
        L = 8
        cplen = 12
        blocklen = vlen + cplen
        framelength = 11
        bits_per_subc = [2] * vlen
        data_blocks = 10

        N = int(1e8)

        profiling = False

        pre0, fd = morellimengali_designer.create(subc, vlen, L)


        ofdm_frames = \
          ofdm_frame_src( vlen, data_blocks, pre0, cplen, framelength,
                          bits_per_subc )

        uut = autocorrelator(vlen / 2, vlen / 2)

        ref = recursive_timing_metric(vlen)

        limit_stream = gr.head(gr.sizeof_float, N)

        self.tb.connect(ofdm_frames, uut, limit_stream,
                        gr.null_sink(gr.sizeof_float))

        #    limit_stream.enable_detailed_profiling( profiling )
        #    uut.s2.enable_detailed_profiling( profiling )

        if not profiling:
            limit_stream2 = gr.head(gr.sizeof_float, N)

            compare = gr.sub_ff()
            err_acc = ofdm.accumulator_ff()
            skip_err = gr.skiphead(gr.sizeof_float, N - 1)
            last_err_val = gr.head(gr.sizeof_float, 1)
            err_sink = gr.vector_sink_f()

            self.tb.connect(ofdm_frames, ref, limit_stream2,
                            gr.null_sink(gr.sizeof_float))

            self.tb.connect(uut, (compare, 0))
            self.tb.connect(ref, (compare, 1))
            self.tb.connect(compare, err_acc)
            self.tb.connect(err_acc, skip_err)
            self.tb.connect(skip_err, last_err_val)
            self.tb.connect(last_err_val, err_sink)


#    log_to_file( self.tb, limit_stream, "data/autocorr_uut.float" )
#    log_to_file( self.tb, limit_stream2, "data/autocorr_ref.float" )

#    r = time_it( self.tb )
        self.tb.run()

        #    print "Expected throughput:  %s Samples/s" % ( eng_notation.num_to_str( float(N) / r ) )

        if not profiling:
            e = numpy.array(err_sink.data())[0]
            print "Err: %.7f" % (e)
Exemple #50
0
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Fm Stereo Tx")

        ##################################################
        # Variables
        ##################################################
        self.st_gain = st_gain = 10
        self.samp_rate = samp_rate = 195.312e3
        self.pilot_gain = pilot_gain = 80e-3
        self.mpx_rate = mpx_rate = 160e3
        self.Mono_gain = Mono_gain = 300e-3
        self.FM_freq = FM_freq = 96.5e6

        ##################################################
        # Blocks
        ##################################################
        _st_gain_sizer = wx.BoxSizer(wx.VERTICAL)
        self._st_gain_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_st_gain_sizer,
            value=self.st_gain,
            callback=self.set_st_gain,
            label='st_gain',
            converter=forms.float_converter(),
            proportion=0,
        )
        self._st_gain_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_st_gain_sizer,
            value=self.st_gain,
            callback=self.set_st_gain,
            minimum=0,
            maximum=100,
            num_steps=100,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )
        self.Add(_st_gain_sizer)
        _pilot_gain_sizer = wx.BoxSizer(wx.VERTICAL)
        self._pilot_gain_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_pilot_gain_sizer,
            value=self.pilot_gain,
            callback=self.set_pilot_gain,
            label='pilot_gain',
            converter=forms.float_converter(),
            proportion=0,
        )
        self._pilot_gain_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_pilot_gain_sizer,
            value=self.pilot_gain,
            callback=self.set_pilot_gain,
            minimum=0,
            maximum=1,
            num_steps=100,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )
        self.Add(_pilot_gain_sizer)
        self.notebook_0 = self.notebook_0 = wx.Notebook(self.GetWin(),
                                                        style=wx.NB_TOP)
        self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "FM")
        self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "audio")
        self.Add(self.notebook_0)
        _Mono_gain_sizer = wx.BoxSizer(wx.VERTICAL)
        self._Mono_gain_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_Mono_gain_sizer,
            value=self.Mono_gain,
            callback=self.set_Mono_gain,
            label='Mono_gain',
            converter=forms.float_converter(),
            proportion=0,
        )
        self._Mono_gain_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_Mono_gain_sizer,
            value=self.Mono_gain,
            callback=self.set_Mono_gain,
            minimum=0,
            maximum=1,
            num_steps=100,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )
        self.Add(_Mono_gain_sizer)
        _FM_freq_sizer = wx.BoxSizer(wx.VERTICAL)
        self._FM_freq_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_FM_freq_sizer,
            value=self.FM_freq,
            callback=self.set_FM_freq,
            label='FM_freq',
            converter=forms.float_converter(),
            proportion=0,
        )
        self._FM_freq_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_FM_freq_sizer,
            value=self.FM_freq,
            callback=self.set_FM_freq,
            minimum=88e6,
            maximum=108e6,
            num_steps=100,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )
        self.Add(_FM_freq_sizer)
        self.wxgui_fftsink2_1 = fftsink2.fft_sink_f(
            self.notebook_0.GetPage(1).GetWin(),
            baseband_freq=0,
            y_per_div=10,
            y_divs=10,
            ref_level=0,
            ref_scale=2.0,
            sample_rate=samp_rate,
            fft_size=1024,
            fft_rate=15,
            average=False,
            avg_alpha=None,
            title="FFT Plot",
            peak_hold=False,
        )
        self.notebook_0.GetPage(1).Add(self.wxgui_fftsink2_1.win)
        self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
            self.notebook_0.GetPage(0).GetWin(),
            baseband_freq=FM_freq,
            y_per_div=10,
            y_divs=10,
            ref_level=0,
            ref_scale=2.0,
            sample_rate=samp_rate,
            fft_size=1024,
            fft_rate=15,
            average=False,
            avg_alpha=None,
            title="FFT Plot",
            peak_hold=False,
        )
        self.notebook_0.GetPage(0).Add(self.wxgui_fftsink2_0.win)
        self.uhd_usrp_sink_0 = uhd.usrp_sink(
            device_addr="addr=192.168.10.2",
            stream_args=uhd.stream_args(
                cpu_format="fc32",
                channels=range(1),
            ),
        )
        self.uhd_usrp_sink_0.set_samp_rate(samp_rate)
        self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0)
        self.uhd_usrp_sink_0.set_gain(0, 0)
        self.uhd_usrp_sink_0.set_antenna("TX/RX", 0)
        self.low_pass_filter_0 = gr.fir_filter_fff(
            1,
            firdes.low_pass(Mono_gain, mpx_rate, 15000, 2000,
                            firdes.WIN_HAMMING, 6.76))
        self.gr_vector_to_streams_0 = gr.vector_to_streams(
            gr.sizeof_short * 1, 2)
        self.gr_sub_xx_0 = gr.sub_ff(1)
        self.gr_sig_source_x_1 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 19000,
                                                 pilot_gain, 0)
        self.gr_sig_source_x_0 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 38000,
                                                 30e-3, 0)
        self.gr_short_to_float_1 = gr.short_to_float(1, 1)
        self.gr_short_to_float_0 = gr.short_to_float(1, 1)
        self.gr_multiply_xx_0 = gr.multiply_vff(1)
        self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc((32.768e3, ))
        self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((30e-6, ))
        self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((30e-6, ))
        self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(980e-3)
        self.gr_file_source_0 = gr.file_source(
            gr.sizeof_short * 2,
            "/home/kranthi/Documents/project/FM Transceiver/FM Transmitter/test.raw",
            True)
        self.gr_add_xx_1 = gr.add_vff(1)
        self.gr_add_xx_0 = gr.add_vff(1)
        self.blks2_rational_resampler_xxx_2 = blks2.rational_resampler_fff(
            interpolation=4,
            decimation=1,
            taps=None,
            fractional_bw=None,
        )
        self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff(
            interpolation=5,
            decimation=1,
            taps=None,
            fractional_bw=None,
        )
        self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff(
            interpolation=5,
            decimation=1,
            taps=None,
            fractional_bw=None,
        )
        self.blks2_fm_preemph_0 = blks2.fm_preemph(fs=mpx_rate, tau=50e-6)
        self.band_pass_filter_0 = gr.fir_filter_fff(
            1,
            firdes.band_pass(st_gain, mpx_rate, 23000, 53000, 2000,
                             firdes.WIN_HAMMING, 6.76))

        ##################################################
        # Connections
        ##################################################
        self.connect((self.gr_file_source_0, 0),
                     (self.gr_vector_to_streams_0, 0))
        self.connect((self.gr_vector_to_streams_0, 0),
                     (self.gr_short_to_float_0, 0))
        self.connect((self.gr_vector_to_streams_0, 1),
                     (self.gr_short_to_float_1, 0))
        self.connect((self.gr_short_to_float_0, 0),
                     (self.gr_multiply_const_vxx_0, 0))
        self.connect((self.gr_short_to_float_1, 0),
                     (self.gr_multiply_const_vxx_1, 0))
        self.connect((self.gr_multiply_const_vxx_0, 0),
                     (self.blks2_rational_resampler_xxx_0, 0))
        self.connect((self.gr_multiply_const_vxx_1, 0),
                     (self.blks2_rational_resampler_xxx_1, 0))
        self.connect((self.blks2_rational_resampler_xxx_0, 0),
                     (self.gr_add_xx_0, 1))
        self.connect((self.blks2_rational_resampler_xxx_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.blks2_rational_resampler_xxx_1, 0),
                     (self.gr_add_xx_0, 0))
        self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0, 0))
        self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 0))
        self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_0, 1))
        self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0))
        self.connect((self.gr_sig_source_x_1, 0), (self.gr_add_xx_1, 0))
        self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 1))
        self.connect((self.low_pass_filter_0, 0), (self.gr_add_xx_1, 2))
        self.connect((self.gr_add_xx_1, 0), (self.blks2_fm_preemph_0, 0))
        self.connect((self.blks2_fm_preemph_0, 0),
                     (self.blks2_rational_resampler_xxx_2, 0))
        self.connect((self.blks2_rational_resampler_xxx_2, 0),
                     (self.gr_frequency_modulator_fc_0, 0))
        self.connect((self.gr_frequency_modulator_fc_0, 0),
                     (self.gr_multiply_const_vxx_2, 0))
        self.connect((self.gr_multiply_const_vxx_2, 0),
                     (self.uhd_usrp_sink_0, 0))
        self.connect((self.gr_multiply_const_vxx_2, 0),
                     (self.wxgui_fftsink2_0, 0))
        self.connect((self.gr_multiply_const_vxx_1, 0),
                     (self.wxgui_fftsink2_1, 0))
 def test_sub_ff_1 (self):
     src1_data = (-1.0,  2.25, -3.5, 4, -5)
     expected_result = (1, -2.25, 3.5, -4, 5)
     op = gr.sub_ff (1)
     self.help_ff ((src1_data,),
                   expected_result, op, port_prefix='SINGLE_PORT')
    def __init__ (self, fg, demod_rate, audio_decimation):
        """
        Hierarchical block for demodulating a broadcast FM signal.
        
        The input is the downconverted complex baseband signal (gr_complex).
        The output is two streams of the demodulated audio (float) 0=Left, 1=Right.
        
        @param fg: flow graph.
        @type fg: flow graph
        @param demod_rate: input sample rate of complex baseband input.
        @type demod_rate: float
        @param audio_decimation: how much to decimate demod_rate to get to audio.
        @type audio_decimation: integer
        """

        bandwidth = 200e3
        audio_rate = demod_rate / audio_decimation


        # We assign to self so that outsiders can grab the demodulator 
        # if they need to.  E.g., to plot its output.
        #
        # input: complex; output: float
        alpha = 0.25*bandwidth * math.pi / demod_rate
        beta = alpha * alpha / 4.0
        max_freq = 2.0*math.pi*100e3/demod_rate
            
        self.fm_demod = gr.pll_freqdet_cf (alpha,beta,max_freq,-max_freq)

        # input: float; output: float
        self.deemph_Left  = fm_deemph (fg, audio_rate)
        self.deemph_Right = fm_deemph (fg, audio_rate)
        
        # compute FIR filter taps for audio filter
        width_of_transition_band = audio_rate / 32
        audio_coeffs = gr.firdes.low_pass (1.0 ,         # gain
                                           demod_rate,      # sampling rate
                                           15000 ,
                                           width_of_transition_band,
                                           gr.firdes.WIN_HAMMING)
        # input: float; output: float
        self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
        if 1:
            # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain
            # We pick off the negative frequency half because we want to base band by it!
            ##  NOTE  THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS

            stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0,
                                                                   demod_rate,
                                                                   -19020,
                                                                   -18980,
                                                                   width_of_transition_band,
                                                                   gr.firdes.WIN_HAMMING)
            
            #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
            #print "stereo carrier filter ", stereo_carrier_filter_coeffs
            #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate

            # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain

            stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0,
                                                                     demod_rate,
                                                                     38000-15000/2,
                                                                     38000+15000/2,
                                                                     width_of_transition_band,
                                                                     gr.firdes.WIN_HAMMING)
            #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
            #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
            # construct overlap add filter system from coefficients for stereo carrier

            self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)

            # carrier is twice the picked off carrier so arrange to do a commplex multiply

            self.stereo_carrier_generator = gr.multiply_cc();

            # Pick off the rds signal

            stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0,
                                                                     demod_rate,
                                                                     57000 - 1500,
                                                                     57000 + 1500,
                                                                     width_of_transition_band,
                                                                     gr.firdes.WIN_HAMMING)
            #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
            #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
            # construct overlap add filter system from coefficients for stereo carrier

            self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)
	    self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs)






	    self.rds_carrier_generator = gr.multiply_cc();
	    self.rds_signal_generator = gr.multiply_cc();
	    self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex);



            alpha = 5 * 0.25 * math.pi / (audio_rate)
            beta = alpha * alpha / 4.0
            max_freq = -2.0*math.pi*18990/audio_rate;
            min_freq = -2.0*math.pi*19010/audio_rate;
            
            self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq);
            #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now 
            

            # set up mixer (multiplier) to get the L-R signal at baseband

            self.stereo_basebander = gr.multiply_cc();

            # pick off the real component of the basebanded L-R signal.  The imaginary SHOULD be zero

            self.LmR_real = gr.complex_to_real();
            self.Make_Left = gr.add_ff();
            self.Make_Right = gr.sub_ff();
            
            self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs)


        if 1:

            # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier
            fg.connect (self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0))
            # send the already filtered carrier to the otherside of the carrier
            fg.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
            # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz.

            # send the new carrier to one side of the mixer (multiplier)
            fg.connect (self.stereo_carrier_generator, (self.stereo_basebander,0))
            # send the demphasized audio to the DSBSC pick off filter,  the complex
            # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
            fg.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
            # the result is BASEBANDED DSBSC with phase zero!

            # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer
            fg.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0))
            #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter
            fg.connect (self.LmR_real,(self.Make_Right,1))

	    # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone
	    fg.connect (self.stereo_basebander,(self.rds_carrier_generator,0))
            fg.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) 
	    # take signal, filter off rds,  send into mixer 0 channel
	    fg.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0))
            # take rds_carrier_generator output and send into mixer 1 channel
	    fg.connect (self.rds_carrier_generator,(self.rds_signal_generator,1))
	    # send basebanded rds signal and send into "processor" which for now is a null sink
	    fg.connect (self.rds_signal_generator,self_rds_signal_processor)
	    

        if 1:
            # pick off the audio, L+R that is what we used to have and send it to the summer
            fg.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))
            # take the picked off L+R audio and send it to the PLUS side of the subtractor
            fg.connect(self.audio_filter,(self.Make_Right, 0))
            # The result of  Make_Left  gets    (L+R) +  (L-R) and results in 2*L
            # The result of Make_Right gets  (L+R) - (L-R) and results in 2*R


            # kludge the signals into a stereo channel
            kludge = gr.kludge_copy(gr.sizeof_float)
            fg.connect(self.Make_Left , self.deemph_Left, (kludge, 0))
            fg.connect(self.Make_Right, self.deemph_Right, (kludge, 1))

           #send it to the audio system
            gr.hier_block.__init__(self,
                                   fg,
                                   self.fm_demod,       # head of the pipeline
                                   kludge)              # tail of the pipeline
        else:
            fg.connect (self.fm_demod, self.audio_filter)
            gr.hier_block.__init__(self,
                                   fg,
                                   self.fm_demod,       # head of the pipeline
                                   self.audio_filter)   # tail of the pipeline
Exemple #53
0
def main():
    parser = OptionParser(option_class=eng_option)
    parser.add_option("-R",
                      "--rx-subdev-spec",
                      type="subdev",
                      default=None,
                      help="select USRP Rx side A or B (default=A)")
    parser.add_option("-f",
                      "--freq",
                      type="eng_float",
                      default=144.800e6,
                      help="set frequency to FREQ",
                      metavar="FREQ")
    parser.add_option("-g",
                      "--gain",
                      type="eng_float",
                      default=None,
                      help="set gain in dB (default is midpoint)")
    parser.add_option("-d",
                      "--do-logging",
                      action="store_true",
                      default=False,
                      help="enable logging on datafiles")
    parser.add_option("-s",
                      "--use-datafile",
                      action="store_true",
                      default=False,
                      help="use usrp.dat (256kbps) as input")
    (options, args) = parser.parse_args()
    if len(args) != 0:
        parser.print_help()
        sys.exit(1)

    markfreq = 2200
    spacefreq = 1200
    bitrate = 1200
    usrp_decim = 250
    if_rate = 64e6 / usrp_decim  #256e3
    sf = (if_rate * 3) / 5  #153600
    bit_oversampling = 8
    sw_decim = int(sf / bitrate / bit_oversampling)  #8
    bf = sf / sw_decim

    symdev = abs(markfreq - spacefreq) / 2
    symcf = min(markfreq, spacefreq) + symdev
    nbfmdev = 3e3
    nbfmk = if_rate / (2 * pi * nbfmdev)
    symk = bf / (2 * pi * symdev)

    fg = gr.flow_graph()

    if options.do_logging:
        logger1 = gr.file_sink(gr.sizeof_gr_complex, "usrpout.dat")
        logger2 = gr.file_sink(gr.sizeof_float, "demod.dat")
        logger3 = gr.file_sink(gr.sizeof_float, "clkrec.dat")
        logger4 = gr.file_sink(gr.sizeof_char, "slicer.dat")

    if options.use_datafile:
        src = gr.file_source(gr.sizeof_gr_complex, "usrp.dat")
    else:
        u = usrp.source_c()
        u.set_decim_rate(usrp_decim)
        if options.rx_subdev_spec is None:
            subdev_spec = usrp.pick_rx_subdevice(u)
        else:
            subdev_spec = options.rx_subdev_spec
        subdev = usrp.selected_subdev(u, subdev_spec)
        print "Using RX d'board %s" % (subdev.side_and_name(), )
        u.set_mux(usrp.determine_rx_mux_value(u, subdev_spec))
        print "MUX:%x" % (usrp.determine_rx_mux_value(u, subdev_spec))
        if options.gain is None:
            g = subdev.gain_range()
            gain = float(g[0] + g[1]) / 2
        else:
            gain = options.gain
        subdev.set_gain(gain)
        print "Gain set to", str(gain)
        r = usrp.tune(u, 0, subdev, options.freq)
        if r:
            print "Frequency set to", options.freq
        else:
            print "Frequency set to", options.freq, "failed"
        src = u

    chan_taps = gr.firdes.low_pass(1, if_rate, 13e3, 4e3, gr.firdes.WIN_HANN)
    chan = gr.fir_filter_ccf(1, chan_taps)  #256e3

    dee = blks.fm_deemph(fg, if_rate, 75e-6)

    fmdem = gr.quadrature_demod_cf(nbfmk)

    res_taps = blks.design_filter(3, 5, 0.4)
    res = blks.rational_resampler_fff(fg, 3, 5, res_taps)  #153600

    lo = gr.sig_source_c(sf, gr.GR_SIN_WAVE, -symcf, 1)
    mix = gr.multiply_cc()
    r2c = gr.float_to_complex()
    lp_taps = gr.firdes.low_pass(sw_decim, sf, 600, 2e3, gr.firdes.WIN_HANN)
    lp = gr.fir_filter_ccf(sw_decim, lp_taps)

    dem = gr.quadrature_demod_cf(symk)

    alpha = 0.0001
    freqoff = gr.single_pole_iir_filter_ff(alpha)
    sub = gr.sub_ff()

    _def_gain_mu = 0.05
    _def_mu = 0.5
    _def_freq_error = 0.00
    _def_omega_relative_limit = 0.005

    _omega = bit_oversampling * (1 + _def_freq_error)
    _gain_omega = .25 * _def_gain_mu * _def_gain_mu

    clkrec = gr.clock_recovery_mm_ff(_omega, _gain_omega, _def_mu,
                                     _def_gain_mu, _def_omega_relative_limit)

    slicer = gr.binary_slicer_fb()

    pktq = gr.msg_queue()
    sink = packetradio.hdlc_framer(pktq, 0)
    watcher = queue_watcher_thread(pktq, rx_callback)

    fg.connect(src, chan, fmdem, dee, res, r2c, (mix, 0))
    fg.connect(lo, (mix, 1))
    fg.connect(mix, lp, dem)
    fg.connect(dem, (sub, 0))
    fg.connect(dem, freqoff, (sub, 1))
    fg.connect(sub, clkrec, slicer)
    fg.connect(slicer, sink)

    if options.do_logging:
        fg.connect(src, logger1)
        fg.connect(sub, logger2)
        fg.connect(clkrec, logger3)
        fg.connect(slicer, logger4)

    fg.start()
    fg.wait()
Exemple #54
0
    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))
Exemple #55
0
    def __init__(self, demod_rate, audio_decimation):
        """
        Hierarchical block for demodulating a broadcast FM signal.

        The input is the downconverted complex baseband signal
        (gr_complex).  The output is two streams of the demodulated
        audio (float) 0=Left, 1=Right.

        @param demod_rate: input sample rate of complex baseband input.
        @type demod_rate: float
        @param audio_decimation: how much to decimate demod_rate to get to audio.
        @type audio_decimation: integer
        """
        gr.hier_block2.__init__(
            self,
            "wfm_rcv_fmdet",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(2, 2, gr.sizeof_float))  # Output signature
        lowfreq = -125e3 / demod_rate
        highfreq = 125e3 / demod_rate
        audio_rate = demod_rate / audio_decimation

        # We assign to self so that outsiders can grab the demodulator
        # if they need to.  E.g., to plot its output.
        #
        # input: complex; output: float

        self.fm_demod = gr.fmdet_cf(demod_rate, lowfreq, highfreq, 0.05)

        # input: float; output: float
        self.deemph_Left = fm_deemph(audio_rate)
        self.deemph_Right = fm_deemph(audio_rate)

        # compute FIR filter taps for audio filter
        width_of_transition_band = audio_rate / 32
        audio_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            demod_rate,  # sampling rate
            15000,
            width_of_transition_band,
            gr.firdes.WIN_HAMMING)

        # input: float; output: float
        self.audio_filter = gr.fir_filter_fff(audio_decimation, audio_coeffs)
        if 1:
            # Pick off the stereo carrier/2 with this filter. It
            # attenuated 10 dB so apply 10 dB gain We pick off the
            # negative frequency half because we want to base band by
            # it!
            ##  NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO
            ##  DEEMPHASIS

            stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(
                10.0, demod_rate, -19020, -18980, width_of_transition_band,
                gr.firdes.WIN_HAMMING)

            #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
            #print "stereo carrier filter ", stereo_carrier_filter_coeffs
            #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate

            # Pick off the double side band suppressed carrier
            # Left-Right audio. It is attenuated 10 dB so apply 10 dB
            # gain

            stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(
                20.0, demod_rate, 38000 - 15000 / 2, 38000 + 15000 / 2,
                width_of_transition_band, gr.firdes.WIN_HAMMING)
            #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
            #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs

            # construct overlap add filter system from coefficients
            # for stereo carrier
            self.stereo_carrier_filter = gr.fir_filter_fcc(
                audio_decimation, stereo_carrier_filter_coeffs)

            # carrier is twice the picked off carrier so arrange to do
            # a commplex multiply
            self.stereo_carrier_generator = gr.multiply_cc()

            # Pick off the rds signal
            stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(
                30.0, demod_rate, 57000 - 1500, 57000 + 1500,
                width_of_transition_band, gr.firdes.WIN_HAMMING)
            #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
            #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
            # construct overlap add filter system from coefficients for stereo carrier

            self.rds_signal_filter = gr.fir_filter_fcc(
                audio_decimation, stereo_rds_filter_coeffs)
            self.rds_carrier_generator = gr.multiply_cc()
            self.rds_signal_generator = gr.multiply_cc()
            self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex)

            loop_bw = 2 * math.pi / 100.0
            max_freq = -2.0 * math.pi * 18990 / audio_rate
            min_freq = -2.0 * math.pi * 19010 / audio_rate
            self.stereo_carrier_pll_recovery = gr.pll_refout_cc(
                loop_bw, max_freq, min_freq)

            #self.stereo_carrier_pll_recovery.squelch_enable(False)
            ##pll_refout does not have squelch yet, so disabled for
            #now

            # set up mixer (multiplier) to get the L-R signal at
            # baseband

            self.stereo_basebander = gr.multiply_cc()

            # pick off the real component of the basebanded L-R
            # signal.  The imaginary SHOULD be zero

            self.LmR_real = gr.complex_to_real()
            self.Make_Left = gr.add_ff()
            self.Make_Right = gr.sub_ff()

            self.stereo_dsbsc_filter = gr.fir_filter_fcc(
                audio_decimation, stereo_dsbsc_filter_coeffs)

        if 1:

            # send the real signal to complex filter to pick off the
            # carrier and then to one side of a multiplier
            self.connect(self, self.fm_demod, self.stereo_carrier_filter,
                         self.stereo_carrier_pll_recovery,
                         (self.stereo_carrier_generator, 0))

            # send the already filtered carrier to the otherside of the carrier
            # the resulting signal from this multiplier is the carrier
            # with correct phase but at -38000 Hz.
            self.connect(self.stereo_carrier_pll_recovery,
                         (self.stereo_carrier_generator, 1))

            # send the new carrier to one side of the mixer (multiplier)
            self.connect(self.stereo_carrier_generator,
                         (self.stereo_basebander, 0))

            # send the demphasized audio to the DSBSC pick off filter,  the complex
            # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
            # the result is BASEBANDED DSBSC with phase zero!
            self.connect(self.fm_demod, self.stereo_dsbsc_filter,
                         (self.stereo_basebander, 1))

            # Pick off the real part since the imaginary is
            # theoretically zero and then to one side of a summer
            self.connect(self.stereo_basebander, self.LmR_real,
                         (self.Make_Left, 0))

            #take the same real part of the DSBSC baseband signal and
            #send it to negative side of a subtracter
            self.connect(self.LmR_real, (self.Make_Right, 1))

            # Make rds carrier by taking the squared pilot tone and
            # multiplying by pilot tone
            self.connect(self.stereo_basebander,
                         (self.rds_carrier_generator, 0))
            self.connect(self.stereo_carrier_pll_recovery,
                         (self.rds_carrier_generator, 1))

            # take signal, filter off rds, send into mixer 0 channel
            self.connect(self.fm_demod, self.rds_signal_filter,
                         (self.rds_signal_generator, 0))

            # take rds_carrier_generator output and send into mixer 1
            # channel
            self.connect(self.rds_carrier_generator,
                         (self.rds_signal_generator, 1))

            # send basebanded rds signal and send into "processor"
            # which for now is a null sink
            self.connect(self.rds_signal_generator, self_rds_signal_processor)

        if 1:
            # pick off the audio, L+R that is what we used to have and
            # send it to the summer
            self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))

            # take the picked off L+R audio and send it to the PLUS
            # side of the subtractor
            self.connect(self.audio_filter, (self.Make_Right, 0))

            # The result of  Make_Left  gets    (L+R) +  (L-R) and results in 2*L
            # The result of Make_Right gets  (L+R) - (L-R) and results in 2*R
            self.connect(self.Make_Left, self.deemph_Left, (self, 0))
            self.connect(self.Make_Right, self.deemph_Right, (self, 1))
    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"))