Exemplo n.º 1
0
    def __init__(self,
                 protocol=None,
                 config_file=None,
                 gain_adjust=None,
                 verbose=0,
                 fullrate_mode=False,
                 alt_input=None):
        gr.hier_block2.__init__(
            self,
            "dv_encoder",
            gr.io_signature(1, 1, gr.sizeof_short),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_char))  # Output signature

        if protocol == 'dmr':
            assert config_file
            ENCODER = op25_repeater.ambe_encoder_sb(verbose)
            ENCODER2 = op25_repeater.ambe_encoder_sb(verbose)
            ENCODER2.set_gain_adjust(gain_adjust)
            DMR = op25_repeater.dmr_bs_tx_bb(verbose, config_file)
            self.connect(self, ENCODER, (DMR, 0))
            if not alt_input:
                alt_input = self
            self.connect(alt_input, ENCODER2, (DMR, 1))
        elif protocol == 'dstar':
            assert config_file
            ENCODER = op25_repeater.dstar_tx_sb(verbose, config_file)
        elif protocol == 'p25':
            ENCODER = op25_repeater.vocoder(
                True,  # 0=Decode,True=Encode
                False,  # Verbose flag
                0,  # flex amount
                "",  # udp ip address
                0,  # udp port
                False)  # dump raw u vectors
        elif protocol == 'ysf':
            assert config_file
            ENCODER = op25_repeater.ysf_tx_sb(verbose, config_file,
                                              fullrate_mode)
        elif protocol.startswith('nxdn'):
            assert config_file
            ENCODER = op25_repeater.nxdn_tx_sb(verbose, config_file,
                                               protocol == 'nxdn96')
        ENCODER.set_gain_adjust(gain_adjust)
        if protocol == 'dmr':
            self.connect(DMR, self)
        else:
            self.connect(self, ENCODER, self)
Exemplo n.º 2
0
Arquivo: op25_tx.py Projeto: wiml/op25
    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=1,
                           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("--args", type="string", default="",
                           help="device args")
        parser.add_option("--gains", type="string", default="",
                           help="gains")
        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 = osmosdr.sink (options.args)       # the USRP sink (consumes samples)
        gain_names = self.u.get_gain_names()
        for name in gain_names:
            gain_range = self.u.get_gain_range(name)
            print("gain: name: %s range: start %d stop %d step %d" % (name, gain_range[0].start(), gain_range[0].stop(), gain_range[0].step()))
        if options.gains:
            for tuple in options.gains.split(","):
                name, gain = tuple.split(":")
                gain = int(gain)
                print("setting gain %s to %d" % (name, gain))
                self.u.set_gain(gain, name)

        self.usrp_rate = 320000
        print('setting sample rate')
        self.u.set_sample_rate(self.usrp_rate)
        self.u.set_center_freq(int(options.freq))
        #self.u.set_bandwidth(self.usrp_rate)

        #self.u = blocks.file_sink(gr.sizeof_gr_complex, 'usrp-samp.dat')

        #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
        self.audio_rate = 32000

#       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:
            i = 0
            t = blocks.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])

        if 1: # else:
          input_audio_rate = 8000
          #self.audio_input = audio.source(input_audio_rate, options.audio_input)
          af = 1333
          audio_input = analog.sig_source_s( input_audio_rate, analog.GR_SIN_WAVE, af, 15000)
          t = op25_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.connect(audio_input, t)
          self.vocoders.append(t)

        sum = blocks.add_cc ()

        # Instantiate N NBFM channels
        step = 100e3
        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))

        t = file_pipeline(offset[2], self.usrp_rate, '2013-320k-filt.dat')
        self.connect(t, (sum, options.nchannels))

        gain = blocks.multiply_const_cc (0.75 / (options.nchannels+1))

        # 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)
