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)
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)
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)
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
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)
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))
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)
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()