diff options
author | Max <ikj1234i@yahoo.com> | 2017-04-01 17:20:39 -0400 |
---|---|---|
committer | Max <ikj1234i@yahoo.com> | 2017-04-01 17:20:39 -0400 |
commit | 11cd46b8e7d59d58931a3ed24c9f0617229815f8 (patch) | |
tree | 87b84af35215a50b4542f4075dc9b07b270a0f31 | |
parent | ff3a65028e4b4320347632660911f05fd80cd78c (diff) |
add osmosdr device support
-rw-r--r-- | op25/gr-op25_repeater/apps/tx/dv_tx.py | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/op25/gr-op25_repeater/apps/tx/dv_tx.py b/op25/gr-op25_repeater/apps/tx/dv_tx.py index c51ebe3..ba9c0ce 100644 --- a/op25/gr-op25_repeater/apps/tx/dv_tx.py +++ b/op25/gr-op25_repeater/apps/tx/dv_tx.py @@ -53,18 +53,24 @@ class my_top_block(gr.top_block): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) + parser.add_option("-a", "--args", type="string", default="", help="device args") parser.add_option("-b", "--bt", type="float", default=0.25, help="specify bt value") parser.add_option("-c", "--config-file", type="string", default=None, help="specify the config file name") parser.add_option("-f", "--file1", type="string", default=None, help="specify the input file slot 1") parser.add_option("-F", "--file2", type="string", default=None, help="specify the input file slot 2 (DMR)") parser.add_option("-g", "--gain", type="float", default=1.0, help="input gain") + parser.add_option("-i", "--if-rate", type="float", default=960000, help="output rate to sdr") parser.add_option("-I", "--audio-input", type="string", default="", help="pcm input device name. E.g., hw:0,0 or /dev/dsp") + parser.add_option("-N", "--gains", type="string", default=None, help="gain settings") parser.add_option("-O", "--audio-output", type="string", default="default", help="pcm output device name. E.g., hw:0,0 or /dev/dsp") parser.add_option("-o", "--output-file", type="string", default=None, help="specify the output file") parser.add_option("-p", "--protocol", type="choice", default=None, choices=('dmr', 'dstar', 'p25', 'ysf'), help="specify protocol") + parser.add_option("-q", "--frequency-correction", type="float", default=0.0, help="ppm") + parser.add_option("-Q", "--frequency", type="float", default=0.0, help="Hz") parser.add_option("-r", "--repeat", action="store_true", default=False, help="input file repeat") parser.add_option("-R", "--fullrate-mode", action="store_true", default=False, help="ysf fullrate") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="output sample rate") + parser.add_option("-t", "--test", type="string", default=None, help="test pattern symbol file") parser.add_option("-v", "--verbose", type="int", default=0, help="additional output") (options, args) = parser.parse_args() @@ -90,6 +96,17 @@ class my_top_block(gr.top_block): 'p25': 2.0, 'ysf': 3.0 } + mod_adjust = { # rough values + 'dmr': 0.3, + 'dstar': 0.075, + 'p25': 0.25, + 'ysf': 0.32 + } + + if options.protocol is None: + print 'protocol [-p] option missing' + sys.exit(0) + output_gain = output_gains[options.protocol] if options.protocol in generators.keys(): generator = generators[options.protocol] @@ -98,7 +115,9 @@ class my_top_block(gr.top_block): if options.protocol in gain_adjust_fullrate.keys(): os.environ['GAIN_ADJUST_FULLRATE'] = str(gain_adjust_fullrate[options.protocol]) - if options.protocol == 'dmr': + if options.test: + ENCODER = blocks.file_source(gr.sizeof_char, options.test, True) + elif options.protocol == 'dmr': max_inputs = 2 ENCODER = op25_repeater.ambe_encoder_sb(options.verbose) ENCODER2 = op25_repeater.ambe_encoder_sb(options.verbose) @@ -116,16 +135,12 @@ class my_top_block(gr.top_block): False) # dump raw u vectors elif options.protocol == 'ysf': ENCODER = op25_repeater.ysf_tx_sb(options.verbose, options.config_file, options.fullrate_mode) - else: - print 'protocol [-p] option missing' - sys.exit(0) - nfiles = 0 if options.file1: nfiles += 1 if options.file2 and options.protocol == 'dmr': nfiles += 1 - if nfiles < max_inputs: + if nfiles < max_inputs and not options.test: AUDIO = audio.source(options.sample_rate, options.audio_input) lpf_taps = filter.firdes.low_pass(1.0, options.sample_rate, 3400.0, 3400 * 0.1, filter.firdes.WIN_HANN) audio_rate = 8000 @@ -140,7 +155,7 @@ class my_top_block(gr.top_block): AMP1 = blocks.multiply_const_ff(options.gain) F2S1 = blocks.float_to_short() self.connect(IN1, S2F1, AMP1, F2S1, ENCODER) - else: + elif not options.test: self.connect(AUDIO_F2S, ENCODER) if options.protocol == 'dmr': @@ -161,15 +176,45 @@ class my_top_block(gr.top_block): if options.output_file: OUT = blocks.file_sink(gr.sizeof_float, options.output_file) - else: + elif not options.args: OUT = audio.sink(options.sample_rate, options.audio_output) - if options.protocol == 'dmr': + if options.protocol == 'dmr' and not options.test: self.connect(DMR, MOD) else: self.connect(ENCODER, MOD) - self.connect(MOD, AMP, OUT) + if options.args: + self.setup_sdr_output(options, mod_adjust[options.protocol]) + interp = filter.rational_resampler_fff(options.if_rate / options.sample_rate, 1) + self.connect(MOD, AMP, interp, self.fm_modulator, self.u) + else: + self.connect(MOD, AMP, OUT) + + def setup_sdr_output(self, options, adjustment): + import osmosdr + max_dev = 12.5e3 + k = 2 * math.pi * max_dev / options.if_rate + + self.fm_modulator = analog.frequency_modulator_fc (k * adjustment) + + self.u = osmosdr.sink (options.args) + gain_names = self.u.get_gain_names() + for name in gain_names: + range = self.u.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(":") + gain = int(gain) + print "setting gain %s to %d" % (name, gain) + self.u.set_gain(gain, name) + + print 'setting sample rate' + self.u.set_sample_rate(options.if_rate) + self.u.set_center_freq(options.frequency) + self.u.set_freq_corr(options.frequency_correction) + #self.u.set_bandwidth(options.if_rate) if __name__ == "__main__": print 'Multiprotocol Digital Voice TX (C) Copyright 2017 Max H. Parke KA1RBI' |