Exemplo n.º 3
0
    def __init__(self,
                 protocol=None,
                 config_file=None,
                 mod_adjust=None,
                 gain_adjust=None,
                 output_gain=None,
                 if_freq=0,
                 if_rate=0,
                 verbose=0,
                 fullrate_mode=False,
                 sample_rate=0,
                 bt=0,
                 alt_input=None):
        gr.hier_block2.__init__(
            self,
            "dv_modulator",
            gr.io_signature(1, 1, gr.sizeof_short),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_gr_complex))  # Output signature

        from dv_tx import RC_FILTER
        if protocol == 'dmr':
            assert config_file
            ENCODER = op25_repeater.ambe_encoder_sb(verbose)
            ENCODER2 = op25_repeater.ambe_encoder_sb(verbose)
            ENCODER2.set_gain_adjust(gain_adjust)
            DMR = op25_repeater.dmr_bs_tx_bb(verbose, config_file)
            self.connect(self, ENCODER, (DMR, 0))
            if not alt_input:
                alt_input = self
            self.connect(alt_input, ENCODER2, (DMR, 1))
        elif protocol == 'dstar':
            assert config_file
            ENCODER = op25_repeater.dstar_tx_sb(verbose, config_file)
        elif protocol == 'p25':
            ENCODER = op25_repeater.vocoder(
                True,  # 0=Decode,True=Encode
                False,  # Verbose flag
                0,  # flex amount
                "",  # udp ip address
                0,  # udp port
                False)  # dump raw u vectors
        elif protocol == 'ysf':
            assert config_file
            ENCODER = op25_repeater.ysf_tx_sb(verbose, config_file,
                                              fullrate_mode)
        ENCODER.set_gain_adjust(gain_adjust)

        MOD = p25_mod_bf(output_sample_rate=sample_rate,
                         dstar=(protocol == 'dstar'),
                         bt=bt,
                         rc=RC_FILTER[protocol])

        AMP = blocks.multiply_const_ff(output_gain)

        max_dev = 12.5e3
        k = 2 * math.pi * max_dev / if_rate

        FM_MOD = analog.frequency_modulator_fc(k * mod_adjust)

        if protocol == 'dmr':
            self.connect(DMR, MOD)
        else:
            self.connect(self, ENCODER, MOD)

        INTERP = filter.rational_resampler_fff(if_rate / sample_rate, 1)

        MIXER = blocks.multiply_cc()
        LO = analog.sig_source_c(if_rate, analog.GR_SIN_WAVE, if_freq, 1.0, 0)

        self.connect(MOD, AMP, INTERP, FM_MOD, (MIXER, 0))
        self.connect(LO, (MIXER, 1))
        self.connect(MIXER, self)
Exemplo n.º 4
0
	def __init__(self,infile, outfile, input_rate, channel_rate, codec_provoice, codec_p25, sslevel, svlevel):
		gr.top_block.__init__(self, "Top Block")
		
		self.input_rate = input_rate
		self.channel_rate = channel_rate
		
		self.source = blocks.file_source(gr.sizeof_gr_complex*1, infile, False)
		self.lp1_decim = int(input_rate/(channel_rate*1.6))
		print self.lp1_decim
		self.lp1 = filter.fir_filter_ccc(self.lp1_decim,firdes.low_pass( 1.0, self.input_rate, (self.channel_rate/2), ((self.channel_rate/2)*0.6), firdes.WIN_HAMMING))

		#self.audiodemod =  gr.quadrature_demod_cf(1)

		audio_pass = (input_rate/self.lp1_decim)*0.25
		audio_stop = audio_pass+2000
		self.audiodemod = analog.fm_demod_cf(channel_rate=(input_rate/self.lp1_decim), audio_decim=1, deviation=15000, audio_pass=audio_pass, audio_stop=audio_stop, gain=8, tau=75e-6)
		
		self.throttle = blocks.throttle(gr.sizeof_gr_complex*1, self.input_rate)

		self.signal_squelch = analog.pwr_squelch_cc(sslevel,0.01, 0, True)
		self.vox_squelch = analog.pwr_squelch_ff(svlevel, 0.0005, 0, True)
		
		self.audiosink = blocks.wavfile_sink(outfile, 1, 8000)

		if codec_provoice:
			self.dsd = dsd.block_ff(dsd.dsd_FRAME_PROVOICE,dsd.dsd_MOD_AUTO_SELECT,1,0,False)
			channel_rate = input_rate/self.lp1_decim
			self.resampler_in = filter.rational_resampler_fff(interpolation=48000, decimation=channel_rate, taps=None, fractional_bw=None, )
			output_rate = 8000
			resampler = filter.rational_resampler_fff(
                                        interpolation=(input_rate/self.lp1_decim),
                                        decimation=output_rate,
                                        taps=None,
                                        fractional_bw=None,
                                )
		elif codec_p25:
			symbol_deviation = 600.0
			symbol_rate = 4800
			channel_rate = input_rate/self.lp1_decim
			
		        fm_demod_gain = channel_rate / (2.0 * pi * symbol_deviation)
		        fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

		        symbol_decim = 1
		        samples_per_symbol = channel_rate // symbol_rate
		        symbol_coeffs = (1.0/samples_per_symbol,) * samples_per_symbol
		        symbol_filter = filter.fir_filter_fff(symbol_decim, symbol_coeffs)

		        autotuneq = gr.msg_queue(2)
		        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, symbol_rate)


		        # symbol slicer
		        levels = [ -2.0, 0.0, 2.0, 4.0 ]
		        slicer = op25.fsk4_slicer_fb(levels)

			imbe = repeater.vocoder(False, True, 0, "", 0, False)
			self.decodequeue = decodequeue = gr.msg_queue(10000)
			decoder = repeater.p25_frame_assembler('', 0, 0, True, True, False, decodequeue)
	
		        float_conversion = blocks.short_to_float(1, 8192)
		        resampler = filter.rational_resampler_fff(
		                        interpolation=8000,
		                        decimation=8000,
		                        taps=None,
		                        fractional_bw=None,
		                )
	
					
		#Tone squelch, custom GRC block that rips off CTCSS squelch to detect 4800 hz tone and latch squelch after that
		if not codec_provoice and not codec_p25:
			#self.tone_squelch = gr.tone_squelch_ff(audiorate, 4800.0, 0.05, 300, 0, True)
			#tone squelch is EDACS ONLY
			self.high_pass = filter.fir_filter_fff(1, firdes.high_pass(1, (input_rate/self.lp1_decim), 300, 30, firdes.WIN_HAMMING, 6.76))
			#output_rate = channel_rate
			resampler = filter.rational_resampler_fff(
                                        interpolation=8000,
                                        decimation=(input_rate/self.lp1_decim),
                                        taps=None,
                                        fractional_bw=None,
			)
		if(codec_provoice):
			self.connect(self.source, self.throttle, self.lp1, self.audiodemod, self.resampler_in, self.dsd, self.audiosink)
		elif(codec_p25):
			self.connect(self.source, self.throttle, self.lp1, fm_demod, symbol_filter, demod_fsk4, slicer, decoder, imbe, float_conversion, resampler, self.audiosink)
		else:
			self.connect(self.source, self.throttle, self.lp1, self.signal_squelch, self.audiodemod, self.high_pass, self.vox_squelch, resampler, self.audiosink)

		self.time_open = time.time()
		self.time_tone = 0
		self.time_activity = 0
