def __init__(self, options, queue):
		gr.top_block.__init__(self)

		if options.filename is not None:
			self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
			self.rate = options.rate

		else:
			self.u = uhd.usrp_source(options.addr,
									 io_type=uhd.io_type.COMPLEX_FLOAT32,
									 num_channels=1)

			if options.subdev is not None:
				self.u.set_subdev_spec(options.subdev, 0)
				
			self.u.set_samp_rate(options.rate)
			self.rate = self.u.get_samp_rate()

			# Set the antenna
			if(options.antenna):
				self.u.set_antenna(options.antenna, 0)
			
			self.centerfreq = options.centerfreq
			print "Tuning to: %fMHz" % (self.centerfreq - options.error)
			if not(self.tune(options.centerfreq - options.error)):
				print "Failed to set initial frequency"

			if options.gain is None: #set to halfway
				g = self.u.get_gain_range()
				options.gain = (g.start()+g.stop()) / 2.0

			print "Setting gain to %i" % options.gain
			self.u.set_gain(options.gain)

			self.u.set_bandwidth(options.bandwidth)

		print "Samples per second is %i" % self.rate

		self._syms_per_sec = 3600;


		options.samples_per_second = self.rate
		options.syms_per_sec = self._syms_per_sec
		options.gain_mu = 0.01
		options.mu=0.5
		options.omega_relative_limit = 0.3
		options.syms_per_sec = self._syms_per_sec
		options.offset = options.centerfreq - options.freq
		print "Control channel offset: %f" % options.offset

		self.demod = fsk_demod(options)
		self.start_correlator = gr.correlate_access_code_tag_bb("10101100",
		                                                        0,
		                                                        "smartnet_preamble") #should mark start of packet
		self.smartnet_deinterleave = smartnet.deinterleave()
		self.smartnet_crc = smartnet.crc(queue)

		if options.filename is None:
			self.connect(self.u, self.demod)
		else:
			self.connect(self.fs, self.demod)

		self.connect(self.demod, self.start_correlator, self.smartnet_deinterleave, self.smartnet_crc)

		#hook up the audio patch
		if options.audio:
			self.audiorate = 48000
			self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000, gr.firdes.WIN_HANN)
			self.prefilter_decim = int(self.rate / self.audiorate) #might have to use a rational resampler for audio
			print "Prefilter decimation: %i" % self.prefilter_decim
			self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(self.prefilter_decim, #decimation
									      self.audiotaps, #taps
									      0, #freq offset
									      self.rate) #sampling rate

			#on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
			#the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
			self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
											   alpha = 0.1, #wat
											   ramp = 10, #wat
											   gate = False)

			self.audiodemod = blks2.fm_demod_cf(self.rate/self.prefilter_decim, #rate
							    1, #audio decimation
							    4000, #deviation
							    3000, #audio passband
							    4000, #audio stopband
							    1, #gain
							    75e-6) #deemphasis constant

			#the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
			self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50, gr.firdes.WIN_HANN)
			self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
			self.audiogain = gr.multiply_const_ff(options.volume)
			self.audiosink = audio.sink (self.audiorate, "")
#			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

			self.mute()

			if options.filename is None:
				self.connect(self.u, self.audio_prefilter)
			else:
				self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
Exemple #2
0
	def __init__(self):
		#grc_wxgui.top_block_gui.__init__(self, title="Top Block")
		gr.top_block.__init__(self)
		print "abc"
		##################################################
		# Variables
		##################################################
		#self.samp_rate = samp_rate = 32000
		self.osr = 4
		self.key = ''
		self.configuration = ''

		self.clock_rate = 52e6
		self.input_rate = self.clock_rate / 72		#TODO: what about usrp value?
		self.gsm_symb_rate = 1625000.0 / 6.0
		self.sps = self.input_rate / self.gsm_symb_rate




		# configure channel filter
		filter_cutoff	= 135e3		#135,417Hz is GSM bandwidth 
		filter_t_width	= 10e3
		offset = 0.0

		##################################################
		# Blocks
		##################################################
		self.gr_null_sink_0 = gr.null_sink(gr.sizeof_gr_complex*1)

		print "Input files: ", downfile, " ", upfile
		self.gr_file_source_0 = gr.file_source(gr.sizeof_gr_complex*1, downfile, False)
		self.gr_file_source_1 = gr.file_source(gr.sizeof_gr_complex*1, upfile, False)


		filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)

		print len(filter_taps)

		self.filter0 = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate)
		self.filter1 = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate)

		self.interpolator_1 = gr.fractional_interpolator_cc(0, self.sps) 

        	self.tuner_callback = tuner(self)
	        self.synchronizer_callback = synchronizer(self)

		#self.buffer =  howto.buffer_cc()

		self.burst_cb = burst_callback(self)

		print ">>>>>Input rate: ", self.input_rate
		#self.burst = gsm.burst_cf(self.burst_cb,self.input_rate)
        	self.receiver = gsm.receiver_cf(self.tuner_callback, self.synchronizer_callback, self.osr, self.key.replace(' ', '').lower(), self.configuration.upper())
		##################################################
		# Connections
		##################################################
		#self.connect((self.gr_file_source_0, 0), (self.filter0, 0), (self.burst, 0))

		self.connect((self.gr_file_source_1, 0), (self.filter1, 0), (self.interpolator_1, 0), (self.receiver, 0))
Exemple #3
0
    def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq, max_dev, ctcss):
        gr.hier_block2.__init__(self, "rx_channel_nfm",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
#                               gr.io_signature(0, 0, 0))
                                gr.io_signature(1, 1, gr.sizeof_float))

        output_sample_rate = 8000

        chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate)

        nphases = 32
        frac_bw = 0.45
        rs_taps = gr.firdes.low_pass(nphases, nphases, frac_bw, 0.5-frac_bw)

        resampler = blks2.pfb_arb_resampler_ccf(
           float(output_sample_rate)/channel_rate,
           (rs_taps),
           nphases
        )

        # FM Demodulator  input: complex; output: float
        k = output_sample_rate/(2*math.pi*max_dev)
        fm_demod = gr.quadrature_demod_cf(k)

        self.connect (self, chan, resampler, fm_demod)
        if ctcss > 0:
            level = 5.0
            len = 0
            ramp = 0
            gate = True
            ctcss = repeater.ctcss_squelch_ff(output_sample_rate, ctcss, level, len, ramp, gate)
            self.connect (fm_demod, ctcss, self)
        else:
            self.connect (fm_demod, self)
Exemple #4
0
    def __init__(self,
                 N_id_1,
                 N_id_2,
                 slot0=True,
                 N_re=128,
                 N_cp_ts=144,
                 freq_corr=0):
        top = gr.top_block("foo")

        source = gr.vector_source_c(range(0, N_re), False, N_re)
        source.set_data(gen_sss_fd(N_id_1, N_id_2, N_re).get_sss(slot0))
        fft = gr.fft_vcc(N_re, False, window.blackmanharris(1024), True)
        cp = digital.ofdm_cyclic_prefixer(N_re, N_re + N_cp_ts * N_re / 2048)
        if freq_corr != 0:
            freq_corr = gr.freq_xlating_fir_filter_ccf(1, 1, freq_corr,
                                                       15000 * N_re)
        sink = gr.vector_sink_c(1)

        top.connect(source, fft, cp)
        if freq_corr != 0:
            top.connect(cp, freq_corr, sink)
        else:
            top.connect(cp, sink)
        top.run()
        self.data = sink.data()
Exemple #5
0
    def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate,
                 channel_rate, lo_freq):
        gr.hier_block2.__init__(self, "rx_channel_cqpsk",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps,
                                              lo_freq, usrp_rate)

        agc = gr.feedforward_agc_cc(16, 1.0)

        gain_omega = 0.125 * options.gain_mu * options.gain_mu

        alpha = options.costas_alpha
        beta = 0.125 * alpha * alpha
        fmin = -0.025
        fmax = 0.025

        clock = repeater.gardner_costas_cc(sps, options.gain_mu, gain_omega,
                                           alpha, beta, fmax, fmin)

        # Perform Differential decoding on the constellation
        diffdec = gr.diff_phasor_cc()

        # take angle of the difference (in radians)
        to_float = gr.complex_to_arg()

        # convert from radians such that signal is in -3/-1/+1/+3
        rescale = gr.multiply_const_ff((1 / (pi / 4)))

        self.connect(self, chan, agc, clock, diffdec, to_float, rescale, self)
Exemple #6
0
    def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq):
        gr.hier_block2.__init__(self, "rx_channel_fm",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate)

        symbol_decim = 1
        symbol_rate = 4800

        self.symbol_deviation = 600.0
        fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
        fm_demod = gr.quadrature_demod_cf(fm_demod_gain)

        symbol_coeffs = gr.firdes_root_raised_cosine(1.0,
                                                     channel_rate,
                                                     symbol_rate, 
                                                     1.0,
                                                     51)
        symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)

        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        demod_fsk4 = fsk4.demod_ff(autotuneq, channel_rate, symbol_rate)
 
        self.connect (self, chan, fm_demod, symbol_filter, demod_fsk4, self)
Exemple #7
0
    def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq):
        gr.hier_block2.__init__(self, "rx_channel_cqpsk",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate)

        agc = gr.feedforward_agc_cc(16, 1.0)

        gain_omega = 0.125 * options.gain_mu * options.gain_mu

        alpha = options.costas_alpha
        beta = 0.125 * alpha * alpha
        fmin = -0.025
        fmax =  0.025

        clock = repeater.gardner_costas_cc(sps, options.gain_mu, gain_omega, alpha, beta, fmax, fmin)

        # Perform Differential decoding on the constellation
        diffdec = gr.diff_phasor_cc()

        # take angle of the difference (in radians)
        to_float = gr.complex_to_arg()

        # convert from radians such that signal is in -3/-1/+1/+3
        rescale = gr.multiply_const_ff( (1 / (pi / 4)) )

        self.connect (self, chan, agc, clock, diffdec, to_float, rescale, self)
Exemple #8
0
	def ais_rx(self, src, freq, designator, options, queue):
		self.rate = options.rate
		self.u = src
		self.coeffs = gr.firdes.low_pass(1,self.rate,7000,1000)
		self._filter_decimation = 4
		self.filter = gr.freq_xlating_fir_filter_ccf(self._filter_decimation, 
													 self.coeffs, 
													 freq,
													 self.rate)

		self._bits_per_sec = 9600.0;

		self._samples_per_symbol = self.rate / self._filter_decimation / self._bits_per_sec

		options.samples_per_symbol = self._samples_per_symbol
		options.gain_mu = 0.3
		options.mu=0.5
		options.omega_relative_limit = 0.0001
		options.bits_per_sec = self._bits_per_sec
		options.fftlen = 4096 #trades off accuracy of freq estimation in presence of noise, vs. delay time.
		options.samp_rate = self.rate / self._filter_decimation
		self.demod = ais_demod(options) #ais_demod.py, hierarchical demodulation block, takes in complex baseband and spits out 1-bit packed bitstream
		self.unstuff = ais.unstuff() #ais_unstuff.cc, unstuffs data
		self.start_correlator = gr.correlate_access_code_tag_bb("1010101010101010", 0, "ais_preamble") #should mark start of packet
		self.stop_correlator = gr.correlate_access_code_tag_bb("01111110", 0, "ais_frame") #should mark start and end of packet
		self.parse = ais.parse(queue, designator) #ais_parse.cc, calculates CRC, parses data into ASCII message, moves data onto queue

		self.connect(self.u,
		             self.filter,
		             self.demod,
		             self.unstuff,
		             self.start_correlator,
		             self.stop_correlator,
		             self.parse) #parse posts messages to the queue, which the main loop reads and prints
Exemple #9
0
    def gsm_receiver( self, input_rate = 400e3):
        filter_cutoff   = 145e3
        filter_t_width  = 10e3
        offset = 0

        #rates
        gsm_symb_rate = 1625000.0 / 6.0
        sps = input_rate / gsm_symb_rate / self.options.osr

        filter_taps    = gr.firdes.low_pass(1.0, input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)
        filtr          = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, input_rate)
        interpolator   = gr.fractional_interpolator_cc(0, sps)

        tuner_callback = tuner(filtr)
        synchronizer_callback  = synchronizer(self)
        receiver       = gsm.receiver_cf( tuner_callback, synchronizer_callback, self.options.osr, self.options.key.replace(' ', '').lower(), self.options.configuration.upper())

        blocks = {}
        blocks[ "synchronizer_callback"]  = synchronizer_callback
        blocks[ "tuner_callback"]         = tuner_callback
        blocks[ "filter_taps"]            = filter_taps
        blocks[ "filtr"]                  = filtr
        blocks[ "interpolator"]           = interpolator
        blocks[ "receiver"]               = receiver
        self.connect( filtr,  interpolator, receiver)

        return blocks, filtr
Exemple #10
0
    def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate,
                 channel_rate, lo_freq):
        gr.hier_block2.__init__(self, "rx_channel_fm",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_float))

        chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps,
                                              lo_freq, usrp_rate)

        symbol_decim = 1
        symbol_rate = 4800

        self.symbol_deviation = 600.0
        fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
        fm_demod = gr.quadrature_demod_cf(fm_demod_gain)

        symbol_coeffs = gr.firdes_root_raised_cosine(1.0, channel_rate,
                                                     symbol_rate, 1.0, 51)
        symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)

        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, symbol_rate)

        self.connect(self, chan, fm_demod, symbol_filter, demod_fsk4, self)
 def _set_filter(self):
     filter_cutoff   = 145e3	
     filter_t_width  = 10e3
     offset = 0
     filter_taps     = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)
     filtr          = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate)
     return filtr
Exemple #12
0
    def _set_filter(self):
        filter_cutoff   = 145e3	
        filter_t_width  = 10e3
        offset = 0
#        print "input_rate:", self.input_rate, "sample rate:", self.sps, " filter_cutoff:", filter_cutoff, " filter_t_width:", filter_t_width
        filter_taps     = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)
        filtr          = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate)
        return filtr
    def __build_graph(self, source, capture_rate):
        # tell the scope the source rate
        self.spectrum.set_sample_rate(capture_rate)
        # channel filter
        self.channel_offset = 0.0
        channel_decim = capture_rate // self.channel_rate
        channel_rate = capture_rate // channel_decim
        trans_width = 12.5e3 / 2
        trans_centre = trans_width + (trans_width / 2)
        # discriminator tap doesn't do freq. xlation, FM demodulation, etc.
        if not self.baseband_input:
            coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre,
                                        trans_width, gr.firdes.WIN_HANN)
            self.channel_filter = gr.freq_xlating_fir_filter_ccf(
                channel_decim, coeffs, 0.0, capture_rate)
            self.set_channel_offset(0.0, 0, self.spectrum.win._units)
            # power squelch
            squelch_db = 0
            self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True)
            self.set_squelch_threshold(squelch_db)
            # FM demodulator
            fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
            fm_demod = gr.quadrature_demod_cf(fm_demod_gain)
        # symbol filter
        symbol_decim = 1
        #symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500)
        # boxcar coefficients for "integrate and dump" filter
        samples_per_symbol = channel_rate // self.symbol_rate
        symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol
        self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)

        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate,
                                        self.symbol_rate)
        # for now no audio output
        sink = gr.null_sink(gr.sizeof_float)
        # connect it all up
        if self.baseband_input:
            self.rescaler = gr.multiply_const_ff(1)
            sinkx = gr.file_sink(gr.sizeof_float, "rx.dat")
            self.__connect([[
                source, self.rescaler, self.symbol_filter, demod_fsk4,
                self.slicer, self.p25_decoder, sink
            ], [self.symbol_filter, self.signal_scope], [demod_fsk4, sinkx],
                            [demod_fsk4, self.symbol_scope]])
            self.connect_data_scope(not self.datascope_raw_input)
        else:
            self.demod_watcher = demod_watcher(autotuneq,
                                               self.adjust_channel_offset)
            self.__connect([[
                source, self.channel_filter, self.squelch, fm_demod,
                self.symbol_filter, demod_fsk4, self.slicer, self.p25_decoder,
                sink
            ], [source, self.spectrum],
                            [self.symbol_filter, self.signal_scope],
                            [demod_fsk4, self.symbol_scope]])
