示例#1
0
文件: audio_imbe.py 项目: alring/op25
    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)
示例#2
0
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file")
        parser.add_option("-g", "--gain", type="eng_float", default=1.0)
        parser.add_option("-L", "--low-pass", type="eng_float", default=15e3, help="low pass cut-off", metavar="Hz")
        parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file")
        parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample 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
        sps = 10
        symbol_rate = 4800
        # output rate will be 48,000
        ntaps = 11 * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        IN = gr.file_source(gr.sizeof_short, options.input_file)
        OUT = gr.file_sink(gr.sizeof_char, options.output_file)

        CVT = gr.short_to_float()
        AMP = gr.multiply_const_ff(options.gain / 32767.0)

        symbol_decim = 1
        symbol_coeffs = gr.firdes.root_raised_cosine (1.0,        	# gain
                                          sample_rate ,  	# sampling rate
                                          symbol_rate,     # symbol rate
                                          0.20,     	# width of trans. band
                                          500) 		# filter type 
        SYMBOL_FILTER = gr.fir_filter_fff (symbol_decim, symbol_coeffs)
        self.msgq = gr.msg_queue(2)

        FSK4 = op25.fsk4_demod_ff(self.msgq, sample_rate, symbol_rate)

        levels = [ -2.0, 0.0, 2.0, 4.0 ]
        SLICER = repeater.fsk4_slicer_fb(levels)

        hostname = "127.0.0.1"
        port = 23456
        debug = 255
        do_imbe = False
        do_output = True
        do_msgq = False
        msgqd = gr.msg_queue(2)
        DECODER = repeater.p25_frame_assembler(hostname, port, debug, do_imbe, do_output, do_msgq, msgqd)

        self.connect(IN, CVT, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODER, OUT)
示例#3
0
文件: usrp_rx.py 项目: alring/op25
    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")
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-1",
                          "--one-channel",
                          action="store_true",
                          default=False,
                          help="software synthesized Q channel")
        parser.add_option("-a",
                          "--agc",
                          action="store_true",
                          default=False,
                          help="automatic gain control (overrides --gain)")
        parser.add_option("-c",
                          "--calibration",
                          type="eng_float",
                          default=0,
                          help="freq offset")
        parser.add_option("-d",
                          "--debug",
                          action="store_true",
                          default=False,
                          help="allow time at init to attach gdb")
        parser.add_option("-C",
                          "--costas-alpha",
                          type="eng_float",
                          default=0.125,
                          help="Costas alpha")
        parser.add_option("-g", "--gain", type="eng_float", default=1.0)
        parser.add_option("-i",
                          "--input-file",
                          type="string",
                          default="in.dat",
                          help="specify the input file")
        parser.add_option("-I",
                          "--imbe",
                          action="store_true",
                          default=False,
                          help="output IMBE codewords")
        parser.add_option("-L",
                          "--low-pass",
                          type="eng_float",
                          default=6.5e3,
                          help="low pass cut-off",
                          metavar="Hz")
        parser.add_option("-o",
                          "--output-file",
                          type="string",
                          default="out.dat",
                          help="specify the output file")
        parser.add_option("-p",
                          "--polarity",
                          action="store_true",
                          default=False,
                          help="use reversed polarity")
        parser.add_option("-r",
                          "--raw-symbols",
                          type="string",
                          default=None,
                          help="dump decoded symbols to file")
        parser.add_option("-s",
                          "--sample-rate",
                          type="int",
                          default=96000,
                          help="input sample rate")
        parser.add_option("-t",
                          "--tone-detect",
                          action="store_true",
                          default=False,
                          help="use experimental tone detect algorithm")
        parser.add_option("-v",
                          "--verbose",
                          action="store_true",
                          default=False,
                          help="additional output")
        parser.add_option("-6",
                          "--k6k",
                          action="store_true",
                          default=False,
                          help="use 6K symbol rate")
        (options, args) = parser.parse_args()

        sample_rate = options.sample_rate
        if options.k6k:
            symbol_rate = 6000
        else:
            symbol_rate = 4800
        samples_per_symbol = sample_rate // symbol_rate

        IN = gr.file_source(gr.sizeof_gr_complex, options.input_file)

        if options.one_channel:
            C2F = gr.complex_to_float()
            F2C = gr.float_to_complex()

        # osc./mixer for mixing signal down to approx. zero IF
        LO = gr.sig_source_c(sample_rate, gr.GR_COS_WAVE, options.calibration,
                             1.0, 0)
        MIXER = gr.multiply_cc()

        # get signal into normalized range (-1.0 - +1.0)
        if options.agc:
            AMP = gr.feedforward_agc_cc(16, 1.0)
        else:
            AMP = gr.multiply_const_cc(options.gain)

        lpf_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass,
                                      options.low_pass * 0.1,
                                      gr.firdes.WIN_HANN)

        decim_amt = 1
        if options.tone_detect:
            if sample_rate != 96000:
                print "warning, only 96K has been tested."
                print "other rates may require theta to be reviewed/adjusted."
            step_size = 7.5e-8
            theta = -4  # optimum timing sampling point
            cic_length = 48
            DEMOD = repeater.tdetect_cc(samples_per_symbol, step_size, theta,
                                        cic_length)
        else:
            # decim by 2 to get 48k rate
            samples_per_symbol /= 2  # for DECIM
            sample_rate /= 2  # for DECIM
            decim_amt = 2
            # create Gardner/Costas loop
            # the loop will not work if the sample levels aren't normalized (above)
            timing_error_gain = 0.025  # loop error gain
            gain_omega = 0.25 * timing_error_gain * timing_error_gain
            alpha = options.costas_alpha
            beta = 0.125 * alpha * alpha
            fmin = -0.025  # fmin and fmax are in radians/s
            fmax = 0.025
            DEMOD = repeater.gardner_costas_cc(samples_per_symbol,
                                               timing_error_gain, gain_omega,
                                               alpha, beta, fmax, fmin)
        DECIM = gr.fir_filter_ccf(decim_amt, lpf_taps)

        # probably too much phase noise etc to attempt coherent demodulation
        # so we use differential
        DIFF = gr.diff_phasor_cc()

        # take angle of the phase difference (in radians)
        TOFLOAT = gr.complex_to_arg()

        # convert from radians such that signal is in [-3, -1, +1, +3]
        RESCALE = gr.multiply_const_ff(1 / (pi / 4.0))

        # optional polarity reversal (should be unnec. - now autodetected)
        p = 1.0
        if options.polarity:
            p = -1.0
        POLARITY = gr.multiply_const_ff(p)

        # hard decision at specified points
        levels = [-2.0, 0.0, 2.0, 4.0]
        SLICER = repeater.fsk4_slicer_fb(levels)

        # assemble received frames and route to Wireshark via UDP
        hostname = "127.0.0.1"
        port = 23456
        debug = 0
        if options.verbose:
            debug = 255
        do_imbe = False
        if options.imbe:
            do_imbe = True
        do_output = True  # enable block's output stream
        do_msgq = False  # msgq output not yet implemented
        msgq = gr.msg_queue(2)
        DECODER = repeater.p25_frame_assembler(hostname, port, debug, do_imbe,
                                               do_output, do_msgq, msgq)

        OUT = gr.file_sink(gr.sizeof_char, options.output_file)

        if options.one_channel:
            self.connect(IN, C2F, F2C, (MIXER, 0))
        else:
            self.connect(IN, (MIXER, 0))
        self.connect(LO, (MIXER, 1))
        self.connect(MIXER, AMP, DECIM, DEMOD, DIFF, TOFLOAT, RESCALE,
                     POLARITY, SLICER, DECODER, OUT)

        if options.raw_symbols:
            SINKC = gr.file_sink(gr.sizeof_char, options.raw_symbols)
            self.connect(SLICER, SINKC)

        if options.debug:
            print 'Ready for GDB to attach (pid = %d)' % (os.getpid(), )
            raw_input("Press 'Enter' to continue...")
