Ejemplo n.º 1
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", "--audio-output", type="string", default="")
        parser.add_option("-f", "--factor", type="eng_float", default=1)
        parser.add_option("-i", "--do-interp", action="store_true", default=False, help="enable output interpolator")
        parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate")
        parser.add_option("-S", "--stretch", type="int", default=0, help="flex amt")
        parser.add_option("-y", "--symbol-rate", type="int", default=4800, help="input symbol rate")
        parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data")
        (options, args) = parser.parse_args()
 
        sample_rate = options.sample_rate
        symbol_rate = options.symbol_rate

        IN = audio.source(sample_rate, options.audio_input)
        audio_output_rate = 8000
        if options.do_interp:
            audio_output_rate = 48000
        OUT = audio.sink(audio_output_rate, options.audio_output)

        symbol_decim = 1
        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.factor)
        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.verbose,	#debug
                                              True,	# do_imbe
                                              True,	# do_output
                                              False,	# do_msgq
                                              framer_msgq)
        IMBE = repeater.vocoder(False,                 # 0=Decode,True=Encode
                                  options.verbose,      # Verbose flag
                                  options.stretch,      # flex amount
                                  "",                   # udp ip address
                                  0,                    # udp port
                                  False)                # dump raw u vectors

        CVT = gr.short_to_float()
        if options.do_interp:
            interp_taps = gr.firdes.low_pass(1.0, 48000, 4000, 4000 * 0.1, gr.firdes.WIN_HANN)
            INTERP = gr.interp_fir_filter_fff(48000 // 8000, interp_taps)
        AMP2 = gr.multiply_const_ff(1.0 / 32767.0)

        self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CVT, AMP2)
        if options.do_interp:
            self.connect(AMP2, INTERP, OUT)
        else:
            self.connect(AMP2, OUT)
Ejemplo n.º 2
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])
Ejemplo n.º 3
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])
Ejemplo n.º 4
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))
Ejemplo n.º 5
0
    def __init__(self):
        gr.top_block.__init__(self)

        parser=OptionParser(option_class=eng_option)
        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
                          help="select USRP Rx side A or B (default=A)")
        parser.add_option("-C", "--costas-alpha", type="eng_float", default=0.125, help="offset frequency", metavar="Hz")
        parser.add_option("-c", "--calibration", type="int", default=0,
                          help="USRP calibration offset", metavar="FREQ")
        parser.add_option("-d","--debug", type="int", default=0, help="debug level")
        parser.add_option("-G", "--gain-mu", type="eng_float", default=0.05, help="Gardner gain")
        parser.add_option("-H", "--hostname", type="string", default="127.0.0.1",
                          help="IP address of asterisk (or wireshark) host")
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("-p", "--port", type="int", default=32001,
                          help="starting port number for chan_usrp")
        parser.add_option("-w", "--wireshark", action="store_true", default=False, help="write data to wireshark")

        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        if options.debug > 10:
            print 'Ready for GDB to attach (pid = %d)' % (os.getpid(),)
            raw_input("Press 'Enter' to continue...")
        
        # build graph
        self.u = usrp.source_c()                    # usrp is data source

        adc_rate = self.u.adc_rate()                # 64 MS/s
        usrp_decim = 60
        self.u.set_decim_rate(usrp_decim)
        usrp_rate = adc_rate / usrp_decim           # 1.0667 M

        channel_decim = 50.0
        channel_rate = usrp_rate / channel_decim    # 8K sps rate
        sps = channel_rate / 4800.0
        print "channel rate %f sps %f" % (channel_rate, sps)

        low_pass = 15e3
        channel_taps = gr.firdes.low_pass(1.0, usrp_rate, low_pass, low_pass * 0.1, gr.firdes.WIN_HANN)

        low_pass_nfm = 7.5e3
        channel_taps_nfm = gr.firdes.low_pass(1.0, usrp_rate, low_pass_nfm, low_pass_nfm * 0.1, gr.firdes.WIN_HANN)

        if options.rx_subdev_spec is None:
            options.rx_subdev_spec = pick_subdevice(self.u)

        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
        print "Using RX d'board %s" % (self.subdev.side_and_name(),)

        for i in xrange(len(channels)):
            freq = channels[i]['freq']
            mode = channels[i]['mode']
            port = channels[i]['port']
            ctcss = 0.0
            if 'ctcss' in channels[i]:
                ctcss = channels[i]['ctcss']
            wireshark = False
            if 'wireshark' in channels[i]:
                wireshark = True
            lo_freq = center_freq - freq
            if mode == 'c4fm':
                channel = rx_channel_c4fm(sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq)
            elif mode == 'cqpsk':
                channel = rx_channel_cqpsk(sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq)
            elif mode == 'fm':
                channel = rx_channel_nfm(sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq, low_pass, ctcss)
            elif mode == 'nfm':
                channel = rx_channel_nfm(sps, channel_decim, channel_taps_nfm, options, usrp_rate, channel_rate, lo_freq, low_pass_nfm, ctcss)
            # reduce float symbols to binary dibits
            levels = [ -2.0, 0.0, 2.0, 4.0 ]
            slicer = repeater.fsk4_slicer_fb(levels)

            if wireshark:
                # build p25 frames from raw dibits and write to wireshark
                msgq = gr.msg_queue(2)
                decoder = repeater.p25_frame_assembler(options.hostname, WIRESHARK_PORT, options.debug, False, False, False, msgq)
                self.connect (self.u, channel, slicer, decoder)
                sinks = gr.file_sink(gr.sizeof_char, "sym-%d.dat" % i)
                self.connect (slicer, sinks)
            else:
                # build p25 frames from raw dibits and extract IMBE speech codewords
                msgq = gr.msg_queue(2)
                decoder = repeater.p25_frame_assembler('', 0, options.debug, True, True, False, msgq)

                # decode the IMBE codewords - outputs speech at 8k rate
                imbe = repeater.vocoder(False, False, 0, "", 0, False)

                # write the audio (8k, signed int16) to asterisk app_rpt via UDP
                chan_rpt = repeater.chan_usrp_rx(options.hostname, port, options.debug)

                self.connect (self.u, channel, slicer, decoder, imbe, chan_rpt)
                fsink = gr.file_sink(gr.sizeof_float, 'fm-sink-%d.dat' % port)
                self.connect (channel, fsink)

                sfn = "chan-%d.bin" % port
                ssink = gr.file_sink(gr.sizeof_char, sfn)
                self.connect (slicer, ssink)
            print "attached channel %d freq %f port %d" % (i+1, lo_freq, port)

        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

        usrp_freq = center_freq + options.calibration

        # set initial values

        self.set_gain(options.gain)

        if not(self.set_freq(usrp_freq)):
            self._set_status_msg("Failed to set initial frequency")