Exemple #14
0
    def __init__(self, options):
        gr.top_block.__init__(self)

        # Create a USRP2 source and set decimation rate
        self._u = usrp2.source_32fc(options.interface, options.mac_addr)
        self._u.set_decim(512)

        # Set receive daughterboard gain
        if options.gain is None:
            g = self._u.gain_range()
            options.gain = float(g[0] + g[1]) / 2
            print "Using mid-point gain of", options.gain, "(", g[0], "-", g[
                1], ")"
        self._u.set_gain(options.gain)

        # Set receive frequency
        if options.lo_offset is not None:
            self._u.set_lo_offset(options.lo_offset)

        tr = self._u.set_center_freq(options.freq)
        if tr == None:
            sys.stderr.write('Failed to set center frequency\n')
            raise SystemExit, 1

        sample_rate = 100e6 / 512
        symbol_rate = 18000
        sps = 2
        # output rate will be 36,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass,
                                          options.low_pass * 0.1,
                                          gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps,
                                                options.calibration,
                                                sample_rate)

        sys.stderr.write("sample rate: %d\n" % (sample_rate))

        DEMOD = cqpsk.cqpsk_demod(samples_per_symbol=sps,
                                  excess_bw=0.35,
                                  costas_alpha=0.03,
                                  gain_mu=0.05,
                                  mu=0.05,
                                  omega_relative_limit=0.05,
                                  log=options.log,
                                  verbose=options.verbose)

        OUT = gr.file_sink(gr.sizeof_float, options.output_file)

        r = float(sample_rate) / float(new_sample_rate)

        INTERPOLATOR = gr.fractional_interpolator_cc(0, r)

        self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT)
    def __init__(self, frame, panel, vbox, argv):
        stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)

	self.frame = frame
	self.panel = panel

	options = get_options()

	sample_rate = int(options.sample_rate)	

	self.asrc = audio.source(sample_rate, options.audio_device, True)

	self.f2c = gr.float_to_complex(1)

	self.connect((self.asrc, 1), (self.f2c, 1))
	self.connect((self.asrc, 0), (self.f2c, 0))

        symbol_rate = 18000
        sps = 2
        # output rate will be 36,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate)

        sys.stderr.write("sample rate: %d\n" %(sample_rate))

        DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps,
                                 excess_bw=0.35,
                                 costas_alpha=0.03,
                                 gain_mu=0.05,
                                 mu=0.05,
                                 omega_relative_limit=0.05,
                                 log=options.log,
                                 verbose=options.verbose)

        OUT = gr.file_sink(gr.sizeof_float, options.output_file)

        r = float(sample_rate) / float(new_sample_rate)

        INTERPOLATOR = gr.fractional_interpolator_cc(0, r)

        self.connect(self.f2c, FILTER, INTERPOLATOR, DEMOD, OUT)

	self.scope = fftsink2.fft_sink_c(panel, fft_size=512,
					 sample_rate=sample_rate,
					 ref_scale=2.0,
					 ref_level=-30, y_divs=10,
					 fft_rate=10,
					 average=True,
					 avg_alpha=0.2)
	self.connect(self.f2c, self.scope)
	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 #17
0
    def __init__(self, options):
        gr.top_block.__init__(self)

        # Create a USRP2 source and set decimation rate
        self._u = usrp2.source_32fc(options.interface, options.mac_addr)
        self._u.set_decim(512)

        # Set receive daughterboard gain
        if options.gain is None:
            g = self._u.gain_range()
            options.gain = float(g[0]+g[1])/2
            print "Using mid-point gain of", options.gain, "(", g[0], "-", g[1], ")"
        self._u.set_gain(options.gain)
 
        # Set receive frequency
        if options.lo_offset is not None:
            self._u.set_lo_offset(options.lo_offset)

        tr = self._u.set_center_freq(options.freq)
        if tr == None:
            sys.stderr.write('Failed to set center frequency\n')
            raise SystemExit, 1

        sample_rate = 100e6/512
        symbol_rate = 18000
        sps = 2
        # output rate will be 36,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate)

        sys.stderr.write("sample rate: %d\n" %(sample_rate))

        DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps,
                                 excess_bw=0.35,
                                 costas_alpha=0.03,
                                 gain_mu=0.05,
                                 mu=0.05,
                                 omega_relative_limit=0.05,
                                 log=options.log,
                                 verbose=options.verbose)

        OUT = gr.file_sink(gr.sizeof_float, options.output_file)

        r = float(sample_rate) / float(new_sample_rate)

        INTERPOLATOR = gr.fractional_interpolator_cc(0, r)

        self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT)
Exemple #18
0
    def __build_graph(self, source, capture_rate):
        # tell the scope the source rate
        self.spectrum.set_sample_rate(capture_rate)
        # channel filter
        self.channel_offset = 0.0
        channel_decim = capture_rate // self.channel_rate
        channel_rate = capture_rate // channel_decim
        trans_width = 12.5e3 / 2
        trans_centre = trans_width + (trans_width / 2)
        coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre,
                                    trans_width, gr.firdes.WIN_HANN)
        self.channel_filter = gr.freq_xlating_fir_filter_ccf(
            channel_decim, coeffs, 0.0, capture_rate)
        self.set_channel_offset(0.0, 0, self.spectrum.win._units)
        # power squelch
        squelch_db = 0
        self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True)
        self.set_squelch_threshold(squelch_db)
        # FM demodulator
        fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
        fm_demod = gr.quadrature_demod_cf(fm_demod_gain)
        # symbol filter
        symbol_decim = 1
        # symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500)
        # boxcar coefficients for "integrate and dump" filter
        samples_per_symbol = channel_rate // self.symbol_rate
        symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol
        symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)
        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        self.demod_watcher = demod_watcher(autotuneq,
                                           self.adjust_channel_offset)
        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate,
                                        self.symbol_rate)
        # symbol slicer
        levels = [-2.0, 0.0, 2.0, 4.0]
        slicer = op25.fsk4_slicer_fb(levels)
        # ALSA output device (if not locked)
        try:
            sink = audio.sink(8000, "plughw:0,0",
                              True)  # ToDo: get actual device from prefs
        except Exception:
            sink = gr.null_sink(gr.sizeof_float)

        # connect it all up
        self.__connect([[
            source, self.channel_filter, self.squelch, fm_demod, symbol_filter,
            demod_fsk4, slicer, self.p25_decoder, sink
        ], [source, self.spectrum], [symbol_filter, self.signal_scope],
                        [demod_fsk4, self.symbol_scope]])
Exemple #19
0
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-c", "--calibration", type="int", default=0, help="freq offset")
        parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file")
        parser.add_option("-l", "--log", action="store_true", default=False, help="dump debug .dat files")
        parser.add_option("-L", "--low-pass", type="eng_float", default=15e3, help="low pass cut-off", metavar="Hz")
        parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file")
        parser.add_option("-s", "--sample-rate", type="int", default=250000, help="input sample rate")
        parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data")
        (options, args) = parser.parse_args()
 
        sample_rate = options.sample_rate
        symbol_rate = 4800
        sps = 10
        # output rate will be 48,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps
        lcm = gru.lcm(sample_rate, new_sample_rate)
        interp = lcm // sample_rate
        decim  = lcm // new_sample_rate

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate)

        sys.stderr.write("interp: %d decim: %d\n" %(interp, decim))

        bpf_taps = gr.firdes.low_pass(1.0, sample_rate * interp, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)
        INTERPOLATOR = gr.interp_fir_filter_ccf (int(interp), bpf_taps)
        DECIMATOR = blks2.rational_resampler_ccf(1, int(decim))

        IN = gr.file_source(gr.sizeof_gr_complex, options.input_file)

        DEMOD = blks2.cqpsk_demod( samples_per_symbol = sps,
                                 excess_bw=0.35,
                                 costas_alpha=0.03,
                                 gain_mu=0.05,
                                 mu=0.05,
                                 omega_relative_limit=0.05,
                                 log=options.log,
                                 verbose=options.verbose)

        msgq = gr.msg_queue()
        DECODER = fsk4.apco25_f(msgq,0)

        self.connect(IN, FILTER, INTERPOLATOR, DECIMATOR, DEMOD, DECODER)
def graph():
    sampling_freq = 19200000

    fg = gr.flow_graph()

    src0 = gr.file_source(gr.sizeof_gr_complex, "/tmp/atsc_pipe_1")

    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)

    c2f = gr.complex_to_float()
    file = gr.file_sink(gr.sizeof_float, "/tmp/atsc_pipe_2")

    fg.connect(src0, duc, c2f, file)

    fg.run()
def graph():
    print os.getpid()
    sampling_freq = 19200000

    tb = gr.top_block()

    src0 = gr.file_source(gr.sizeof_gr_complex, "/tmp/atsc_pipe_1")

    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)

    c2f = gr.complex_to_float()
    file = gr.file_sink(gr.sizeof_float, "/tmp/atsc_pipe_2")

    tb.connect(src0, duc, c2f, file)

    tb.run()
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-c", "--calibration", type="eng_float", default=0, help="freq offset")
        parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file")
        parser.add_option("-l", "--log", action="store_true", default=False, help="dump debug .dat files")
        parser.add_option("-L", "--low-pass", type="eng_float", default=25e3, help="low pass cut-off", metavar="Hz")
        parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file")
        parser.add_option("-s", "--sample-rate", type="int", default=100000000/512, help="input sample rate")
        parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data")
        (options, args) = parser.parse_args()
 
        sample_rate = options.sample_rate
        symbol_rate = 18000
        sps = 2
        # output rate will be 36,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate)

        sys.stderr.write("sample rate: %d\n" %(sample_rate))

        IN = gr.file_source(gr.sizeof_gr_complex, options.input_file)

        DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps,
                                 excess_bw=0.35,
                                 costas_alpha=0.03,
                                 gain_mu=0.05,
                                 mu=0.05,
                                 omega_relative_limit=0.05,
                                 log=options.log,
                                 verbose=options.verbose)


        OUT = gr.file_sink(gr.sizeof_float, options.output_file)

        r = float(sample_rate) / float(new_sample_rate)

        INTERPOLATOR = gr.fractional_interpolator_cc(0, r)

        self.connect(IN, FILTER, INTERPOLATOR, DEMOD, OUT)
Exemple #23
0
 def __init__(self, N_id_1, N_id_2, slot0=True, N_re=128, N_cp_ts=144, freq_corr=0):
   top = gr.top_block("foo");
   
   source = gr.vector_source_c(range(0,N_re), False, N_re)
   source.set_data(gen_sss_fd(N_id_1, N_id_2, N_re).get_sss(slot0)); 
   fft = gr.fft_vcc(N_re, False, window.blackmanharris(1024), True)
   cp = digital.ofdm_cyclic_prefixer(N_re, N_re+N_cp_ts*N_re/2048)
   if freq_corr != 0:
     freq_corr = gr.freq_xlating_fir_filter_ccf(1, 1, freq_corr, 15000*N_re)
   sink = gr.vector_sink_c(1)
   
   top.connect(source, fft, cp)
   if freq_corr != 0:
     top.connect(cp, freq_corr, sink)
   else:
     top.connect(cp, sink)
   top.run()
   self.data = sink.data()
Exemple #24
0
 def __init__(self, N_id_2, N_re=128, N_cp_ts=144, freq_corr=0, repeat=False):
   gr.hier_block2.__init__(
       self, "PSS source time-domain",
       gr.io_signature(0, 0, 0),
       gr.io_signature(1, 1, gr.sizeof_gr_complex),
   )
   
   self.pss_fd = pss_source_fd(N_id_2, N_re, repeat);
   self.fft = gr.fft_vcc(N_re, False, window.blackmanharris(1024), True)
   self.cp = digital.ofdm_cyclic_prefixer(N_re, N_re+N_cp_ts*N_re/2048)
   if freq_corr != 0:
     self.freq_corr = gr.freq_xlating_fir_filter_ccf(1, 1, freq_corr, 15000*N_re)
   
   self.connect(self.pss_fd, self.fft, self.cp)
   if freq_corr != 0:
     self.connect(self.cp, self.freq_corr, self)
   else:
     self.connect(self.cp, self)
    def resetapp(void):
	pre_status = getServerStatus()
	if getServerStatus() == True:
		setServerStatus(False)
		self.serverlabel_state.SetLabel("Not Connected:")
		self.btnstart_server.SetLabel("Start Server")
	time.sleep(0.2)

        tb.stop()
        tb.wait()
        self.disconnect(self.src, self.tuner, self.interpolator,self.receiver, self.converter, self.output)
        sample_rate = self.src.get_sample_rate()
        sys.stderr.write("sample rate: %d\n" % (sample_rate))

        gsm_symb_rate = 1625000.0 / 6.0
        sps = sample_rate / gsm_symb_rate / 4
        out_sample_rate = gsm_symb_rate * 4

        self.offset = 0

        taps = gr.firdes.low_pass(1.0, sample_rate, 145e3, 10e3, gr.firdes.WIN_HANN)
        self.tuner = gr.freq_xlating_fir_filter_ccf(1, taps, self.offset, sample_rate)

        self.interpolator = gr.fractional_interpolator_cc(0, sps)
        #channel type
        options.configuration = self.channel_combo_box.get_value()
        #use key or not
        options.key = "0000000000000000"#use this as default        
        if self.cb_imsi.GetValue() == True:
            options.key = str(self.edit_key.GetValue())

       
        self.receiver = gsm.receiver_cf(
        self.tune_corrector_callback, self.synchronizer_callback, 4,
        options.key.replace(' ', '').lower(),
        options.configuration.upper())

        self.output = gr.file_sink(gr.sizeof_float, options.output_file)
    #self.interpolator, self.receiver,
        self.connect(self.src, self.tuner, self.interpolator,self.receiver, self.converter, self.output)
        #ending
        time.sleep(0.3)

        tb.Run(True)
Exemple #26
0
    def __build_graph(self, source, capture_rate):
        # tell the scope the source rate
        self.spectrum.set_sample_rate(capture_rate)
        # channel filter
        self.channel_offset = 0.0
        channel_decim = capture_rate // self.channel_rate
        channel_rate = capture_rate // channel_decim
        trans_width = 12.5e3 / 2;
        trans_centre = trans_width + (trans_width / 2)
        coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN)
        self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, 0.0, capture_rate)
        self.set_channel_offset(0.0)
        # power squelch
        squelch_db = 0
        self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True)
        self.set_squelch_threshold(squelch_db)
        # FM demodulator
        fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
        fm_demod = gr.quadrature_demod_cf(fm_demod_gain)
        # symbol filter        
        symbol_decim = 1
        # symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500)
        # boxcar coefficients for "integrate and dump" filter
        samples_per_symbol = channel_rate // self.symbol_rate
        symbol_coeffs = (1.0/samples_per_symbol,)*samples_per_symbol
        symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)
        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset)
        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, self.symbol_rate)
        # symbol slicer
        levels = [ -2.0, 0.0, 2.0, 4.0 ]
        slicer = op25.fsk4_slicer_fb(levels)
        # ALSA output device (if not locked)
        try:
            sink = audio.sink(8000, "plughw:0,0", True) # ToDo: get actual device from prefs
        except Exception:
            sink = gr.null_sink(gr.sizeof_float)

        # connect it all up
        self.__connect([[source, self.channel_filter, self.squelch, fm_demod, symbol_filter, demod_fsk4, slicer, self.p25_decoder, sink],
                        [source, self.spectrum],
                        [symbol_filter, self.signal_scope],
                        [demod_fsk4, self.symbol_scope]])
Exemple #27
0
    def __init__(self, options):
        gr.top_block.__init__(self)

	sample_rate = int(options.sample_rate)	

	self.asrc = audio.source(sample_rate, options.audio_device, True)

	self.f2c = gr.float_to_complex(1)

	self.connect((self.asrc, 1), (self.f2c, 1))
	self.connect((self.asrc, 0), (self.f2c, 0))

        symbol_rate = 18000
        sps = 2
        # output rate will be 36,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate)

        sys.stderr.write("sample rate: %d\n" %(sample_rate))

        DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps,
                                 excess_bw=0.35,
                                 costas_alpha=0.03,
                                 gain_mu=0.05,
                                 mu=0.05,
                                 omega_relative_limit=0.05,
                                 log=options.log,
                                 verbose=options.verbose)

        OUT = gr.file_sink(gr.sizeof_float, options.output_file)

        r = float(sample_rate) / float(new_sample_rate)

        INTERPOLATOR = gr.fractional_interpolator_cc(0, r)

        self.connect(self.f2c, FILTER, INTERPOLATOR, DEMOD, OUT)
Exemple #28
0
    def ais_rx(self, src, freq, designator, options, queue):
        self.rate = options.rate
        self.u = src
        self.coeffs = gr.firdes.low_pass(1, self.rate, 7000, 1000)
        self._filter_decimation = int(self.rate / 64.0e3)
        print "%s: Sampling @ %f, decim @ %d" % (designator, self.rate,
                                                 self._filter_decimation)
        self.filter = gr.freq_xlating_fir_filter_ccf(self._filter_decimation,
                                                     self.coeffs, freq,
                                                     self.rate)

        self._bits_per_sec = 9600.0

        self._samples_per_symbol = self.rate / self._filter_decimation / self._bits_per_sec

        options.samples_per_symbol = self._samples_per_symbol
        options.gain_mu = 0.3
        options.mu = 0.5
        options.omega_relative_limit = 0.0001
        options.bits_per_sec = self._bits_per_sec
        options.fftlen = 4096  #trades off accuracy of freq estimation in presence of noise, vs. delay time.
        options.samp_rate = self.rate / self._filter_decimation
        self.demod = ais_demod(
            options
        )  #ais_demod.py, hierarchical demodulation block, takes in complex baseband and spits out 1-bit packed bitstream
        self.unstuff = ais.unstuff()  #ais_unstuff.cc, unstuffs data
        self.start_correlator = gr.correlate_access_code_tag_bb(
            "1010101010101010", 0,
            "ais_preamble")  #should mark start of packet
        self.stop_correlator = gr.correlate_access_code_tag_bb(
            "01111110", 0, "ais_frame")  #should mark start and end of packet
        self.parse = ais.parse(
            queue, designator
        )  #ais_parse.cc, calculates CRC, parses data into ASCII message, moves data onto queue

        self.connect(
            self.u, self.filter, self.demod, self.unstuff,
            self.start_correlator, self.stop_correlator, self.parse
        )  #parse posts messages to the queue, which the main loop reads and prints