示例#5
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)
示例#6
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")
示例#7
0
文件: disctap_rx.py 项目: alring/op25
    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)
示例#8
0
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-1", "--one-channel", action="store_true", default=False, help="software synthesized Q channel")
        parser.add_option("-c", "--calibration", type="eng_float", default=0, help="freq offset")
        parser.add_option("-d", "--debug", action="store_true", default=False, help="allow time at init to attach gdb")
        parser.add_option("-C", "--costas-alpha", type="eng_float", default=0.125, help="Costas alpha")
        parser.add_option("-g", "--gain", type="eng_float", default=1.0)
        parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file")
        parser.add_option("-I", "--imbe", action="store_true", default=False, help="output IMBE codewords")
        parser.add_option("-L", "--low-pass", type="eng_float", default=6.5e3, help="low pass cut-off", metavar="Hz")
        parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file")
        parser.add_option("-p", "--polarity", action="store_true", default=False, help="use reversed polarity")
        parser.add_option("-s", "--sample-rate", type="int", default=96000, help="input sample rate")
        parser.add_option("-t", "--tone-detect", action="store_true", default=False, help="use experimental tone detect algorithm")
        parser.add_option("-v", "--verbose", action="store_true", default=False, help="additional output")
        (options, args) = parser.parse_args()
 
        sample_rate = options.sample_rate
        symbol_rate = 4800
        samples_per_symbol = sample_rate // symbol_rate

        IN = gr.file_source(gr.sizeof_gr_complex, options.input_file)

        if options.one_channel:
            C2F = gr.complex_to_float()
            F2C = gr.float_to_complex()

        # osc./mixer for mixing signal down to approx. zero IF
        LO = gr.sig_source_c (sample_rate, gr.GR_COS_WAVE, options.calibration, 1.0, 0)
        MIXER = gr.multiply_cc()

        # get signal into normalized range (-1.0 - +1.0)
        # FIXME: add AGC
        AMP = gr.multiply_const_cc(options.gain)

        lpf_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)

        decim_amt = 1
        if options.tone_detect:
            if sample_rate != 96000:
                print "warning, only 96K has been tested."
                print "other rates may require theta to be reviewed/adjusted."
            step_size = 7.5e-8
            theta = -4	# optimum timing sampling point
            cic_length = 48
            DEMOD = repeater.tdetect_cc(samples_per_symbol, step_size, theta, cic_length)
        else:
            # decim by 2 to get 48k rate
            samples_per_symbol /= 2	# for DECIM
            sample_rate /= 2	# for DECIM
            decim_amt = 2
            # create Gardner/Costas loop
            # the loop will not work if the sample levels aren't normalized (above)
            timing_error_gain = 0.025   # loop error gain
            gain_omega = 0.25 * timing_error_gain * timing_error_gain
            alpha = options.costas_alpha
            beta = 0.125 * alpha * alpha
            fmin = -0.025   # fmin and fmax are in radians/s
            fmax =  0.025
            DEMOD = repeater.gardner_costas_cc(samples_per_symbol, timing_error_gain, gain_omega, alpha, beta, fmax, fmin)
        DECIM = gr.fir_filter_ccf (decim_amt, lpf_taps)

        # probably too much phase noise etc to attempt coherent demodulation
        # so we use differential
        DIFF = gr.diff_phasor_cc()

        # take angle of the phase difference (in radians)
        TOFLOAT = gr.complex_to_arg()

        # convert from radians such that signal is in [-3, -1, +1, +3]
        RESCALE = gr.multiply_const_ff(1 / (pi / 4.0))

        # optional polarity reversal (should be unnec. - now autodetected)
        p = 1.0
        if options.polarity:
            p = -1.0
        POLARITY = gr.multiply_const_ff(p)

        # hard decision at specified points
        levels = [-2.0, 0.0, 2.0, 4.0 ]
        SLICER = repeater.fsk4_slicer_fb(levels)

        # assemble received frames and route to Wireshark via UDP
        hostname = "127.0.0.1"
        port = 23456
        debug = 0
	if options.verbose:
                debug = 255
        do_imbe = False
        if options.imbe:
                do_imbe = True
        do_output = True # enable block's output stream
        do_msgq = False  # msgq output not yet implemented
        msgq = gr.msg_queue(2)
        DECODER = repeater.p25_frame_assembler(hostname, port, debug, do_imbe, do_output, do_msgq, msgq)

        OUT = gr.file_sink(gr.sizeof_char, options.output_file)

        if options.one_channel:
            self.connect(IN, C2F, F2C, (MIXER, 0))
        else:
            self.connect(IN, (MIXER, 0))
        self.connect(LO, (MIXER, 1))
        self.connect(MIXER, AMP, DECIM, DEMOD, DIFF, TOFLOAT, RESCALE, POLARITY, SLICER, DECODER, OUT)

        if options.debug:
            print 'Ready for GDB to attach (pid = %d)' % (os.getpid(),)
            raw_input("Press 'Enter' to continue...")