Ejemplo n.º 6
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)
Ejemplo n.º 7
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)
Ejemplo n.º 8
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))
Ejemplo n.º 9
0
    def __init__(self):
        gr.top_block.__init__(self)

        parser = OptionParser(option_class=eng_option)
        parser.add_option("-R",
                          "--rx-subdev-spec",
                          type="subdev",
                          default=None,
                          help="select USRP Rx side A or B (default=A)")
        parser.add_option("-C",
                          "--costas-alpha",
                          type="eng_float",
                          default=0.125,
                          help="offset frequency",
                          metavar="Hz")
        parser.add_option("-c",
                          "--calibration",
                          type="int",
                          default=0,
                          help="USRP calibration offset",
                          metavar="FREQ")
        parser.add_option("-d",
                          "--debug",
                          type="int",
                          default=0,
                          help="debug level")
        parser.add_option("-G",
                          "--gain-mu",
                          type="eng_float",
                          default=0.05,
                          help="Gardner gain")
        parser.add_option("-H",
                          "--hostname",
                          type="string",
                          default="127.0.0.1",
                          help="IP address of asterisk (or wireshark) host")
        parser.add_option("-g",
                          "--gain",
                          type="eng_float",
                          default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("-p",
                          "--port",
                          type="int",
                          default=32001,
                          help="starting port number for chan_usrp")
        parser.add_option("-w",
                          "--wireshark",
                          action="store_true",
                          default=False,
                          help="write data to wireshark")

        (options, args) = parser.parse_args()
        if len(args) != 0:
            parser.print_help()
            sys.exit(1)

        if options.debug > 10:
            print 'Ready for GDB to attach (pid = %d)' % (os.getpid(), )
            raw_input("Press 'Enter' to continue...")

        # build graph
        self.u = usrp.source_c()  # usrp is data source

        adc_rate = self.u.adc_rate()  # 64 MS/s
        usrp_decim = 60
        self.u.set_decim_rate(usrp_decim)
        usrp_rate = adc_rate / usrp_decim  # 1.0667 M

        channel_decim = 50.0
        channel_rate = usrp_rate / channel_decim  # 8K sps rate
        sps = channel_rate / 4800.0
        print "channel rate %f sps %f" % (channel_rate, sps)

        low_pass = 15e3
        channel_taps = gr.firdes.low_pass(1.0, usrp_rate, low_pass,
                                          low_pass * 0.1, gr.firdes.WIN_HANN)

        low_pass_nfm = 7.5e3
        channel_taps_nfm = gr.firdes.low_pass(1.0, usrp_rate, low_pass_nfm,
                                              low_pass_nfm * 0.1,
                                              gr.firdes.WIN_HANN)

        if options.rx_subdev_spec is None:
            options.rx_subdev_spec = pick_subdevice(self.u)

        self.u.set_mux(
            usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
        print "Using RX d'board %s" % (self.subdev.side_and_name(), )

        for i in xrange(len(channels)):
            freq = channels[i]['freq']
            mode = channels[i]['mode']
            port = channels[i]['port']
            ctcss = 0.0
            if 'ctcss' in channels[i]:
                ctcss = channels[i]['ctcss']
            wireshark = False
            if 'wireshark' in channels[i]:
                wireshark = True
            lo_freq = center_freq - freq
            if mode == 'c4fm':
                channel = rx_channel_c4fm(sps, channel_decim, channel_taps,
                                          options, usrp_rate, channel_rate,
                                          lo_freq)
            elif mode == 'cqpsk':
                channel = rx_channel_cqpsk(sps, channel_decim, channel_taps,
                                           options, usrp_rate, channel_rate,
                                           lo_freq)
            elif mode == 'fm':
                channel = rx_channel_nfm(sps, channel_decim, channel_taps,
                                         options, usrp_rate, channel_rate,
                                         lo_freq, low_pass, ctcss)
            elif mode == 'nfm':
                channel = rx_channel_nfm(sps, channel_decim, channel_taps_nfm,
                                         options, usrp_rate, channel_rate,
                                         lo_freq, low_pass_nfm, ctcss)
            # reduce float symbols to binary dibits
            levels = [-2.0, 0.0, 2.0, 4.0]
            slicer = repeater.fsk4_slicer_fb(levels)

            if wireshark:
                # build p25 frames from raw dibits and write to wireshark
                msgq = gr.msg_queue(2)
                decoder = repeater.p25_frame_assembler(options.hostname,
                                                       WIRESHARK_PORT,
                                                       options.debug, False,
                                                       False, False, msgq)
                self.connect(self.u, channel, slicer, decoder)
                sinks = gr.file_sink(gr.sizeof_char, "sym-%d.dat" % i)
                self.connect(slicer, sinks)
            else:
                # build p25 frames from raw dibits and extract IMBE speech codewords
                msgq = gr.msg_queue(2)
                decoder = repeater.p25_frame_assembler('', 0, options.debug,
                                                       True, True, False, msgq)

                # decode the IMBE codewords - outputs speech at 8k rate
                imbe = repeater.vocoder(False, False, 0, "", 0, False)

                # write the audio (8k, signed int16) to asterisk app_rpt via UDP
                chan_rpt = repeater.chan_usrp_rx(options.hostname, port,
                                                 options.debug)

                self.connect(self.u, channel, slicer, decoder, imbe, chan_rpt)
                fsink = gr.file_sink(gr.sizeof_float, 'fm-sink-%d.dat' % port)
                self.connect(channel, fsink)

                sfn = "chan-%d.bin" % port
                ssink = gr.file_sink(gr.sizeof_char, sfn)
                self.connect(slicer, ssink)
            print "attached channel %d freq %f port %d" % (i + 1, lo_freq,
                                                           port)

        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

        usrp_freq = center_freq + options.calibration

        # set initial values

        self.set_gain(options.gain)

        if not (self.set_freq(usrp_freq)):
            self._set_status_msg("Failed to set initial frequency")
Ejemplo n.º 10
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)
Ejemplo n.º 11
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)
Ejemplo n.º 12
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", "--audio-output", type="string", default="")
        parser.add_option("-f", "--factor", type="eng_float", default=1)
        parser.add_option("-i",
                          "--do-interp",
                          action="store_true",
                          default=False,
                          help="enable output interpolator")
        parser.add_option("-s",
                          "--sample-rate",
                          type="int",
                          default=48000,
                          help="input sample rate")
        parser.add_option("-S",
                          "--stretch",
                          type="int",
                          default=0,
                          help="flex amt")
        parser.add_option("-y",
                          "--symbol-rate",
                          type="int",
                          default=4800,
                          help="input symbol rate")
        parser.add_option("-v",
                          "--verbose",
                          action="store_true",
                          default=False,
                          help="dump demodulation data")
        (options, args) = parser.parse_args()

        sample_rate = options.sample_rate
        symbol_rate = options.symbol_rate

        IN = audio.source(sample_rate, options.audio_input)
        audio_output_rate = 8000
        if options.do_interp:
            audio_output_rate = 48000
        OUT = audio.sink(audio_output_rate, options.audio_output)

        symbol_decim = 1
        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.factor)
        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.verbose,  #debug
            True,  # do_imbe
            True,  # do_output
            False,  # do_msgq
            framer_msgq)
        IMBE = repeater.vocoder(
            False,  # 0=Decode,True=Encode
            options.verbose,  # Verbose flag
            options.stretch,  # flex amount
            "",  # udp ip address
            0,  # udp port
            False)  # dump raw u vectors

        CVT = gr.short_to_float()
        if options.do_interp:
            interp_taps = gr.firdes.low_pass(1.0, 48000, 4000, 4000 * 0.1,
                                             gr.firdes.WIN_HANN)
            INTERP = gr.interp_fir_filter_fff(48000 // 8000, interp_taps)
        AMP2 = gr.multiply_const_ff(1.0 / 32767.0)

        self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CVT,
                     AMP2)
        if options.do_interp:
            self.connect(AMP2, INTERP, OUT)
        else:
            self.connect(AMP2, OUT)