Exemple #29
0
    def __build_graph(self, source, capture_rate):
        # tell the scope the source rate
        self.spectrum.set_sample_rate(capture_rate)
        # channel filter
        self.channel_offset = 0.0
        channel_decim = capture_rate // self.channel_rate
        channel_rate = capture_rate // channel_decim
        trans_width = 12.5e3 / 2;
        trans_centre = trans_width + (trans_width / 2)
        coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN)
        self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, -9500.0, capture_rate)
        self.set_channel_offset(0.0, 0, self.spectrum.win._units)
        # power squelch
        squelch_db = -60
        self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True)
        self.set_squelch_threshold(squelch_db)
        # FM demodulator
        fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
        fm_demod = gr.quadrature_demod_cf(fm_demod_gain)
        # symbol filter        
        symbol_decim = 1
        #symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500)
        # boxcar coefficients for "integrate and dump" filter
        samples_per_symbol = channel_rate // self.symbol_rate
        symbol_coeffs = (1.0/samples_per_symbol,)*samples_per_symbol
        symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)

        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset)
        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, self.symbol_rate)
        reverser = gr.multiply_const_ff(-1.0)
        # for now no audio output
        sink = gr.null_sink(gr.sizeof_float)
        # connect it all up
        self.__connect([[source, self.channel_filter, self.squelch, fm_demod, symbol_filter, demod_fsk4, reverser, self.slicer, self.p25_decoder, sink],
                        [source, self.spectrum],
                        [symbol_filter, self.signal_scope],
                        [demod_fsk4, self.symbol_scope]])
Exemple #30
0
	def setup_filter(self):
		#test w/o filter (for buffer latency)
		#self.filter = self.source
		#return
		
		options = self.options

		# configure channel filter
		filter_cutoff	= 145e3		#135,417Hz is GSM bandwidth 
		filter_t_width	= 10e3

		#Only DSP adjust for offset on datafile, adjust tuner for USRP
		#TODO: see if we can change this offset at runtime based on freq detection
		if options.inputfile:
			offset = self.offset
		else:
			offset = 0.0

		filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)
		self.filter = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate)

		self.connect(self.source, self.filter)
	def setup_filter(self):
		#test w/o filter (for buffer latency)
		#self.filter = self.source
		#return
		
		options = self.options

		# configure channel filter
		filter_cutoff	= 145e3		#135,417Hz is GSM bandwidth 
		filter_t_width	= 10e3

		#Only DSP adjust for offset on datafile, adjust tuner for USRP
		#TODO: see if we can change this offset at runtime based on freq detection
		if options.inputfile:
			offset = self.offset
		else:
			offset = 0.0

		filter_taps = gr.firdes.low_pass(1.0, self.input_rate, filter_cutoff, filter_t_width, gr.firdes.WIN_HAMMING)
		self.filter = gr.freq_xlating_fir_filter_ccf(1, filter_taps, offset, self.input_rate)

		self.connect(self.source, self.filter)
Exemple #32
0
    def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate,
                 channel_rate, lo_freq, max_dev, ctcss):
        gr.hier_block2.__init__(
            self,
            "rx_channel_nfm",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            #                               gr.io_signature(0, 0, 0))
            gr.io_signature(1, 1, gr.sizeof_float))

        output_sample_rate = 8000

        chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps,
                                              lo_freq, usrp_rate)

        nphases = 32
        frac_bw = 0.45
        rs_taps = gr.firdes.low_pass(nphases, nphases, frac_bw, 0.5 - frac_bw)

        resampler = blks2.pfb_arb_resampler_ccf(
            float(output_sample_rate) / channel_rate, (rs_taps), nphases)

        # FM Demodulator  input: complex; output: float
        k = output_sample_rate / (2 * math.pi * max_dev)
        fm_demod = gr.quadrature_demod_cf(k)

        self.connect(self, chan, resampler, fm_demod)
        if ctcss > 0:
            level = 5.0
            len = 0
            ramp = 0
            gate = True
            ctcss = repeater.ctcss_squelch_ff(output_sample_rate, ctcss, level,
                                              len, ramp, gate)
            self.connect(fm_demod, ctcss, self)
        else:
            self.connect(fm_demod, self)
Exemple #33
0
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-c",
                          "--calibration",
                          type="int",
                          default=0,
                          help="freq offset")
        parser.add_option("-i",
                          "--input-file",
                          type="string",
                          default="in.dat",
                          help="specify the input file")
        parser.add_option("-l",
                          "--log",
                          action="store_true",
                          default=False,
                          help="dump debug .dat files")
        parser.add_option("-L",
                          "--low-pass",
                          type="eng_float",
                          default=15e3,
                          help="low pass cut-off",
                          metavar="Hz")
        parser.add_option("-o",
                          "--output-file",
                          type="string",
                          default="out.dat",
                          help="specify the output file")
        parser.add_option("-s",
                          "--sample-rate",
                          type="int",
                          default=250000,
                          help="input sample rate")
        parser.add_option("-v",
                          "--verbose",
                          action="store_true",
                          default=False,
                          help="dump demodulation data")
        (options, args) = parser.parse_args()

        sample_rate = options.sample_rate
        symbol_rate = 4800
        sps = 10
        # output rate will be 48,000
        ntaps = 11 * sps
        new_sample_rate = symbol_rate * sps
        lcm = gru.lcm(sample_rate, new_sample_rate)
        interp = lcm // sample_rate
        decim = lcm // new_sample_rate

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass,
                                          options.low_pass * 0.1,
                                          gr.firdes.WIN_HANN)

        FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps,
                                                options.calibration,
                                                sample_rate)

        sys.stderr.write("interp: %d decim: %d\n" % (interp, decim))

        bpf_taps = gr.firdes.low_pass(1.0, sample_rate * interp,
                                      options.low_pass, options.low_pass * 0.1,
                                      gr.firdes.WIN_HANN)
        INTERPOLATOR = gr.interp_fir_filter_ccf(int(interp), bpf_taps)
        DECIMATOR = blks2.rational_resampler_ccf(1, int(decim))

        IN = gr.file_source(gr.sizeof_gr_complex, options.input_file)

        DEMOD = blks2.cqpsk_demod(samples_per_symbol=sps,
                                  excess_bw=0.35,
                                  costas_alpha=0.03,
                                  gain_mu=0.05,
                                  mu=0.05,
                                  omega_relative_limit=0.05,
                                  log=options.log,
                                  verbose=options.verbose)

        msgq = gr.msg_queue()
        DECODER = fsk4.apco25_f(msgq, 0)

        self.connect(IN, FILTER, INTERPOLATOR, DECIMATOR, DEMOD, DECODER)
Exemple #34
0
    def __init__(self, talkgroup, options):
        gr.hier_block2.__init__(
            self,
            "fsk_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, gr.sizeof_char))  # Output signature

        print "Starting log_receiver init()"
        self.samp_rate = samp_rate = int(options.rate)
        self.samp_per_sym = samp_per_sym = 10
        self.decim = decim = 20
        self.xlate_bandwidth = xlate_bandwidth = 24260.0
        self.xlate_offset = xlate_offset = 0
        self.channel_rate = channel_rate = op25.SYMBOL_RATE * samp_per_sym
        self.audio_mul = audio_mul = 1
        self.pre_channel_rate = pre_channel_rate = int(samp_rate / decim)

        self.squelch = squelch = -55
        self.auto_tune_offset = auto_tune_offset = 0
        self.audiorate = 44100  #options.audiorate
        self.rate = options.rate
        self.talkgroup = talkgroup
        self.directory = options.directory

        if options.squelch is None:
            options.squelch = 28

        if options.volume is None:
            options.volume = 3.0

        ##################################################
        # Blocks
        ##################################################
        print "Setting up Blocks"

        self.audiotaps = gr.firdes.low_pass(1, samp_rate, 8000, 2000,
                                            gr.firdes.WIN_HANN)

        self.prefilter_decim = int(self.rate / self.audiorate)

        #the audio prefilter is a channel selection filter.
        self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
            self.prefilter_decim,  #decimation
            self.audiotaps,  #taps
            0,  #freq offset
            int(samp_rate))  #sampling rate

        self.audiodemod = blks2.fm_demod_cf(
            self.rate / self.prefilter_decim,  #rate
            1,  #audio decimation
            4000,  #deviation
            3000,  #audio passband
            4000,  #audio stopband
            options.volume,  #gain
            75e-6)  #deemphasis constant

        #the filtering removes FSK data woobling from the subaudible channel
        self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50,
                                                 gr.firdes.WIN_HANN)

        self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)

        self.gr_quadrature_demod_cf_0 = analog.quadrature_demod_cf(
            1.6)  #(channel_rate/(2.0 * math.pi * op25.SYMBOL_DEVIATION)))
        self.gr_freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(
            decim, (firdes.low_pass(1, samp_rate, xlate_bandwidth / 2, 2000)),
            0, samp_rate)
        self.gr_fir_filter_xxx_0 = filter.fir_filter_fff(
            1, ((1.0 / samp_per_sym, ) * samp_per_sym))

        self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff(
            (10.**(audio_mul / 10.), ))
        self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_ccc(
            interpolation=channel_rate,
            decimation=pre_channel_rate,
            taps=None,
            fractional_bw=None,
        )
        self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff(
            interpolation=self.audiorate,
            decimation=8000,
            taps=None,
            fractional_bw=None,
        )

        #here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating.

        self.tmpfilename = "/tmp/%s.wav" % (
            "".join([
                random.choice(string.letters + string.digits) for x in range(8)
            ])
        )  #if this looks glaringly different, it's because i totally cribbed it from a blog.

        self.valve = grc_blks2.valve(gr.sizeof_float, bool(1))
        self.dsd_block_ff_0 = dsd.block_ff(dsd.dsd_FRAME_AUTO_DETECT,
                                           dsd.dsd_MOD_AUTO_SELECT, 3, 2, True)

        #open the logfile for appending
        self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup)
        self.timestampfile = open(self.timestampfilename, 'a')

        self.filename = "%s/%i.wav" % (self.directory, self.talkgroup)
        self.audiosink = smartnet.wavsink(
            self.filename, 1, self.audiorate, 8
        )  #blocks.wavfile_sink(self.filename, 1, self.audiorate, 8) this version allows appending to existing files.

        self.audio_sink_0 = audio.sink(44100, "", True)

        self.timestamp = 0.0

        #print "Finishing logging receiver init()."

        self.mute()  #start off muted.
        print "Connecting blocks"

        ##################################################
        # Connections
        ##################################################

        self.connect(self.blks2_rational_resampler_xxx_0,
                     self.blocks_multiply_const_vxx_0)

        self.connect(self.gr_fir_filter_xxx_0, self.valve, self.dsd_block_ff_0)
        self.connect(self.dsd_block_ff_0, self.blks2_rational_resampler_xxx_0)

        ## Start
        self.connect(self, self.gr_freq_xlating_fir_filter_xxx_0,
                     self.blks2_rational_resampler_xxx_1,
                     self.gr_quadrature_demod_cf_0, self.gr_fir_filter_xxx_0)

        ## End
        # self.connect(self.blocks_multiply_const_vxx_0, self.audio_sink_0) # Plays the audio
        self.connect(self.blocks_multiply_const_vxx_0,
                     self.audiosink)  # Records the audio
Exemple #35
0
    def __init__(self, subdev_spec, center_freq, offset_freq, decim, squelch, gain):

        gr.top_block.__init__(self)

        # configure USRP
        u = usrp.source_c()
        u.set_decim_rate(decim)
        capture_rate = u.adc_freq() / u.decim_rate()
        if subdev_spec is None:
            subdev_spec = usrp.pick_rx_subdevice(u)
        subdev = usrp.selected_subdev(u, subdev_spec)
        u.set_mux(usrp.determine_rx_mux_value(u, subdev_spec))
        print "Using RX d'board %s" % (subdev.side_and_name(),)

        if gain is None:
            g = subdev.gain_range()
            gain = float(g[0] + g[1]) / 2
        subdev.set_gain(gain)
        u.tune(0, subdev, center_freq)
                
        # setup receiver attributes
        channel_rate = 125000
        symbol_rate = 4800
        
        # channel filter
        self.channel_offset = offset_freq
        channel_decim = capture_rate // channel_rate
        channel_rate = capture_rate // channel_decim
        trans_width = 12.5e3 / 2;
        trans_centre = trans_width + (trans_width / 2)
        coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN)
        self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, self.channel_offset, capture_rate)
        self.connect(u, self.channel_filter)

        # power squelch
        power_squelch = gr.pwr_squelch_cc(squelch, 1e-3, 0, True)
        self.connect(self.channel_filter, power_squelch)

        # FM demodulator
        self.symbol_deviation = 600.0
        fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
        fm_demod = gr.quadrature_demod_cf(fm_demod_gain)
        self.connect(power_squelch, fm_demod)

        # symbol filter        
        symbol_decim = 1
        samples_per_symbol = channel_rate // symbol_rate
        symbol_coeffs = (1.0/samples_per_symbol,) * samples_per_symbol
        symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs)
        self.connect(fm_demod, symbol_filter)

        # C4FM demodulator
        autotuneq = gr.msg_queue(2)
        self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset)
        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, symbol_rate)
        self.connect(symbol_filter, demod_fsk4)

        # symbol slicer
        levels = [ -2.0, 0.0, 2.0, 4.0 ]
        slicer = op25.fsk4_slicer_fb(levels)
        self.connect(demod_fsk4, slicer)

        # frame decoder
        decoder = op25.decoder_bf()
        self.connect(slicer, decoder)

        # try to connect audio output device
        try:
            audio_sink = audio.sink(8000, "plughw:0,0", True)
            self.connect(decoder, audio_sink)
        except Exception:
            sink = gr.null_sink(gr.sizeof_float)
            self.connect(decoder, sink)
