diff options
author | max <max@65a5c917-d112-43f1-993d-58c26a4786be> | 2013-09-17 02:00:16 +0000 |
---|---|---|
committer | max <max@65a5c917-d112-43f1-993d-58c26a4786be> | 2013-09-17 02:00:16 +0000 |
commit | 86373169c7a5c5affcba478119f52e7a94b4ef33 (patch) | |
tree | d50d26010866c1e9715a2669b172d3eaa0a55b15 | |
parent | fb53d788aede8e5a14cab04a4080540ac22f48f9 (diff) |
osmosdr, updates
git-svn-id: http://op25.osmocom.org/svn/trunk@324 65a5c917-d112-43f1-993d-58c26a4786be
-rwxr-xr-x | repeater/src/python/scope.py | 145 |
1 files changed, 78 insertions, 67 deletions
diff --git a/repeater/src/python/scope.py b/repeater/src/python/scope.py index cb91c68..5434196 100755 --- a/repeater/src/python/scope.py +++ b/repeater/src/python/scope.py @@ -2,7 +2,7 @@ # Copyright 2008-2011 Steve Glass # -# Copyright 2011 KA1RBI +# Copyright 2011, 2012, 2013 KA1RBI # # Copyright 2003,2004,2005,2006 Free Software Foundation, Inc. # (from radiorausch) @@ -35,7 +35,10 @@ import math import numpy import time import re -import Numeric +try: + import Numeric +except: + pass from gnuradio import audio, eng_notation, op25, gr, gru, repeater from gnuradio import blks2 @@ -43,7 +46,6 @@ from gnuradio.eng_option import eng_option from gnuradio.wxgui import stdgui2, fftsink2, scopesink2, form from math import pi from optparse import OptionParser -from usrpm import usrp_dbid import gnuradio.wxgui.plot as plot @@ -63,6 +65,8 @@ class p25_rx_block (stdgui2.std_top_block): # command line argument parsing parser = OptionParser(option_class=eng_option) + parser.add_option("--args", type="string", default="", help="device args") + parser.add_option("--antenna", type="string", default="", help="select antenna") parser.add_option("-a", "--audio", action="store_true", default=False, help="use direct audio input") parser.add_option("-A", "--audio-if", action="store_true", default=False, help="soundcard IF mode (use --calibration to set IF freq)") parser.add_option("-I", "--audio-input", type="string", default="", help="pcm input device name. E.g., hw:0,0 or /dev/dsp") @@ -73,8 +77,11 @@ class p25_rx_block (stdgui2.std_top_block): parser.add_option("-f", "--frequency", type="eng_float", default=0.0, help="USRP center frequency", metavar="Hz") parser.add_option("-F", "--ifile", type="string", default=None, help="read input from complex capture file") parser.add_option("-s", "--seek", type="int", default=0, help="ifile seek in K") - parser.add_option("-d", "--decim", type="int", default=200, help="source decimation factor") + parser.add_option("-S", "--sample-rate", type="int", default=320e3, help="source samp rate") + parser.add_option("-t", "--tone-detect", action="store_true", default=False, help="use experimental tone detect algorithm") parser.add_option("-v", "--verbosity", type="int", default=10, help="message debug level") + parser.add_option("-V", "--vocoder", action="store_true", default=False, help="voice codec") + parser.add_option("-o", "--offset", type="eng_float", default=0.0, help="tuning offset frequency [to circumvent DC offset]", metavar="Hz") parser.add_option("-p", "--pause", action="store_true", default=False, help="block on startup") parser.add_option("-w", "--wireshark", action="store_true", default=False, help="output data to Wireshark") parser.add_option("-W", "--wireshark-host", type="string", default="127.0.0.1", help="Wireshark host") @@ -90,16 +97,18 @@ class p25_rx_block (stdgui2.std_top_block): self.channel_rate = 0 self.baseband_input = False - # do we have a USRP? + # check if osmocom is accessible try: - self.usrp = None - from gnuradio import usrp - self.usrp = usrp.source_c() - self.channel_rate = self.usrp.adc_freq() / options.decim + self.src = None + import osmosdr + self.src = osmosdr.source_c(options.args) + self.channel_rate = options.sample_rate except Exception: - print "USRP source_c creation failure" + print "osmosdr source_c creation failure" ignore = True + print 'gain names ', self.src.get_gain_names() + if options.audio: self.channel_rate = 48000 self.baseband_input = True @@ -145,7 +154,7 @@ class p25_rx_block (stdgui2.std_top_block): self.open_file(options.input) elif options.frequency: self._set_state("CAPTURING") - self.open_usrp(options.rx_subdev_spec, options.decim, options.gain, options.frequency, True) + self.open_usrp() elif options.audio_if: self._set_state("CAPTURING") self.open_audio_c(self.channel_rate, options.gain, options.audio_input) @@ -169,7 +178,7 @@ class p25_rx_block (stdgui2.std_top_block): self.spectrum.set_sample_rate(capture_rate) # channel filter self.channel_offset = 0.0 - channel_decim = capture_rate // self.channel_rate + channel_decim = int(capture_rate // self.channel_rate) channel_rate = capture_rate // channel_decim trans_width = 12.5e3 / 2; trans_centre = trans_width + (trans_width / 2) @@ -197,8 +206,17 @@ class p25_rx_block (stdgui2.std_top_block): udp_port = WIRESHARK_PORT if self.options.raw_symbols: self.sink_sf = gr.file_sink(gr.sizeof_char, self.options.raw_symbols) - self.sink_s = repeater.p25_frame_assembler(self.options.wireshark_host, udp_port, self.options.verbosity, 0, 0, 0, msgq) - + do_imbe = 1 + do_output = 1 + self.sink_s = repeater.p25_frame_assembler(self.options.wireshark_host, udp_port, self.options.verbosity, do_imbe, do_output, 0, msgq) + if self.options.vocoder: + self.sink_imbe = repeater.vocoder(0, 0, 0, '', 0, 0) + self.audio_s2f = gr.short_to_float() + self.audio_scaler = gr.multiply_const_ff(1 / 32768.0) + self.audio_output = audio.sink(8000, "pulse", True) + self.connect(self.sink_imbe, self.audio_s2f, self.audio_scaler, self.audio_output) + else: + self.sink_imbe = gr.null_sink(gr.sizeof_char) if self.baseband_input: gain = self.options.gain else: @@ -234,9 +252,9 @@ class p25_rx_block (stdgui2.std_top_block): self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, 0.0, capture_rate) self.set_channel_offset(0.0, 0, "") # local osc - self.lo_freq = 0.0 + self.lo_freq = self.options.offset if self.options.audio_if or self.options.ifile: - self.lo_freq = self.options.calibration + self.lo_freq += self.options.calibration self.lo = gr.sig_source_c (channel_rate, gr.GR_SIN_WAVE, self.lo_freq, 1.0, 0) self.mixer = gr.multiply_cc() lpf_coeffs = gr.firdes.low_pass(1.0, self.channel_rate, 12000, 1200, gr.firdes.WIN_HANN) @@ -249,10 +267,7 @@ class p25_rx_block (stdgui2.std_top_block): rs_taps = gr.firdes.low_pass(nphases, nphases, frac_bw, 0.5-frac_bw) self.arb_resampler = blks2.pfb_arb_resampler_ccf( - float(self.basic_rate)/float(capture_rate), - (rs_taps), - nphases, - ) + float(self.basic_rate)/float(capture_rate)) fm_demod_gain = self.basic_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf(fm_demod_gain) @@ -264,29 +279,31 @@ class p25_rx_block (stdgui2.std_top_block): self.options.excess_bw, # excess bandwidth (roll-off factor) ntaps) - self.symbol_filter_c = gr.interp_fir_filter_ccf(1, rrc_taps) + #self.symbol_filter_c = gr.interp_fir_filter_ccf(1, rrc_taps) + self.symbol_filter_c = gr.multiply_const_cc(1.0) self.resamplers = [] for speed in speeds: resampler = blks2.pfb_arb_resampler_ccf( - float(speed)/float(self.symbol_rate), - (rs_taps), - nphases, - ) + float(speed)/float(self.symbol_rate)) self.resamplers.append(resampler) - theta = pi - - gain_mu= self.options.gain_mu - omega = float(sps) - gain_omega = 0.1 * gain_mu * gain_mu + if self.options.tone_detect: + step_size = 7.5e-8 + theta = -2 + cic_length = 48 + self.clock = repeater.tdetect_cc(sps, step_size, theta, cic_length) + else: + gain_mu= self.options.gain_mu + omega = float(sps) + gain_omega = 0.1 * gain_mu * gain_mu - alpha = self.options.costas_alpha - beta = 0.125 * alpha * alpha - fmin = -0.025 - fmax = 0.025 + alpha = self.options.costas_alpha + beta = 0.125 * alpha * alpha + fmin = -0.025 + fmax = 0.025 - self.clock = repeater.gardner_costas_cc(omega, gain_mu, gain_omega, alpha, beta, fmax, fmin) + self.clock = repeater.gardner_costas_cc(omega, gain_mu, gain_omega, alpha, beta, fmax, fmin) self.agc = gr.feedforward_agc_cc(16, 1.0) @@ -303,6 +320,7 @@ class p25_rx_block (stdgui2.std_top_block): self.__connect([[source, (self.mixer, 0)], [self.lo, (self.mixer, 1)]]) self.set_connection(fft=1) + self.connect_fsk4_demod() # Connect up the flow graph # @@ -389,7 +407,7 @@ class p25_rx_block (stdgui2.std_top_block): if sel == 0: # spectrum if not self.baseband_input: self.set_connection(fft=1) - self.disconnect_demods() + self.connect_demods() elif sel == 1: # c4fm self.set_connection(c4fm=1) self.connect_fsk4_demod() @@ -414,7 +432,7 @@ class p25_rx_block (stdgui2.std_top_block): elif sel == 6: # fac - fast auto correlation if not self.baseband_input: self.set_connection(fac=1) - self.disconnect_demods() + self.connect_demods() self.unlock() # initialize the UI @@ -594,7 +612,7 @@ class p25_rx_block (stdgui2.std_top_block): the result of that operation and our target_frequency to determine the value for the digital down converter. """ - r = self.usrp.tune(0, self.subdev, target_freq + self.options.calibration) + r = self.src.set_center_freq(target_freq + self.options.calibration + self.options.offset) if r: self.myform['freq'].set_value(target_freq) # update displayed va @@ -648,22 +666,15 @@ class p25_rx_block (stdgui2.std_top_block): # setup to rx from USRP # - def __set_rx_from_usrp(self, subdev_spec, decimation_rate, gain, frequency, preserve): - from gnuradio import usrp - # setup USRP - self.usrp.set_decim_rate(decimation_rate) - if subdev_spec is None: - subdev_spec = usrp.pick_rx_subdevice(self.usrp) - self.usrp.set_mux(usrp.determine_rx_mux_value(self.usrp, subdev_spec)) - self.subdev = usrp.selected_subdev(self.usrp, subdev_spec) - capture_rate = self.usrp.adc_freq() / self.usrp.decim_rate() + def __set_rx_from_osmosdr(self): + # setup osmosdr + capture_rate = self.src.set_sample_rate(self.options.sample_rate) + if self.options.antenna: + self.src.set_antenna(self.options.antenna) self.info["capture-rate"] = capture_rate - if gain is None: - g = self.subdev.gain_range() - gain = float(g[0]+g[1])/2 - self.subdev.set_gain(gain) - self.subdev.set_bw(1e6) - r = self.usrp.tune(0, self.subdev, frequency + self.options.calibration) + self.src.set_bandwidth(capture_rate) + r = self.src.set_center_freq(self.options.frequency + self.options.calibration+ self.options.offset) + print 'set_center_freq: %d' % r if not r: raise RuntimeError("failed to set USRP frequency") # capture file @@ -678,7 +689,7 @@ class p25_rx_block (stdgui2.std_top_block): else: self.capture_filename = None # everything else - self.__build_graph(self.usrp, capture_rate) + self.__build_graph(self.src, capture_rate) # Change the UI state # @@ -743,7 +754,7 @@ class p25_rx_block (stdgui2.std_top_block): delta_hz *= self.symbol_deviation delta_hz = max(delta_hz, -max_delta_hz) delta_hz = min(delta_hz, max_delta_hz) - self.channel_filter.set_center_freq(self.channel_offset - delta_hz) + self.channel_filter.set_center_freq(self.channel_offset - delta_hz+ self.options.offset) # Close an open file # @@ -923,14 +934,14 @@ class p25_rx_block (stdgui2.std_top_block): # Open the USRP # - def open_usrp(self, subdev_spec, decim, gain, frequency, preserve): + def open_usrp(self): # try: self.info = { "capture-rate": "unknown", - "center-freq": frequency, + "center-freq": self.options.frequency, "source-dev": "USRP", - "source-decim": decim } - self.__set_rx_from_usrp(subdev_spec, decim, gain, frequency, preserve) + "source-decim": 1 } + self.__set_rx_from_osmosdr() self._set_titlebar("Capturing") self._set_state("CAPTURING") # except Exception, x: @@ -940,7 +951,7 @@ class p25_rx_block (stdgui2.std_top_block): # def set_channel_offset(self, offset_hz, scale, units): self.channel_offset = -offset_hz - self.channel_filter.set_center_freq(self.channel_offset) + self.channel_filter.set_center_freq(self.channel_offset+ self.options.offset) self.frame.SetStatusText("Channel offset: " + str(offset_hz * scale) + units, 1) # Set the RF squelch threshold level @@ -958,12 +969,12 @@ class p25_rx_block (stdgui2.std_top_block): self.disconnect(self.source, self.baseband_amp, self.float_resamplers[self.current_speed], self.symbol_filter) else: self.disconnect(self.mixer, self.lpf, self.arb_resampler, self.resamplers[idx], self.fm_demod, self.baseband_amp, self.symbol_filter) - self.disconnect(self.symbol_filter, self.fsk4_demod, self.buffer, self.slicer, self.sink_s) + self.disconnect(self.symbol_filter, self.fsk4_demod, self.buffer, self.slicer, self.sink_s, self.sink_imbe) if self.options.raw_symbols: self.disconnect(self.slicer, self.sink_sf) self.fsk4_demod_connected = False if self.psk_demod_connected: - self.disconnect(self.mixer, self.lpf, self.arb_resampler, self.resamplers[idx], self.agc, self.symbol_filter_c, self.clock, self.diffdec, self.to_float, self.rescale, self.buffer, self.slicer, self.sink_s) + self.disconnect(self.mixer, self.lpf, self.arb_resampler, self.resamplers[idx], self.agc, self.symbol_filter_c, self.clock, self.diffdec, self.to_float, self.rescale, self.buffer, self.slicer, self.sink_s, self.sink_imbe) if self.options.raw_symbols: self.disconnect(self.slicer, self.sink_sf) self.psk_demod_connected = False @@ -972,7 +983,7 @@ class p25_rx_block (stdgui2.std_top_block): # assumes lock held or init self.disconnect_demods() idx = self.current_speed - self.connect(self.mixer, self.lpf, self.arb_resampler, self.resamplers[idx], self.agc, self.symbol_filter_c, self.clock, self.diffdec, self.to_float, self.rescale, self.buffer, self.slicer, self.sink_s) + self.connect(self.mixer, self.lpf, self.arb_resampler, self.resamplers[idx], self.agc, self.symbol_filter_c, self.clock, self.diffdec, self.to_float, self.rescale, self.buffer, self.slicer, self.sink_s, self.sink_imbe) if self.options.raw_symbols: self.connect(self.slicer, self.sink_sf) self.psk_demod_connected = True @@ -985,7 +996,7 @@ class p25_rx_block (stdgui2.std_top_block): self.connect(self.source, self.baseband_amp, self.float_resamplers[self.current_speed], self.symbol_filter) else: self.connect(self.mixer, self.lpf, self.arb_resampler, self.resamplers[idx], self.fm_demod, self.baseband_amp, self.symbol_filter) - self.connect(self.symbol_filter, self.fsk4_demod, self.buffer, self.slicer, self.sink_s) + self.connect(self.symbol_filter, self.fsk4_demod, self.buffer, self.slicer, self.sink_s, self.sink_imbe) if self.options.raw_symbols: self.connect(self.slicer, self.sink_sf) self.fsk4_demod_connected = True @@ -1287,7 +1298,7 @@ class datascope_sink_f(gr.hier_block2): gr.io_signature(0,0,0)) msgq = gr.msg_queue(2) # message queue that holds at most 2 messages - self.st = gr.message_sink(gr.sizeof_float, msgq, dont_block=1) + self.st = gr.message_sink(gr.sizeof_float, msgq, 1) self.connect((self, 0), self.st) self.win = datascope_window(datascope_win_info (msgq, sample_rate, frame_decim, @@ -1506,7 +1517,7 @@ class constellation_plot_c(gr.hier_block2): gr.io_signature(0,0,0)) msgq = gr.msg_queue(2) # message queue that holds at most 2 messages - self.st = gr.message_sink(gr.sizeof_gr_complex, msgq, dont_block=1) + self.st = gr.message_sink(gr.sizeof_gr_complex, msgq, 1) self.connect((self, 0), self.st) self.win = constellation_plot_window(constellation_plot_win_info (msgq, sample_rate, frame_decim, None, title), parent, num_plots=num_plots) @@ -1858,7 +1869,7 @@ class correlation_plot_f(gr.hier_block2): gr.io_signature(0,0,0)) msgq = gr.msg_queue(2) # message queue that holds at most 2 messages - self.st = gr.message_sink(gr.sizeof_float, msgq, dont_block=1) + self.st = gr.message_sink(gr.sizeof_float, msgq, 1) self.connect((self, 0), self.st) self.win = correlation_plot_window(correlation_plot_win_info (msgq, sps, frame_decim, None, title), parent, sps=sps) |