From 0fcef6a5be9d06ead09ea73f8c46e6245c5295a4 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 22 Dec 2017 18:05:29 -0500 Subject: rx.py --- op25/gr-op25_repeater/apps/rx.py | 74 ++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/op25/gr-op25_repeater/apps/rx.py b/op25/gr-op25_repeater/apps/rx.py index d872e0d..6717d32 100755 --- a/op25/gr-op25_repeater/apps/rx.py +++ b/op25/gr-op25_repeater/apps/rx.py @@ -65,7 +65,7 @@ from gr_gnuplot import fft_sink_c from gr_gnuplot import symbol_sink_f from gr_gnuplot import eye_sink_f -from terminal import curses_terminal +from terminal import op25_terminal from sockaudio import socket_audio #speeds = [300, 600, 900, 1200, 1440, 1800, 1920, 2400, 2880, 3200, 3600, 3840, 4000, 4800, 6000, 6400, 7200, 8000, 9600, 14400, 19200] @@ -105,6 +105,7 @@ class p25_rx_block (gr.top_block): parser.add_option("-F", "--ifile", type="string", default=None, help="read input from complex capture file") parser.add_option("-H", "--hamlib-model", type="int", default=None, help="specify model for hamlib") parser.add_option("-s", "--seek", type="int", default=0, help="ifile seek in K") + parser.add_option("-l", "--terminal-type", type="string", default='curses', help="'curses' or udp port") parser.add_option("-L", "--logfile-workers", type="int", default=None, help="number of demodulators to instantiate") 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") @@ -116,7 +117,6 @@ class p25_rx_block (gr.top_block): 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") parser.add_option("-r", "--raw-symbols", type="string", default=None, help="dump decoded symbols to file") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0), help="select USRP Rx side A or B (default=A)") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set USRP gain in dB (default is midpoint) or set audio gain") parser.add_option("-G", "--gain-mu", type="eng_float", default=0.025, help="gardner gain") parser.add_option("-N", "--gains", type="string", default=None, help="gain settings") @@ -156,8 +156,8 @@ class p25_rx_block (gr.top_block): range = self.src.get_gain_range(name) print "gain: name: %s range: start %d stop %d step %d" % (name, range[0].start(), range[0].stop(), range[0].step()) if options.gains: - for tuple in options.gains.split(","): - name, gain = tuple.split(":") + for tup in options.gains.split(","): + name, gain = tup.split(":") gain = int(gain) print "setting gain %s to %d" % (name, gain) self.src.set_gain(gain, name) @@ -228,7 +228,7 @@ class p25_rx_block (gr.top_block): pass # attach terminal thread - self.terminal = curses_terminal(self.input_q, self.output_q) + self.terminal = op25_terminal(self.input_q, self.output_q, self.options.terminal_type) # attach audio thread if self.options.udp_player: @@ -241,7 +241,8 @@ class p25_rx_block (gr.top_block): def __build_graph(self, source, capture_rate): global speeds global WIRESHARK_PORT - # tell the scope the source rate + + sps = 5 # samples / symbol self.rx_q = gr.msg_queue(100) udp_port = 0 @@ -253,7 +254,7 @@ class p25_rx_block (gr.top_block): self.xor_cache = {} if self.baseband_input: - self.demod = p25_demodulator.p25_demod_fb(input_rate=capture_rate) + self.demod = p25_demodulator.p25_demod_fb(input_rate=capture_rate, excess_bw=self.options.excess_bw) else: # complex input # local osc self.lo_freq = self.options.offset + self.options.fine_tune @@ -263,9 +264,10 @@ class p25_rx_block (gr.top_block): demod_type = self.options.demod_type, relative_freq = self.lo_freq, offset = self.options.offset, - if_rate = 48000, + if_rate = sps * 4800, gain_mu = self.options.gain_mu, costas_alpha = self.options.costas_alpha, + excess_bw = self.options.excess_bw, symbol_rate = self.symbol_rate) num_ambe = 0 @@ -294,7 +296,7 @@ class p25_rx_block (gr.top_block): self.kill_sink = self.fft_sink elif self.options.plot_mode == 'datascope': assert self.options.demod_type == 'fsk4' ## datascope requires fsk4 demod-type - self.eye_sink = eye_sink_f(sps=10) + self.eye_sink = eye_sink_f(sps=sps) self.demod.connect_bb('symbol_filter', self.eye_sink) self.kill_sink = self.eye_sink @@ -364,9 +366,11 @@ class p25_rx_block (gr.top_block): if hash not in self.xor_cache: self.xor_cache[hash] = lfsr.p25p2_lfsr(params['nac'], params['sysid'], params['wacn']).xor_chars self.decoder.set_xormask(self.xor_cache[hash], hash) - sps = self.basic_rate / 6000 + rate = 6000 else: - sps = self.basic_rate / 4800 + rate = 4800 + sps = self.basic_rate / rate + self.demod.set_symbol_rate(rate) # this and the foll. call should be merged? self.demod.clock.set_omega(float(sps)) def change_freq(self, params): @@ -430,7 +434,8 @@ class p25_rx_block (gr.top_block): def set_audio_scaler(self, vol): #print 'audio scaler: %f' % ((1 / 32768.0) * (vol * 0.1)) - self.decoder.set_scaler_k((1 / 32768.0) * (vol * 0.1)) + if hasattr(self.decoder, 'set_scaler_k'): + self.decoder.set_scaler_k((1 / 32768.0) * (vol * 0.1)) def set_rtl_ppm(self, ppm): self.src.set_freq_corr(ppm) @@ -636,24 +641,35 @@ class du_queue_watcher(threading.Thread): msg = self.msgq.delete_head() self.callback(msg) +class rx_main(object): + def __init__(self): + self.keep_running = True + self.tb = p25_rx_block() + self.q_watcher = du_queue_watcher(self.tb.output_q, self.process_qmsg) + + def process_qmsg(self, msg): + if self.tb.process_qmsg(msg): + self.keep_running = False + + def run(self): + try: + self.tb.start() + while self.keep_running: + time.sleep(1) + except: + sys.stderr.write('main: exception occurred\n') + sys.stderr.write('main: exception:\n%s\n' % traceback.format_exc()) + if self.tb.terminal: + self.tb.terminal.end_terminal() + if self.tb.audio: + self.tb.audio.stop() + self.tb.stop() + if self.tb.kill_sink: + self.tb.kill_sink.kill() + # Start the receiver # if __name__ == "__main__": - tb = p25_rx_block() - tb.start() - try: - while True: - msg = tb.output_q.delete_head() - if tb.process_qmsg(msg): - break - except: - sys.stderr.write('main: exception occurred\n') - sys.stderr.write('main: exception:\n%s\n' % traceback.format_exc()) - if tb.terminal: - tb.terminal.end_curses() - if tb.audio: - tb.audio.stop() - tb.stop() - if tb.kill_sink: - tb.kill_sink.kill() + rx = rx_main() + rx.run() -- cgit v1.2.3