Exemple #36
0
    def __init__(self, options, queue):
        gr.top_block.__init__(self, "usrp_flex")
        self.options = options
        self.offset = 0.0
        self.adj_time = time.time()
        self.verbose = options.verbose

        if options.from_file is None:
            # Set up USRP source
            self.u = uhd.usrp_source(device_addr=options.address,
                                     stream_args=uhd.stream_args('fc32'))

            # Grab 250 KHz of spectrum
            # (A UHD facility to get sample rate range and granularity would be useful)
            self.u.set_samp_rate(250e3)
            rate = self.u.get_samp_rate()
            if rate != 250e3:
                print "Unable to set required sample rate of 250 Ksps (got %f)" % rate
                sys.exit(1)

            # Tune daughterboard
            r = self.u.set_center_freq(options.freq + options.calibration, 0)
            if not r:
                frange = self.u.get_freq_range()
                sys.stderr.write(("\nRequested frequency (%f) out or range [%f, %f]\n") % \
                                     (freq, frange.start(), frange.stop()))
                sys.exit(1)

            # if no gain was specified, use the mid-point in dB
            if options.rx_gain is None:
                grange = self.u.get_gain_range()
                options.rx_gain = float(grange.start() + grange.stop()) / 2.0
                print "\nNo gain specified."
                print "Setting gain to %f (from [%f, %f])" % \
                    (options.rx_gain, grange.start(), grange.stop())

            self.u.set_gain(options.rx_gain, 0)

        else:
            # Use supplied file as source of samples
            self.u = gr.file_source(gr.sizeof_gr_complex, options.from_file)
            if options.verbose:
                print "Reading samples from", options.from_file

        if options.log and not options.from_file:
            usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
            self.connect(self.u, usrp_sink)

        # Set up 22KHz-wide bandpass about center frequency. Decimate by 10
        # to get channel rate of 25Ksps
        taps = optfir.low_pass(
            1.0,  # Filter gain
            250e3,  # Sample rate
            11000,  # One-sided modulation bandwidth
            12500,  # One-sided channel bandwidth
            0.1,  # Passband ripple
            60)  # Stopband attenuation

        if options.verbose:
            print "Channel filter has", len(taps), "taps."

        self.chan = gr.freq_xlating_fir_filter_ccf(
            10,  # Decimation rate
            taps,  # Filter taps
            0.0,  # Offset frequency
            250e3)  # Sample rate

        if options.log:
            chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
            self.connect(self.chan, chan_sink)

        # FLEX protocol demodulator
        self.flex = pager.flex_demod(queue, options.freq, options.verbose,
                                     options.log)

        self.connect(self.u, self.chan, self.flex)
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Top Block")

        options = get_options()

        self.ifreq = options.frequency
        self.rfgain = options.gain

        self.src = osmosdr.source_c(options.args)
        self.src.set_center_freq(self.ifreq)
        self.src.set_sample_rate(int(options.sample_rate))
        #sq5bpf: dodalem ppm
        self.src.set_freq_corr(8)

        if self.rfgain is None:
            self.src.set_gain_mode(1)
            self.iagc = 1
            self.rfgain = 0
        else:
            self.iagc = 0
            self.src.set_gain_mode(0)
            self.src.set_gain(self.rfgain)

        # may differ from the requested rate
        sample_rate = self.src.get_sample_rate()
        sys.stderr.write("sample rate: %d\n" % (sample_rate))

        symbol_rate = 18000
        sps = 2  # output rate will be 36,000
        out_sample_rate = symbol_rate * sps

        options.low_pass = options.low_pass / 2.0

        if sample_rate == 96000:  # FunCube Dongle
            first_decim = 2
        else:
            first_decim = 10

        self.offset = 0

        taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass,
                                  options.low_pass * 0.2, gr.firdes.WIN_HANN)
        self.tuner = gr.freq_xlating_fir_filter_ccf(first_decim, taps,
                                                    self.offset, sample_rate)

        self.demod = cqpsk.cqpsk_demod(samples_per_symbol=sps,
                                       excess_bw=0.35,
                                       costas_alpha=0.03,
                                       gain_mu=0.05,
                                       mu=0.05,
                                       omega_relative_limit=0.05,
                                       log=options.log,
                                       verbose=options.verbose)

        self.output = gr.file_sink(gr.sizeof_float, options.output_file)

        rerate = float(
            sample_rate / float(first_decim)) / float(out_sample_rate)
        sys.stderr.write("resampling factor: %f\n" % rerate)

        if rerate.is_integer():
            sys.stderr.write("using pfb decimator\n")
            self.resamp = blks2.pfb_decimator_ccf(int(rerate))
        else:
            sys.stderr.write("using pfb resampler\n")
            self.resamp = blks2.pfb_arb_resampler_ccf(1 / rerate)

        self.connect(self.src, self.tuner, self.resamp, self.demod,
                     self.output)

        self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
        self.Main.AddPage(grc_wxgui.Panel(self.Main), "Wideband Spectrum")
        self.Main.AddPage(grc_wxgui.Panel(self.Main), "Channel Spectrum")
        self.Main.AddPage(grc_wxgui.Panel(self.Main), "Soft Bits")

        def set_ifreq(ifreq):
            self.ifreq = ifreq
            self._ifreq_text_box.set_value(self.ifreq)
            self.src.set_center_freq(self.ifreq)

        self._ifreq_text_box = forms.text_box(
            parent=self.GetWin(),
            value=self.ifreq,
            callback=set_ifreq,
            label="Center Frequency",
            converter=forms.float_converter(),
        )
        self.Add(self._ifreq_text_box)

        def set_iagc(iagc):
            self.iagc = iagc
            self._agc_check_box.set_value(self.iagc)
            self.src.set_gain_mode(self.iagc, 0)
            self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

        self._agc_check_box = forms.check_box(
            parent=self.GetWin(),
            value=self.iagc,
            callback=set_iagc,
            label="Automatic Gain",
            true=1,
            false=0,
        )

        self.Add(self._agc_check_box)

        def set_rfgain(rfgain):
            self.rfgain = rfgain
            self._rfgain_slider.set_value(self.rfgain)
            self._rfgain_text_box.set_value(self.rfgain)
            self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

        _rfgain_sizer = wx.BoxSizer(wx.VERTICAL)
        self._rfgain_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_rfgain_sizer,
            value=self.rfgain,
            callback=set_rfgain,
            label="RF Gain",
            converter=forms.float_converter(),
            proportion=0,
        )
        self._rfgain_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_rfgain_sizer,
            value=self.rfgain,
            callback=set_rfgain,
            minimum=0,
            maximum=50,
            num_steps=200,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )

        self.Add(_rfgain_sizer)

        self.Add(self.Main)

        def fftsink2_callback(x, y):
            x = x - self.ifreq
            sys.stderr.write("sq5bpf: x: %d \n" % x)
            if abs(x / (sample_rate / 2)) > 0.9:
                set_ifreq(self.ifreq + x / 2)
            else:
                sys.stderr.write("coarse tuned to: %d Hz\n" % x)
                self.offset = -x
                self.tuner.set_center_freq(self.offset)
                self._rxfreq_text_box.set_value(self.ifreq -
                                                self.offset)  #sq5bpf

        self.scope = fftsink2.fft_sink_c(
            self.Main.GetPage(0).GetWin(),
            title="Wideband Spectrum (click to coarse tune)",
            baseband_freq=self.ifreq,  #sq5bpf
            fft_size=1024,
            sample_rate=sample_rate,
            ref_scale=2.0,
            ref_level=0,
            y_divs=10,
            fft_rate=10,
            average=False,
            avg_alpha=0.6)

        self.Main.GetPage(0).Add(self.scope.win)
        self.scope.set_callback(fftsink2_callback)

        self.connect(self.src, self.scope)

        def fftsink2_callback2(x, y):
            self.offset = self.offset - (x / 10)
            sys.stderr.write("fine tuned to: %d Hz\n" % self.offset)
            self.tuner.set_center_freq(self.offset)
            self._rxfreq_text_box.set_value(self.ifreq - self.offset)  #sq5bpf

        self.scope2 = fftsink2.fft_sink_c(
            self.Main.GetPage(1).GetWin(),
            title="Channel Spectrum (click to fine tune)",
            fft_size=1024,
            sample_rate=out_sample_rate,
            ref_scale=2.0,
            ref_level=-20,
            y_divs=10,
            fft_rate=10,
            average=False,
            avg_alpha=0.6)

        self.Main.GetPage(1).Add(self.scope2.win)
        self.scope2.set_callback(fftsink2_callback2)

        self.connect(self.resamp, self.scope2)

        self.scope3 = scopesink2.scope_sink_f(
            self.Main.GetPage(2).GetWin(),
            title="Soft Bits",
            sample_rate=out_sample_rate,
            v_scale=0,
            v_offset=0,
            t_scale=0.001,
            ac_couple=False,
            xy_mode=False,
            num_inputs=1,
            trig_mode=gr.gr_TRIG_MODE_AUTO,
            y_axis_label="Counts",
        )
        self.Main.GetPage(2).Add(self.scope3.win)

        self.connect(self.demod, self.scope3)
        #sq5bpf
        self._rxfreq_text_box = forms.text_box(
            parent=self.GetWin(),
            value=self.ifreq - self.offset,
            label="RX Freq",
            converter=forms.float_converter(),
        )
        self.Add(self._rxfreq_text_box)
    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=1008.0e3,
                          help="set frequency to FREQ", metavar="FREQ")
        parser.add_option("-I", "--use-if-freq", action="store_true", default=False,
                          help="use intermediate freq (compensates DC problems in quadrature boards)" )
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is maximum)")
        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="",
                          help="pcm device name.  E.g., hw:0,0 or surround51 or /dev/dsp")

        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)
        
        self.frame = frame
        self.panel = panel
        self.use_IF=options.use_if_freq
        if self.use_IF:
          self.IF_freq=64000.0 
        else:
          self.IF_freq=0.0
        
        self.vol = 0
        self.state = "FREQ"
        self.freq = 0

        # build graph

        #TODO: add an AGC after the channel filter and before the AM_demod
        
        self.u = usrp.source_c()                    # usrp is data source

        adc_rate = self.u.adc_rate()                # 64 MS/s
        usrp_decim = 250
        self.u.set_decim_rate(usrp_decim)
        usrp_rate = adc_rate / usrp_decim           # 256 kS/s
        chanfilt_decim = 4
        demod_rate = usrp_rate / chanfilt_decim     # 64 kHz
        audio_decimation = 2
        audio_rate = demod_rate / audio_decimation  # 32 kHz

        if options.rx_subdev_spec is None:
            options.rx_subdev_spec = pick_subdevice(self.u)

        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 RX d'board %s" % (self.subdev.side_and_name(),)


        chan_filt_coeffs = optfir.low_pass (1,           # gain
                                            usrp_rate,   # sampling rate
                                            8e3,        # passband cutoff
                                            12e3,       # stopband cutoff
                                            1.0,         # passband ripple
                                            60)          # stopband attenuation
        #print len(chan_filt_coeffs)
        self.chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
        if self.use_IF:
          # Turn If to baseband and filter.
          self.chan_filt = gr.freq_xlating_fir_filter_ccf (chanfilt_decim, chan_filt_coeffs, self.IF_freq, usrp_rate)
        else:
          self.chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
        self.am_demod = gr.complex_to_mag()

        self.volume_control = gr.multiply_const_ff(self.vol)

        audio_filt_coeffs = optfir.low_pass (1,           # gain
                                            demod_rate,   # sampling rate
                                            8e3,        # passband cutoff
                                            10e3,       # stopband cutoff
                                            0.1,         # passband ripple
                                            60)          # stopband attenuation
        self.audio_filt=gr.fir_filter_fff(audio_decimation,audio_filt_coeffs)
        # sound card as final sink
        audio_sink = audio.sink (int (audio_rate),
                                 options.audio_output,
                                 False)  # ok_to_block
        
        # now wire it all together
        self.connect (self.u, self.chan_filt, self.am_demod, self.audio_filt, self.volume_control, audio_sink)

        self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)

        if options.gain is None:
            g = self.subdev.gain_range()
            if True:
              # if no gain was specified, use the maximum gain available 
              # (usefull for Basic_RX which is relatively deaf and the most probable board to be used for AM)
              # TODO: check db type to decide on default gain.
              options.gain = float(g[1])
            else:
              # if no gain was specified, use the mid-point in dB
              options.gain = float(g[0]+g[1])/2


        if options.volume is None:
            g = self.volume_range()
            options.volume = float(g[0]*3+g[1])/4
            
        if abs(options.freq) < 1e3:
            options.freq *= 1e3

        # set initial values

        self.set_gain(options.gain)
        self.set_vol(options.volume)
        if not(self.set_freq(options.freq)):
            self._set_status_msg("Failed to set initial frequency")
Exemple #39
0
    def __init__(self, options, queue):
        gr.top_block.__init__(self, "usrp_flex")
        self.options = options
        self.offset = 0.0
        self.adj_time = time.time()
        self.verbose = options.verbose

        if options.from_file is None:
            # Set up USRP source with specified RX daughterboard
            self.src = usrp.source_c()
            if options.rx_subdev_spec == None:
                options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src)
            self.subdev = usrp.selected_subdev(self.src,
                                               options.rx_subdev_spec)
            self.src.set_mux(
                usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))

            # Grab 250 KHz of spectrum (sample rate becomes 250 ksps complex)
            self.src.set_decim_rate(256)

            # If no gain specified, set to midrange
            if options.gain is None:
                g = self.subdev.gain_range()
                options.gain = (g[0] + g[1]) / 2.0
            self.subdev.set_gain(options.gain)

            # Tune daughterboard
            actual_frequency = options.frequency + options.calibration
            tune_result = usrp.tune(self.src, 0, self.subdev, actual_frequency)
            if not tune_result:
                sys.stderr.write("Failed to set center frequency to " +
                                 ` actual_frequency ` + "\n")
                sys.exit(1)

            if options.verbose:
                print "Using RX daughterboard", self.subdev.side_and_name()
                print "USRP gain is", options.gain
                print "USRP tuned to", actual_frequency

        else:
            # Use supplied file as source of samples
            self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
            if options.verbose:
                print "Reading samples from", options.from_file

        if options.log and not options.from_file:
            usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
            self.connect(self.src, usrp_sink)

        # Set up 22KHz-wide bandpass about center frequency. Decimate by 10
        # to get channel rate of 25Ksps
        taps = optfir.low_pass(
            1.0,  # Filter gain
            250e3,  # Sample rate
            11000,  # One-sided modulation bandwidth
            12500,  # One-sided channel bandwidth
            0.1,  # Passband ripple
            60)  # Stopband attenuation

        if options.verbose:
            print "Channel filter has", len(taps), "taps."

        self.chan = gr.freq_xlating_fir_filter_ccf(
            10,  # Decimation rate
            taps,  # Filter taps
            0.0,  # Offset frequency
            250e3)  # Sample rate

        if options.log:
            chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
            self.connect(self.chan, chan_sink)

        # FLEX protocol demodulator
        self.flex = pager.flex_demod(queue, options.frequency, options.verbose,
                                     options.log)

        self.connect(self.src, self.chan, self.flex)
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)

        # Menu Bar
        self.frame_1_menubar = wx.MenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wx.Menu()
        self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL)
        wxglade_tmp_menu.AppendItem(self.Exit)
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
        # Menu Bar end
        self.panel_1 = wx.Panel(self, -1)
        self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB")
        self.button_2 = wx.Button(self, ID_BUTTON_2, "USB")
        self.button_3 = wx.Button(self, ID_BUTTON_3, "AM")
        self.button_4 = wx.Button(self, ID_BUTTON_4, "CW")
        self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper")
        self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower")
        self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.panel_5 = wx.Panel(self, -1)
        self.label_1 = wx.StaticText(self, -1, " Band\nCenter")
        self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "")
        self.panel_6 = wx.Panel(self, -1)
        self.panel_7 = wx.Panel(self, -1)
        self.panel_2 = wx.Panel(self, -1)
        self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq")
        self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000)
        self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100)
        self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol")
        self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500)
        self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20)
        self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time")
        self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew")
        self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd")
        self.panel_3 = wx.Panel(self, -1)
        self.label_2 = wx.StaticText(self, -1, "PGA               ")
        self.panel_4 = wx.Panel(self, -1)
        self.panel_8 = wx.Panel(self, -1)
        self.panel_9 = wx.Panel(self, -1)
        self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier")
        self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.label_4 = wx.StaticText(self, -1, "Antenna Tune")
        self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.panel_10 = wx.Panel(self, -1)
        self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune")
        self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate")
        self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset")
        self.panel_11 = wx.Panel(self, -1)
        self.panel_12 = wx.Panel(self, -1)

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        parser = OptionParser(option_class=eng_option)
        parser.add_option(
            "-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ"
        )
        parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE")
        parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE")
        parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE")
        parser.add_option("-d", "--decim", type="int", default=250, help="USRP decimation")
        parser.add_option(
            "-R",
            "--rx-subdev-spec",
            type="subdev",
            default=None,
            help="select USRP Rx side A or B (default=first one with a daughterboard)",
        )
        (options, args) = parser.parse_args()

        self.usrp_center = options.ddc_freq
        usb_rate = 64e6 / options.decim
        self.slider_range = usb_rate * 0.9375
        self.f_lo = self.usrp_center - (self.slider_range / 2)
        self.f_hi = self.usrp_center + (self.slider_range / 2)
        self.af_sample_rate = 32000
        fir_decim = long(usb_rate / self.af_sample_rate)

        # data point arrays for antenna tuner
        self.xdata = []
        self.ydata = []

        self.tb = gr.top_block()

        # radio variables, initial conditions
        self.frequency = self.usrp_center
        # these map the frequency slider (0-6000) to the actual range
        self.f_slider_offset = self.f_lo
        self.f_slider_scale = 10000 / options.decim
        self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi)
        self.text_ctrl_1.SetValue(str(int(self.usrp_center)))
        self.slider_5.SetValue(0)
        self.AM_mode = False

        self.slider_3.SetValue((self.frequency - self.f_slider_offset) / self.f_slider_scale)
        self.spin_ctrl_1.SetValue(int(self.frequency))

        POWERMATE = True
        try:
            self.pm = powermate.powermate(self)
        except:
            sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n")
            POWERMATE = False

        if POWERMATE:
            powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate)
            powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton)
        self.active_button = 7

        # command line options
        if options.audio_file == "":
            SAVE_AUDIO_TO_FILE = False
        else:
            SAVE_AUDIO_TO_FILE = True
        if options.radio_file == "":
            SAVE_RADIO_TO_FILE = False
        else:
            SAVE_RADIO_TO_FILE = True
        if options.input_file == "":
            self.PLAY_FROM_USRP = True
        else:
            self.PLAY_FROM_USRP = False

        if self.PLAY_FROM_USRP:
            self.src = usrp.source_s(decim_rate=options.decim)
            if options.rx_subdev_spec is None:
                options.rx_subdev_spec = pick_subdevice(self.src)
            self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))
            self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec)
            self.src.tune(0, self.subdev, self.usrp_center)
            self.tune_offset = 0  # -self.usrp_center - self.src.rx_freq(0)

        else:
            self.src = gr.file_source(gr.sizeof_short, options.input_file)
            self.tune_offset = 2200  # 2200 works for 3.5-4Mhz band

        # save radio data to a file
        if SAVE_RADIO_TO_FILE:
            file = gr.file_sink(gr.sizeof_short, options.radio_file)
            self.tb.connect(self.src, file)

        # 2nd DDC
        xlate_taps = gr.firdes.low_pass(1.0, usb_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING)
        self.xlate = gr.freq_xlating_fir_filter_ccf(fir_decim, xlate_taps, self.tune_offset, usb_rate)

        # convert rf data in interleaved short int form to complex
        s2ss = gr.stream_to_streams(gr.sizeof_short, 2)
        s2f1 = gr.short_to_float()
        s2f2 = gr.short_to_float()
        src_f2c = gr.float_to_complex()
        self.tb.connect(self.src, s2ss)
        self.tb.connect((s2ss, 0), s2f1)
        self.tb.connect((s2ss, 1), s2f2)
        self.tb.connect(s2f1, (src_f2c, 0))
        self.tb.connect(s2f2, (src_f2c, 1))

        # Complex Audio filter
        audio_coeffs = gr.firdes.complex_band_pass(
            1.0,  # gain
            self.af_sample_rate,  # sample rate
            -3000,  # low cutoff
            0,  # high cutoff
            100,  # transition
            gr.firdes.WIN_HAMMING,
        )  # window
        self.slider_1.SetValue(0)
        self.slider_2.SetValue(-3000)

        self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs)

        # Main +/- 16Khz spectrum display
        self.fft = fftsink2.fft_sink_c(
            self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)
        )

        # AM Sync carrier
        if AM_SYNC_DISPLAY:
            self.fft2 = fftsink.fft_sink_c(
                self.tb,
                self.panel_9,
                y_per_div=20,
                fft_size=512,
                sample_rate=self.af_sample_rate,
                average=True,
                size=(640, 240),
            )

        c2f = gr.complex_to_float()

        # AM branch
        self.sel_am = gr.multiply_const_cc(0)
        # the following frequencies turn out to be in radians/sample
        # gr.pll_refout_cc(alpha,beta,min_freq,max_freq)
        # suggested alpha = X, beta = .25 * X * X
        pll = gr.pll_refout_cc(
            0.5, 0.0625, (2.0 * math.pi * 7.5e3 / self.af_sample_rate), (2.0 * math.pi * 6.5e3 / self.af_sample_rate)
        )
        self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0))
        am_det = gr.multiply_cc()
        # these are for converting +7.5kHz to -7.5kHz
        # for some reason gr.conjugate_cc() adds noise ??
        c2f2 = gr.complex_to_float()
        c2f3 = gr.complex_to_float()
        f2c = gr.float_to_complex()
        phaser1 = gr.multiply_const_ff(1)
        phaser2 = gr.multiply_const_ff(-1)

        # filter for pll generated carrier
        pll_carrier_coeffs = gr.firdes.complex_band_pass(
            2.0,  # gain
            self.af_sample_rate,  # sample rate
            7400,  # low cutoff
            7600,  # high cutoff
            100,  # transition
            gr.firdes.WIN_HAMMING,
        )  # window

        self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs)

        self.sel_sb = gr.multiply_const_ff(1)
        combine = gr.add_ff()

        # AGC
        sqr1 = gr.multiply_ff()
        intr = gr.iir_filter_ffd([0.004, 0], [0, 0.999])
        offset = gr.add_const_ff(1)
        agc = gr.divide_ff()

        self.scale = gr.multiply_const_ff(0.00001)
        dst = audio.sink(long(self.af_sample_rate))

        self.tb.connect(src_f2c, self.xlate, self.fft)
        self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0))
        self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3)
        self.tb.connect((c2f3, 0), phaser1, (f2c, 0))
        self.tb.connect((c2f3, 1), phaser2, (f2c, 1))
        self.tb.connect(f2c, (am_det, 1))
        self.tb.connect(am_det, c2f2, (combine, 0))
        self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1))
        if AM_SYNC_DISPLAY:
            self.tb.connect(self.pll_carrier_filter, self.fft2)
        self.tb.connect(combine, self.scale)
        self.tb.connect(self.scale, (sqr1, 0))
        self.tb.connect(self.scale, (sqr1, 1))
        self.tb.connect(sqr1, intr, offset, (agc, 1))
        self.tb.connect(self.scale, (agc, 0))
        self.tb.connect(agc, dst)

        if SAVE_AUDIO_TO_FILE:
            f_out = gr.file_sink(gr.sizeof_short, options.audio_file)
            sc1 = gr.multiply_const_ff(64000)
            f2s1 = gr.float_to_short()
            self.tb.connect(agc, sc1, f2s1, f_out)

        self.tb.start()

        # for mouse position reporting on fft display
        em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win)
        # and left click to re-tune
        em.eventManager.Register(self.Click, wx.EVT_LEFT_DOWN, self.fft.win)

        # start a timer to check for web commands
        if WEB_CONTROL:
            self.timer = UpdateTimer(self, 1000)  # every 1000 mSec, 1 Sec

        wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb)
        wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb)
        wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am)
        wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw)
        wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd)
        wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew)
        wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate)
        wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button)
        wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter)
        wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter)
        wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune)
        wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume)
        wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga)
        wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier)
        wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune)
        wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune)

        wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