Exemplo n.º 5
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=1,
                           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("--args", type="string", default="",
                           help="device args")
        parser.add_option("--gains", type="string", default="",
                           help="gains")
        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 = osmosdr.sink (options.args)       # the USRP sink (consumes samples)
        gain_names = self.u.get_gain_names()
        for name in gain_names:
            gain_range = self.u.get_gain_range(name)
            print "gain: name: %s range: start %d stop %d step %d" % (name, gain_range[0].start(), gain_range[0].stop(), gain_range[0].step())
        if options.gains:
            for tuple in options.gains.split(","):
                name, gain = tuple.split(":")
                gain = int(gain)
                print "setting gain %s to %d" % (name, gain)
                self.u.set_gain(gain, name)

        self.usrp_rate = 320000
        print 'setting sample rate'
        self.u.set_sample_rate(self.usrp_rate)
        self.u.set_center_freq(int(options.freq))
        #self.u.set_bandwidth(self.usrp_rate)

        #self.u = blocks.file_sink(gr.sizeof_gr_complex, 'usrp-samp.dat')

        #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
        self.audio_rate = 32000

#       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:
            i = 0
            t = blocks.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])

        if 1: # else:
          input_audio_rate = 8000
          #self.audio_input = audio.source(input_audio_rate, options.audio_input)
          af = 1333
          audio_input = analog.sig_source_s( input_audio_rate, analog.GR_SIN_WAVE, af, 15000)
          t = op25_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.connect(audio_input, t)
          self.vocoders.append(t)

        sum = blocks.add_cc ()

        # Instantiate N NBFM channels
        step = 100e3
        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))

        t = file_pipeline(offset[2], self.usrp_rate, '2013-320k-filt.dat')
        self.connect(t, (sum, options.nchannels))

        gain = blocks.multiply_const_cc (0.75 / (options.nchannels+1))

        # 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)
