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])
Exemple #3
0
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
Exemple #7
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])
Exemple #8
0
    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
Exemple #9
0
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
Exemple #10
0
    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
Exemple #13
0
    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):

        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 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)
Exemple #22
0
    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
Exemple #23
0
    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)
Exemple #25
0
    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))
Exemple #26
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)
Exemple #27
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 = 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)
Exemple #28
0
    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))
Exemple #29
0
    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)
Exemple #30
0
    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)
Exemple #31
0
    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))
Exemple #32
0
    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)
Exemple #34
0
def float_to_short(N):
    op = gr.float_to_short()
    tb = helper(N, op, gr.sizeof_float, gr.sizeof_short, 1, 1)
    return tb
Exemple #35
0
def float_to_short(N):
    op = gr.float_to_short()
    tb = helper(N, op, gr.sizeof_float, gr.sizeof_short, 1, 1)
    return tb
Exemple #36
0
    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)
Exemple #37
0
    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))
Exemple #38
0
    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)