Exemple #41
0
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Top Block")

        options = get_options()

        self.tune_corrector_callback = tune_corrector(self)
        self.synchronizer_callback = synchronizer(self)
        self.converter = gr.vector_to_stream(gr.sizeof_float, 142)

        self.ifreq = options.frequency
        self.rfgain = options.gain

        self.src = osmosdr.source_c(options.args)

        # added by scateu @ 2014-1-9
        self.src.set_freq_corr(0, 0)
        self.src.set_dc_offset_mode(1, 0)
        self.src.set_iq_balance_mode(0, 0)
        self.src.set_gain_mode(0, 0)
        self.src.set_gain(14, 0)
        self.src.set_if_gain(58, 0)
        self.src.set_bb_gain(20, 0)
        self.src.set_antenna("", 0)
        self.src.set_bandwidth(0, 0)

        self.src.set_center_freq(self.ifreq)
        self.src.set_sample_rate(int(options.sample_rate))

        if self.rfgain is None:
            self.src.set_gain_mode(1)
            self.iagc = 1
            self.rfgain = 0
        else:
            self.iagc = 0
            self.src.set_gain_mode(0)
            self.src.set_gain(self.rfgain)

        # may differ from the requested rate
        sample_rate = self.src.get_sample_rate()
        sys.stderr.write("sample rate: %d\n" % (sample_rate))

        gsm_symb_rate = 1625000.0 / 6.0
        sps = sample_rate / gsm_symb_rate / 4
        out_sample_rate = gsm_symb_rate * 4

        self.offset = 0

        taps = gr.firdes.low_pass(1.0, sample_rate, 145e3, 10e3,
                                  gr.firdes.WIN_HANN)
        self.tuner = gr.freq_xlating_fir_filter_ccf(1, taps, self.offset,
                                                    sample_rate)

        self.interpolator = gr.fractional_interpolator_cc(0, sps)

        self.receiver = gsm.receiver_cf(self.tune_corrector_callback,
                                        self.synchronizer_callback, 4,
                                        options.key.replace(' ', '').lower(),
                                        options.configuration.upper())

        self.output = gr.file_sink(gr.sizeof_float, options.output_file)

        self.connect(self.src, self.tuner, self.interpolator, self.receiver,
                     self.converter, self.output)

        def set_ifreq(ifreq):
            self.ifreq = ifreq
            self._ifreq_text_box.set_value(self.ifreq)
            self.src.set_center_freq(self.ifreq)

        self._ifreq_text_box = forms.text_box(
            parent=self.GetWin(),
            value=self.ifreq,
            callback=set_ifreq,
            label="Center Frequency",
            converter=forms.float_converter(),
        )
        self.Add(self._ifreq_text_box)

        def set_iagc(iagc):
            self.iagc = iagc
            self._agc_check_box.set_value(self.iagc)
            self.src.set_gain_mode(self.iagc, 0)
            self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

        self._agc_check_box = forms.check_box(
            parent=self.GetWin(),
            value=self.iagc,
            callback=set_iagc,
            label="Automatic Gain",
            true=1,
            false=0,
        )

        self.Add(self._agc_check_box)

        def set_rfgain(rfgain):
            self.rfgain = rfgain
            self._rfgain_slider.set_value(self.rfgain)
            self._rfgain_text_box.set_value(self.rfgain)
            self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

        _rfgain_sizer = wx.BoxSizer(wx.VERTICAL)
        self._rfgain_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_rfgain_sizer,
            value=self.rfgain,
            callback=set_rfgain,
            label="RF Gain",
            converter=forms.float_converter(),
            proportion=0,
        )
        self._rfgain_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_rfgain_sizer,
            value=self.rfgain,
            callback=set_rfgain,
            minimum=0,
            maximum=50,
            num_steps=200,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )

        self.Add(_rfgain_sizer)

        def fftsink2_callback(x, y):
            if abs(x / (sample_rate / 2)) > 0.9:
                set_ifreq(self.ifreq + x / 2)
            else:
                sys.stderr.write("coarse tuned to: %d Hz\n" % x)
                self.offset = -x
                self.tuner.set_center_freq(self.offset)

        self.scope = fftsink2.fft_sink_c(
            self.GetWin(),
            title="Wideband Spectrum (click to coarse tune)",
            fft_size=1024,
            sample_rate=sample_rate,
            ref_scale=2.0,
            ref_level=0,
            y_divs=10,
            fft_rate=10,
            average=False,
            avg_alpha=0.3)

        self.Add(self.scope.win)
        self.scope.set_callback(fftsink2_callback)

        self.connect(self.src, self.scope)

        def fftsink2_callback2(x, y):
            self.offset = self.offset - (x / 10)
            sys.stderr.write("fine tuned to: %d Hz\n" % self.offset)
            self.tuner.set_center_freq(self.offset)

        self.scope2 = fftsink2.fft_sink_c(
            self.GetWin(),
            title="Channel Spectrum (click to fine tune)",
            fft_size=1024,
            sample_rate=gsm_symb_rate * 4,
            ref_scale=2.0,
            ref_level=-20,
            y_divs=10,
            fft_rate=10,
            average=False,
            avg_alpha=0.3)

        self.Add(self.scope2.win)
        self.scope2.set_callback(fftsink2_callback2)

        self.connect(self.interpolator, self.scope2)