Exemplo n.º 6
0
    def __init__(self, output_rate=48000):
        gr.hier_block2.__init__(
            self,
            "C4FM Transmitter",
            gr.io_signature(1, 1, gr.sizeof_float * 1),
            gr.io_signaturev(3, 3, [
                gr.sizeof_gr_complex * 1, gr.sizeof_float * 1,
                gr.sizeof_char * 1
            ]),
        )

        ##################################################
        # Parameters
        ##################################################
        self.output_rate = output_rate

        ##################################################
        # Variables
        ##################################################
        self.if_rate = if_rate = 48000

        self.taps = taps = firdes.low_pass(output_rate / if_rate, output_rate,
                                           12500 / 2, 100, firdes.WIN_HANN,
                                           6.76)

        ##################################################
        # Blocks
        ##################################################
        self.symbol_mapper = p25_symbol_mapper_bf(
            symbol00=1.0 / 3.0,
            symbol01=1.0,
            symbol10=-1.0 / 3.0,
            symbol11=-1.0,
        )
        self.p25_c4fm_modulator_ff_0 = p25_c4fm_modulator_ff(
            gain=6.0,
            input_rate=4800,
            output_rate=if_rate,
        )
        self.op25_vocoder_0 = op25_repeater.vocoder(True, False, 0, "", 0,
                                                    False)
        self.interp_fir_filter_xxx_0 = filter.interp_fir_filter_ccf(
            output_rate / if_rate, (taps))
        self.interp_fir_filter_xxx_0.declare_sample_delay(0)
        self.fm_mod = p25_fm_modulator_fc(
            factor=1,
            max_deviation=2.5e3,
            samp_rate=if_rate,
        )
        self.float_to_short = blocks.float_to_short(1, 32768)

        ##################################################
        # Connections
        ##################################################
        self.connect((self.float_to_short, 0), (self.op25_vocoder_0, 0))
        self.connect((self.fm_mod, 0), (self.interp_fir_filter_xxx_0, 0))
        self.connect((self.interp_fir_filter_xxx_0, 0), (self, 0))
        self.connect((self.op25_vocoder_0, 0), (self, 2))
        self.connect((self.op25_vocoder_0, 0), (self.symbol_mapper, 0))
        self.connect((self.p25_c4fm_modulator_ff_0, 0), (self.fm_mod, 0))
        self.connect((self.p25_c4fm_modulator_ff_0, 0), (self, 1))
        self.connect((self, 0), (self.float_to_short, 0))
        self.connect((self.symbol_mapper, 0),
                     (self.p25_c4fm_modulator_ff_0, 0))
