def __init__(self, Source): gr.top_block.__init__(self, "Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 750e3 self.transition = transition = 100e3 self.cutoff = cutoff = 100000 ################################################## # Blocks ################################################## self.frame_source = FrameS.FrameSource(Source) self.gr_short_to_float_0 = gr.short_to_float(1, 32768) self.gr_short_to_float_1 = gr.short_to_float(1, 32768) self.high_pass_filter_0 = gr.fir_filter_fff(1, firdes.high_pass( 1, samp_rate, cutoff, transition, firdes.WIN_RECTANGULAR, 6.76)) self.high_pass_filter_1 = gr.fir_filter_fff(1, firdes.high_pass( 1, samp_rate, cutoff, transition, firdes.WIN_RECTANGULAR, 6.76)) self.gr_float_to_short_0 = gr.float_to_short(1, 32768) self.gr_float_to_short_1 = gr.float_to_short(1, 32768) self.threshold = Threshold.CustomTwoChannelThreshold() self.gr_interleave = gr.interleave(gr.sizeof_short*1) self.frame_sink = FrameTFS.FrameToFileSink() ################################################## # Connections ################################################## self.connect((self.frame_source, 0), (self.gr_short_to_float_0, 0)) self.connect((self.frame_source, 1), (self.gr_short_to_float_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.high_pass_filter_0, 0)) self.connect((self.gr_short_to_float_1, 0), (self.high_pass_filter_1, 0)) self.connect((self.high_pass_filter_0, 0), (self.gr_float_to_short_0, 0)) self.connect((self.high_pass_filter_1, 0), (self.gr_float_to_short_1, 0)) self.connect((self.gr_float_to_short_0, 0), (self.threshold, 0)) self.connect((self.gr_float_to_short_1, 0), (self.threshold, 1)) self.connect((self.threshold, 0), (self.gr_interleave, 0)) self.connect((self.threshold, 1), (self.gr_interleave, 1)) self.connect((self.gr_interleave, 0), (self.frame_sink, 0))
def __init__(self, options, queue): gr.top_block.__init__(self, "mhp") self.audio_amps = [] self.converters = [] self.vocoders = [] self.output_files = [] input_audio_rate = 8000 self.audio_input = audio.source(input_audio_rate, options.audio_input) for i in range(options.nchannels): udp_port = options.udp_port + i if options.output_files: t = gr.file_sink(gr.sizeof_char, "baseband-%d.dat" % i) self.output_files.append(t) udp_port = 0 t = gr.multiply_const_ff(32767 * options.audio_gain) self.audio_amps.append(t) t = gr.float_to_short() self.converters.append(t) t = repeater.vocoder( True, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount options.udp_addr, # udp ip address udp_port, # udp port or zero False) # dump raw u vectors self.vocoders.append(t) for i in range(options.nchannels): self.connect((self.audio_input, i), self.audio_amps[i], self.converters[i], self.vocoders[i]) if options.output_files: self.connect(self.vocoders[i], self.output_files[i])
def build_graph(): sample_rate = 8000 scale_factor = 32000 tb = gr.top_block() src = audio.source(sample_rate, "plughw:0,0") src_scale = gr.multiply_const_ff(scale_factor) interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short() enc = cvsd_vocoder.encode_sb() dec = cvsd_vocoder.decode_bs() s2f = gr.short_to_float() decim = blks2.rational_resampler_fff(1, 8) sink_scale = gr.multiply_const_ff(1.0 / scale_factor) sink = audio.sink(sample_rate, "plughw:0,0") tb.connect(src, src_scale, interp, f2s, enc) tb.connect(enc, dec, s2f, decim, sink_scale, sink) if 0: # debug tb.conect(src, gr.file_sink(gr.sizeof_float, "source.dat")) tb.conect(src_scale, gr.file_sink(gr.sizeof_float, "src_scale.dat")) tb.conect(interp, gr.file_sink(gr.sizeof_float, "interp.dat")) tb.conect(f2s, gr.file_sink(gr.sizeof_short, "f2s.dat")) tb.conect(enc, gr.file_sink(gr.sizeof_char, "enc.dat")) tb.conect(dec, gr.file_sink(gr.sizeof_short, "dec.dat")) tb.conect(s2f, gr.file_sink(gr.sizeof_float, "s2f.dat")) tb.conect(decim, gr.file_sink(gr.sizeof_float, "decim.dat")) tb.conect(sink_scale, gr.file_sink(gr.sizeof_float, "sink_scale.dat")) return tb
def __init__(self, uhd_address, options): gr.top_block.__init__(self) self.uhd_addr = uhd_address self.freq = options.freq self.samp_rate = options.samp_rate self.gain = options.gain self.threshold = options.threshold self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, stream_args=uhd.stream_args('fc32')) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000 * [ 0, ] + 1000 * [ 1, ] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = gr.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() ## average to debounce self.avg = gr.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = gr.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = gr.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect(self.uhd_src, self.det) self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) self.connect(self.f2s, (self.tagger, 1))
def __init__(self, uhd_address, options): gr.top_block.__init__(self) self.uhd_addr = uhd_address self.freq = options.freq self.samp_rate = options.samp_rate self.gain = options.gain self.threshold = options.threshold self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000*[0,] + 1000*[1,] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = gr.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() ## average to debounce self.avg = gr.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = gr.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = gr.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect(self.uhd_src, self.det) self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) self.connect(self.f2s, (self.tagger, 1))
def build_graph(): sample_rate = 8000 scale_factor = 32000 tb = gr.top_block() src = audio.source(sample_rate, "plughw:0,0") src_scale = gr.multiply_const_ff(scale_factor) interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short () enc = vocoder.cvsd_encode_sb() dec = vocoder.cvsd_decode_bs() s2f = gr.short_to_float () decim = blks2.rational_resampler_fff(1, 8) sink_scale = gr.multiply_const_ff(1.0/scale_factor) sink = audio.sink(sample_rate, "plughw:0,0") tb.connect(src, src_scale, interp, f2s, enc) tb.connect(enc, dec, s2f, decim, sink_scale, sink) if 0: # debug tb.conect(src, gr.file_sink(gr.sizeof_float, "source.dat")) tb.conect(src_scale, gr.file_sink(gr.sizeof_float, "src_scale.dat")) tb.conect(interp, gr.file_sink(gr.sizeof_float, "interp.dat")) tb.conect(f2s, gr.file_sink(gr.sizeof_short, "f2s.dat")) tb.conect(enc, gr.file_sink(gr.sizeof_char, "enc.dat")) tb.conect(dec, gr.file_sink(gr.sizeof_short, "dec.dat")) tb.conect(s2f, gr.file_sink(gr.sizeof_float, "s2f.dat")) tb.conect(decim, gr.file_sink(gr.sizeof_float, "decim.dat")) tb.conect(sink_scale, gr.file_sink(gr.sizeof_float, "sink_scale.dat")) return tb
def __init__(self, options, queue): gr.top_block.__init__(self, "mhp") self.audio_amps = [] self.converters = [] self.vocoders = [] self.output_files = [] input_audio_rate = 8000 self.audio_input = audio.source(input_audio_rate, options.audio_input) for i in range (options.nchannels): udp_port = options.udp_port + i if options.output_files: t = gr.file_sink(gr.sizeof_char, "baseband-%d.dat" % i) self.output_files.append(t) udp_port = 0 t = gr.multiply_const_ff(32767 * options.audio_gain) self.audio_amps.append(t) t = gr.float_to_short() self.converters.append(t) t = repeater.vocoder(True, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount options.udp_addr, # udp ip address udp_port, # udp port or zero False) # dump raw u vectors self.vocoders.append(t) for i in range (options.nchannels): self.connect((self.audio_input, i), self.audio_amps[i], self.converters[i], self.vocoders[i]) if options.output_files: self.connect(self.vocoders[i], self.output_files[i])
def __init__(self): gr.flow_graph.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option( "-T", "--tx-subdev-spec", type="subdev", default=None, help= "select USRP Tx side A or B (default=first one with a daughterboard)" ) parser.add_option("-c", "--cordic-freq", type="eng_float", default=434845200, help="set Tx cordic frequency to FREQ", metavar="FREQ") (options, args) = parser.parse_args() print "cordic_freq = %s" % (eng_notation.num_to_str( options.cordic_freq)) self.normal_gain = 8000 self.u = usrp.sink_s() dac_rate = self.u.dac_rate() self._freq = 1000 self._spb = 256 self._interp = int(128e6 / self._spb / self._freq) self.fs = 128e6 / self._interp print "Interpolation:", self._interp self.u.set_interp_rate(self._interp) # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) self.u.set_mux( usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec)) self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) print "Using TX d'board %s" % (self.subdev.side_and_name(), ) self.u.tune(self.subdev._which, self.subdev, options.cordic_freq) self.sin = gr.sig_source_f(self.fs, gr.GR_SIN_WAVE, self._freq, 1, 0) self.gain = gr.multiply_const_ff(self.normal_gain) self.ftos = gr.float_to_short() self.filesink = gr.file_sink(gr.sizeof_float, 'sin.dat') self.connect(self.sin, self.gain) self.connect(self.gain, self.ftos, self.u) #self.connect(self.gain, self.filesink) self.set_gain(self.subdev.gain_range()[1]) # set max Tx gain self.set_auto_tr(True) # enable Auto Transmit/Receive switching
def build_graph(): tb = gr.top_block() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () enc = vocoder.ulaw_encode_sb() dec = vocoder.ulaw_decode_bs() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) return tb
def __init__(self, audio_input_dev): gr.hier_block2.__init__(self, "audio_rx", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature sample_rate = 8000 src = audio.source(sample_rate, audio_input_dev) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short() voice_coder = gsm_full_rate.encode_sp() self.packets_from_encoder = gr.msg_queue() packet_sink = gr.message_sink(33, self.packets_from_encoder, False) self.connect(src, src_scale, f2s, voice_coder, packet_sink)
def build_graph(): fg = gr.flow_graph() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () enc = gsm_full_rate.encode_sp() dec = gsm_full_rate.decode_ps() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) fg.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) return fg
def build_graph(): tb = gr.top_block() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () enc = vocoder.g723_40_encode_sb() dec = vocoder.g723_40_decode_bs() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) return tb
def __init__(self, audio_input_dev): gr.hier_block2.__init__(self, "audio_rx", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature sample_rate = 44100 src = audio.source(sample_rate, audio_input_dev) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short() voice_coder = gsm_full_rate.encode_sp() self.packets_from_encoder = gr.msg_queue() packet_sink = gr.message_sink(33, self.packets_from_encoder, False) self.connect(src, src_scale, f2s, voice_coder, packet_sink)
def test_002(self): src_data = (32766, 32767, 32768, -32767, -32768, -32769) expected_result = [32766, 32767, 32767, -32767, -32768, -32768] src = gr.vector_source_f(src_data) op = gr.float_to_short() dst = gr.vector_sink_s() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_001(self): src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5) expected_result = [0, 1, 2, 3, 4, 6, -1, -2, -3, -4, -6] src = gr.vector_source_f(src_data) op = gr.float_to_short() dst = gr.vector_sink_s() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_001(self): # Pad source data becasue of gr_sptr->output_multiple src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5,0,0,0,0,0) expected_result = [0, 1, 2, 3, 4, 6, -1, -2, -3, -4, -6,0,0,0,0,0] src = gr.vector_source_f(src_data) op = gr.float_to_short() dst = gr.vector_sink_s() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_002(self): src_data = ( 32766, 32767, 32768, -32767, -32768, -32769) expected_result = [ 32766, 32767, 32767, -32767, -32768, -32768 ] src = gr.vector_source_f(src_data) op = gr.float_to_short() dst = gr.vector_sink_s() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_003(self): scale = 2 vlen = 3 src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3) expected_result = [0, 2, 4, 7, 9, 11, -2, -4, -7] src = gr.vector_source_f(src_data) s2v = gr.stream_to_vector(gr.sizeof_float, vlen) op = gr.float_to_short(vlen, scale) v2s = gr.vector_to_stream(gr.sizeof_short, vlen) dst = gr.vector_sink_s() self.tb.connect(src, s2v, op, v2s, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_002(self): # Pad source data becasue of gr_sptr->output_multiple src_data = ( 32766, 32767, 32768, -32767, -32768, -32769,0,0,0,0,0,0,0,0,0,0) expected_result = [ 32766, 32767, 32767, -32767, -32768, -32768,0,0,0,0,0,0,0,0,0,0 ] src = gr.vector_source_f(src_data) op = gr.float_to_short() dst = gr.vector_sink_s() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def __init__(self): gr.flow_graph.__init__(self) parser = OptionParser (option_class=eng_option) parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, help="select USRP Tx side A or B (default=first one with a daughterboard)") parser.add_option ("-c", "--cordic-freq", type="eng_float", default=434845200, help="set Tx cordic frequency to FREQ", metavar="FREQ") (options, args) = parser.parse_args () print "cordic_freq = %s" % (eng_notation.num_to_str (options.cordic_freq)) self.normal_gain = 8000 self.u = usrp.sink_s() dac_rate = self.u.dac_rate(); self._freq = 1000 self._spb = 256 self._interp = int(128e6 / self._spb / self._freq) self.fs = 128e6 / self._interp print "Interpolation:", self._interp self.u.set_interp_rate(self._interp) # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) self.u.set_mux(usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec)) self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) print "Using TX d'board %s" % (self.subdev.side_and_name(),) self.u.tune(self.subdev._which, self.subdev, options.cordic_freq) self.sin = gr.sig_source_f(self.fs, gr.GR_SIN_WAVE, self._freq, 1, 0) self.gain = gr.multiply_const_ff (self.normal_gain) self.ftos = gr.float_to_short() self.filesink = gr.file_sink(gr.sizeof_float, 'sin.dat') self.connect(self.sin, self.gain) self.connect(self.gain, self.ftos, self.u) #self.connect(self.gain, self.filesink) self.set_gain(self.subdev.gain_range()[1]) # set max Tx gain self.set_auto_tr(True) # enable Auto Transmit/Receive switching
def __init__(self, resample=8, bw=0.5): ''' When using the CVSD vocoder, appropriate sampling rates are from 8k to 64k with resampling rates from 1 to 8. A rate of 8k with a resampling rate of 8 provides a good quality signal. ''' gr.hier_block2.__init__(self, "cvsd_encode", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature scale_factor = 32000.0 self.interp = resample src_scale = gr.multiply_const_ff(scale_factor) taps = gr.firdes.low_pass(self.interp, self.interp, bw, 2*bw) interp = gr.interp_fir_filter_fff(self.interp, taps) f2s = gr.float_to_short() enc = vocoder_swig.cvsd_encode_sb() self.connect(self, src_scale, interp, f2s, enc, self)
def test_003(self): scale = 2 vlen = 3 # Pad source data becasue of gr_sptr->output_multiple src_data = (0.0, 1.1, 2.2,0,0,0,0,0,0,0,0,0,0,0,0,0, \ 3.3, 4.4, 5.5,0,0,0,0,0,0,0,0,0,0,0,0,0, \ -1.1, -2.2, -3.30,0,0,0,0,0,0,0,0,0,0,0,0,0) expected_result = [0, 2, 4,0,0,0,0,0,0,0,0,0,0,0,0,0, \ 7, 9, 11,0,0,0,0,0,0,0,0,0,0,0,0,0,\ -2, -4, -7,0,0,0,0,0,0,0,0,0,0,0,0,0] src = gr.vector_source_f(src_data) s2v = gr.stream_to_vector(gr.sizeof_float, vlen) op = gr.float_to_short(vlen, scale) v2s = gr.vector_to_stream(gr.sizeof_short, vlen) dst = gr.vector_sink_s() self.tb.connect(src, s2v, op, v2s, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def __init__(self, FileOrDir): gr.top_block.__init__(self, "Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 750e3 self.transition = transition = 100e3 self.cutoff = cutoff = 100000 ################################################## # Blocks ################################################## self.frame_source = fs.frame_source_ss(FileOrDir) self.gr_short_to_float_0 = gr.short_to_float(1, 32768) self.gr_short_to_float_1 = gr.short_to_float(1, 32768) self.high_pass_filter_0 = gr.fir_filter_fff(1, firdes.high_pass(1, # gain samp_rate, # sampling rate cutoff, # cutoff frequency transition, # transition width firdes.WIN_RECTANGULAR, # filter type 6.76)) # beta = 6.76 by default self.high_pass_filter_1 = gr.fir_filter_fff(1, firdes.high_pass(1, # gain samp_rate, # sampling rate cutoff, # cutoff frequency transition, # transition width firdes.WIN_RECTANGULAR, # filter type 6.76)) # beta = 6.76 by default self.gr_float_to_short_0 = gr.float_to_short(1, 32768) self.gr_float_to_short_1 = gr.float_to_short(1, 32768) self.gr_threshold = tct.two_channel_threshold_ssss(983, 600, 500) self.gr_interleave = gr.interleave(gr.sizeof_short*1) self.frame_sink = FrameTFS.FrameToFileSink() ################################################## # Connections ################################################## self.connect((self.frame_source, 0), (self.gr_short_to_float_0, 0)) self.connect((self.frame_source, 1), (self.gr_short_to_float_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.high_pass_filter_0, 0)) self.connect((self.gr_short_to_float_1, 0), (self.high_pass_filter_1, 0)) self.connect((self.high_pass_filter_0, 0), (self.gr_float_to_short_0, 0)) self.connect((self.high_pass_filter_1, 0), (self.gr_float_to_short_1, 0)) self.connect((self.gr_float_to_short_0, 0), (self.gr_threshold, 0)) self.connect((self.gr_float_to_short_1, 0), (self.gr_threshold, 1)) self.connect((self.gr_threshold, 0), (self.gr_interleave, 0)) self.connect((self.gr_threshold, 1), (self.gr_interleave, 1)) self.connect((self.gr_interleave, 0), (self.frame_sink, 0))
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-a", "--audio-input", type="string", default="") parser.add_option("-A", "--analog-gain", type="float", default=1.0, help="output gain for analog channel") parser.add_option("-c", "--ctcss-freq", type="float", default=0.0, help="CTCSS tone frequency") parser.add_option("-d", "--debug", type="int", default=0, help="debug level") parser.add_option("-g", "--gain", type="eng_float", default=1, help="adjusts input level for standard data levels") parser.add_option("-H", "--hostname", type="string", default="127.0.0.1", help="asterisk host IP") parser.add_option("-p", "--port", type="int", default=32001, help="chan_usrp UDP port") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-S", "--stretch", type="int", default=0) (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = 4800 symbol_decim = 1 IN = audio.source(sample_rate, options.audio_input) symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain sample_rate, # sampling rate symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff(symbol_decim, symbol_coeffs) AMP = gr.multiply_const_ff(options.gain) msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(msgq, sample_rate, symbol_rate) levels = levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) framer_msgq = gr.msg_queue(2) DECODE = repeater.p25_frame_assembler( '', # udp hostname 0, # udp port no. options.debug, #debug True, # do_imbe True, # do_output False, # do_msgq framer_msgq) IMBE = repeater.vocoder( False, # 0=Decode,True=Encode options.debug, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors CHAN_RPT = repeater.chan_usrp_rx(options.hostname, options.port, options.debug) self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CHAN_RPT) # blocks for second channel (fm rx) output_sample_rate = 8000 decim_amt = sample_rate / output_sample_rate RESAMP = blks2.rational_resampler_fff(1, decim_amt) if options.ctcss_freq > 0: level = 5.0 len = 0 ramp = 0 gate = True CTCSS = repeater.ctcss_squelch_ff(output_sample_rate, options.ctcss_freq, level, len, ramp, gate) AMP2 = gr.multiply_const_ff(32767.0 * options.analog_gain) CVT = gr.float_to_short() CHAN_RPT2 = repeater.chan_usrp_rx(options.hostname, options.port + 1, options.debug) if options.ctcss_freq > 0: self.connect(IN, RESAMP, CTCSS, AMP2, CVT, CHAN_RPT2) else: self.connect(IN, RESAMP, AMP2, CVT, CHAN_RPT2)
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-a", "--audio-input", type="string", default="") parser.add_option("-A", "--analog-gain", type="float", default=1.0, help="output gain for analog channel") parser.add_option("-c", "--ctcss-freq", type="float", default=0.0, help="CTCSS tone frequency") parser.add_option("-d", "--debug", type="int", default=0, help="debug level") parser.add_option("-g", "--gain", type="eng_float", default=1, help="adjusts input level for standard data levels") parser.add_option("-H", "--hostname", type="string", default="127.0.0.1", help="asterisk host IP") parser.add_option("-p", "--port", type="int", default=32001, help="chan_usrp UDP port") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-S", "--stretch", type="int", default=0) (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = 4800 symbol_decim = 1 IN = audio.source(sample_rate, options.audio_input) symbol_coeffs = gr.firdes.root_raised_cosine(1.0, # gain sample_rate , # sampling rate symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff (symbol_decim, symbol_coeffs) AMP = gr.multiply_const_ff(options.gain) msgq = gr.msg_queue(2) FSK4 = fsk4.demod_ff(msgq, sample_rate, symbol_rate) levels = levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) framer_msgq = gr.msg_queue(2) DECODE = repeater.p25_frame_assembler('', # udp hostname 0, # udp port no. options.debug, #debug True, # do_imbe True, # do_output False, # do_msgq framer_msgq) IMBE = repeater.vocoder(False, # 0=Decode,True=Encode options.debug, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors CHAN_RPT = repeater.chan_usrp_rx(options.hostname, options.port, options.debug) self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CHAN_RPT) # blocks for second channel (fm rx) output_sample_rate = 8000 decim_amt = sample_rate / output_sample_rate RESAMP = blks2.rational_resampler_fff(1, decim_amt) if options.ctcss_freq > 0: level = 5.0 len = 0 ramp = 0 gate = True CTCSS = repeater.ctcss_squelch_ff(output_sample_rate, options.ctcss_freq, level, len, ramp, gate) AMP2 = gr.multiply_const_ff(32767.0 * options.analog_gain) CVT = gr.float_to_short() CHAN_RPT2 = repeater.chan_usrp_rx(options.hostname, options.port+1, options.debug) if options.ctcss_freq > 0: self.connect(IN, RESAMP, CTCSS, AMP2, CVT, CHAN_RPT2) else: self.connect(IN, RESAMP, AMP2, CVT, CHAN_RPT2)
def __init__(self, frequency, sample_rate, uhd_address="192.168.10.2", trigger=False): gr.top_block.__init__(self) self.freq = frequency self.samp_rate = sample_rate self.uhd_addr = uhd_address self.gain = 32 self.trigger = trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) self.ann0 = gr.annotator_alltoall(100000, gr.sizeof_gr_complex) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000 * [ 0, ] + 1000 * [ 1, ] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst self.c2m = gr.complex_to_mag_squared() self.iir = gr.single_pole_iir_filter_ff(0.0001) self.sub = gr.sub_ff() self.mult = gr.multiply_const_ff(32768) self.f2s = gr.float_to_short() self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect((self.uhd_src, 0), (self.c2m, 0)) self.connect((self.c2m, 0), (self.sub, 0)) self.connect((self.c2m, 0), (self.iir, 0)) self.connect((self.iir, 0), (self.sub, 1)) self.connect((self.sub, 0), (self.mult, 0)) self.connect((self.mult, 0), (self.f2s, 0)) self.connect((self.f2s, 0), (self.tagger, 1))
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, frame, panel, vbox, argv): MAX_CHANNELS = 7 stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) parser = OptionParser(option_class=eng_option) parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, help="select USRP Tx side A or B") parser.add_option("-e", "--enable-fft", action="store_true", default=False, help="enable spectrum plot (and use more CPU)") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set Tx frequency to FREQ [required]", metavar="FREQ") parser.add_option("-i", "--file-input", action="store_true", default=False, help="input from baseband-0.dat, baseband-1.dat ...") parser.add_option("-g", "--audio-gain", type="eng_float", default=1.0, help="input audio gain multiplier") parser.add_option("-n", "--nchannels", type="int", default=2, help="number of Tx channels [1,4]") parser.add_option("-a", "--udp-addr", type="string", default="127.0.0.1", help="UDP host IP address") parser.add_option("-p", "--udp-port", type="int", default=0, help="UDP port number") parser.add_option("-r", "--repeat", action="store_true", default=False, help="continuously replay input file") parser.add_option("-S", "--stretch", type="int", default=0, help="elastic buffer trigger value") parser.add_option("-v", "--verbose", action="store_true", default=False, help="print out stats") parser.add_option( "-I", "--audio-input", type="string", default="", help="pcm input device name. E.g., hw:0,0 or /dev/dsp") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) if options.nchannels < 1 or options.nchannels > MAX_CHANNELS: sys.stderr.write( "op25_tx: nchannels out of range. Must be in [1,%d]\n" % MAX_CHANNELS) sys.exit(1) if options.freq is None: sys.stderr.write("op25_tx: must specify frequency with -f FREQ\n") parser.print_help() sys.exit(1) # ---------------------------------------------------------------- # Set up constants and parameters self.u = usrp.sink_c() # the USRP sink (consumes samples) self.dac_rate = self.u.dac_rate() # 128 MS/s self.usrp_interp = 400 self.u.set_interp_rate(self.usrp_interp) self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s self.sw_interp = 10 self.audio_rate = self.usrp_rate / self.sw_interp # 32 kS/s # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) m = usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec) #print "mux = %#04x" % (m,) self.u.set_mux(m) self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) print "Using TX d'board %s" % (self.subdev.side_and_name(), ) self.subdev.set_gain(self.subdev.gain_range()[0]) # set min Tx gain if not self.set_freq(options.freq): freq_range = self.subdev.freq_range() print "Failed to set frequency to %s. Daughterboard supports %s to %s" % ( eng_notation.num_to_str( options.freq), eng_notation.num_to_str( freq_range[0]), eng_notation.num_to_str(freq_range[1])) raise SystemExit self.subdev.set_enable(True) # enable transmitter # instantiate vocoders self.vocoders = [] if options.file_input: for i in range(options.nchannels): t = gr.file_source(gr.sizeof_char, "baseband-%d.dat" % i, options.repeat) self.vocoders.append(t) elif options.udp_port > 0: self.udp_sources = [] for i in range(options.nchannels): t = gr.udp_source(1, options.udp_addr, options.udp_port + i, 216) self.udp_sources.append(t) arity = 2 t = gr.packed_to_unpacked_bb(arity, gr.GR_MSB_FIRST) self.vocoders.append(t) self.connect(self.udp_sources[i], self.vocoders[i]) else: self.audio_amps = [] self.converters = [] input_audio_rate = 8000 self.audio_input = audio.source(input_audio_rate, options.audio_input) for i in range(options.nchannels): t = gr.multiply_const_ff(32767 * options.audio_gain) self.audio_amps.append(t) t = gr.float_to_short() self.converters.append(t) t = repeater.vocoder( True, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors self.vocoders.append(t) self.connect((self.audio_input, i), self.audio_amps[i], self.converters[i], self.vocoders[i]) sum = gr.add_cc() # Instantiate N NBFM channels step = 25e3 offset = (0 * step, 1 * step, -1 * step, 2 * step, -2 * step, 3 * step, -3 * step) for i in range(options.nchannels): t = pipeline(self.vocoders[i], offset[i], self.audio_rate, self.usrp_rate) self.connect(t, (sum, i)) gain = gr.multiply_const_cc(4000.0 / options.nchannels) # connect it all self.connect(sum, gain) self.connect(gain, self.u) # plot an FFT to verify we are sending what we want if options.enable_fft: post_mod = fftsink2.fft_sink_c(panel, title="Post Modulation", fft_size=512, sample_rate=self.usrp_rate, y_per_div=20, ref_level=40) self.connect(sum, post_mod) vbox.Add(post_mod.win, 1, wx.EXPAND)
def __init__(self, options, queue): gr.top_block.__init__(self, "mhp") self.audio_amps = [] self.converters = [] self.vocoders = [] self.filters = [] self.c4fm = [] self.output_gain = [] input_audio_rate = 8000 output_audio_rate = 48000 c4fm_rate = 96000 if not options.input_files: self.audio_input = audio.source(input_audio_rate, options.audio_input) self.audio_output = audio.sink (output_audio_rate, options.audio_output) for i in range (options.nchannels): if options.input_files: t = gr.file_source(gr.sizeof_char, "baseband-%d.dat" % i, options.repeat) self.vocoders.append(t) else: t = gr.multiply_const_ff(32767 * options.audio_gain) self.audio_amps.append(t) t = gr.float_to_short() self.converters.append(t) t = repeater.vocoder(True, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors self.vocoders.append(t) t = op25_c4fm_mod.p25_mod(output_sample_rate=c4fm_rate, log=False, verbose=True) self.c4fm.append(t) # FIXME: it would seem as if direct output at 48000 would be the # obvious way to go, but for unknown reasons, it produces hideous # distortion in the output waveform. For the same unknown # reasons, it's clean if we output at 96000 and then decimate # back down to 48k... t = blks2.rational_resampler_fff(1, 2) # 96000 -> 48000 self.filters.append(t) t = gr.multiply_const_ff(options.output_gain) self.output_gain.append(t) for i in range (options.nchannels): if not options.input_files: self.connect(self.audio_amps[i], self.converters[i], self.vocoders[i]) self.connect(self.vocoders[i], self.c4fm[i], self.filters[i], self.output_gain[i]) if options.nchannels == 1: if not options.input_files: self.connect(self.audio_input, self.audio_amps[0]) self.connect(self.output_gain[0], self.audio_output) else: for i in range (options.nchannels): if not options.input_files: self.connect((self.audio_input, i), self.audio_amps[i]) self.connect(self.output_gain[i], (self.audio_output, i))
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser(option_class=eng_option) 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("-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-Q", "--observing", type="eng_float", default=0.0, help="set observing frequency to FREQ") parser.add_option("-a", "--avg", type="eng_float", default=1.0, help="set spectral averaging alpha") parser.add_option("-V", "--favg", type="eng_float", default=2.0, help="set folder averaging alpha") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-l", "--reflevel", type="eng_float", default=30.0, help="Set pulse display reference level") parser.add_option("-L", "--lowest", type="eng_float", default=1.5, help="Lowest valid frequency bin") parser.add_option("-e", "--longitude", type="eng_float", default=-76.02, help="Set Observer Longitude") parser.add_option("-c", "--latitude", type="eng_float", default=44.85, help="Set Observer Latitude") parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT") parser.add_option ("-t", "--threshold", type="eng_float", default=2.5, help="pulsar threshold") parser.add_option("-p", "--lowpass", type="eng_float", default=100, help="Pulse spectra cutoff freq") parser.add_option("-P", "--prefix", default="./", help="File prefix") parser.add_option("-u", "--pulsefreq", type="eng_float", default=0.748, help="Observation pulse rate") parser.add_option("-D", "--dm", type="eng_float", default=1.0e-5, help="Dispersion Measure") parser.add_option("-O", "--doppler", type="eng_float", default=1.0, help="Doppler ratio") parser.add_option("-B", "--divbase", type="eng_float", default=20, help="Y/Div menu base") parser.add_option("-I", "--division", type="eng_float", default=100, help="Y/Div") parser.add_option("-A", "--audio_source", default="plughw:0,0", help="Audio input device spec") parser.add_option("-N", "--num_pulses", default=1, type="eng_float", help="Number of display pulses") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True self.reflevel = options.reflevel self.divbase = options.divbase self.division = options.division self.audiodev = options.audio_source self.mult = int(options.num_pulses) # Low-pass cutoff for post-detector filter # Set to 100Hz usually, since lots of pulsars fit in this # range self.lowpass = options.lowpass # What is lowest valid frequency bin in post-detector FFT? # There's some pollution very close to DC self.lowest_freq = options.lowest # What (dB) threshold to use in determining spectral candidates self.threshold = options.threshold # Filename prefix for recording file self.prefix = options.prefix # Dispersion Measure (DM) self.dm = options.dm # Doppler shift, as a ratio # 1.0 == no doppler shift # 1.005 == a little negative shift # 0.995 == a little positive shift self.doppler = options.doppler # # Input frequency and observing frequency--not necessarily the # same thing, if we're looking at the IF of some downconverter # that's ahead of the USRP and daughtercard. This distinction # is important in computing the correct de-dispersion filter. # self.frequency = options.freq if options.observing <= 0: self.observing_freq = options.freq else: self.observing_freq = options.observing # build the graph self.u = usrp.source_c(decim_rate=options.decim) self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) # # Recording file, in case we ever need to record baseband data # self.recording = gr.file_sink(gr.sizeof_char, "/dev/null") self.recording_state = False self.pulse_recording = gr.file_sink(gr.sizeof_short, "/dev/null") self.pulse_recording_state = False # # We come up with recording turned off, but the user may # request recording later on self.recording.close() self.pulse_recording.close() # # Need these two for converting 12-bit baseband signals to 8-bit # self.tofloat = gr.complex_to_float() self.tochar = gr.float_to_char() # Need this for recording pulses (post-detector) self.toshort = gr.float_to_short() # # The spectral measurer sets this when it has a valid # average spectral peak-to-peak distance # We can then use this to program the parameters for the epoch folder # # We set a sentimental value here self.pulse_freq = options.pulsefreq # Folder runs at this raw sample rate self.folder_input_rate = 20000 # Each pulse in the epoch folder is sampled at 128 times the nominal # pulse rate self.folding = 128 # # Try to find candidate parameters for rational resampler # save_i = 0 candidates = [] for i in range(20,300): input_rate = self.folder_input_rate output_rate = int(self.pulse_freq * i) interp = gru.lcm(input_rate, output_rate) / input_rate decim = gru.lcm(input_rate, output_rate) / output_rate if (interp < 500 and decim < 250000): candidates.append(i) # We didn't find anything, bail! if (len(candidates) < 1): print "Couldn't converge on resampler parameters" sys.exit(1) # # Now try to find candidate with the least sampling error # mindiff = 999.999 for i in candidates: diff = self.pulse_freq * i diff = diff - int(diff) if (diff < mindiff): mindiff = diff save_i = i # Recompute rates input_rate = self.folder_input_rate output_rate = int(self.pulse_freq * save_i) # Compute new interp and decim, based on best candidate interp = gru.lcm(input_rate, output_rate) / input_rate decim = gru.lcm(input_rate, output_rate) / output_rate # Save optimized folding parameters, used later self.folding = save_i self.interp = int(interp) self.decim = int(decim) # So that we can view N pulses in the pulse viewer window FOLD_MULT=self.mult # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) self.cardtype = self.u.daughterboard_id(0) # Compute raw input rate input_rate = self.u.adc_freq() / self.u.decim_rate() # BW==input_rate for complex data self.bw = input_rate # # Set baseband filter bandwidth if DBS_RX: # if self.cardtype == usrp_dbid.DBS_RX: lbw = input_rate / 2 if lbw < 1.0e6: lbw = 1.0e6 self.subdev.set_bw(lbw) # # We use this as a crude volume control for the audio output # #self.volume = gr.multiply_const_ff(10**(-1)) # # Create location data for ephem package # self.locality = ephem.Observer() self.locality.long = str(options.longitude) self.locality.lat = str(options.latitude) # # What is the post-detector LPF cutoff for the FFT? # PULSAR_MAX_FREQ=int(options.lowpass) # First low-pass filters down to input_rate/FIRST_FACTOR # and decimates appropriately FIRST_FACTOR=int(input_rate/(self.folder_input_rate/2)) first_filter = gr.firdes.low_pass (1.0, input_rate, input_rate/FIRST_FACTOR, input_rate/(FIRST_FACTOR*20), gr.firdes.WIN_HAMMING) # Second filter runs at the output rate of the first filter, # And low-pass filters down to PULSAR_MAX_FREQ*10 # second_input_rate = int(input_rate/(FIRST_FACTOR/2)) second_filter = gr.firdes.band_pass(1.0, second_input_rate, 0.10, PULSAR_MAX_FREQ*10, PULSAR_MAX_FREQ*1.5, gr.firdes.WIN_HAMMING) # Third filter runs at PULSAR_MAX_FREQ*20 # and filters down to PULSAR_MAX_FREQ # third_input_rate = PULSAR_MAX_FREQ*20 third_filter = gr.firdes_band_pass(1.0, third_input_rate, 0.10, PULSAR_MAX_FREQ, PULSAR_MAX_FREQ/10.0, gr.firdes.WIN_HAMMING) # # Create the appropriate FFT scope # self.scope = ra_fftsink.ra_fft_sink_f (panel, fft_size=int(options.fft_size), sample_rate=PULSAR_MAX_FREQ*2, title="Post-detector spectrum", ofunc=self.pulsarfunc, xydfunc=self.xydfunc, fft_rate=200) # # Tell scope we're looking from DC to PULSAR_MAX_FREQ # self.scope.set_baseband_freq (0.0) # # Setup stripchart for showing pulse profiles # hz = "%5.3fHz " % self.pulse_freq per = "(%5.3f sec)" % (1.0/self.pulse_freq) sr = "%d sps" % (int(self.pulse_freq*self.folding)) times = " %d Pulse Intervals" % self.mult self.chart = ra_stripchartsink.stripchart_sink_f (panel, sample_rate=1, stripsize=self.folding*FOLD_MULT, parallel=True, title="Pulse Profiles: "+hz+per+times, xlabel="Seconds @ "+sr, ylabel="Level", autoscale=True, divbase=self.divbase, scaling=1.0/(self.folding*self.pulse_freq)) self.chart.set_ref_level(self.reflevel) self.chart.set_y_per_div(self.division) # De-dispersion filter setup # # Do this here, just before creating the filter # that will use the taps. # ntaps = self.compute_disp_ntaps(self.dm,self.bw,self.observing_freq) # Taps for the de-dispersion filter self.disp_taps = Numeric.zeros(ntaps,Numeric.Complex64) # Compute the de-dispersion filter now self.compute_dispfilter(self.dm,self.doppler, self.bw,self.observing_freq) # # Call constructors for receive chains # # # Now create the FFT filter using the computed taps self.dispfilt = gr.fft_filter_ccc(1, self.disp_taps) # # Audio sink # #print "input_rate ", second_input_rate, "audiodev ", self.audiodev #self.audio = audio.sink(second_input_rate, self.audiodev) # # The three post-detector filters # Done this way to allow an audio path (up to 10Khz) # ...and also because going from xMhz down to ~100Hz # In a single filter doesn't seem to work. # self.first = gr.fir_filter_fff (FIRST_FACTOR/2, first_filter) p = second_input_rate / (PULSAR_MAX_FREQ*20) self.second = gr.fir_filter_fff (int(p), second_filter) self.third = gr.fir_filter_fff (10, third_filter) # Detector self.detector = gr.complex_to_mag_squared() self.enable_comb_filter = False # Epoch folder comb filter if self.enable_comb_filter == True: bogtaps = Numeric.zeros(512, Numeric.Float64) self.folder_comb = gr.fft_filter_ccc(1,bogtaps) # Rational resampler self.folder_rr = blks2.rational_resampler_fff(self.interp, self.decim) # Epoch folder bandpass bogtaps = Numeric.zeros(1, Numeric.Float64) self.folder_bandpass = gr.fir_filter_fff (1, bogtaps) # Epoch folder F2C/C2F self.folder_f2c = gr.float_to_complex() self.folder_c2f = gr.complex_to_float() # Epoch folder S2P self.folder_s2p = gr.serial_to_parallel (gr.sizeof_float, self.folding*FOLD_MULT) # Epoch folder IIR Filter (produces average pulse profiles) self.folder_iir = gr.single_pole_iir_filter_ff(1.0/options.favg, self.folding*FOLD_MULT) # # Set all the epoch-folder goop up # self.set_folding_params() # # Start connecting configured modules in the receive chain # # Connect raw USRP to de-dispersion filter, detector self.connect(self.u, self.dispfilt, self.detector) # Connect detector output to FIR LPF # in two stages, followed by the FFT scope self.connect(self.detector, self.first, self.second, self.third, self.scope) # Connect audio output #self.connect(self.first, self.volume) #self.connect(self.volume, (self.audio, 0)) #self.connect(self.volume, (self.audio, 1)) # Connect epoch folder if self.enable_comb_filter == True: self.connect (self.first, self.folder_bandpass, self.folder_rr, self.folder_f2c, self.folder_comb, self.folder_c2f, self.folder_s2p, self.folder_iir, self.chart) else: self.connect (self.first, self.folder_bandpass, self.folder_rr, self.folder_s2p, self.folder_iir, self.chart) # Connect baseband recording file (initially /dev/null) self.connect(self.u, self.tofloat, self.tochar, self.recording) # Connect pulse recording file (initially /dev/null) self.connect(self.first, self.toshort, self.pulse_recording) # # Build the GUI elements # self._build_gui(vbox) # Make GUI agree with command-line self.myform['average'].set_value(int(options.avg)) self.myform['foldavg'].set_value(int(options.favg)) # Make spectral averager agree with command line if options.avg != 1.0: self.scope.set_avg_alpha(float(1.0/options.avg)) self.scope.set_average(True) # set initial values if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.subdev.gain_range() options.gain = float(g[0]+g[1])/2 if options.freq is None: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0]+r[1])/2 self.set_gain(options.gain) #self.set_volume(-10.0) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['DM'].set_value(self.dm) self.myform['Doppler'].set_value(self.doppler) # # Start the timer that shows current LMST on the GUI # self.lmst_timer.Start(1000)
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 float_to_short(N): op = gr.float_to_short() tb = helper(N, op, gr.sizeof_float, gr.sizeof_short, 1, 1) return tb
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser(option_class=eng_option) 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( "-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-Q", "--observing", type="eng_float", default=0.0, help="set observing frequency to FREQ") parser.add_option("-a", "--avg", type="eng_float", default=1.0, help="set spectral averaging alpha") parser.add_option("-V", "--favg", type="eng_float", default=2.0, help="set folder averaging alpha") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-l", "--reflevel", type="eng_float", default=30.0, help="Set pulse display reference level") parser.add_option("-L", "--lowest", type="eng_float", default=1.5, help="Lowest valid frequency bin") parser.add_option("-e", "--longitude", type="eng_float", default=-76.02, help="Set Observer Longitude") parser.add_option("-c", "--latitude", type="eng_float", default=44.85, help="Set Observer Latitude") parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT") parser.add_option("-t", "--threshold", type="eng_float", default=2.5, help="pulsar threshold") parser.add_option("-p", "--lowpass", type="eng_float", default=100, help="Pulse spectra cutoff freq") parser.add_option("-P", "--prefix", default="./", help="File prefix") parser.add_option("-u", "--pulsefreq", type="eng_float", default=0.748, help="Observation pulse rate") parser.add_option("-D", "--dm", type="eng_float", default=1.0e-5, help="Dispersion Measure") parser.add_option("-O", "--doppler", type="eng_float", default=1.0, help="Doppler ratio") parser.add_option("-B", "--divbase", type="eng_float", default=20, help="Y/Div menu base") parser.add_option("-I", "--division", type="eng_float", default=100, help="Y/Div") parser.add_option("-A", "--audio_source", default="plughw:0,0", help="Audio input device spec") parser.add_option("-N", "--num_pulses", default=1, type="eng_float", help="Number of display pulses") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True self.reflevel = options.reflevel self.divbase = options.divbase self.division = options.division self.audiodev = options.audio_source self.mult = int(options.num_pulses) # Low-pass cutoff for post-detector filter # Set to 100Hz usually, since lots of pulsars fit in this # range self.lowpass = options.lowpass # What is lowest valid frequency bin in post-detector FFT? # There's some pollution very close to DC self.lowest_freq = options.lowest # What (dB) threshold to use in determining spectral candidates self.threshold = options.threshold # Filename prefix for recording file self.prefix = options.prefix # Dispersion Measure (DM) self.dm = options.dm # Doppler shift, as a ratio # 1.0 == no doppler shift # 1.005 == a little negative shift # 0.995 == a little positive shift self.doppler = options.doppler # # Input frequency and observing frequency--not necessarily the # same thing, if we're looking at the IF of some downconverter # that's ahead of the USRP and daughtercard. This distinction # is important in computing the correct de-dispersion filter. # self.frequency = options.freq if options.observing <= 0: self.observing_freq = options.freq else: self.observing_freq = options.observing # build the graph self.u = usrp.source_c(decim_rate=options.decim) self.u.set_mux( usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) # # Recording file, in case we ever need to record baseband data # self.recording = gr.file_sink(gr.sizeof_char, "/dev/null") self.recording_state = False self.pulse_recording = gr.file_sink(gr.sizeof_short, "/dev/null") self.pulse_recording_state = False # # We come up with recording turned off, but the user may # request recording later on self.recording.close() self.pulse_recording.close() # # Need these two for converting 12-bit baseband signals to 8-bit # self.tofloat = gr.complex_to_float() self.tochar = gr.float_to_char() # Need this for recording pulses (post-detector) self.toshort = gr.float_to_short() # # The spectral measurer sets this when it has a valid # average spectral peak-to-peak distance # We can then use this to program the parameters for the epoch folder # # We set a sentimental value here self.pulse_freq = options.pulsefreq # Folder runs at this raw sample rate self.folder_input_rate = 20000 # Each pulse in the epoch folder is sampled at 128 times the nominal # pulse rate self.folding = 128 # # Try to find candidate parameters for rational resampler # save_i = 0 candidates = [] for i in range(20, 300): input_rate = self.folder_input_rate output_rate = int(self.pulse_freq * i) interp = gru.lcm(input_rate, output_rate) / input_rate decim = gru.lcm(input_rate, output_rate) / output_rate if (interp < 500 and decim < 250000): candidates.append(i) # We didn't find anything, bail! if (len(candidates) < 1): print "Couldn't converge on resampler parameters" sys.exit(1) # # Now try to find candidate with the least sampling error # mindiff = 999.999 for i in candidates: diff = self.pulse_freq * i diff = diff - int(diff) if (diff < mindiff): mindiff = diff save_i = i # Recompute rates input_rate = self.folder_input_rate output_rate = int(self.pulse_freq * save_i) # Compute new interp and decim, based on best candidate interp = gru.lcm(input_rate, output_rate) / input_rate decim = gru.lcm(input_rate, output_rate) / output_rate # Save optimized folding parameters, used later self.folding = save_i self.interp = int(interp) self.decim = int(decim) # So that we can view N pulses in the pulse viewer window FOLD_MULT = self.mult # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) self.cardtype = self.u.daughterboard_id(0) # Compute raw input rate input_rate = self.u.adc_freq() / self.u.decim_rate() # BW==input_rate for complex data self.bw = input_rate # # Set baseband filter bandwidth if DBS_RX: # if self.cardtype == usrp_dbid.DBS_RX: lbw = input_rate / 2 if lbw < 1.0e6: lbw = 1.0e6 self.subdev.set_bw(lbw) # # We use this as a crude volume control for the audio output # #self.volume = gr.multiply_const_ff(10**(-1)) # # Create location data for ephem package # self.locality = ephem.Observer() self.locality.long = str(options.longitude) self.locality.lat = str(options.latitude) # # What is the post-detector LPF cutoff for the FFT? # PULSAR_MAX_FREQ = int(options.lowpass) # First low-pass filters down to input_rate/FIRST_FACTOR # and decimates appropriately FIRST_FACTOR = int(input_rate / (self.folder_input_rate / 2)) first_filter = gr.firdes.low_pass(1.0, input_rate, input_rate / FIRST_FACTOR, input_rate / (FIRST_FACTOR * 20), gr.firdes.WIN_HAMMING) # Second filter runs at the output rate of the first filter, # And low-pass filters down to PULSAR_MAX_FREQ*10 # second_input_rate = int(input_rate / (FIRST_FACTOR / 2)) second_filter = gr.firdes.band_pass(1.0, second_input_rate, 0.10, PULSAR_MAX_FREQ * 10, PULSAR_MAX_FREQ * 1.5, gr.firdes.WIN_HAMMING) # Third filter runs at PULSAR_MAX_FREQ*20 # and filters down to PULSAR_MAX_FREQ # third_input_rate = PULSAR_MAX_FREQ * 20 third_filter = gr.firdes_band_pass(1.0, third_input_rate, 0.10, PULSAR_MAX_FREQ, PULSAR_MAX_FREQ / 10.0, gr.firdes.WIN_HAMMING) # # Create the appropriate FFT scope # self.scope = ra_fftsink.ra_fft_sink_f(panel, fft_size=int(options.fft_size), sample_rate=PULSAR_MAX_FREQ * 2, title="Post-detector spectrum", ofunc=self.pulsarfunc, xydfunc=self.xydfunc, fft_rate=200) # # Tell scope we're looking from DC to PULSAR_MAX_FREQ # self.scope.set_baseband_freq(0.0) # # Setup stripchart for showing pulse profiles # hz = "%5.3fHz " % self.pulse_freq per = "(%5.3f sec)" % (1.0 / self.pulse_freq) sr = "%d sps" % (int(self.pulse_freq * self.folding)) times = " %d Pulse Intervals" % self.mult self.chart = ra_stripchartsink.stripchart_sink_f( panel, sample_rate=1, stripsize=self.folding * FOLD_MULT, parallel=True, title="Pulse Profiles: " + hz + per + times, xlabel="Seconds @ " + sr, ylabel="Level", autoscale=True, divbase=self.divbase, scaling=1.0 / (self.folding * self.pulse_freq)) self.chart.set_ref_level(self.reflevel) self.chart.set_y_per_div(self.division) # De-dispersion filter setup # # Do this here, just before creating the filter # that will use the taps. # ntaps = self.compute_disp_ntaps(self.dm, self.bw, self.observing_freq) # Taps for the de-dispersion filter self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64) # Compute the de-dispersion filter now self.compute_dispfilter(self.dm, self.doppler, self.bw, self.observing_freq) # # Call constructors for receive chains # # # Now create the FFT filter using the computed taps self.dispfilt = gr.fft_filter_ccc(1, self.disp_taps) # # Audio sink # #print "input_rate ", second_input_rate, "audiodev ", self.audiodev #self.audio = audio.sink(second_input_rate, self.audiodev) # # The three post-detector filters # Done this way to allow an audio path (up to 10Khz) # ...and also because going from xMhz down to ~100Hz # In a single filter doesn't seem to work. # self.first = gr.fir_filter_fff(FIRST_FACTOR / 2, first_filter) p = second_input_rate / (PULSAR_MAX_FREQ * 20) self.second = gr.fir_filter_fff(int(p), second_filter) self.third = gr.fir_filter_fff(10, third_filter) # Detector self.detector = gr.complex_to_mag_squared() self.enable_comb_filter = False # Epoch folder comb filter if self.enable_comb_filter == True: bogtaps = Numeric.zeros(512, Numeric.Float64) self.folder_comb = gr.fft_filter_ccc(1, bogtaps) # Rational resampler self.folder_rr = blks2.rational_resampler_fff(self.interp, self.decim) # Epoch folder bandpass bogtaps = Numeric.zeros(1, Numeric.Float64) self.folder_bandpass = gr.fir_filter_fff(1, bogtaps) # Epoch folder F2C/C2F self.folder_f2c = gr.float_to_complex() self.folder_c2f = gr.complex_to_float() # Epoch folder S2P self.folder_s2p = gr.serial_to_parallel(gr.sizeof_float, self.folding * FOLD_MULT) # Epoch folder IIR Filter (produces average pulse profiles) self.folder_iir = gr.single_pole_iir_filter_ff( 1.0 / options.favg, self.folding * FOLD_MULT) # # Set all the epoch-folder goop up # self.set_folding_params() # # Start connecting configured modules in the receive chain # # Connect raw USRP to de-dispersion filter, detector self.connect(self.u, self.dispfilt, self.detector) # Connect detector output to FIR LPF # in two stages, followed by the FFT scope self.connect(self.detector, self.first, self.second, self.third, self.scope) # Connect audio output #self.connect(self.first, self.volume) #self.connect(self.volume, (self.audio, 0)) #self.connect(self.volume, (self.audio, 1)) # Connect epoch folder if self.enable_comb_filter == True: self.connect(self.first, self.folder_bandpass, self.folder_rr, self.folder_f2c, self.folder_comb, self.folder_c2f, self.folder_s2p, self.folder_iir, self.chart) else: self.connect(self.first, self.folder_bandpass, self.folder_rr, self.folder_s2p, self.folder_iir, self.chart) # Connect baseband recording file (initially /dev/null) self.connect(self.u, self.tofloat, self.tochar, self.recording) # Connect pulse recording file (initially /dev/null) self.connect(self.first, self.toshort, self.pulse_recording) # # Build the GUI elements # self._build_gui(vbox) # Make GUI agree with command-line self.myform['average'].set_value(int(options.avg)) self.myform['foldavg'].set_value(int(options.favg)) # Make spectral averager agree with command line if options.avg != 1.0: self.scope.set_avg_alpha(float(1.0 / options.avg)) self.scope.set_average(True) # set initial values if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.subdev.gain_range() options.gain = float(g[0] + g[1]) / 2 if options.freq is None: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0] + r[1]) / 2 self.set_gain(options.gain) #self.set_volume(-10.0) if not (self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['DM'].set_value(self.dm) self.myform['Doppler'].set_value(self.doppler) # # Start the timer that shows current LMST on the GUI # self.lmst_timer.Start(1000)
def __init__(self, options, queue): gr.top_block.__init__(self, "mhp") self.audio_amps = [] self.converters = [] self.vocoders = [] self.filters = [] self.c4fm = [] self.output_gain = [] input_audio_rate = 8000 output_audio_rate = 48000 c4fm_rate = 96000 if not options.input_files: self.audio_input = audio.source(input_audio_rate, options.audio_input) self.audio_output = audio.sink(output_audio_rate, options.audio_output) for i in range(options.nchannels): if options.input_files: t = gr.file_source(gr.sizeof_char, "baseband-%d.dat" % i, options.repeat) self.vocoders.append(t) else: t = gr.multiply_const_ff(32767 * options.audio_gain) self.audio_amps.append(t) t = gr.float_to_short() self.converters.append(t) t = repeater.vocoder( True, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors self.vocoders.append(t) t = op25_c4fm_mod.p25_mod(output_sample_rate=c4fm_rate, log=False, verbose=True) self.c4fm.append(t) # FIXME: it would seem as if direct output at 48000 would be the # obvious way to go, but for unknown reasons, it produces hideous # distortion in the output waveform. For the same unknown # reasons, it's clean if we output at 96000 and then decimate # back down to 48k... t = blks2.rational_resampler_fff(1, 2) # 96000 -> 48000 self.filters.append(t) t = gr.multiply_const_ff(options.output_gain) self.output_gain.append(t) for i in range(options.nchannels): if not options.input_files: self.connect(self.audio_amps[i], self.converters[i], self.vocoders[i]) self.connect(self.vocoders[i], self.c4fm[i], self.filters[i], self.output_gain[i]) if options.nchannels == 1: if not options.input_files: self.connect(self.audio_input, self.audio_amps[0]) self.connect(self.output_gain[0], self.audio_output) else: for i in range(options.nchannels): if not options.input_files: self.connect((self.audio_input, i), self.audio_amps[i]) self.connect(self.output_gain[i], (self.audio_output, i))
def __init__(self, frame, panel, vbox, argv): MAX_CHANNELS = 7 stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) parser = OptionParser (option_class=eng_option) parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None, help="select USRP Tx side A or B") parser.add_option("-e","--enable-fft", action="store_true", default=False, help="enable spectrum plot (and use more CPU)") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set Tx frequency to FREQ [required]", metavar="FREQ") parser.add_option("-i","--file-input", action="store_true", default=False, help="input from baseband-0.dat, baseband-1.dat ...") parser.add_option("-g", "--audio-gain", type="eng_float", default=1.0, help="input audio gain multiplier") parser.add_option("-n", "--nchannels", type="int", default=2, help="number of Tx channels [1,4]") parser.add_option("-a", "--udp-addr", type="string", default="127.0.0.1", help="UDP host IP address") parser.add_option("-p", "--udp-port", type="int", default=0, help="UDP port number") parser.add_option("-r","--repeat", action="store_true", default=False, help="continuously replay input file") parser.add_option("-S", "--stretch", type="int", default=0, help="elastic buffer trigger value") parser.add_option("-v","--verbose", action="store_true", default=False, help="print out stats") parser.add_option("-I", "--audio-input", type="string", default="", help="pcm input device name. E.g., hw:0,0 or /dev/dsp") (options, args) = parser.parse_args () if len(args) != 0: parser.print_help() sys.exit(1) if options.nchannels < 1 or options.nchannels > MAX_CHANNELS: sys.stderr.write ("op25_tx: nchannels out of range. Must be in [1,%d]\n" % MAX_CHANNELS) sys.exit(1) if options.freq is None: sys.stderr.write("op25_tx: must specify frequency with -f FREQ\n") parser.print_help() sys.exit(1) # ---------------------------------------------------------------- # Set up constants and parameters self.u = usrp.sink_c () # the USRP sink (consumes samples) self.dac_rate = self.u.dac_rate() # 128 MS/s self.usrp_interp = 400 self.u.set_interp_rate(self.usrp_interp) self.usrp_rate = self.dac_rate / self.usrp_interp # 320 kS/s self.sw_interp = 10 self.audio_rate = self.usrp_rate / self.sw_interp # 32 kS/s # determine the daughterboard subdevice we're using if options.tx_subdev_spec is None: options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u) m = usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec) #print "mux = %#04x" % (m,) self.u.set_mux(m) self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec) print "Using TX d'board %s" % (self.subdev.side_and_name(),) self.subdev.set_gain(self.subdev.gain_range()[0]) # set min Tx gain if not self.set_freq(options.freq): freq_range = self.subdev.freq_range() print "Failed to set frequency to %s. Daughterboard supports %s to %s" % ( eng_notation.num_to_str(options.freq), eng_notation.num_to_str(freq_range[0]), eng_notation.num_to_str(freq_range[1])) raise SystemExit self.subdev.set_enable(True) # enable transmitter # instantiate vocoders self.vocoders = [] if options.file_input: for i in range (options.nchannels): t = gr.file_source(gr.sizeof_char, "baseband-%d.dat" % i, options.repeat) self.vocoders.append(t) elif options.udp_port > 0: self.udp_sources = [] for i in range (options.nchannels): t = gr.udp_source(1, options.udp_addr, options.udp_port + i, 216) self.udp_sources.append(t) arity = 2 t = gr.packed_to_unpacked_bb(arity, gr.GR_MSB_FIRST) self.vocoders.append(t) self.connect(self.udp_sources[i], self.vocoders[i]) else: self.audio_amps = [] self.converters = [] input_audio_rate = 8000 self.audio_input = audio.source(input_audio_rate, options.audio_input) for i in range (options.nchannels): t = gr.multiply_const_ff(32767 * options.audio_gain) self.audio_amps.append(t) t = gr.float_to_short() self.converters.append(t) t = repeater.vocoder(True, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors self.vocoders.append(t) self.connect((self.audio_input, i), self.audio_amps[i], self.converters[i], self.vocoders[i]) sum = gr.add_cc () # Instantiate N NBFM channels step = 25e3 offset = (0 * step, 1 * step, -1 * step, 2 * step, -2 * step, 3 * step, -3 * step) for i in range (options.nchannels): t = pipeline(self.vocoders[i], offset[i], self.audio_rate, self.usrp_rate) self.connect(t, (sum, i)) gain = gr.multiply_const_cc (4000.0 / options.nchannels) # connect it all self.connect (sum, gain) self.connect (gain, self.u) # plot an FFT to verify we are sending what we want if options.enable_fft: post_mod = fftsink2.fft_sink_c(panel, title="Post Modulation", fft_size=512, sample_rate=self.usrp_rate, y_per_div=20, ref_level=40) self.connect (sum, post_mod) vbox.Add (post_mod.win, 1, wx.EXPAND)