Exemple #42
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("-a", "--args", type="string", default="",
                          help="UHD device address args [default=%default]")
        parser.add_option("", "--spec", type="string", default=None,
	                  help="Subdevice of UHD device where appropriate")
        parser.add_option("-A", "--antenna", type="string", default=None,
                          help="select Rx Antenna where appropriate")
        parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6,
                          help="set sample rate (bandwidth) [default=%default]")
        parser.add_option("-f", "--freq", type="eng_float", default=1008.0e3,
                          help="set frequency to FREQ", metavar="FREQ")
        parser.add_option("-I", "--use-if-freq", action="store_true", default=False,
                          help="use intermediate freq (compensates DC problems in quadrature boards)" )
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is maximum)")
        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="default",
                          help="pcm device name.  E.g., hw:0,0 or surround51 or /dev/dsp")

        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        self.frame = frame
        self.panel = panel
        self.use_IF=options.use_if_freq
        if self.use_IF:
          self.IF_freq=64000.0
        else:
          self.IF_freq=0.0

        self.vol = 0
        self.state = "FREQ"
        self.freq = 0

        # build graph
        self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32'))

        # Set the subdevice spec
        if(options.spec):
            self.u.set_subdev_spec(options.spec, 0)

        # Set the antenna
        if(options.antenna):
            self.u.set_antenna(options.antenna, 0)

        usrp_rate  = 256e3
        demod_rate = 64e3
        audio_rate = 32e3
        chanfilt_decim = int(usrp_rate // demod_rate)
        audio_decim = int(demod_rate // audio_rate)

        self.u.set_samp_rate(usrp_rate)
        dev_rate = self.u.get_samp_rate()

        # Resample signal to exactly self.usrp_rate
        # FIXME: make one of the follow-on filters an arb resampler
        rrate = usrp_rate / dev_rate
        self.resamp = blks2.pfb_arb_resampler_ccf(rrate)

        chan_filt_coeffs = gr.firdes.low_pass_2 (1,          # gain
                                                 usrp_rate,  # sampling rate
                                                 8e3,        # passband cutoff
                                                 4e3,        # transition bw
                                                 60)         # stopband attenuation

        if self.use_IF:
          # Turn If to baseband and filter.
          self.chan_filt = gr.freq_xlating_fir_filter_ccf (chanfilt_decim,
                                                           chan_filt_coeffs,
                                                           self.IF_freq,
                                                           usrp_rate)
        else:
          self.chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)

        self.agc = gr.agc_cc(0.1, 1, 1, 100000)
        self.am_demod = gr.complex_to_mag()
        self.volume_control = gr.multiply_const_ff(self.vol)

        audio_filt_coeffs = gr.firdes.low_pass_2 (1,          # gain
                                                  demod_rate, # sampling rate
                                                  8e3,        # passband cutoff
                                                  2e3,        # transition bw
                                                  60)         # stopband attenuation
        self.audio_filt=gr.fir_filter_fff(audio_decim, audio_filt_coeffs)

        # sound card as final sink
        self.audio_sink = audio.sink (int (audio_rate),
                                      options.audio_output,
                                      False)  # ok_to_block

        # now wire it all together
        self.connect (self.u, self.resamp, self.chan_filt, self.agc,
                      self.am_demod, self.audio_filt,
                      self.volume_control, self.audio_sink)

        self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)

        if options.gain is None:
            g = self.u.get_gain_range()
            # if no gain was specified, use the mid gain
            options.gain = (g.start() + g.stop())/2.0

        if options.volume is None:
            v = self.volume_range()
            options.volume = float(v[0]*3+v[1])/4.0

        if abs(options.freq) < 1e3:
            options.freq *= 1e3

        # set initial values

        self.set_gain(options.gain)
        self.set_vol(options.volume)
        if not(self.set_freq(options.freq)):
            self._set_status_msg("Failed to set initial frequency")
    def __init__(self, options, queue):
        gr.top_block.__init__(self)

        if options.filename is not None:
            self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
            self.rate = options.rate

        else:
            self.u = uhd.usrp_source(options.addr,
                                     io_type=uhd.io_type.COMPLEX_FLOAT32,
                                     num_channels=1)

            if options.subdev is not None:
                self.u.set_subdev_spec(options.subdev, 0)

            self.u.set_samp_rate(options.rate)
            self.rate = self.u.get_samp_rate()

            # Set the antenna
            if (options.antenna):
                self.u.set_antenna(options.antenna, 0)

            self.centerfreq = options.centerfreq
            print "Tuning to: %fMHz" % (self.centerfreq - options.error)
            if not (self.tune(options.centerfreq - options.error)):
                print "Failed to set initial frequency"

            if options.gain is None:  #set to halfway
                g = self.u.get_gain_range()
                options.gain = (g.start() + g.stop()) / 2.0

            print "Setting gain to %i" % options.gain
            self.u.set_gain(options.gain)

            self.u.set_bandwidth(options.bandwidth)

        print "Samples per second is %i" % self.rate

        self._syms_per_sec = 3600

        options.samples_per_second = self.rate
        options.syms_per_sec = self._syms_per_sec
        options.gain_mu = 0.01
        options.mu = 0.5
        options.omega_relative_limit = 0.3
        options.syms_per_sec = self._syms_per_sec
        options.offset = options.centerfreq - options.freq
        print "Control channel offset: %f" % options.offset

        self.demod = fsk_demod(options)
        self.start_correlator = gr.correlate_access_code_tag_bb(
            "10101100", 0, "smartnet_preamble")  #should mark start of packet
        self.smartnet_deinterleave = smartnet.deinterleave()
        self.smartnet_crc = smartnet.crc(queue)

        if options.filename is None:
            self.connect(self.u, self.demod)
        else:
            self.connect(self.fs, self.demod)

        self.connect(self.demod, self.start_correlator,
                     self.smartnet_deinterleave, self.smartnet_crc)

        #hook up the audio patch
        if options.audio:
            self.audiorate = 48000
            self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000,
                                                gr.firdes.WIN_HANN)
            self.prefilter_decim = int(
                self.rate / self.audiorate
            )  #might have to use a rational resampler for audio
            print "Prefilter decimation: %i" % self.prefilter_decim
            self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
                self.prefilter_decim,  #decimation
                self.audiotaps,  #taps
                0,  #freq offset
                self.rate)  #sampling rate

            #on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
            #the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
            self.squelch = gr.pwr_squelch_cc(
                options.squelch,  #squelch point
                alpha=0.1,  #wat
                ramp=10,  #wat
                gate=False)

            self.audiodemod = blks2.fm_demod_cf(
                self.rate / self.prefilter_decim,  #rate
                1,  #audio decimation
                4000,  #deviation
                3000,  #audio passband
                4000,  #audio stopband
                1,  #gain
                75e-6)  #deemphasis constant

            #the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
            self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300,
                                                     50, gr.firdes.WIN_HANN)
            self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
            self.audiogain = gr.multiply_const_ff(options.volume)
            self.audiosink = audio.sink(self.audiorate, "")
            #			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

            self.mute()

            if options.filename is None:
                self.connect(self.u, self.audio_prefilter)
            else:
                self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
            self.connect(self.audio_prefilter, self.squelch, self.audiodemod,
                         self.audiofilt, self.audiogain, self.audiosink)
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("-a",
                          "--args",
                          type="string",
                          default="",
                          help="UHD device address args [default=%default]")
        parser.add_option("",
                          "--spec",
                          type="string",
                          default=None,
                          help="Subdevice of UHD device where appropriate")
        parser.add_option("-A",
                          "--antenna",
                          type="string",
                          default=None,
                          help="select Rx Antenna where appropriate")
        parser.add_option(
            "-s",
            "--samp-rate",
            type="eng_float",
            default=1e6,
            help="set sample rate (bandwidth) [default=%default]")
        parser.add_option("-f",
                          "--freq",
                          type="eng_float",
                          default=1008.0e3,
                          help="set frequency to FREQ",
                          metavar="FREQ")
        parser.add_option(
            "-I",
            "--use-if-freq",
            action="store_true",
            default=False,
            help=
            "use intermediate freq (compensates DC problems in quadrature boards)"
        )
        parser.add_option("-g",
                          "--gain",
                          type="eng_float",
                          default=None,
                          help="set gain in dB (default is maximum)")
        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="",
            help="pcm device name.  E.g., hw:0,0 or surround51 or /dev/dsp")

        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        self.frame = frame
        self.panel = panel
        self.use_IF = options.use_if_freq
        if self.use_IF:
            self.IF_freq = 64000.0
        else:
            self.IF_freq = 0.0

        self.vol = 0
        self.state = "FREQ"
        self.freq = 0

        # build graph
        self.u = uhd.usrp_source(device_addr=options.args,
                                 stream_args=uhd.stream_args('fc32'))

        usrp_rate = 256e3
        demod_rate = 64e3
        audio_rate = 32e3
        chanfilt_decim = int(usrp_rate // demod_rate)
        audio_decim = int(demod_rate // audio_rate)

        self.u.set_samp_rate(usrp_rate)
        dev_rate = self.u.get_samp_rate()

        # Resample signal to exactly self.usrp_rate
        # FIXME: make one of the follow-on filters an arb resampler
        rrate = usrp_rate / dev_rate
        self.resamp = blks2.pfb_arb_resampler_ccf(rrate)

        chan_filt_coeffs = gr.firdes.low_pass_2(
            1,  # gain
            usrp_rate,  # sampling rate
            8e3,  # passband cutoff
            4e3,  # transition bw
            60)  # stopband attenuation

        if self.use_IF:
            # Turn If to baseband and filter.
            self.chan_filt = gr.freq_xlating_fir_filter_ccf(
                chanfilt_decim, chan_filt_coeffs, self.IF_freq, usrp_rate)
        else:
            self.chan_filt = gr.fir_filter_ccf(chanfilt_decim,
                                               chan_filt_coeffs)

        self.agc = gr.agc_cc(0.1, 1, 1, 100000)
        self.am_demod = gr.complex_to_mag()
        self.volume_control = gr.multiply_const_ff(self.vol)

        audio_filt_coeffs = gr.firdes.low_pass_2(
            1,  # gain
            demod_rate,  # sampling rate
            8e3,  # passband cutoff
            2e3,  # transition bw
            60)  # stopband attenuation
        self.audio_filt = gr.fir_filter_fff(audio_decim, audio_filt_coeffs)

        # sound card as final sink
        self.audio_sink = audio.sink(int(audio_rate), options.audio_output,
                                     False)  # ok_to_block

        # now wire it all together
        self.connect(self.u, self.resamp, self.chan_filt, self.agc,
                     self.am_demod, self.audio_filt, self.volume_control,
                     self.audio_sink)

        self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)

        if options.gain is None:
            g = self.u.get_gain_range()
            if True:
                # if no gain was specified, use the mid gain
                options.gain = (g.start() + g.stop()) / 2.0
                options.gain = g.stop()

        if options.volume is None:
            v = self.volume_range()
            options.volume = float(v[0] * 3 + v[1]) / 4.0

        if abs(options.freq) < 1e3:
            options.freq *= 1e3

        # set initial values

        self.set_gain(options.gain)
        self.set_vol(options.volume)
        if not (self.set_freq(options.freq)):
            self._set_status_msg("Failed to set initial frequency")

        # Set the subdevice spec
        if (options.spec):
            self.u.set_subdev_spec(options.spec, 0)

        # Set the antenna
        if (options.antenna):
            self.u.set_antenna(options.antenna, 0)
  def __init__(self):
    grc_wxgui.top_block_gui.__init__(self, title="Top Block")

    options = get_options()

    self.ifreq = options.frequency
    self.rfgain = options.gain
    self.offset = options.frequency_offset

    self.src = osmosdr.source_c(options.args)
    self.src.set_center_freq(self.ifreq)
    self.src.set_sample_rate(int(options.sample_rate))

    if self.rfgain is None:
        self.src.set_gain_mode(1)
        self.iagc = 1
        self.rfgain = 0
    else:
        self.iagc = 0
        self.src.set_gain_mode(0)
        self.src.set_gain(self.rfgain)

    # may differ from the requested rate
    sample_rate = self.src.get_sample_rate()
    sys.stderr.write("sample rate: %d\n" % (sample_rate))

    symbol_rate = 18000
    sps = 2 # output rate will be 36,000
    out_sample_rate = symbol_rate * sps

    options.low_pass = options.low_pass / 2.0

    if sample_rate == 96000: # FunCube Dongle
        first_decim = 2
    else:
        first_decim = 10

    self.offset = 0

    taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.2, gr.firdes.WIN_HANN)
    self.tuner = gr.freq_xlating_fir_filter_ccf(first_decim, taps, self.offset, sample_rate)

    self.demod = cqpsk.cqpsk_demod(
        samples_per_symbol = sps,
        excess_bw=0.35,
        costas_alpha=0.03,
        gain_mu=0.05,
        mu=0.05,
        omega_relative_limit=0.05,
        log=options.log,
        verbose=options.verbose)

    self.output = gr.file_sink(gr.sizeof_float, options.output_file)

    rerate = float(sample_rate / float(first_decim)) / float(out_sample_rate)
    sys.stderr.write("resampling factor: %f\n" % rerate)

    if rerate.is_integer():
        sys.stderr.write("using pfb decimator\n")
        self.resamp = blks2.pfb_decimator_ccf(int(rerate))
    else:
        sys.stderr.write("using pfb resampler\n")
        self.resamp = blks2.pfb_arb_resampler_ccf(1 / rerate)

    self.connect(self.src, self.tuner, self.resamp, self.demod, self.output)

    self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
    self.Main.AddPage(grc_wxgui.Panel(self.Main), "Wideband Spectrum")
    self.Main.AddPage(grc_wxgui.Panel(self.Main), "Channel Spectrum")
    self.Main.AddPage(grc_wxgui.Panel(self.Main), "Soft Bits")

    def set_ifreq(ifreq):
        self.ifreq = ifreq
        self._ifreq_text_box.set_value(self.ifreq)
        self.src.set_center_freq(self.ifreq)

    self._ifreq_text_box = forms.text_box(
        parent=self.GetWin(),
        value=self.ifreq,
        callback=set_ifreq,
        label="Center Frequency",
        converter=forms.float_converter(),
    )
    self.Add(self._ifreq_text_box)

    def set_iagc(iagc):
        self.iagc = iagc
        self._agc_check_box.set_value(self.iagc)
        self.src.set_gain_mode(self.iagc, 0)
        self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

    self._agc_check_box = forms.check_box(
        parent=self.GetWin(),
        value=self.iagc,
        callback=set_iagc,
        label="Automatic Gain",
        true=1,
        false=0,
    )

    self.Add(self._agc_check_box)

    def set_rfgain(rfgain):
        self.rfgain = rfgain
        self._rfgain_slider.set_value(self.rfgain)
        self._rfgain_text_box.set_value(self.rfgain)
        self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

    _rfgain_sizer = wx.BoxSizer(wx.VERTICAL)
    self._rfgain_text_box = forms.text_box(
        parent=self.GetWin(),
        sizer=_rfgain_sizer,
        value=self.rfgain,
        callback=set_rfgain,
        label="RF Gain",
        converter=forms.float_converter(),
        proportion=0,
    )
    self._rfgain_slider = forms.slider(
        parent=self.GetWin(),
        sizer=_rfgain_sizer,
        value=self.rfgain,
        callback=set_rfgain,
        minimum=0,
        maximum=50,
        num_steps=200,
        style=wx.SL_HORIZONTAL,
        cast=float,
        proportion=1,
    )

    self.Add(_rfgain_sizer)

    self.Add(self.Main)

    def fftsink2_callback(x, y):
        if abs(x / (sample_rate / 2)) > 0.9:
            set_ifreq(self.ifreq + x / 2)
        else:
            self.offset = -x
            sys.stderr.write("coarse tuned to: %d Hz => %d Hz\n" % (self.offset, (self.ifreq + self.offset)))
            self.tuner.set_center_freq(self.offset)

    self.scope = fftsink2.fft_sink_c(self.Main.GetPage(0).GetWin(),
        title="Wideband Spectrum (click to coarse tune)",
        fft_size=1024,
        sample_rate=sample_rate,
        ref_scale=2.0,
        ref_level=0,
        y_divs=10,
        fft_rate=10,
        average=False,
        avg_alpha=0.6)

    self.Main.GetPage(0).Add(self.scope.win)
    self.scope.set_callback(fftsink2_callback)

    self.connect(self.src, self.scope)

    def fftsink2_callback2(x, y):
        self.offset = self.offset - (x / 10)
        sys.stderr.write("fine tuned to: %d Hz => %d Hz\n" % (self.offset, (self.ifreq + self.offset)))
        self.tuner.set_center_freq(self.offset)

    self.scope2 = fftsink2.fft_sink_c(self.Main.GetPage(1).GetWin(),
        title="Channel Spectrum (click to fine tune)",
        fft_size=1024,
        sample_rate=out_sample_rate,
        ref_scale=2.0,
        ref_level=-20,
        y_divs=10,
        fft_rate=10,
        average=False,
        avg_alpha=0.6)

    self.Main.GetPage(1).Add(self.scope2.win)
    self.scope2.set_callback(fftsink2_callback2)

    self.connect(self.resamp, self.scope2)

    self.scope3 = scopesink2.scope_sink_f(
        self.Main.GetPage(2).GetWin(),
        title="Soft Bits",
        sample_rate=out_sample_rate,
        v_scale=0,
        v_offset=0,
        t_scale=0.001,
        ac_couple=False,
        xy_mode=False,
        num_inputs=1,
        trig_mode=gr.gr_TRIG_MODE_AUTO,
        y_axis_label="Counts",
	)
    self.Main.GetPage(2).Add(self.scope3.win)

    self.connect(self.demod, self.scope3)
Exemple #46
0
    def __init__(self, talkgroup, options):
        gr.hier_block2.__init__(
            self,
            "fsk_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, gr.sizeof_char))  # Output signature

        #print "Starting log_receiver init()"

        self.audiorate = options.audiorate
        self.rate = options.rate
        self.talkgroup = talkgroup
        self.directory = options.directory

        if options.squelch is None:
            options.squelch = 28

        if options.volume is None:
            options.volume = 3.0

        self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000,
                                            gr.firdes.WIN_HANN)

        self.prefilter_decim = int(self.rate / self.audiorate)

        #the audio prefilter is a channel selection filter.
        self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
            self.prefilter_decim,  #decimation
            self.audiotaps,  #taps
            0,  #freq offset
            int(self.rate))  #sampling rate

        #on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
        #the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
        self.squelch = gr.pwr_squelch_cc(
            options.squelch,  #squelch point
            alpha=0.1,  #wat
            ramp=10,  #wat
            gate=True
        )  #gated so that the audio recording doesn't contain blank spaces between transmissions

        self.audiodemod = blks2.fm_demod_cf(
            self.rate / self.prefilter_decim,  #rate
            1,  #audio decimation
            4000,  #deviation
            3000,  #audio passband
            4000,  #audio stopband
            options.volume,  #gain
            75e-6)  #deemphasis constant

        #the filtering removes FSK data woobling from the subaudible channel
        self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50,
                                                 gr.firdes.WIN_HANN)

        self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)

        #self.audiogain = gr.multiply_const_ff(options.volume)

        #here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating.

        self.tmpfilename = "/tmp/%s.wav" % (
            "".join([
                random.choice(string.letters + string.digits) for x in range(8)
            ])
        )  #if this looks glaringly different, it's because i totally cribbed it from a blog.

        self.valve = grc_blks2.valve(gr.sizeof_float, bool(1))

        #self.prefiltervalve = grc_blks2.valve(gr.sizeof_gr_complex, bool(1))

        #open the logfile for appending
        self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup)
        self.timestampfile = open(self.timestampfilename, 'a')

        self.filename = "%s/%i.wav" % (self.directory, self.talkgroup)
        self.audiosink = smartnet.wavsink(
            self.filename, 1, self.audiorate,
            8)  #this version allows appending to existing files.

        #		self.connect(self, self.audio_prefilter, self.squelch, self.audiodemod, self.valve, self.audiofilt, self.audiosink)
        self.connect(self, self.audio_prefilter, self.audiodemod, self.valve,
                     self.audiofilt, self.audiosink)

        self.timestamp = 0.0

        #print "Finishing logging receiver init()."

        self.mute()  #start off muted.
    def __init__(self, options, queue):
        gr.top_block.__init__(self)

        if options.filename is not None:
            self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
            self.rate = options.rate

        else:
            #self.u = uhd.usrp_source(options.addr,
            #						 io_type=uhd.io_type.COMPLEX_FLOAT32,
            #						 num_channels=1)

            self.rtl = osmosdr.source_c(args="nchan=" + str(1) + " " + "")
            self.rtl.set_sample_rate(options.rate)
            self.rate = options.rate  #self.rtl.get_samp_rate()
            self.rtl.set_center_freq(options.centerfreq, 0)
            #self.rtl.set_freq_corr(options.ppm, 0)

            self.centerfreq = options.centerfreq
            print "Tuning to: %fMHz" % (self.centerfreq - options.error)
            if not (self.tune(options.centerfreq - options.error)):
                print "Failed to set initial frequency"

            if options.gain is None:
                options.gain = 10
            if options.bbgain is None:
                options.bbgain = 25
            if options.ifgain is None:
                options.ifgain = 25

            print "Setting RF gain to %i" % options.gain
            print "Setting BB gain to %i" % options.bbgain
            print "Setting IF gain to %i" % options.ifgain

            self.rtl.set_gain(options.gain, 0)
            self.rtl.set_if_gain(options.ifgain, 0)
            self.rtl.set_bb_gain(options.bbgain, 0)
            #self.rtl.set_gain_mode(1,0)

        print "Samples per second is %i" % self.rate

        self._syms_per_sec = 3600

        options.samples_per_second = self.rate
        options.syms_per_sec = self._syms_per_sec
        options.gain_mu = 0.01
        options.mu = 0.5
        options.omega_relative_limit = 0.3
        options.syms_per_sec = self._syms_per_sec
        options.offset = options.centerfreq - options.freq
        print "Control channel offset: %f" % options.offset

        self.offset = gr.sig_source_c(self.rate, gr.GR_SIN_WAVE,
                                      options.offset, 1.0, 0.0)

        # for some reason using the xlating filter to do the offset makes thing barf with the HackRF, Multiply CC seems to work

        options.offset = 0

        self.mixer = gr.multiply_cc()

        self.demod = fsk_demod(options)
        self.start_correlator = gr.correlate_access_code_tag_bb(
            "10101100", 0, "smartnet_preamble")  #should mark start of packet
        self.smartnet_deinterleave = smartnet.deinterleave()
        self.smartnet_crc = smartnet.crc(queue)

        #rerate = float(self.rate / float(first_decim)) / float(7200)
        #print "resampling factor: %f\n" % rerate

        #if rerate.is_integer():
        #    print "using pfb decimator\n"
        #    self.resamp = blks2.pfb_decimator_ccf(int(rerate))
        #else:
        #    print "using pfb resampler\n"
        #    self.resamp = blks2.pfb_arb_resampler_ccf(1 / rerate)

        if options.filename is None:
            #self.connect(self.u, self.demod)
            self.connect(self.rtl, (self.mixer, 0))
            self.connect(self.offset, (self.mixer, 1))
            self.connect(self.mixer, self.demod)
            #    self.connect(self.rtl, self.demod)
        else:
            self.connect(self.fs, self.demod)

        self.connect(self.demod, self.start_correlator,
                     self.smartnet_deinterleave, self.smartnet_crc)

        #hook up the audio patch
        if options.audio:
            self.audiorate = 48000
            self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000,
                                                gr.firdes.WIN_HANN)
            self.prefilter_decim = int(
                self.rate / self.audiorate
            )  #might have to use a rational resampler for audio
            print "Prefilter decimation: %i" % self.prefilter_decim
            self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
                self.prefilter_decim,  #decimation
                self.audiotaps,  #taps
                0,  #freq offset
                self.rate)  #sampling rate

            #on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
            #the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
            #self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
            #								   alpha = 0.1, #wat
            #								   ramp = 10, #wat
            #								   gate = False)

            self.audiodemod = blks2.fm_demod_cf(
                self.rate / self.prefilter_decim,  #rate
                1,  #audio decimation
                4000,  #deviation
                3000,  #audio passband
                4000,  #audio stopband
                1,  #gain
                75e-6)  #deemphasis constant

            #the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
            self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300,
                                                     50, gr.firdes.WIN_HANN)
            self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
            self.audiogain = gr.multiply_const_ff(options.volume)
            self.audiosink = audio.sink(self.audiorate, "")
            #			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

            #self.mute()

            if options.filename is None:
                #self.connect(self.u, self.audio_prefilter)
                self.connect(self.rtl, self.audio_prefilter)
            else:
                self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
#	real		self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
            self.connect(self.audio_prefilter, self.audiodemod, self.audiofilt,
                         self.audiogain, self.audiosink)