Exemplo n.º 7
0
    def __init__(self):
        global output_gains, gain_adjust, gain_adjust_fullrate, mod_adjust
        gr.top_block.__init__(self)
        parser = OptionParser(option_class=eng_option)

        parser.add_option("-a",
                          "--args",
                          type="string",
                          default="",
                          help="device args")
        parser.add_option("-A",
                          "--alt-modulator-rate",
                          type="int",
                          default=50000,
                          help="when mod rate is not a submutiple of IF rate")
        parser.add_option("-b",
                          "--bt",
                          type="float",
                          default=0.5,
                          help="specify bt value")
        parser.add_option("-c",
                          "--config-file",
                          type="string",
                          default=None,
                          help="specify the config file name")
        parser.add_option("-f",
                          "--file1",
                          type="string",
                          default=None,
                          help="specify the input file slot 1")
        parser.add_option("-F",
                          "--file2",
                          type="string",
                          default=None,
                          help="specify the input file slot 2 (DMR)")
        parser.add_option("-g",
                          "--gain",
                          type="float",
                          default=1.0,
                          help="input gain")
        parser.add_option("-i",
                          "--if-rate",
                          type="int",
                          default=480000,
                          help="output rate to sdr")
        parser.add_option(
            "-I",
            "--audio-input",
            type="string",
            default="",
            help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
        parser.add_option("-k",
                          "--symbol-sink",
                          type="string",
                          default=None,
                          help="write symbols to file (optional)")
        parser.add_option("-N",
                          "--gains",
                          type="string",
                          default=None,
                          help="gain settings")
        parser.add_option(
            "-O",
            "--audio-output",
            type="string",
            default="default",
            help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
        parser.add_option("-o",
                          "--output-file",
                          type="string",
                          default=None,
                          help="specify the output file")
        parser.add_option("-p",
                          "--protocol",
                          type="choice",
                          default=None,
                          choices=('dmr', 'dstar', 'p25', 'ysf'),
                          help="specify protocol: dmr, dstar, p25, ysf")
        parser.add_option("-q",
                          "--frequency-correction",
                          type="float",
                          default=0.0,
                          help="ppm")
        parser.add_option("-Q",
                          "--frequency",
                          type="float",
                          default=0.0,
                          help="Hz")
        parser.add_option("-r",
                          "--repeat",
                          action="store_true",
                          default=False,
                          help="input file repeat")
        parser.add_option("-R",
                          "--fullrate-mode",
                          action="store_true",
                          default=False,
                          help="ysf fullrate")
        parser.add_option("-s",
                          "--modulator-rate",
                          type="int",
                          default=48000,
                          help="must be submultiple of IF rate - see also -A")
        parser.add_option("-S",
                          "--alsa-rate",
                          type="int",
                          default=48000,
                          help="sound source/sink sample rate")
        parser.add_option("-t",
                          "--test",
                          type="string",
                          default=None,
                          help="test pattern symbol file")
        parser.add_option("-v",
                          "--verbose",
                          type="int",
                          default=0,
                          help="additional output")
        (options, args) = parser.parse_args()

        max_inputs = 1

        if options.protocol is None:
            print 'protocol [-p] option missing'
            sys.exit(0)

        if options.protocol == 'ysf' or options.protocol == 'dmr' or options.protocol == 'dstar':
            assert options.config_file  # dstar, dmr and ysf require config file ("-c FILENAME" option)

        output_gain = output_gains[options.protocol]

        if options.test:  # input file is in symbols of size=char
            ENCODER = blocks.file_source(gr.sizeof_char, options.test, True)
        elif options.protocol == 'dmr':
            max_inputs = 2
            ENCODER = op25_repeater.ambe_encoder_sb(options.verbose)
            ENCODER2 = op25_repeater.ambe_encoder_sb(options.verbose)
            ENCODER2.set_gain_adjust(gain_adjust['dmr'])
            DMR = op25_repeater.dmr_bs_tx_bb(options.verbose,
                                             options.config_file)
            self.connect(ENCODER, (DMR, 0))
            self.connect(ENCODER2, (DMR, 1))
        elif options.protocol == 'dstar':
            ENCODER = op25_repeater.dstar_tx_sb(options.verbose,
                                                options.config_file)
        elif options.protocol == 'p25':
            ENCODER = op25_repeater.vocoder(
                True,  # 0=Decode,True=Encode
                False,  # Verbose flag
                0,  # flex amount
                "",  # udp ip address
                0,  # udp port
                False)  # dump raw u vectors
        elif options.protocol == 'ysf':
            ENCODER = op25_repeater.ysf_tx_sb(options.verbose,
                                              options.config_file,
                                              options.fullrate_mode)
            if options.fullrate_mode:
                ENCODER.set_gain_adjust(gain_adjust_fullrate['ysf'])
            else:
                ENCODER.set_gain_adjust(gain_adjust['ysf'])
        if options.protocol == 'p25' and not options.test:
            ENCODER.set_gain_adjust(gain_adjust_fullrate[options.protocol])
        elif not options.test and not options.protocol == 'ysf':
            ENCODER.set_gain_adjust(gain_adjust[options.protocol])
        nfiles = 0
        if options.file1:
            nfiles += 1
        if options.file2 and options.protocol == 'dmr':
            nfiles += 1
        if nfiles < max_inputs and not options.test:
            AUDIO = audio.source(options.alsa_rate, options.audio_input)
            lpf_taps = filter.firdes.low_pass(1.0, options.alsa_rate, 3400.0,
                                              3400 * 0.1,
                                              filter.firdes.WIN_HANN)
            audio_rate = 8000
            AUDIO_DECIM = filter.fir_filter_fff(
                int(options.alsa_rate / audio_rate), lpf_taps)
            AUDIO_SCALE = blocks.multiply_const_ff(32767.0 * options.gain)
            AUDIO_F2S = blocks.float_to_short()
            self.connect(AUDIO, AUDIO_DECIM, AUDIO_SCALE, AUDIO_F2S)

        if options.file1:
            IN1 = blocks.file_source(gr.sizeof_short, options.file1,
                                     options.repeat)
            S2F1 = blocks.short_to_float()
            AMP1 = blocks.multiply_const_ff(options.gain)
            F2S1 = blocks.float_to_short()
            self.connect(IN1, S2F1, AMP1, F2S1, ENCODER)
        elif not options.test:
            self.connect(AUDIO_F2S, ENCODER)

        if options.protocol == 'dmr':
            if options.file2:
                IN2 = blocks.file_source(gr.sizeof_short, options.file2,
                                         options.repeat)
                S2F2 = blocks.short_to_float()
                AMP2 = blocks.multiply_const_ff(options.gain)
                F2S2 = blocks.float_to_short()
                self.connect(IN2, S2F2, AMP2, F2S2, ENCODER2)
            else:
                self.connect(AUDIO_F2S, ENCODER2)

        MOD = p25_mod_bf(output_sample_rate=options.modulator_rate,
                         dstar=(options.protocol == 'dstar'),
                         bt=options.bt,
                         rc=RC_FILTER[options.protocol])
        AMP = blocks.multiply_const_ff(output_gain)

        if options.output_file:
            OUT = blocks.file_sink(gr.sizeof_float, options.output_file)
        elif not options.args:
            OUT = audio.sink(options.alsa_rate, options.audio_output)

        if options.symbol_sink:
            SYMBOL_SINK = blocks.file_sink(gr.sizeof_char, options.symbol_sink)
        if options.protocol == 'dmr' and not options.test:
            self.connect(DMR, MOD)
            if options.symbol_sink:
                self.connect(DMR, SYMBOL_SINK)
        else:
            self.connect(ENCODER, MOD)
            if options.symbol_sink:
                self.connect(ENCODER, SYMBOL_SINK)

        if options.args:
            self.setup_sdr_output(options, mod_adjust[options.protocol])
            f1 = float(options.if_rate) / options.modulator_rate
            i1 = int(options.if_rate / options.modulator_rate)
            if f1 - i1 > 1e-3:
                f1 = float(options.if_rate) / options.alt_modulator_rate
                i1 = int(options.if_rate / options.alt_modulator_rate)
                if f1 - i1 > 1e-3:
                    print '*** Error, sdr rate %d not an integer multiple of alt modulator rate %d - ratio=%f' % (
                        options.if_rate, options.alt_modulator_rate, f1)
                    sys.exit(0)
                a_resamp = filter.pfb.arb_resampler_fff(
                    options.alt_modulator_rate / float(options.modulator_rate))
                sys.stderr.write(
                    'adding resampler for rate change %d ===> %d\n' %
                    (options.modulator_rate, options.alt_modulator_rate))
                interp = filter.rational_resampler_fff(
                    options.if_rate / options.alt_modulator_rate, 1)
                self.connect(MOD, AMP, a_resamp, interp, self.fm_modulator,
                             self.u)
            else:
                interp = filter.rational_resampler_fff(
                    options.if_rate / options.modulator_rate, 1)
                self.connect(MOD, AMP, interp, self.fm_modulator, self.u)
        else:
            self.connect(MOD, AMP, OUT)
Exemplo n.º 8
0
    def configure_blocks(self, protocol):
        if protocol == 'provoice' or protocol == 'analog_edacs':
            protocol = 'analog'
        self.log.debug('configure_blocks(%s)' % protocol)
        if not (protocol == 'p25' or protocol == 'p25_tdma'
                or protocol == 'p25_cqpsk' or protocol == 'p25_cqpsk_tdma'
                or protocol == 'provoice' or protocol == 'dsd_p25'
                or protocol == 'analog' or protocol == 'none'):
            raise Exception('Invalid protocol %s' % protocol)
        if self.protocol == protocol:
            return True
        self.lock()
        if self.protocol == 'analog':
            self.disconnect(self.source, self.signal_squelch, self.audiodemod,
                            self.high_pass, self.resampler, self.sink)
            self.signal_squelch = None
            self.audiodemod = None
            self.high_pass = None
            self.resampler = None

        elif self.protocol == 'p25' or 'p25_tdma':
            try:
                self.disconnect(self.source, self.prefilter,
                                self.fm_demod)  #, (self.subtract,0))
                self.disconnect(self.fm_demod, self.symbol_filter,
                                self.demod_fsk4, self.slicer, self.decoder,
                                self.float_conversion, self.sink)
                self.disconnect(self.slicer, self.decoder2, self.qsink)
                self.demod_watcher.keep_running = False

            except:
                pass
            #self.disconnect(self.fm_demod, self.avg, self.mult, (self.subtract,1))

            self.prefilter = None
            self.fm_demod = None
            #self.avg = None
            #self.mult = None
            #self.subtract = None
            self.symbol_filter = None
            self.demod_fsk4 = None
            self.slicer = None
            self.decoder = None
            self.decoder2 = None
            self.qsink = None
            self.imbe = None
            self.float_conversion = None
            self.resampler = None
        elif self.protocol == 'p25_cqpsk' or self.protocol == 'p25_cqpsk_tdma':
            self.disconnect(self.source, self.resampler, self.agc,
                            self.symbol_filter_c, self.clock, self.diffdec,
                            self.to_float, self.rescale, self.slicer,
                            self.decoder2, self.qsink)  #, (self.subtract,0))
            self.disconnect(self.slicer, self.decoder, self.float_conversion,
                            self.sink)

            self.prefilter = None
            self.resampler = None
            self.agc = None
            self.symbol_filter_c = None
            self.clock = None
            self.diffdec = None
            self.to_float = None
            self.rescale = None
            self.slicer = None

            self.imbe = None
            self.decodequeue3 = None
            self.decodequeue2 = None
            self.decodequeue = None

            self.demod_watcher = None
            self.decoder = None
            self.decoder2 = None
            self.qsink = None
            self.float_conversion = None

        elif self.protocol == 'provoice':
            self.disconnect(self.source, self.fm_demod, self.resampler_in,
                            self.dsd, self.out_squelch, self.sink)
            self.fm_demod = None
            self.resampler_in = None
            self.dsd = None
            self.out_squelch = None
        elif self.protocol == 'dsd_p25':
            self.disconnect(self.source, self.fm_demod, self.resampler_in,
                            self.dsd, self.sink)
            self.fm_demod = None
            self.resampler_in = None
            self.dsd = None
        self.protocol = protocol

        if protocol == 'analog':
            self.signal_squelch = analog.pwr_squelch_cc(-100, 0.01, 0, True)
            #self.tone_squelch = gr.tone_squelch_ff(audiorate, 4800.0, 0.05, 300, 0, True)
            #tone squelch is EDACS ONLY
            self.audiodemod = analog.fm_demod_cf(
                channel_rate=self.input_rate,
                audio_decim=1,
                deviation=15000,
                audio_pass=(self.input_rate * 0.25),
                audio_stop=((self.input_rate * 0.25) + 2000),
                gain=8,
                tau=75e-6)
            self.high_pass = filter.fir_filter_fff(
                1,
                firdes.high_pass(1, self.input_rate, 300, 30,
                                 firdes.WIN_HAMMING, 6.76))
            self.resampler = filter.rational_resampler_fff(
                interpolation=8000,
                decimation=self.input_rate,
                taps=None,
                fractional_bw=None,
            )
            self.connect(self.source, self.signal_squelch, self.audiodemod,
                         self.high_pass, self.resampler, self.sink)
        elif protocol == 'p25' or protocol == 'p25_tdma':
            self.symbol_deviation = symbol_deviation = 600.0
            if protocol == 'p25_tdma':
                symbol_rate = 6000
            else:
                symbol_rate = 4800
            channel_rate = self.input_rate

            self.prefilter = filter.freq_xlating_fir_filter_ccc(
                1, (1, ), 0, self.input_rate)

            fm_demod_gain = channel_rate / (2.0 * pi * symbol_deviation)
            self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

            #self.avg = blocks.moving_average_ff(1000, 1, 4000)
            #self.mult = blocks.multiply_const_vff((0.001, ))
            #self.subtract = blocks.sub_ff(1)

            symbol_decim = 1
            samples_per_symbol = channel_rate // symbol_rate
            symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol
            self.symbol_filter = filter.fir_filter_fff(symbol_decim,
                                                       symbol_coeffs)

            autotuneq = gr.msg_queue(2)
            self.demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate,
                                                 symbol_rate)

            # symbol slicer
            levels = [-2.0, 0.0, 2.0, 4.0]
            self.slicer = op25.fsk4_slicer_fb(levels)

            self.imbe = repeater.vocoder(False, True, 0, "", 0, False)
            self.decodequeue3 = decodequeue3 = gr.msg_queue(10000)
            self.decodequeue2 = decodequeue2 = gr.msg_queue(10000)
            self.decodequeue = decodequeue = gr.msg_queue(10000)

            self.demod_watcher = None  #demod_watcher(decodequeue2, self.adjust_channel_offset)

            self.decoder = repeater.p25_frame_assembler(
                '', 0, 0, True, True, False, decodequeue2, True,
                (True if protocol == 'p25_tdma' else False))
            self.decoder2 = repeater.p25_frame_assembler(
                '', 0, 0, False, True, False, decodequeue3, False, False)

            self.qsink = blocks.message_sink(gr.sizeof_char, self.decodequeue,
                                             False)

            self.float_conversion = blocks.short_to_float(1, 8192)

            self.connect(self.source, self.prefilter,
                         self.fm_demod)  #, (self.subtract,0))
            #self.connect(self.fm_demod, self.symbol_filter, self.demod_fsk4, self.slicer, self.decoder, self.imbe, self.float_conversion, self.sink)
            self.connect(self.fm_demod, self.symbol_filter, self.demod_fsk4,
                         self.slicer, self.decoder, self.float_conversion,
                         self.sink)
            self.connect(self.slicer, self.decoder2, self.qsink)
            #self.connect(self.fm_demod, self.avg, self.mult, (self.subtract,1))
        elif protocol == 'p25_cqpsk' or protocol == 'p25_cqpsk_tdma':
            self.symbol_deviation = symbol_deviation = 600.0
            self.resampler = blocks.multiply_const_cc(1.0)
            self.agc = analog.feedforward_agc_cc(1024, 1.0)
            self.symbol_filter_c = blocks.multiply_const_cc(1.0)

            gain_mu = 0.025
            if protocol == 'p25_cqpsk_tdma':
                symbol_rate = 6000
            else:
                symbol_rate = 4800
            omega = float(self.input_rate) / float(symbol_rate)
            gain_omega = 0.1 * gain_mu * gain_mu

            alpha = 0.04
            beta = 0.125 * alpha * alpha
            fmax = 1200  # Hz
            fmax = 2 * pi * fmax / float(self.input_rate)

            self.clock = repeater.gardner_costas_cc(omega, gain_mu, gain_omega,
                                                    alpha, beta, fmax, -fmax)
            self.diffdec = digital.diff_phasor_cc()
            self.to_float = blocks.complex_to_arg()
            self.rescale = blocks.multiply_const_ff((1 / (pi / 4)))

            # symbol slicer
            levels = [-2.0, 0.0, 2.0, 4.0]
            self.slicer = op25.fsk4_slicer_fb(levels)

            #self.imbe = repeater.vocoder(False, True, 0, "", 0, False)
            self.decodequeue3 = decodequeue3 = gr.msg_queue(2)
            self.decodequeue2 = decodequeue2 = gr.msg_queue(2)
            self.decodequeue = decodequeue = gr.msg_queue(10000)

            #self.demod_watcher = demod_watcher(decodequeue2, self.adjust_channel_offset)
            self.decoder = repeater.p25_frame_assembler(
                '', 0, 0, True, True, False, decodequeue2, True,
                (False if protocol == 'p25_cqpsk' else True))
            self.decoder2 = repeater.p25_frame_assembler(
                '', 0, 0, False, True, True, decodequeue3, False, False)

            #temp for debug
            #self.debug_sink = blocks.file_sink(1, '/dev/null')
            #self.connect(self.slicer, self.debug_sink)

            self.qsink = blocks.message_sink(gr.sizeof_char, self.decodequeue,
                                             False)

            self.float_conversion = blocks.short_to_float(1, 8192)

            self.connect(self.source, self.resampler, self.agc,
                         self.symbol_filter_c, self.clock, self.diffdec,
                         self.to_float, self.rescale, self.slicer,
                         self.decoder2, self.qsink)  #, (self.subtract,0))
            self.connect(self.slicer, self.decoder, self.float_conversion,
                         self.sink)
        elif protocol == 'provoice':
            fm_demod_gain = 0.6
            self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

            self.resampler_in = filter.rational_resampler_fff(
                interpolation=48000,
                decimation=self.input_rate,
                taps=None,
                fractional_bw=None,
            )
            self.dsd = dsd.block_ff(dsd.dsd_FRAME_PROVOICE,
                                    dsd.dsd_MOD_AUTO_SELECT, 3, 0, False)
            self.out_squelch = analog.pwr_squelch_ff(-100, 0.01, 0, True)

            self.connect(self.source, self.fm_demod, self.resampler_in,
                         self.dsd, self.out_squelch, self.sink)
        elif protocol == 'dsd_p25':
            symbol_deviation = 600.0
            fm_demod_gain = 0.4  #self.input_rate / (2.0 * pi * symbol_deviation)
            self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

            self.resampler_in = filter.rational_resampler_fff(
                interpolation=48000,
                decimation=self.input_rate,
                taps=None,
                fractional_bw=None,
            )
            self.dsd = dsd.block_ff(dsd.dsd_FRAME_P25_PHASE_1,
                                    dsd.dsd_MOD_AUTO_SELECT, 3, 3, False)

            self.connect(self.source, self.fm_demod, self.resampler_in,
                         self.dsd, self.sink)
        self.unlock()