def __init__(self, channel_rate, auto_tune_msgq=None): gr.hier_block2.__init__(self, "op25_fsk4", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) self.symbol_rate = SYMBOL_RATE #print "Channel rate:", channel_rate self.channel_rate = channel_rate self.auto_tune_msgq = auto_tune_msgq if self.auto_tune_msgq is None: self.auto_tune_msgq = gr.msg_queue(2) # C4FM demodulator #print "Symbol rate:", self.symbol_rate try: self.demod_fsk4 = _op25.fsk4_demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) if _verbose: print "Using new fsk4_demod_ff" except: try: self.demod_fsk4 = fsk4.demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) # LEGACY if _verbose: print "Using legacy fsk4.demod_ff" except: raise Exception("Could not find a FSK4 demodulator to use") self.connect(self, self.demod_fsk4, self)
def __init__(self, sps, channel_decim, channel_taps, options, usrp_rate, channel_rate, lo_freq): gr.hier_block2.__init__(self, "rx_channel_fm", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) chan = gr.freq_xlating_fir_filter_ccf(int(channel_decim), channel_taps, lo_freq, usrp_rate) symbol_decim = 1 symbol_rate = 4800 self.symbol_deviation = 600.0 fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) fm_demod = gr.quadrature_demod_cf(fm_demod_gain) symbol_coeffs = gr.firdes_root_raised_cosine(1.0, channel_rate, symbol_rate, 1.0, 51) symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator autotuneq = gr.msg_queue(2) demod_fsk4 = fsk4.demod_ff(autotuneq, channel_rate, symbol_rate) self.connect (self, chan, fm_demod, symbol_filter, demod_fsk4, self)
def __init__(self, channel_rate, auto_tune_msgq=None): gr.hier_block2.__init__(self, "op25_fsk4", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) self.symbol_rate = SYMBOL_RATE #print "[OP25] Channel rate:", channel_rate self.channel_rate = channel_rate self.auto_tune_msgq = auto_tune_msgq self.auto_tune_message_callback = None if self.auto_tune_msgq is None: self.auto_tune_msgq = gr.msg_queue(2) self.auto_tune_message_callback = message_callback.message_callback(self.auto_tune_msgq) # C4FM demodulator #print "[OP25] Symbol rate:", self.symbol_rate try: self.demod_fsk4 = op25.fsk4_demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) if _verbose: print "[OP25] Using new fsk4_demod_ff" except Exception, e: print "[OP25] New fsk4_demod_ff not available:", e try: self.demod_fsk4 = fsk4.demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) # LEGACY if _verbose: print "[OP25] Using legacy fsk4.demod_ff" except Exception, e: print e raise Exception("Could not find a FSK4 demodulator to use")
def __init__(self, channel_rate, auto_tune_msgq=None): gr.hier_block2.__init__(self, "op25_fsk4", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) self.symbol_rate = SYMBOL_RATE #print "[OP25] Channel rate:", channel_rate self.channel_rate = channel_rate self.auto_tune_msgq = auto_tune_msgq self.auto_tune_message_callback = None if self.auto_tune_msgq is None: self.auto_tune_msgq = gr.msg_queue(2) self.auto_tune_message_callback = message_callback.message_callback( self.auto_tune_msgq) # C4FM demodulator #print "[OP25] Symbol rate:", self.symbol_rate try: self.demod_fsk4 = op25.fsk4_demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) if _verbose: print "[OP25] Using new fsk4_demod_ff" except Exception, e: print "[OP25] New fsk4_demod_ff not available:", e try: self.demod_fsk4 = fsk4.demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) # LEGACY if _verbose: print "[OP25] Using legacy fsk4.demod_ff" except Exception, e: print e raise Exception("Could not find a FSK4 demodulator to use")
def __init__(self, options, queue): gr.top_block.__init__(self, "usrp_flex") self.options = options self.offset = 0.0 self.file_offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose if options.from_file is None: self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + '' ) self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_center_freq(options.frequency, 0) self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_dc_offset_mode(0, 0) self.rtlsdr_source_0.set_iq_balance_mode(0, 0) self.rtlsdr_source_0.set_gain_mode(True, 0) self.rtlsdr_source_0.set_gain(50, 0) self.rtlsdr_source_0.set_if_gain(20, 0) self.rtlsdr_source_0.set_bb_gain(20, 0) self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_bandwidth(0, 0) else: # Use supplied file as source of samples self.file_offset = options.calibration print "File input offset", self.offset self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file) if options.verbose: print "Reading samples from", options.from_file if options.log and not options.from_file: usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat') self.connect(self.src, usrp_sink) # following is rig to allow fast and easy swapping of signal configuration # blocks between this example and the oscope example which uses self.msgq self.msgq = queue #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f(self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass(1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 20 # decimation self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter channel_taps = optfir.low_pass(1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ---------- End of configuration if options.verbose: print "Channel filter has", len(channel_taps), "taps." self.chan = gr.freq_xlating_fir_filter_ccf(self.channel_decimation , # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf (self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff (symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate , self.symbol_rate) if options.log: chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat') self.connect(self.chan, chan_sink) if options.log: chan_sink2 = gr.file_sink(gr.sizeof_float, 'demod.dat') self.connect(self.demod_fsk4, chan_sink2) self.connect(self.src, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing)
def create(self): self.op25_msgq = gr.msg_queue(2) self.slicer = None try: levels = [ -2.0, 0.0, 2.0, 4.0 ] self.slicer = _op25.fsk4_slicer_fb(levels) self.p25_decoder = _op25.decoder_bf() # FIXME: Message queue? if _verbose: print "Using new decoder_bf" except: try: self.p25_decoder = _op25.decoder_ff(self.op25_msgq) # LEGACY if _verbose: print "Using legacy decoder_ff" except: raise Exception("Could not find a decoder to use") # Reference code #self.decode_watcher = decode_watcher(self.op25_msgq, self.traffic) if (self.key is not None) and (len(self.key) > 0): # Relates to key string passed in from GRC block self.set_key(self.key) # Reference code #trans_width = 12.5e3 / 2; #trans_centre = trans_width + (trans_width / 2) # discriminator tap doesn't do freq. xlation, FM demodulation, etc. # coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN) # self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, 0.0, capture_rate) # self.set_channel_offset(0.0, 0, self.spectrum.win._units) # # power squelch # squelch_db = 0 # self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True) # self.set_squelch_threshold(squelch_db) # # FM demodulator # fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) # fm_demod = gr.quadrature_demod_cf(fm_demod_gain) # symbol filter #symbol_decim = 1 #symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500) # boxcar coefficients for "integrate and dump" filter #samples_per_symbol = channel_rate // self.symbol_rate #symbol_duration = float(self.symbol_rate) / channel_rate #print "Symbol duration:", symbol_duration #print "Samples per symbol:", samples_per_symbol #symbol_coeffs = (1.0/samples_per_symbol,)*samples_per_symbol #self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator #print "Symbol rate:", self.symbol_rate if self.auto_tune_msgq is None: self.auto_tune_msgq = gr.msg_queue(2) try: self.demod_fsk4 = _op25.fsk4_demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) if _verbose: print "Using new fsk4_demod_ff" except: try: self.demod_fsk4 = fsk4.demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) # LEGACY if _verbose: print "Using legacy fsk4.demod_ff" except: raise Exception("Could not find a FSK4 demodulator to use") # Reference code #self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset) #list = [[self, self.channel_filter, self.squelch, fm_demod, self.symbol_filter, demod_fsk4, self.p25_decoder, self.sink]] self.connect(self, self.demod_fsk4) if self.slicer: self.connect(self.demod_fsk4, self.slicer) self.connect(self.slicer, self.p25_decoder) else: self.connect(self.demod_fsk4, self.p25_decoder) self.connect(self.p25_decoder, (self, 0)) if self.output_dibits: self.connect(self.demod_fsk4, (self, 1))
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)
def create(self): self.op25_msgq = gr.msg_queue(2) self.slicer = None try: levels = [-2.0, 0.0, 2.0, 4.0] self.slicer = _op25.fsk4_slicer_fb(levels) self.p25_decoder = _op25.decoder_bf() # FIXME: Message queue? if _verbose: print "Using new decoder_bf" except: try: self.p25_decoder = _op25.decoder_ff(self.op25_msgq) # LEGACY if _verbose: print "Using legacy decoder_ff" except: raise Exception("Could not find a decoder to use") # Reference code #self.decode_watcher = decode_watcher(self.op25_msgq, self.traffic) if (self.key is not None) and ( len(self.key) > 0): # Relates to key string passed in from GRC block self.set_key(self.key) # Reference code #trans_width = 12.5e3 / 2; #trans_centre = trans_width + (trans_width / 2) # discriminator tap doesn't do freq. xlation, FM demodulation, etc. # coeffs = gr.firdes.low_pass(1.0, capture_rate, trans_centre, trans_width, gr.firdes.WIN_HANN) # self.channel_filter = gr.freq_xlating_fir_filter_ccf(channel_decim, coeffs, 0.0, capture_rate) # self.set_channel_offset(0.0, 0, self.spectrum.win._units) # # power squelch # squelch_db = 0 # self.squelch = gr.pwr_squelch_cc(squelch_db, 1e-3, 0, True) # self.set_squelch_threshold(squelch_db) # # FM demodulator # fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) # fm_demod = gr.quadrature_demod_cf(fm_demod_gain) # symbol filter #symbol_decim = 1 #symbol_coeffs = gr.firdes.root_raised_cosine(1.0, channel_rate, self.symbol_rate, 0.2, 500) # boxcar coefficients for "integrate and dump" filter #samples_per_symbol = channel_rate // self.symbol_rate #symbol_duration = float(self.symbol_rate) / channel_rate #print "Symbol duration:", symbol_duration #print "Samples per symbol:", samples_per_symbol #symbol_coeffs = (1.0/samples_per_symbol,)*samples_per_symbol #self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # C4FM demodulator #print "Symbol rate:", self.symbol_rate if self.auto_tune_msgq is None: self.auto_tune_msgq = gr.msg_queue(2) try: self.demod_fsk4 = _op25.fsk4_demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) if _verbose: print "Using new fsk4_demod_ff" except: try: self.demod_fsk4 = fsk4.demod_ff(self.auto_tune_msgq, self.channel_rate, self.symbol_rate) # LEGACY if _verbose: print "Using legacy fsk4.demod_ff" except: raise Exception("Could not find a FSK4 demodulator to use") # Reference code #self.demod_watcher = demod_watcher(autotuneq, self.adjust_channel_offset) #list = [[self, self.channel_filter, self.squelch, fm_demod, self.symbol_filter, demod_fsk4, self.p25_decoder, self.sink]] self.connect(self, self.demod_fsk4) if self.slicer: self.connect(self.demod_fsk4, self.slicer) self.connect(self.slicer, self.p25_decoder) else: self.connect(self.demod_fsk4, self.p25_decoder) self.connect(self.p25_decoder, (self, 0)) if self.output_dibits: self.connect(self.demod_fsk4, (self, 1))
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel self.offset = 0.0 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=first one with a daughterboard)" ) parser.add_option( "-d", "--decim", type="int", default=256, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option( "-p", "--protocol", type="int", default=0, help="set protocol: 0 = RDLAP 19.2kbps (default); 1 = APCO25") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option("--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") parser.add_option( "-C", "--basic-complex", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as a single Complex input channel" ) parser.add_option( "-D", "--basic-dualchan", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as seperate Real input channels" ) parser.add_option( "-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") parser.add_option( "-v", "--v-scale", type="eng_float", default=1000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option( "-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True # build the graph if options.basic_dualchan: self.num_inputs = 2 else: self.num_inputs = 1 if options.no_hb or (options.decim < 8): #Min decimation of this firmware is 4. #contains 4 Rx paths without halfbands and 0 tx paths. self.fpga_filename = "std_4rx_0tx.rbf" self.u = usrp.source_c(nchan=self.num_inputs, decim_rate=options.decim, fpga_filename=self.fpga_filename) else: #Min decimation of standard firmware is 8. #standard fpga firmware "std_2rxhb_2tx.rbf" #contains 2 Rx paths with halfband filters and 2 tx paths (the default) self.u = usrp.source_c(nchan=self.num_inputs, decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.u) if options.width_8: width = 8 shift = 8 format = self.u.make_format(width, shift) #print "format =", hex(format) r = self.u.set_format(format) #print "set_format =", r # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) if (options.basic_complex or options.basic_dualchan): if ((self.subdev.dbid() == usrp_dbid.BASIC_RX) or (self.subdev.dbid() == usrp_dbid.LF_RX)): side = options.rx_subdev_spec[0] # side A = 0, side B = 1 if options.basic_complex: #force Basic_RX and LF_RX in complex mode (use both I and Q channel) print "Receiver daughterboard forced in complex mode. Both inputs will combined to form a single complex channel." self.dualchan = False if side == 0: self.u.set_mux( 0x00000010 ) #enable adc 0 and 1 to form a single complex input on side A else: #side ==1 self.u.set_mux( 0x00000032 ) #enable adc 3 and 2 to form a single complex input on side B elif options.basic_dualchan: #force Basic_RX and LF_RX in dualchan mode (use input A for channel 0 and input B for channel 1) print "Receiver daughterboard forced in dualchannel mode. Each input will be used to form a seperate channel." self.dualchan = True if side == 0: self.u.set_mux( gru.hexint(0xf0f0f1f0) ) #enable adc 0, side A to form a real input on channel 0 and adc1,side A to form a real input on channel 1 else: #side ==1 self.u.set_mux( 0xf0f0f3f2 ) #enable adc 2, side B to form a real input on channel 0 and adc3,side B to form a real input on channel 1 else: sys.stderr.write( 'options basic_dualchan or basic_complex is only supported for Basic Rx or LFRX at the moment\n' ) sys.exit(1) else: self.dualchan = False self.u.set_mux( usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) input_rate = self.u.adc_freq() / self.u.decim_rate() self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) if self.dualchan: # deinterleave two channels from FPGA self.di = gr.deinterleave(gr.sizeof_gr_complex) self.connect(self.u, self.di) self.connect((self.di, 0), (self.scope, 0)) self.connect((self.di, 1), (self.scope, 1)) else: self.connect(self.u, self.scope) self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages self.queue_watcher = queue_watcher(self.msgq, self.adjust_freq_norm) #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f( self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 20 # decimation self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ----------------- End of setup block self.chan = gr.freq_xlating_fir_filter_ccf( self.channel_decimation, # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate self.scope2 = scopesink2.scope_sink_f(panel, sample_rate=self.symbol_rate, frame_decim=1, v_scale=2, t_scale=0.025, num_inputs=self.num_inputs) # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf(self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate, self.symbol_rate) #self.rdlap_processing = fsk4.rdlap_f(self.msgq, 0) self.connect(self.u, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing) self.connect(self.demod_fsk4, self.scope2) # --------------- End of most of the 4L-FSK hack & slash self._build_gui(vbox) # set initial values if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.subdev.gain_range() options.gain = float(g[0] + g[1]) / 2 if options.freq is None: if ((self.subdev.dbid() == usrp_dbid.BASIC_RX) or (self.subdev.dbid() == usrp_dbid.LF_RX)): #for Basic RX and LFRX if no freq is specified you probably want 0.0 Hz and not 45 GHz options.freq = 0.0 else: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0] + r[1]) / 2 self.set_gain(options.gain) if self.show_debug_info: # self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if self.num_inputs == 2: self.myform['baseband2'].set_value(0) self.myform['ddc2'].set_value(0) if not (self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") if self.num_inputs == 2: if not (self.set_freq2(options.freq)): self._set_status_msg( "Failed to set initial frequency for channel 2")
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel self.offset = 0.0 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=first one with a daughterboard)" ) parser.add_option( "-d", "--decim", type="int", default=1, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option( "-p", "--protocol", type="int", default=0, help="set protocol: 0 = RDLAP 19.2kbps (default); 1 = APCO25") parser.add_option("-g", "--gain", type="eng_float", default=1, help="set gain multiplier") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option("--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") parser.add_option( "-C", "--basic-complex", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as a single Complex input channel" ) parser.add_option( "-D", "--basic-dualchan", action="store_true", default=False, help= "Use both inputs of a basicRX or LFRX as seperate Real input channels" ) parser.add_option( "-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") 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("-s", "--sample-rate", type="int", default=48000, help="sound card input sample rate") parser.add_option( "-v", "--v-scale", type="eng_float", default=1000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option( "-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True # build the graph self.num_inputs = 1 self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 1 # decimation (final rate should be at least several symbol rate) self.input_sample_rate = options.sample_rate / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f( self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 1 # decimation self.input_sample_rate = options.sample_rate / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ----------------- End of setup block self.audio_input = audio.source(options.sample_rate, options.audio_input) self.audio_gain = gr.multiply_const_ff(options.gain) self.scope2 = scopesink2.scope_sink_f(panel, sample_rate=self.symbol_rate, frame_decim=1, v_scale=2, t_scale=0.025, num_inputs=self.num_inputs) # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate, self.symbol_rate) #self.rdlap_processing = fsk4.rdlap_f(self.msgq, 0) self.connect(self.audio_input, self.audio_gain, self.symbol_filter, self.demod_fsk4, self.protocol_processing) self.connect(self.demod_fsk4, self.scope2) # --------------- End of most of the 4L-FSK hack & slash self._build_gui(vbox) # set initial values self.set_gain(options.gain) if self.show_debug_info: # self.myform['decim'].set_value(self.u.decim_rate()) self.myform['dbname'].set_value("alsa") self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if self.num_inputs == 2: self.myform['baseband2'].set_value(0) self.myform['ddc2'].set_value(0)
def __init__(self, options, queue): gr.top_block.__init__(self, "usrp_flex") self.options = options self.offset = 0.0 self.file_offset = 0.0 self.adj_time = time.time() self.verbose = options.verbose if options.from_file is None: # Set up USRP source with specified RX daughterboard self.src = usrp.source_c() if options.rx_subdev_spec == None: options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src) self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) self.src.set_mux( usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) # set FPGA decimation rate self.src.set_decim_rate(options.decim) # If no gain specified, set to midrange if options.gain is None: g = self.subdev.gain_range() options.gain = (g[0] + g[1]) / 2.0 self.subdev.set_gain(options.gain) # Tune daughterboard actual_frequency = options.frequency + options.calibration tune_result = usrp.tune(self.src, 0, self.subdev, actual_frequency) if not tune_result: sys.stderr.write("Failed to set center frequency to " + ` actual_frequency ` + "\n") sys.exit(1) if options.verbose: print "Using RX daughterboard", self.subdev.side_and_name() print "USRP gain is", options.gain print "USRP tuned to", actual_frequency else: # Use supplied file as source of samples self.file_offset = options.calibration print "File input offset", self.offset self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file) if options.verbose: print "Reading samples from", options.from_file if options.log and not options.from_file: usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat') self.connect(self.src, usrp_sink) # following is rig to allow fast and easy swapping of signal configuration # blocks between this example and the oscope example which uses self.msgq self.msgq = queue #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f( self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 20 # decimation self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = 64e6 / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ---------- End of configuration if options.verbose: print "Channel filter has", len(channel_taps), "taps." self.chan = gr.freq_xlating_fir_filter_ccf( self.channel_decimation, # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf(self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate, self.symbol_rate) if options.log: chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat') self.connect(self.chan, chan_sink) if options.log: chan_sink2 = gr.file_sink(gr.sizeof_float, 'demod.dat') self.connect(self.demod_fsk4, chan_sink2) self.connect(self.src, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing)
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel self.offset = 0.0 # Channel frequency offset parser = OptionParser(option_class=eng_option) parser.add_option( "-p", "--protocol", type="int", default=1, help="set protocol: 0 = RDLAP 19.2kbps; 1 = APCO25 (default)") parser.add_option("-g", "--gain", type="eng_float", default=1.0, help="set linear input gain (default: %default)") parser.add_option("-x", "--freq-translation", type="eng_float", default=0.0, help="initial channel frequency translation") parser.add_option( "-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") parser.add_option( "-v", "--v-scale", type="eng_float", default=5000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option( "-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") 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("-r", "--sample-rate", type="eng_float", default=48000, help="set sample rate to RATE (default: %default)") parser.add_option( "-d", "--channel-decim", type="int", default=None, help= "set channel decimation factor to n [default depends on protocol]") parser.add_option("-w", "--wav-file", type="string", default=None, help="WAV input path") parser.add_option("-f", "--data-file", type="string", default=None, help="Data input path") parser.add_option("-B", "--base-band", action="store_true", default=False) parser.add_option("-R", "--repeat", action="store_true", default=False) parser.add_option("-o", "--wav-out", type="string", default=None, help="WAV output path") parser.add_option("-G", "--wav-out-gain", type="eng_float", default=0.05, help="set WAV output gain (default: %default)") parser.add_option("-F", "--data-out", type="string", default=None, help="Data output path") parser.add_option("-C", "--carrier-freq", type="eng_float", default=None, help="set data output carrier frequency to FREQ", metavar="FREQ") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.options = options if options.wav_file is not None: #try: self.input_file = gr.wavfile_source(options.wav_file, options.repeat) #except: # print "WAV file not found or not a WAV file" # sys.exit(1) print "WAV input: %i Hz, %i bits, %i channels" % ( self.input_file.sample_rate(), self.input_file.bits_per_sample(), self.input_file.channels()) self.sample_rate = self.input_file.sample_rate() self.input_stream = gr.throttle(gr.sizeof_float, self.sample_rate) self.connect(self.input_file, self.input_stream) self.src = gr.multiply_const_ff(options.gain) elif options.data_file is not None: if options.base_band: sample_size = gr.sizeof_float print "Data file is baseband (float)" self.src = gr.multiply_const_ff(options.gain) else: sample_size = gr.sizeof_gr_complex print "Data file is IF (complex)" self.src = gr.multiply_const_cc(options.gain) self.input_file = gr.file_source(sample_size, options.data_file, options.repeat) self.sample_rate = options.sample_rate # E.g. 250000 print "Data file sampling rate = " + str(self.sample_rate) self.input_stream = gr.throttle(sample_size, self.sample_rate) self.connect(self.input_file, self.input_stream) else: self.sample_rate = options.sample_rate print "Soundcard sampling rate = " + str(self.sample_rate) self.input_stream = audio.source( self.sample_rate, options.audio_input) # float samples self.src = gr.multiply_const_ff(options.gain) print "Fixed input gain = " + str(options.gain) self.connect(self.input_stream, self.src) if options.wav_out is not None: output_rate = int(self.sample_rate) if options.channel_decim is not None: output_rate /= options.channel_decim self.wav_out = gr.wavfile_sink(options.wav_out, 1, output_rate, 16) print "Opened WAV output file: " + options.wav_out + " at rate: " + str( output_rate) else: self.wav_out = None if options.data_out is not None: if options.carrier_freq is None: self.data_out = gr.file_sink(gr.sizeof_float, options.data_out) print "Opened float data output file: " + options.data_out else: self.data_out = gr.file_sink(gr.sizeof_gr_complex, options.data_out) print "Opened complex data output file: " + options.data_out else: self.data_out = None self.num_inputs = 1 input_rate = self.sample_rate #title='IF', #size=(1024,800), if (options.data_file is not None) and (options.base_band == False): self.scope = scopesink2.scope_sink_c( panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) else: self.scope = scopesink2.scope_sink_f( panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) #self.di = gr.deinterleave(gr.sizeof_float) #self.di = gr.complex_to_float(1) #self.di = gr.complex_to_imag() #self.dr = gr.complex_to_real() #self.connect(self.src,self.dr) #self.connect(self.src,self.di) #self.null = gr.null_sink(gr.sizeof_double) #self.connect(self.src,self.di) #self.connect((self.di,0),(self.scope,0)) #self.connect((self.di,1),(self.scope,1)) #self.connect(self.dr,(self.scope,0)) #self.connect(self.di,(self.scope,1)) self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages self.queue_watcher = queue_watcher(self.msgq, self.adjust_freq_norm) #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, print "RD-LAP selected" self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps if options.channel_decim is None: self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) else: self.channel_decimation = options.channel_decim self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = self.sample_rate self.protocol_processing = fsk4.rdlap_f( self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # alpha 500) # taps if options.protocol == 1: # ---------- APCO-25 C4FM Test Data print "APCO selected" self.symbol_rate = 4800 # symbol rate if options.channel_decim is None: self.channel_decimation = 20 # decimation else: self.channel_decimation = options.channel_decim self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = self.sample_rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter if (options.data_file is not None) and (options.base_band == False): channel_taps = optfir.low_pass( 1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.2, # Passband ripple (was 0.1) 60) # Stopband attenuation else: channel_taps = None # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # alpha 500) # taps # ----------------- End of setup block print "Input rate = " + str(self.input_sample_rate) print "Channel decimation = " + str(self.channel_decimation) print "Channel rate = " + str(self.channel_rate) if channel_taps is not None: self.chan = gr.freq_xlating_fir_filter_ccf( self.channel_decimation, # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate if (options.freq_translation != 0): print "Channel center frequency = " + str( options.freq_translation) self.chan.set_center_freq(options.freq_translation) else: self.chan = None if options.carrier_freq is not None: print "Carrier frequency = " + str(options.carrier_freq) self.sig_carrier = gr.sig_source_c(self.channel_rate, gr.GR_COS_WAVE, options.carrier_freq, 1, 0) self.carrier_mul = gr.multiply_vcc(1) # cc(gr.sizeof_gr_complex) self.connect(self.sig_carrier, (self.carrier_mul, 0)) self.connect(self.chan, (self.carrier_mul, 1)) self.sig_i_carrier = gr.sig_source_f(self.channel_rate, gr.GR_COS_WAVE, options.carrier_freq, 1, 0) self.sig_q_carrier = gr.sig_source_f(self.channel_rate, gr.GR_COS_WAVE, options.carrier_freq, 1, (pi / 2.0)) self.carrier_i_mul = gr.multiply_ff(1) self.carrier_q_mul = gr.multiply_ff(1) self.iq_to_float = gr.complex_to_float(1) self.carrier_iq_add = gr.add_ff(1) self.connect(self.carrier_mul, self.iq_to_float) self.connect((self.iq_to_float, 0), (self.carrier_i_mul, 0)) self.connect((self.iq_to_float, 1), (self.carrier_q_mul, 0)) self.connect(self.sig_i_carrier, (self.carrier_i_mul, 1)) self.connect(self.sig_q_carrier, (self.carrier_q_mul, 1)) self.connect(self.carrier_i_mul, (self.carrier_iq_add, 0)) self.connect(self.carrier_q_mul, (self.carrier_iq_add, 1)) else: self.sig_carrier = None self.carrier_mul = None #lf_channel_taps = optfir.low_pass(1.0, # Filter gain # self.input_sample_rate, # Sample rate # 2500, # One-sided modulation bandwidth # 3250, # One-sided channel bandwidth # 0.1, # Passband ripple (0.1) # 60, # Stopband attenuation # 9) # Extra taps (default 2, which doesn't work at 48kHz) #self.lf = gr.fir_filter_fff(self.channel_decimation, lf_channel_taps) self.scope2 = scopesink2.scope_sink_f(panel, sample_rate=self.symbol_rate, frame_decim=1, v_scale=2, t_scale=0.025, num_inputs=self.num_inputs) # also note: this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf(self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate, self.symbol_rate) if (self.chan is not None): self.connect(self.src, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing) if options.wav_out is not None: print "WAV output gain = " + str(options.wav_out_gain) self.scaled_wav_data = gr.multiply_const_ff( float(options.wav_out_gain)) self.connect(self.scaled_wav_data, self.wav_out) if self.carrier_mul is None: self.connect(self.fm_demod, self.scaled_wav_data) else: self.connect(self.carrier_iq_add, self.scaled_wav_data) if self.data_out is not None: if self.carrier_mul is None: self.connect(self.fm_demod, self.data_out) else: self.connect(self.carrier_mul, self.data_out) # During signal, -4..4 #self.connect(self.fm_demod, self.scope2) else: self.connect(self.src, self.symbol_filter, self.demod_fsk4, self.protocol_processing) self.connect(self.src, self.scope) #self.connect(self.lf, self.scope) self.connect(self.demod_fsk4, self.scope2) #self.connect(self.symbol_filter, self.scope2) # --------------- End of most of the 4L-FSK hack & slash self._build_gui(vbox) # set initial values if options.gain is None: options.gain = 0 self.set_gain(options.gain)
def __init__( self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__( self, frame, panel, vbox, argv) self.frame = frame self.panel = panel self.offset = 0.0 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=first one with a daughterboard)") parser.add_option("-d", "--decim", type="int", default=1, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-p", "--protocol", type="int", default=0, help="set protocol: 0 = RDLAP 19.2kbps (default); 1 = APCO25") parser.add_option("-g", "--gain", type="eng_float", default=1, help="set gain multiplier") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option( "--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") parser.add_option("-C", "--basic-complex", action="store_true", default=False, help="Use both inputs of a basicRX or LFRX as a single Complex input channel") parser.add_option("-D", "--basic-dualchan", action="store_true", default=False, help="Use both inputs of a basicRX or LFRX as seperate Real input channels") parser.add_option("-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") 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("-s", "--sample-rate", type="int", default=48000, help="sound card input sample rate") parser.add_option("-v", "--v-scale", type="eng_float", default=1000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True # build the graph self.num_inputs=1 self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 1 # decimation (final rate should be at least several symbol rate) self.input_sample_rate = options.sample_rate / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.rdlap_f(self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type if options.protocol == 1: # ---------- APCO-25 C4FM Test Data self.symbol_rate = 4800 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps self.channel_decimation = 1 # decimation self.input_sample_rate = options.sample_rate / options.decim # for USRP: 64MHz / FPGA decimation rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type # ----------------- End of setup block self.audio_input = audio.source(options.sample_rate, options.audio_input) self.audio_gain = gr.multiply_const_ff(options.gain) self.scope2 = scopesink2.scope_sink_f(panel, sample_rate=self.symbol_rate, frame_decim=1, v_scale=2, t_scale= 0.025, num_inputs=self.num_inputs) # also note: # this specifies the nominal frequency deviation for the 4-level fsk signal symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff (symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate , self.symbol_rate) #self.rdlap_processing = fsk4.rdlap_f(self.msgq, 0) self.connect(self.audio_input, self.audio_gain, self.symbol_filter, self.demod_fsk4, self.protocol_processing) self.connect(self.demod_fsk4, self.scope2) # --------------- End of most of the 4L-FSK hack & slash self._build_gui(vbox) # set initial values self.set_gain(options.gain) if self.show_debug_info: # self.myform['decim'].set_value(self.u.decim_rate()) self.myform['dbname'].set_value("alsa") self.myform['baseband'].set_value(0) self.myform['ddc'].set_value(0) if self.num_inputs==2: self.myform['baseband2'].set_value(0) self.myform['ddc2'].set_value(0)
def __init__( self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__( self, frame, panel, vbox, argv) self.frame = frame self.panel = panel self.offset = 0.0 # Channel frequency offset parser = OptionParser(option_class=eng_option) parser.add_option("-p", "--protocol", type="int", default=1, help="set protocol: 0 = RDLAP 19.2kbps; 1 = APCO25 (default)") parser.add_option("-g", "--gain", type="eng_float", default=1.0, help="set linear input gain (default: %default)") parser.add_option("-x", "--freq-translation", type="eng_float", default=0.0, help="initial channel frequency translation") parser.add_option("-n", "--frame-decim", type="int", default=1, help="set oscope frame decimation factor to n [default=1]") parser.add_option("-v", "--v-scale", type="eng_float", default=5000, help="set oscope initial V/div to SCALE [default=%default]") parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6, help="set oscope initial s/div to SCALE [default=50us]") 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("-r", "--sample-rate", type="eng_float", default=48000, help="set sample rate to RATE (default: %default)") parser.add_option("-d", "--channel-decim", type="int", default=None, help="set channel decimation factor to n [default depends on protocol]") parser.add_option("-w", "--wav-file", type="string", default=None, help="WAV input path") parser.add_option("-f", "--data-file", type="string", default=None, help="Data input path") parser.add_option("-B", "--base-band", action="store_true", default=False) parser.add_option("-R", "--repeat", action="store_true", default=False) parser.add_option("-o", "--wav-out", type="string", default=None, help="WAV output path") parser.add_option("-G", "--wav-out-gain", type="eng_float", default=0.05, help="set WAV output gain (default: %default)") parser.add_option("-F", "--data-out", type="string", default=None, help="Data output path") parser.add_option("-C", "--carrier-freq", type="eng_float", default=None, help="set data output carrier frequency to FREQ", metavar="FREQ") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.options = options if options.wav_file is not None: #try: self.input_file = gr.wavfile_source(options.wav_file, options.repeat) #except: # print "WAV file not found or not a WAV file" # sys.exit(1) print "WAV input: %i Hz, %i bits, %i channels" % (self.input_file.sample_rate(), self.input_file.bits_per_sample(), self.input_file.channels()) self.sample_rate = self.input_file.sample_rate() self.input_stream = gr.throttle(gr.sizeof_float, self.sample_rate) self.connect(self.input_file, self.input_stream) self.src = gr.multiply_const_ff(options.gain) elif options.data_file is not None: if options.base_band: sample_size = gr.sizeof_float print "Data file is baseband (float)" self.src = gr.multiply_const_ff(options.gain) else: sample_size = gr.sizeof_gr_complex print "Data file is IF (complex)" self.src = gr.multiply_const_cc(options.gain) self.input_file = gr.file_source(sample_size, options.data_file, options.repeat) self.sample_rate = options.sample_rate # E.g. 250000 print "Data file sampling rate = " + str(self.sample_rate) self.input_stream = gr.throttle(sample_size, self.sample_rate) self.connect(self.input_file, self.input_stream) else: self.sample_rate = options.sample_rate print "Soundcard sampling rate = " + str(self.sample_rate) self.input_stream = audio.source(self.sample_rate, options.audio_input) # float samples self.src = gr.multiply_const_ff(options.gain) print "Fixed input gain = " + str(options.gain) self.connect(self.input_stream, self.src) if options.wav_out is not None: output_rate = int(self.sample_rate) if options.channel_decim is not None: output_rate /= options.channel_decim self.wav_out = gr.wavfile_sink(options.wav_out, 1, output_rate, 16) print "Opened WAV output file: " + options.wav_out + " at rate: " + str(output_rate) else: self.wav_out = None if options.data_out is not None: if options.carrier_freq is None: self.data_out = gr.file_sink(gr.sizeof_float, options.data_out) print "Opened float data output file: " + options.data_out else: self.data_out = gr.file_sink(gr.sizeof_gr_complex, options.data_out) print "Opened complex data output file: " + options.data_out else: self.data_out = None self.num_inputs = 1 input_rate = self.sample_rate #title='IF', #size=(1024,800), if (options.data_file is not None) and (options.base_band == False): self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) else: self.scope = scopesink2.scope_sink_f(panel, sample_rate=input_rate, frame_decim=options.frame_decim, v_scale=options.v_scale, t_scale=options.t_scale, num_inputs=self.num_inputs) #self.di = gr.deinterleave(gr.sizeof_float) #self.di = gr.complex_to_float(1) #self.di = gr.complex_to_imag() #self.dr = gr.complex_to_real() #self.connect(self.src,self.dr) #self.connect(self.src,self.di) #self.null = gr.null_sink(gr.sizeof_double) #self.connect(self.src,self.di) #self.connect((self.di,0),(self.scope,0)) #self.connect((self.di,1),(self.scope,1)) #self.connect(self.dr,(self.scope,0)) #self.connect(self.di,(self.scope,1)) self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages self.queue_watcher = queue_watcher(self.msgq, self.adjust_freq_norm) #------------------------------------------------------------------------------- if options.protocol == 0: # ---------- RD-LAP 19.2 kbps (9600 ksps), 25kHz channel, print "RD-LAP selected" self.symbol_rate = 9600 # symbol rate; at 2 bits/symbol this corresponds to 19.2kbps if options.channel_decim is None: self.channel_decimation = 10 # decimation (final rate should be at least several symbol rate) else: self.channel_decimation = options.channel_decim self.max_frequency_offset = 12000.0 # coarse carrier tracker leash, ~ half a channel either way self.symbol_deviation = 1200.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = self.sample_rate self.protocol_processing = fsk4.rdlap_f(self.msgq, 0) # desired protocol processing block selected here self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter characteristics channel_taps = optfir.low_pass(1.0, # Filter gain self.input_sample_rate, # Sample rate 10000, # One-sided modulation bandwidth 12000, # One-sided channel bandwidth 0.1, # Passband ripple 60) # Stopband attenuation # symbol shaping filter characteristics symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate , # sampling rate self.symbol_rate, # symbol rate 0.2, # alpha 500) # taps if options.protocol == 1: # ---------- APCO-25 C4FM Test Data print "APCO selected" self.symbol_rate = 4800 # symbol rate if options.channel_decim is None: self.channel_decimation = 20 # decimation else: self.channel_decimation = options.channel_decim self.max_frequency_offset = 6000.0 # coarse carrier tracker leash self.symbol_deviation = 600.0 # this is frequency offset from center of channel to +1 / -1 symbols self.input_sample_rate = self.sample_rate self.protocol_processing = fsk4.apco25_f(self.msgq, 0) self.channel_rate = self.input_sample_rate / self.channel_decimation # channel selection filter if (options.data_file is not None) and (options.base_band == False): channel_taps = optfir.low_pass(1.0, # Filter gain self.input_sample_rate, # Sample rate 5000, # One-sided modulation bandwidth 6500, # One-sided channel bandwidth 0.2, # Passband ripple (was 0.1) 60) # Stopband attenuation else: channel_taps = None # symbol shaping filter symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain self.channel_rate, # sampling rate self.symbol_rate, # symbol rate 0.2, # alpha 500) # taps # ----------------- End of setup block print "Input rate = " + str(self.input_sample_rate) print "Channel decimation = " + str(self.channel_decimation) print "Channel rate = " + str(self.channel_rate) if channel_taps is not None: self.chan = gr.freq_xlating_fir_filter_ccf(self.channel_decimation, # Decimation rate channel_taps, # Filter taps 0.0, # Offset frequency self.input_sample_rate) # Sample rate if (options.freq_translation != 0): print "Channel center frequency = " + str(options.freq_translation) self.chan.set_center_freq(options.freq_translation) else: self.chan = None if options.carrier_freq is not None: print "Carrier frequency = " + str(options.carrier_freq) self.sig_carrier = gr.sig_source_c(self.channel_rate, gr.GR_COS_WAVE, options.carrier_freq, 1, 0) self.carrier_mul = gr.multiply_vcc(1) # cc(gr.sizeof_gr_complex) self.connect(self.sig_carrier, (self.carrier_mul, 0)) self.connect(self.chan, (self.carrier_mul, 1)) self.sig_i_carrier = gr.sig_source_f(self.channel_rate, gr.GR_COS_WAVE, options.carrier_freq, 1, 0) self.sig_q_carrier = gr.sig_source_f(self.channel_rate, gr.GR_COS_WAVE, options.carrier_freq, 1, (pi / 2.0)) self.carrier_i_mul = gr.multiply_ff(1) self.carrier_q_mul = gr.multiply_ff(1) self.iq_to_float = gr.complex_to_float(1) self.carrier_iq_add = gr.add_ff(1) self.connect(self.carrier_mul, self.iq_to_float) self.connect((self.iq_to_float, 0), (self.carrier_i_mul, 0)) self.connect((self.iq_to_float, 1), (self.carrier_q_mul, 0)) self.connect(self.sig_i_carrier, (self.carrier_i_mul, 1)) self.connect(self.sig_q_carrier, (self.carrier_q_mul, 1)) self.connect(self.carrier_i_mul, (self.carrier_iq_add, 0)) self.connect(self.carrier_q_mul, (self.carrier_iq_add, 1)) else: self.sig_carrier = None self.carrier_mul = None #lf_channel_taps = optfir.low_pass(1.0, # Filter gain # self.input_sample_rate, # Sample rate # 2500, # One-sided modulation bandwidth # 3250, # One-sided channel bandwidth # 0.1, # Passband ripple (0.1) # 60, # Stopband attenuation # 9) # Extra taps (default 2, which doesn't work at 48kHz) #self.lf = gr.fir_filter_fff(self.channel_decimation, lf_channel_taps) self.scope2 = scopesink2.scope_sink_f(panel, sample_rate=self.symbol_rate, frame_decim=1, v_scale=2, t_scale=0.025, num_inputs=self.num_inputs) # also note: this specifies the nominal frequency deviation for the 4-level fsk signal self.fm_demod_gain = self.channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = gr.quadrature_demod_cf(self.fm_demod_gain) symbol_decim = 1 self.symbol_filter = gr.fir_filter_fff(symbol_decim, symbol_coeffs) # eventually specify: sample rate, symbol rate self.demod_fsk4 = fsk4.demod_ff(self.msgq, self.channel_rate, self.symbol_rate) if (self.chan is not None): self.connect(self.src, self.chan, self.fm_demod, self.symbol_filter, self.demod_fsk4, self.protocol_processing) if options.wav_out is not None: print "WAV output gain = " + str(options.wav_out_gain) self.scaled_wav_data = gr.multiply_const_ff(float(options.wav_out_gain)) self.connect(self.scaled_wav_data, self.wav_out) if self.carrier_mul is None: self.connect(self.fm_demod, self.scaled_wav_data) else: self.connect(self.carrier_iq_add, self.scaled_wav_data) if self.data_out is not None: if self.carrier_mul is None: self.connect(self.fm_demod, self.data_out) else: self.connect(self.carrier_mul, self.data_out) # During signal, -4..4 #self.connect(self.fm_demod, self.scope2) else: self.connect(self.src, self.symbol_filter, self.demod_fsk4, self.protocol_processing) self.connect(self.src, self.scope) #self.connect(self.lf, self.scope) self.connect(self.demod_fsk4, self.scope2) #self.connect(self.symbol_filter, self.scope2) # --------------- End of most of the 4L-FSK hack & slash self._build_gui(vbox) # set initial values if options.gain is None: options.gain = 0 self.set_gain(options.gain)