Exemple #48
0
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)

        # Menu Bar
        self.frame_1_menubar = wx.MenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wx.Menu()
        self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit",
                                wx.ITEM_NORMAL)
        wxglade_tmp_menu.AppendItem(self.Exit)
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
        # Menu Bar end
        self.panel_1 = wx.Panel(self, -1)
        self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB")
        self.button_2 = wx.Button(self, ID_BUTTON_2, "USB")
        self.button_3 = wx.Button(self, ID_BUTTON_3, "AM")
        self.button_4 = wx.Button(self, ID_BUTTON_4, "CW")
        self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper")
        self.slider_fcutoff_hi = wx.Slider(self,
                                           ID_SLIDER_1,
                                           0,
                                           -15798,
                                           15799,
                                           style=wx.SL_HORIZONTAL
                                           | wx.SL_LABELS)
        self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower")
        self.slider_fcutoff_lo = wx.Slider(self,
                                           ID_SLIDER_2,
                                           0,
                                           -15799,
                                           15798,
                                           style=wx.SL_HORIZONTAL
                                           | wx.SL_LABELS)
        self.panel_5 = wx.Panel(self, -1)
        self.label_1 = wx.StaticText(self, -1, " Band\nCenter")
        self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "")
        self.panel_6 = wx.Panel(self, -1)
        self.panel_7 = wx.Panel(self, -1)
        self.panel_2 = wx.Panel(self, -1)
        self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq")
        self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000)
        self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100)
        self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol")
        self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500)
        self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20)
        self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time")
        self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew")
        self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd")
        self.panel_3 = wx.Panel(self, -1)
        self.label_2 = wx.StaticText(self, -1, "PGA               ")
        self.panel_4 = wx.Panel(self, -1)
        self.panel_8 = wx.Panel(self, -1)
        self.panel_9 = wx.Panel(self, -1)
        self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier")
        self.slider_6 = wx.Slider(self,
                                  ID_SLIDER_6,
                                  50,
                                  0,
                                  200,
                                  style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.label_4 = wx.StaticText(self, -1, "Antenna Tune")
        self.slider_7 = wx.Slider(self,
                                  ID_SLIDER_7,
                                  1575,
                                  950,
                                  2200,
                                  style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.panel_10 = wx.Panel(self, -1)
        self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune")
        self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate")
        self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset")
        self.panel_11 = wx.Panel(self, -1)
        self.panel_12 = wx.Panel(self, -1)

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        parser = OptionParser(option_class=eng_option)
        parser.add_option("",
                          "--address",
                          type="string",
                          default="addr=192.168.10.2",
                          help="Address of UHD device, [default=%default]")
        parser.add_option("-c",
                          "--ddc-freq",
                          type="eng_float",
                          default=3.9e6,
                          help="set Rx DDC frequency to FREQ",
                          metavar="FREQ")
        parser.add_option(
            "-s",
            "--samp-rate",
            type="eng_float",
            default=256e3,
            help="set sample rate (bandwidth) [default=%default]")
        parser.add_option("-a",
                          "--audio_file",
                          default="",
                          help="audio output file",
                          metavar="FILE")
        parser.add_option("-r",
                          "--radio_file",
                          default="",
                          help="radio output file",
                          metavar="FILE")
        parser.add_option("-i",
                          "--input_file",
                          default="",
                          help="radio input file",
                          metavar="FILE")
        parser.add_option(
            "-O",
            "--audio-output",
            type="string",
            default="",
            help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse")

        (options, args) = parser.parse_args()

        self.usrp_center = options.ddc_freq
        input_rate = options.samp_rate
        self.slider_range = input_rate * 0.9375
        self.f_lo = self.usrp_center - (self.slider_range / 2)
        self.f_hi = self.usrp_center + (self.slider_range / 2)
        self.af_sample_rate = 32000
        fir_decim = long(input_rate / self.af_sample_rate)

        # data point arrays for antenna tuner
        self.xdata = []
        self.ydata = []

        self.tb = gr.top_block()

        # radio variables, initial conditions
        self.frequency = self.usrp_center
        # these map the frequency slider (0-6000) to the actual range
        self.f_slider_offset = self.f_lo
        self.f_slider_scale = 10000
        self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi)
        self.text_ctrl_1.SetValue(str(int(self.usrp_center)))
        self.slider_5.SetValue(0)
        self.AM_mode = False

        self.slider_3.SetValue(
            (self.frequency - self.f_slider_offset) / self.f_slider_scale)
        self.spin_ctrl_1.SetValue(int(self.frequency))

        POWERMATE = True
        try:
            self.pm = powermate.powermate(self)
        except:
            sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n")
            POWERMATE = False

        if POWERMATE:
            powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate)
            powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton)
        self.active_button = 7

        # command line options
        if options.audio_file == "": SAVE_AUDIO_TO_FILE = False
        else: SAVE_AUDIO_TO_FILE = True
        if options.radio_file == "": SAVE_RADIO_TO_FILE = False
        else: SAVE_RADIO_TO_FILE = True
        if options.input_file == "": self.PLAY_FROM_USRP = True
        else: self.PLAY_FROM_USRP = False

        if self.PLAY_FROM_USRP:
            self.src = uhd.usrp_source(device_addr=options.address,
                                       io_type=uhd.io_type.COMPLEX_FLOAT32,
                                       num_channels=1)
            self.src.set_samp_rate(input_rate)
            input_rate = self.src.get_samp_rate()

            self.src.set_center_freq(self.usrp_center, 0)
            self.tune_offset = 0

        else:
            self.src = gr.file_source(gr.sizeof_short, options.input_file)
            self.tune_offset = 2200  # 2200 works for 3.5-4Mhz band

            # convert rf data in interleaved short int form to complex
            s2ss = gr.stream_to_streams(gr.sizeof_short, 2)
            s2f1 = gr.short_to_float()
            s2f2 = gr.short_to_float()
            src_f2c = gr.float_to_complex()
            self.tb.connect(self.src, s2ss)
            self.tb.connect((s2ss, 0), s2f1)
            self.tb.connect((s2ss, 1), s2f2)
            self.tb.connect(s2f1, (src_f2c, 0))
            self.tb.connect(s2f2, (src_f2c, 1))

        # save radio data to a file
        if SAVE_RADIO_TO_FILE:
            radio_file = gr.file_sink(gr.sizeof_short, options.radio_file)
            self.tb.connect(self.src, radio_file)

# 2nd DDC
        xlate_taps = gr.firdes.low_pass ( \
           1.0, input_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING )
        self.xlate = gr.freq_xlating_fir_filter_ccf ( \
           fir_decim, xlate_taps, self.tune_offset, input_rate )

        # Complex Audio filter
        audio_coeffs = gr.firdes.complex_band_pass(
            1.0,  # gain
            self.af_sample_rate,  # sample rate
            -3000,  # low cutoff
            0,  # high cutoff
            100,  # transition
            gr.firdes.WIN_HAMMING)  # window
        self.slider_fcutoff_hi.SetValue(0)
        self.slider_fcutoff_lo.SetValue(-3000)

        self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs)

        # Main +/- 16Khz spectrum display
        self.fft = fftsink2.fft_sink_c(self.panel_2,
                                       fft_size=512,
                                       sample_rate=self.af_sample_rate,
                                       average=True,
                                       size=(640, 240))

        # AM Sync carrier
        if AM_SYNC_DISPLAY:
            self.fft2 = fftsink.fft_sink_c(self.tb,
                                           self.panel_9,
                                           y_per_div=20,
                                           fft_size=512,
                                           sample_rate=self.af_sample_rate,
                                           average=True,
                                           size=(640, 240))

        c2f = gr.complex_to_float()

        # AM branch
        self.sel_am = gr.multiply_const_cc(0)
        # the following frequencies turn out to be in radians/sample
        # gr.pll_refout_cc(alpha,beta,min_freq,max_freq)
        # suggested alpha = X, beta = .25 * X * X
        pll = gr.pll_refout_cc(.5, .0625,
                               (2. * math.pi * 7.5e3 / self.af_sample_rate),
                               (2. * math.pi * 6.5e3 / self.af_sample_rate))
        self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0))
        am_det = gr.multiply_cc()
        # these are for converting +7.5kHz to -7.5kHz
        # for some reason gr.conjugate_cc() adds noise ??
        c2f2 = gr.complex_to_float()
        c2f3 = gr.complex_to_float()
        f2c = gr.float_to_complex()
        phaser1 = gr.multiply_const_ff(1)
        phaser2 = gr.multiply_const_ff(-1)

        # filter for pll generated carrier
        pll_carrier_coeffs = gr.firdes.complex_band_pass(
            2.0,  # gain
            self.af_sample_rate,  # sample rate
            7400,  # low cutoff
            7600,  # high cutoff
            100,  # transition
            gr.firdes.WIN_HAMMING)  # window

        self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs)

        self.sel_sb = gr.multiply_const_ff(1)
        combine = gr.add_ff()

        #AGC
        sqr1 = gr.multiply_ff()
        intr = gr.iir_filter_ffd([.004, 0], [0, .999])
        offset = gr.add_const_ff(1)
        agc = gr.divide_ff()

        self.scale = gr.multiply_const_ff(0.00001)
        dst = audio.sink(long(self.af_sample_rate), options.audio_output)

        if self.PLAY_FROM_USRP:
            self.tb.connect(self.src, self.xlate, self.fft)
        else:
            self.tb.connect(src_f2c, self.xlate, self.fft)

        self.tb.connect(self.xlate, self.audio_filter, self.sel_am,
                        (am_det, 0))
        self.tb.connect(self.sel_am, pll, self.pll_carrier_scale,
                        self.pll_carrier_filter, c2f3)
        self.tb.connect((c2f3, 0), phaser1, (f2c, 0))
        self.tb.connect((c2f3, 1), phaser2, (f2c, 1))
        self.tb.connect(f2c, (am_det, 1))
        self.tb.connect(am_det, c2f2, (combine, 0))
        self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1))

        if AM_SYNC_DISPLAY:
            self.tb.connect(self.pll_carrier_filter, self.fft2)

        self.tb.connect(combine, self.scale)
        self.tb.connect(self.scale, (sqr1, 0))
        self.tb.connect(self.scale, (sqr1, 1))
        self.tb.connect(sqr1, intr, offset, (agc, 1))
        self.tb.connect(self.scale, (agc, 0))
        self.tb.connect(agc, dst)

        if SAVE_AUDIO_TO_FILE:
            f_out = gr.file_sink(gr.sizeof_short, options.audio_file)
            sc1 = gr.multiply_const_ff(64000)
            f2s1 = gr.float_to_short()
            self.tb.connect(agc, sc1, f2s1, f_out)

        self.tb.start()

        # for mouse position reporting on fft display
        self.fft.win.Bind(wx.EVT_LEFT_UP, self.Mouse)
        # and left click to re-tune
        self.fft.win.Bind(wx.EVT_LEFT_DOWN, self.Click)

        # start a timer to check for web commands
        if WEB_CONTROL:
            self.timer = UpdateTimer(self, 1000)  # every 1000 mSec, 1 Sec

        wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb)
        wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb)
        wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am)
        wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw)
        wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd)
        wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew)
        wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate)
        wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button)
        wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button)
        wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter)
        wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter)
        wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune)
        wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume)
        wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga)
        wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier)
        wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune)
        wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune)

        wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
    def __init__(self, options):
	gr.top_block.__init__(self)
	self.options = options

	(dev_rate, channel_rate, audio_rate,
	 channel_pass, channel_stop, demod) = demod_params[options.modulation]

        DEV = uhd_src(options.args,             # UHD device address
                      options.spec,             # device subdev spec
                      options.antenna,          # device antenna
                      dev_rate,         	# device sample rate
                      options.gain, 	    	# Receiver gain
                      options.calibration)      # Frequency offset
	DEV.tune(options.frequency)

	if_rate = DEV.rate()
        channel_decim = int(if_rate // channel_rate)
	audio_decim = int(channel_rate // audio_rate)

	CHAN_taps = optfir.low_pass(1.0,          # Filter gain
                                    if_rate, 	  # Sample rate
                                    channel_pass, # One sided modulation bandwidth
                                    channel_stop, # One sided channel bandwidth
                                    0.1, 	  # Passband ripple
                                    60) 	  # Stopband attenuation

	CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate
	                                      CHAN_taps,     # Filter taps
					      0.0, 	     # Offset frequency
					      if_rate)	     # Sample rate

	RFSQL = gr.pwr_squelch_cc(options.rf_squelch,    # Power threshold
	                          125.0/channel_rate, 	 # Time constant
				  int(channel_rate/20),  # 50ms rise/fall
				  False)		 # Zero, not gate output

	AGC = gr.agc_cc(1.0/channel_rate,  # Time constant
			1.0,     	   # Reference power 
			1.0,               # Initial gain
			1.0)		   # Maximum gain

	DEMOD = demod(channel_rate, audio_decim)

	# From RF to audio
        #self.connect(DEV, CHAN, RFSQL, AGC, DEMOD)
        self.connect(DEV, CHAN, DEMOD)

	# Optionally add CTCSS and RSAMP if needed
	tail = DEMOD
	if options.ctcss != None and options.ctcss > 60.0:
	    CTCSS = gr.ctcss_squelch_ff(audio_rate,    # Sample rate
				        options.ctcss) # Squelch tone
	    self.connect(DEMOD, CTCSS)
	    tail = CTCSS

	if options.output_rate != audio_rate:
	    out_lcm = gru.lcm(audio_rate, options.output_rate)
	    out_interp = int(out_lcm // audio_rate)
	    out_decim = int(out_lcm // options.output_rate)
	    RSAMP = blks2.rational_resampler_fff(out_interp, out_decim)
	    self.connect(tail, RSAMP)
	    tail = RSAMP 

	# Send to audio output device
        AUDIO = audio.sink(int(options.output_rate),
                           options.audio_output)
	self.connect(tail, AUDIO)

        # Direct asynchronous notifications to callback function
        if self.options.show_async_msg:
            self.async_msgq = gr.msg_queue(0)
            self.async_src = uhd.amsg_source("", self.async_msgq)
            self.async_rcv = gru.msgq_runner(self.async_msgq, self.async_callback)
    def __init__(self, options, queue):
        gr.top_block.__init__(self, "usrp_flex")
        self.options = options
	self.offset = 0.0
	self.file_offset = 0.0
	self.adj_time = time.time()
	self.verbose = options.verbose
			
	if options.from_file is None:
        
        
        self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + '' )
        self.rtlsdr_source_0.set_sample_rate(samp_rate)
        self.rtlsdr_source_0.set_center_freq(options.frequency, 0)
        self.rtlsdr_source_0.set_freq_corr(0, 0)
        self.rtlsdr_source_0.set_dc_offset_mode(0, 0)
        self.rtlsdr_source_0.set_iq_balance_mode(0, 0)
        self.rtlsdr_source_0.set_gain_mode(True, 0)
        self.rtlsdr_source_0.set_gain(50, 0)
        self.rtlsdr_source_0.set_if_gain(20, 0)
        self.rtlsdr_source_0.set_bb_gain(20, 0)
        self.rtlsdr_source_0.set_antenna('', 0)
        self.rtlsdr_source_0.set_bandwidth(0, 0)


                    
        else:
            # Use supplied file as source of samples
	    self.file_offset = options.calibration
            print "File input offset", self.offset
            self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
            if options.verbose:
                print "Reading samples from", options.from_file
	    
        if options.log and not options.from_file:
            usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
            self.connect(self.src, usrp_sink)

        # following is rig to allow fast and easy swapping of signal configuration
        # blocks between this example and the oscope example which uses self.msgq
	self.msgq = queue


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


        if options.protocol == 0:

  	  # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, 
          self.symbol_rate = 9600				# symbol rate; at 2 bits/symbol this corresponds to 19.2kbps
 	  self.channel_decimation = 10				# decimation (final rate should be at least several symbol rate)
	  self.max_frequency_offset = 12000.0			# coarse carrier tracker leash, ~ half a channel either way
	  self.symbol_deviation = 1200.0			# this is frequency offset from center of channel to +1 / -1 symbols
          self.input_sample_rate = 64e6 / options.decim		# for USRP: 64MHz / FPGA decimation rate	
	  self.protocol_processing = fsk4.rdlap_f(self.msgq, 0)	# desired protocol processing block selected here

          self.channel_rate = self.input_sample_rate / self.channel_decimation

          # channel selection filter characteristics
          channel_taps = optfir.low_pass(1.0,   # Filter gain
                               self.input_sample_rate, # Sample rate
                               10000, # One-sided modulation bandwidth
                               12000, # One-sided channel bandwidth
                               0.1,   # Passband ripple
                               60)    # Stopband attenuation

	  # symbol shaping filter characteristics
          symbol_coeffs = gr.firdes.root_raised_cosine (1.0,            	# gain
                                          self.channel_rate ,       	# sampling rate
                                          self.symbol_rate,             # symbol rate
                                          0.2,                		# width of trans. band
                                          500) 				# filter type 


        if options.protocol == 1:

	  # ---------- APCO-25 C4FM Test Data
          self.symbol_rate = 4800					# symbol rate; at 2 bits/symbol this corresponds to 19.2kbps
	  self.channel_decimation = 20				# decimation
	  self.max_frequency_offset = 6000.0			# coarse carrier tracker leash 
	  self.symbol_deviation = 600.0				# this is frequency offset from center of channel to +1 / -1 symbols
          self.input_sample_rate = 64e6 / options.decim		# for USRP: 64MHz / FPGA decimation rate	
	  self.protocol_processing = fsk4.apco25_f(self.msgq, 0)
          self.channel_rate = self.input_sample_rate / self.channel_decimation


          # channel selection filter
          channel_taps = optfir.low_pass(1.0,   # Filter gain
                               self.input_sample_rate, # Sample rate
                               5000, # One-sided modulation bandwidth
                               6500, # One-sided channel bandwidth
                               0.1,   # Passband ripple
                               60)    # Stopband attenuation

	  # symbol shaping filter
          symbol_coeffs = gr.firdes.root_raised_cosine (1.0,            	# gain
                                          self.channel_rate ,       	# sampling rate
                                          self.symbol_rate,             # symbol rate
                                          0.2,                		# width of trans. band
                                          500) 				# filter type 



        # ---------- End of configuration 

	
	if options.verbose:
	    print "Channel filter has", len(channel_taps), "taps."


        self.chan = gr.freq_xlating_fir_filter_ccf(self.channel_decimation ,    # Decimation rate
                                              channel_taps,  # Filter taps
                                              0.0,   # Offset frequency
                                              self.input_sample_rate) # Sample rate


	# also note: 
        # this specifies the nominal frequency deviation for the 4-level fsk signal
	self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation)
        self.fm_demod = gr.quadrature_demod_cf (self.fm_demod_gain)
        symbol_decim = 1
        self.symbol_filter = gr.fir_filter_fff (symbol_decim, symbol_coeffs)

        # eventually specify: sample rate, symbol rate
        self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate , self.symbol_rate)


	if options.log:
	    chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
	    self.connect(self.chan, chan_sink)


        if options.log:
          chan_sink2 = gr.file_sink(gr.sizeof_float, 'demod.dat')
          self.connect(self.demod_fsk4, chan_sink2)

	self.connect(self.src, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing)
        self.src.set_gain(self.rfgain)

       

    # may differ from the requested rate
    sample_rate = self.src.get_sample_rate()
    sys.stderr.write("sample rate: %d\n" % (sample_rate))

    gsm_symb_rate = 1625000.0 / 6.0
    sps = sample_rate / gsm_symb_rate / 4
    out_sample_rate = gsm_symb_rate * 4

    self.offset = 0

    taps = gr.firdes.low_pass(1.0, sample_rate, 145e3, 10e3, gr.firdes.WIN_HANN)
    self.tuner = gr.freq_xlating_fir_filter_ccf(1, taps, self.offset, sample_rate)

    self.interpolator = gr.fractional_interpolator_cc(0, sps)
    #options.configuration = "2S"
    self.receiver = gsm.receiver_cf(
         self.tune_corrector_callback, self.synchronizer_callback, 4,
         options.key.replace(' ', '').lower(),
         options.configuration.upper())

    self.output = gr.file_sink(gr.sizeof_float, options.output_file)

    self.connect(self.src, self.tuner, self.interpolator,self.receiver, self.converter, self.output)

    def set_ifreq(ifreq):
        self.ifreq = ifreq
        self._ifreq_text_box.set_value(self.ifreq)
	def __init__(self, options, queue):
		gr.top_block.__init__(self)

		if options.filename is not None:
			self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
			self.rate = options.rate

		else:
			#self.u = uhd.usrp_source(options.addr,
			#						 io_type=uhd.io_type.COMPLEX_FLOAT32,
			#						 num_channels=1)

                    
                    self.rtl = osmosdr.source_c( args="nchan=" + str(1) + " " + ""  )
                    self.rtl.set_sample_rate(options.rate)
                    self.rate = options.rate #self.rtl.get_samp_rate()
                    self.rtl.set_center_freq(options.centerfreq, 0)
                    #self.rtl.set_freq_corr(options.ppm, 0)
                    
		
                    self.centerfreq = options.centerfreq
                    print "Tuning to: %fMHz" % (self.centerfreq - options.error)
                    if not(self.tune(options.centerfreq - options.error)):
			print "Failed to set initial frequency"

                    if options.gain is None: 
			options.gain = 10
                    if options.bbgain is None: 
			options.bbgain = 25
                    if options.ifgain is None: 
			options.ifgain = 25


                    print "Setting RF gain to %i" % options.gain
                    print "Setting BB gain to %i" % options.bbgain
                    print "Setting IF gain to %i" % options.ifgain

                    self.rtl.set_gain(options.gain, 0) 
                    self.rtl.set_if_gain(options.ifgain,0)
                    self.rtl.set_bb_gain(options.bbgain,0)
                    #self.rtl.set_gain_mode(1,0)

		print "Samples per second is %i" % self.rate

		self._syms_per_sec = 3600;


		options.samples_per_second = self.rate
		options.syms_per_sec = self._syms_per_sec
		options.gain_mu = 0.01
		options.mu=0.5
		options.omega_relative_limit = 0.3
		options.syms_per_sec = self._syms_per_sec
		options.offset = options.centerfreq - options.freq
		print "Control channel offset: %f" % options.offset

                self.offset = gr.sig_source_c(self.rate, gr.GR_SIN_WAVE,
                                              options.offset, 1.0, 0.0)
		
		# for some reason using the xlating filter to do the offset makes thing barf with the HackRF, Multiply CC seems to work

		options.offset = 0

                self.mixer = gr.multiply_cc()

		self.demod = fsk_demod(options)
		self.start_correlator = gr.correlate_access_code_tag_bb("10101100",
		                                                        0,
		                                                        "smartnet_preamble") #should mark start of packet
		self.smartnet_deinterleave = smartnet.deinterleave()
		self.smartnet_crc = smartnet.crc(queue)

                #rerate = float(self.rate / float(first_decim)) / float(7200)
                #print "resampling factor: %f\n" % rerate
                
                #if rerate.is_integer():
                #    print "using pfb decimator\n"
                #    self.resamp = blks2.pfb_decimator_ccf(int(rerate))
                #else:
                #    print "using pfb resampler\n"
                #    self.resamp = blks2.pfb_arb_resampler_ccf(1 / rerate)

		if options.filename is None:
			#self.connect(self.u, self.demod)
                    self.connect(self.rtl, (self.mixer, 0))
                    self.connect(self.offset, (self.mixer, 1))                    
                    self.connect(self.mixer, self.demod)
                    #    self.connect(self.rtl, self.demod)
		else:
			self.connect(self.fs, self.demod)

		self.connect(self.demod, self.start_correlator, self.smartnet_deinterleave, self.smartnet_crc)

		#hook up the audio patch
		if options.audio:
			self.audiorate = 48000
			self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000, gr.firdes.WIN_HANN)
			self.prefilter_decim = int(self.rate / self.audiorate) #might have to use a rational resampler for audio
			print "Prefilter decimation: %i" % self.prefilter_decim
			self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(self.prefilter_decim, #decimation
									      self.audiotaps, #taps
									      0, #freq offset
									      self.rate) #sampling rate

			#on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
			#the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
			#self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
			#								   alpha = 0.1, #wat
			#								   ramp = 10, #wat
			#								   gate = False)

			self.audiodemod = blks2.fm_demod_cf(self.rate/self.prefilter_decim, #rate
							    1, #audio decimation
							    4000, #deviation
							    3000, #audio passband
							    4000, #audio stopband
							    1, #gain
							    75e-6) #deemphasis constant

			#the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
			self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50, gr.firdes.WIN_HANN)
			self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
			self.audiogain = gr.multiply_const_ff(options.volume)
			self.audiosink = audio.sink (self.audiorate, "")