示例#9
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)
示例#10
0
    def __init__(self):
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-i",
                          "--input-file",
                          type="string",
                          default="in.dat",
                          help="specify the input file")
        parser.add_option("-g", "--gain", type="eng_float", default=1.0)
        parser.add_option("-L",
                          "--low-pass",
                          type="eng_float",
                          default=15e3,
                          help="low pass cut-off",
                          metavar="Hz")
        parser.add_option("-o",
                          "--output-file",
                          type="string",
                          default="out.dat",
                          help="specify the output file")
        parser.add_option("-s",
                          "--sample-rate",
                          type="int",
                          default=48000,
                          help="input sample 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
        sps = 10
        symbol_rate = 4800
        # output rate will be 48,000
        ntaps = 11 * sps

        channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass,
                                          options.low_pass * 0.1,
                                          gr.firdes.WIN_HANN)

        IN = gr.file_source(gr.sizeof_short, options.input_file)
        OUT = gr.file_sink(gr.sizeof_char, options.output_file)

        CVT = gr.short_to_float()
        AMP = gr.multiply_const_ff(options.gain / 32767.0)

        symbol_decim = 1
        symbol_coeffs = gr.firdes.root_raised_cosine(
            1.0,  # gain
            sample_rate,  # sampling rate
            symbol_rate,  # symbol rate
            0.20,  # width of trans. band
            500)  # filter type
        SYMBOL_FILTER = gr.fir_filter_fff(symbol_decim, symbol_coeffs)
        self.msgq = gr.msg_queue(2)

        FSK4 = op25.fsk4_demod_ff(self.msgq, sample_rate, symbol_rate)

        levels = [-2.0, 0.0, 2.0, 4.0]
        SLICER = repeater.fsk4_slicer_fb(levels)

        hostname = "127.0.0.1"
        port = 23456
        debug = 255
        do_imbe = False
        do_output = True
        do_msgq = False
        msgqd = gr.msg_queue(2)
        DECODER = repeater.p25_frame_assembler(hostname, port, debug, do_imbe,
                                               do_output, do_msgq, msgqd)

        self.connect(IN, CVT, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODER, OUT)