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)
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))
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)
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()
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)
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)
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)
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
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
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
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]])
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)
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 __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]])
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)
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()
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)
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]])
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)
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
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]])
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)
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)
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 __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
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)
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")
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)
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)
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)
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)
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)
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)
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)
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)