#			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

			#self.mute()

			if options.filename is None:
				#self.connect(self.u, self.audio_prefilter)
                                self.connect(self.rtl, self.audio_prefilter)
			else:
				self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
#	real		self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
			self.connect(self.audio_prefilter, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
  def __init__(self):
    grc_wxgui.top_block_gui.__init__(self, title="Top Block")

    options = get_options()

    self.tune_corrector_callback = tune_corrector(self)
    self.synchronizer_callback = synchronizer(self)
    self.converter = gr.vector_to_stream(gr.sizeof_float, 142)

    self.ifreq = options.frequency
    self.rfgain = options.gain

    self.src = osmosdr.source_c(options.args)
    self.src.set_center_freq(self.ifreq)
    self.src.set_sample_rate(int(options.sample_rate))

    if self.rfgain is None:
        self.src.set_gain_mode(1)
        self.iagc = 1
        self.rfgain = 0
    else:
        self.iagc = 0
        self.src.set_gain_mode(0)
        self.src.set_gain(self.rfgain)

    # may differ from the requested rate
    sample_rate = self.src.get_sample_rate()
    sys.stderr.write("sample rate: %d\n" % (sample_rate))

    gsm_symb_rate = 1625000.0 / 6.0
    sps = sample_rate / gsm_symb_rate / 4
    out_sample_rate = gsm_symb_rate * 4

    self.offset = 0

    taps = gr.firdes.low_pass(1.0, sample_rate, 145e3, 10e3, gr.firdes.WIN_HANN)
    self.tuner = gr.freq_xlating_fir_filter_ccf(1, taps, self.offset, sample_rate)

    self.interpolator = gr.fractional_interpolator_cc(0, sps)

    self.receiver = gsm.receiver_cf(
        self.tune_corrector_callback, self.synchronizer_callback, 4,
        options.key.replace(' ', '').lower(),
        options.configuration.upper())

    self.output = gr.file_sink(gr.sizeof_float, options.output_file)

    self.connect(self.src, self.tuner, self.interpolator, self.receiver, self.converter, self.output)

    def set_ifreq(ifreq):
        self.ifreq = ifreq
        self._ifreq_text_box.set_value(self.ifreq)
        self.src.set_center_freq(self.ifreq)

    self._ifreq_text_box = forms.text_box(
        parent=self.GetWin(),
        value=self.ifreq,
        callback=set_ifreq,
        label="Center Frequency",
        converter=forms.float_converter(),
    )
    self.Add(self._ifreq_text_box)

    def set_iagc(iagc):
        self.iagc = iagc
        self._agc_check_box.set_value(self.iagc)
        self.src.set_gain_mode(self.iagc, 0)
        self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

    self._agc_check_box = forms.check_box(
        parent=self.GetWin(),
        value=self.iagc,
        callback=set_iagc,
        label="Automatic Gain",
        true=1,
        false=0,
    )

    self.Add(self._agc_check_box)

    def set_rfgain(rfgain):
        self.rfgain = rfgain
        self._rfgain_slider.set_value(self.rfgain)
        self._rfgain_text_box.set_value(self.rfgain)
        self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

    _rfgain_sizer = wx.BoxSizer(wx.VERTICAL)
    self._rfgain_text_box = forms.text_box(
        parent=self.GetWin(),
        sizer=_rfgain_sizer,
        value=self.rfgain,
        callback=set_rfgain,
        label="RF Gain",
        converter=forms.float_converter(),
        proportion=0,
    )
    self._rfgain_slider = forms.slider(
        parent=self.GetWin(),
        sizer=_rfgain_sizer,
        value=self.rfgain,
        callback=set_rfgain,
        minimum=0,
        maximum=50,
        num_steps=200,
        style=wx.SL_HORIZONTAL,
        cast=float,
        proportion=1,
    )

    self.Add(_rfgain_sizer)

    def fftsink2_callback(x, y):
        if abs(x / (sample_rate / 2)) > 0.9:
            set_ifreq(self.ifreq + x / 2)
        else:
            sys.stderr.write("coarse tuned to: %d Hz\n" % x)
            self.offset = -x
            self.tuner.set_center_freq(self.offset)

    self.scope = fftsink2.fft_sink_c(self.GetWin(),
        title="Wideband Spectrum (click to coarse tune)",
        fft_size=1024,
        sample_rate=sample_rate,
        ref_scale=2.0,
        ref_level=0,
        y_divs=10,
        fft_rate=10,
        average=False,
        avg_alpha=0.3)

    self.Add(self.scope.win)
    self.scope.set_callback(fftsink2_callback)

    self.connect(self.src, self.scope)

    def fftsink2_callback2(x, y):
        self.offset = self.offset - (x / 10)
        sys.stderr.write("fine tuned to: %d Hz\n" % self.offset)
        self.tuner.set_center_freq(self.offset)

    self.scope2 = fftsink2.fft_sink_c(self.GetWin(),
        title="Channel Spectrum (click to fine tune)",
        fft_size=1024,
        sample_rate=gsm_symb_rate * 4,
        ref_scale=2.0,
        ref_level=-20,
        y_divs=10,
        fft_rate=10,
        average=False,
        avg_alpha=0.3)

    self.Add(self.scope2.win)
    self.scope2.set_callback(fftsink2_callback2)

    self.connect(self.interpolator, self.scope2)
Exemple #54
0
    def __init__(self, subdev_spec, gain, audio_output):
	gr.hier_block2.__init__(self, "receive_path",
				gr.io_signature(0, 0, 0), # Input signature
				gr.io_signature(0, 0, 0)) # Output signature

        self.u = usrp.source_c ()
        adc_rate = self.u.adc_rate()

        self.if_rate = 256e3                         # 256 kS/s
        usrp_decim = int(adc_rate // self.if_rate)
        if_decim = 4
        self.u.set_decim_rate(usrp_decim)
        self.quad_rate = self.if_rate // if_decim    #  64 kS/s
        audio_decim = 2
        audio_rate = self.quad_rate // audio_decim   #  32 kS/s

        if subdev_spec is None:
            subdev_spec = usrp.pick_rx_subdevice(self.u)
        self.subdev = usrp.selected_subdev(self.u, subdev_spec)
        print "RX using", self.subdev.name()

        self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec))

        # Create filter to get actual channel we want
        chan_coeffs = gr.firdes.low_pass (1.0,                # gain
                                          self.if_rate,       # sampling rate
                                          13e3,               # low pass cutoff freq
                                          4e3,                # width of trans. band
                                          gr.firdes.WIN_HANN) # filter type 

        print "len(rx_chan_coeffs) =", len(chan_coeffs)

        # Decimating Channel filter with frequency translation
        # complex in and out, float taps
        self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim,       # decimation rate
                                                  chan_coeffs,    # taps
                                                  0,              # frequency translation amount
                                                  self.if_rate)   # input sample rate

        # instantiate the guts of the single channel receiver
        self.fmrx = blks2.nbfm_rx(audio_rate, self.quad_rate)

        # standard squelch block
        self.squelch = blks2.standard_squelch(audio_rate)

        # audio gain / mute block
        self._audio_gain = gr.multiply_const_ff(1.0)

        # sound card as final sink
        audio_sink = audio.sink (int(audio_rate), audio_output)
        
        # now wire it all together
        self.connect (self.u, self.ddc, self.fmrx, self.squelch, self._audio_gain, audio_sink)

        if gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.subdev.gain_range()
            gain = float(g[0]+g[1])/2

        self.enabled = True
        self.set_gain(gain)
        v = self.volume_range()
        self.set_volume((v[0]+v[1])/2)
        s = self.squelch_range()
        self.set_squelch((s[0]+s[1])/2)
Exemple #55
0
    def __init__(self, subdev_spec, gain, audio_output):
        gr.hier_block2.__init__(
            self,
            "receive_path",
            gr.io_signature(0, 0, 0),  # Input signature
            gr.io_signature(0, 0, 0))  # Output signature

        self.u = usrp.source_c()
        adc_rate = self.u.adc_rate()

        self.if_rate = 256e3  # 256 kS/s
        usrp_decim = int(adc_rate // self.if_rate)
        if_decim = 4
        self.u.set_decim_rate(usrp_decim)
        self.quad_rate = self.if_rate // if_decim  #  64 kS/s
        audio_decim = 2
        self.audio_rate = self.quad_rate // audio_decim  #  32 kS/s

        if subdev_spec is None:
            subdev_spec = usrp.pick_rx_subdevice(self.u)
        self.subdev = usrp.selected_subdev(self.u, subdev_spec)
        print "Using RX d'board %s" % (self.subdev.side_and_name(), )

        self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec))

        # Create filter to get actual channel we want
        chan_coeffs = gr.firdes.low_pass(
            1.0,  # gain
            self.if_rate,  # sampling rate
            8e3,  # low pass cutoff freq
            2e3,  # width of trans. band
            gr.firdes.WIN_HANN)  # filter type

        print "len(rx_chan_coeffs) =", len(chan_coeffs)

        # Decimating Channel filter with frequency translation
        # complex in and out, float taps
        self.ddc = gr.freq_xlating_fir_filter_ccf(
            if_decim,  # decimation rate
            chan_coeffs,  # taps
            0,  # frequency translation amount
            self.if_rate)  # input sample rate

        if USE_SIMPLE_SQUELCH:
            self.squelch = gr.simple_squelch_cc(20)
        else:
            self.squelch = blks2.standard_squelch(self.audio_rate)

    # instantiate the guts of the single channel receiver
        self.fmrx = blks2.nbfm_rx(self.audio_rate, self.quad_rate)

        # audio gain / mute block
        self._audio_gain = gr.multiply_const_ff(1.0)

        # sound card as final sink
        audio_sink = audio.sink(int(self.audio_rate), audio_output)

        # now wire it all together
        if USE_SIMPLE_SQUELCH:
            self.connect(self.u, self.ddc, self.squelch, self.fmrx,
                         self._audio_gain, audio_sink)
        else:
            self.connect(self.u, self.ddc, self.fmrx, self.squelch,
                         self._audio_gain, audio_sink)

        if gain is None:
            # if no gain was specified, use the mid-point in dB
            g = self.subdev.gain_range()
            gain = float(g[0] + g[1]) / 2

        self.set_gain(gain)

        v = self.volume_range()
        self.set_volume((v[0] + v[1]) / 2)
        s = self.squelch_range()
        self.set_squelch((s[0] + s[1]) / 2)