def test_diff_phasor_cc(self): src_data = (0+0j, 1+0j, -1+0j, 3+4j, -3-4j, -3+4j) expected_result = (0+0j, 0+0j, -1+0j, -3-4j, -25+0j, -7-24j) src = blocks.vector_source_c(src_data) op = digital.diff_phasor_cc() dst = blocks.vector_sink_c() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() # run the graph and wait for it to finish actual_result = dst.data() # fetch the contents of the sink self.assertComplexTuplesAlmostEqual(expected_result, actual_result)
def __init__(self, costas_alpha=0.04, gain_mu=0.025, input_rate=48000, output_rate=4800): gr.hier_block2.__init__( self, "CQPSK Demodulator", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_float*1), ) ################################################## # Parameters ################################################## self.costas_alpha = costas_alpha self.gain_mu = gain_mu self.input_rate = input_rate self.output_rate = output_rate ################################################## # Variables ################################################## self.alpha = alpha = costas_alpha self.omega = omega = float(input_rate) / float(output_rate) self.gain_omega = gain_omega = 0.1 * gain_mu * gain_mu self.fmax = fmax = 2 * math.pi * 2400 / float(input_rate) self.beta = beta = 0.125 * alpha * alpha ################################################## # Blocks ################################################## self.to_float = blocks.complex_to_arg(1) self.rescale = blocks.multiply_const_vff((1 / (math.pi / 4), )) self.diffdec = digital.diff_phasor_cc() self.clock = op25_repeater.gardner_costas_cc(omega, gain_mu, gain_omega, alpha, beta, fmax, -fmax) self.agc = analog.feedforward_agc_cc(16, 1.0) ################################################## # Connections ################################################## self.connect((self.agc, 0), (self.clock, 0)) self.connect((self.clock, 0), (self.diffdec, 0)) self.connect((self.diffdec, 0), (self.to_float, 0)) self.connect((self, 0), (self.agc, 0)) self.connect((self.rescale, 0), (self, 0)) self.connect((self.to_float, 0), (self.rescale, 0))
def __init__(self, input_rate=None, demod_type='cqpsk', relative_freq=0, offset=0, if_rate=_def_if_rate, gain_mu=_def_gain_mu, costas_alpha=_def_costas_alpha, symbol_rate=_def_symbol_rate): """ Hierarchical block for P25 demodulation. The complex input is tuned, decimated and demodulated @param input_rate: sample rate of complex input channel @type input_rate: int """ gr.hier_block2.__init__( self, "p25_demod_cb", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature # gr.io_signature(0, 0, 0)) # Output signature p25_demod_base.__init__(self, if_rate=if_rate, symbol_rate=symbol_rate) self.input_rate = input_rate self.if_rate = if_rate self.symbol_rate = symbol_rate self.connect_state = None self.offset = 0 self.sps = 0.0 self.lo_freq = 0 self.float_sink = None self.complex_sink = None # local osc self.lo = analog.sig_source_c(input_rate, analog.GR_SIN_WAVE, 0, 1.0, 0) self.mixer = blocks.multiply_cc() lpf_coeffs = filter.firdes.low_pass(1.0, input_rate, 7250, 725, filter.firdes.WIN_HANN) decimation = int(input_rate / if_rate) self.lpf = filter.fir_filter_ccf(decimation, lpf_coeffs) resampled_rate = float(input_rate) / float( decimation) # rate at output of self.lpf self.arb_resampler = filter.pfb.arb_resampler_ccf( float(self.if_rate) / resampled_rate) self.connect(self, (self.mixer, 0)) self.connect(self.lo, (self.mixer, 1)) self.connect(self.mixer, self.lpf, self.arb_resampler) levels = [-2.0, 0.0, 2.0, 4.0] self.slicer = op25_repeater.fsk4_slicer_fb(levels) omega = float(self.if_rate) / float(self.symbol_rate) gain_omega = 0.1 * gain_mu * gain_mu alpha = costas_alpha beta = 0.125 * alpha * alpha fmax = 2400 # Hz fmax = 2 * pi * fmax / float(self.if_rate) self.clock = op25_repeater.gardner_costas_cc(omega, gain_mu, gain_omega, alpha, beta, fmax, -fmax) self.agc = analog.feedforward_agc_cc(16, 1.0) # Perform Differential decoding on the constellation self.diffdec = digital.diff_phasor_cc() # take angle of the difference (in radians) self.to_float = blocks.complex_to_arg() # convert from radians such that signal is in -3/-1/+1/+3 self.rescale = blocks.multiply_const_ff((1 / (pi / 4))) # fm demodulator (needed in fsk4 case) fm_demod_gain = if_rate / (2.0 * pi * _def_symbol_deviation) self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain) self.connect_chain(demod_type) self.connect(self.slicer, self) self.set_relative_frequency(relative_freq)
def __init__(self, input_rate = None, demod_type = 'cqpsk', filter_type = None, excess_bw = _def_excess_bw, relative_freq = 0, offset = 0, if_rate = _def_if_rate, gain_mu = _def_gain_mu, costas_alpha = _def_costas_alpha, symbol_rate = _def_symbol_rate): """ Hierarchical block for P25 demodulation. The complex input is tuned, decimated and demodulated @param input_rate: sample rate of complex input channel @type input_rate: int """ gr.hier_block2.__init__(self, "p25_demod_cb", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature # gr.io_signature(0, 0, 0)) # Output signature p25_demod_base.__init__(self, if_rate=if_rate, symbol_rate=symbol_rate, filter_type=filter_type) self.input_rate = input_rate self.if_rate = if_rate self.symbol_rate = symbol_rate self.connect_state = None self.aux_fm_connected = False self.offset = 0 self.sps = 0.0 self.lo_freq = 0 self.float_sink = None self.complex_sink = None self.if1 = 0 self.if2 = 0 self.t_cache = {} if filter_type == 'rrc': self.set_baseband_gain(0.61) # local osc self.lo = analog.sig_source_c (input_rate, analog.GR_SIN_WAVE, 0, 1.0, 0) self.mixer = blocks.multiply_cc() decimator_values = get_decim(input_rate) if decimator_values: self.decim, self.decim2 = decimator_values self.if1 = input_rate / self.decim self.if2 = self.if1 / self.decim2 sys.stderr.write( 'Using two-stage decimator for speed=%d, decim=%d/%d if1=%d if2=%d\n' % (input_rate, self.decim, self.decim2, self.if1, self.if2)) bpf_coeffs = filter.firdes.complex_band_pass(1.0, input_rate, -self.if1/2, self.if1/2, self.if1/2, filter.firdes.WIN_HAMMING) self.t_cache[0] = bpf_coeffs fa = 6250 fb = self.if2 / 2 lpf_coeffs = filter.firdes.low_pass(1.0, self.if1, (fb+fa)/2, fb-fa, filter.firdes.WIN_HAMMING) self.bpf = filter.fir_filter_ccc(self.decim, bpf_coeffs) self.lpf = filter.fir_filter_ccf(self.decim2, lpf_coeffs) resampled_rate = self.if2 self.bfo = analog.sig_source_c (self.if1, analog.GR_SIN_WAVE, 0, 1.0, 0) self.connect(self, self.bpf, (self.mixer, 0)) self.connect(self.bfo, (self.mixer, 1)) else: sys.stderr.write( 'Unable to use two-stage decimator for speed=%d\n' % (input_rate)) # local osc self.lo = analog.sig_source_c (input_rate, analog.GR_SIN_WAVE, 0, 1.0, 0) lpf_coeffs = filter.firdes.low_pass(1.0, input_rate, 7250, 1450, filter.firdes.WIN_HANN) decimation = int(input_rate / if_rate) self.lpf = filter.fir_filter_ccf(decimation, lpf_coeffs) resampled_rate = float(input_rate) / float(decimation) # rate at output of self.lpf self.connect(self, (self.mixer, 0)) self.connect(self.lo, (self.mixer, 1)) self.connect(self.mixer, self.lpf) if self.if_rate != resampled_rate: self.if_out = filter.pfb.arb_resampler_ccf(float(self.if_rate) / resampled_rate) self.connect(self.lpf, self.if_out) else: self.if_out = self.lpf fa = 6250 fb = fa + 625 cutoff_coeffs = filter.firdes.low_pass(1.0, self.if_rate, (fb+fa)/2, fb-fa, filter.firdes.WIN_HANN) self.cutoff = filter.fir_filter_ccf(1, cutoff_coeffs) omega = float(self.if_rate) / float(self.symbol_rate) gain_omega = 0.1 * gain_mu * gain_mu alpha = costas_alpha beta = 0.125 * alpha * alpha fmax = 2400 # Hz fmax = 2*pi * fmax / float(self.if_rate) self.clock = op25_repeater.gardner_costas_cc(omega, gain_mu, gain_omega, alpha, beta, fmax, -fmax) self.agc = analog.feedforward_agc_cc(16, 1.0) # Perform Differential decoding on the constellation self.diffdec = digital.diff_phasor_cc() # take angle of the difference (in radians) self.to_float = blocks.complex_to_arg() # convert from radians such that signal is in -3/-1/+1/+3 self.rescale = blocks.multiply_const_ff( (1 / (pi / 4)) ) # fm demodulator (needed in fsk4 case) fm_demod_gain = if_rate / (2.0 * pi * _def_symbol_deviation) self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain) self.connect_chain(demod_type) self.connect(self.slicer, self) self.set_relative_frequency(relative_freq)
def __init__(self, samples_per_symbol=_def_samples_per_symbol, excess_bw=_def_excess_bw, costas_alpha=_def_costas_alpha, gain_mu=_def_gain_mu, mu=_def_mu, omega_relative_limit=_def_omega_relative_limit, gray_code=_def_gray_code, verbose=_def_verbose, log=_def_log): """ Hierarchical block for RRC-filtered CQPSK demodulation The input is the complex modulated signal at baseband. The output is a stream of floats in [ -3 / -1 / +1 / +3 ] @param samples_per_symbol: samples per symbol >= 2 @type samples_per_symbol: float @param excess_bw: Root-raised cosine filter excess bandwidth @type excess_bw: float @param costas_alpha: loop filter gain @type costas_alphas: float @param gain_mu: for M&M block @type gain_mu: float @param mu: for M&M block @type mu: float @param omega_relative_limit: for M&M block @type omega_relative_limit: float @param gray_code: Tell modulator to Gray code the bits @type gray_code: bool @param verbose: Print information about modulator? @type verbose: bool @param debug: Print modualtion data to files? @type debug: bool """ gr.hier_block2.__init__(self, "cqpsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature self._samples_per_symbol = samples_per_symbol self._excess_bw = excess_bw self._costas_alpha = costas_alpha self._mm_gain_mu = gain_mu self._mm_mu = mu self._mm_omega_relative_limit = omega_relative_limit self._gray_code = gray_code if samples_per_symbol < 2: raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol arity = pow(2,self.bits_per_symbol()) # Automatic gain control scale = (1.0/16384.0) self.pre_scaler = blocks.multiply_const_cc(scale) # scale the signal from full-range to +-1 #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) self.agc = analog.feedforward_agc_cc(16, 2.0) # RRC data filter ntaps = 11 * samples_per_symbol self.rrc_taps = firdes.root_raised_cosine( 1.0, # gain self._samples_per_symbol, # sampling rate 1.0, # symbol rate self._excess_bw, # excess bandwidth (roll-off factor) ntaps) self.rrc_filter=filter.interp_fir_filter_ccf(1, self.rrc_taps) if not self._mm_gain_mu: sbs_to_mm = {2: 0.050, 3: 0.075, 4: 0.11, 5: 0.125, 6: 0.15, 7: 0.15} self._mm_gain_mu = sbs_to_mm[samples_per_symbol] self._mm_omega = self._samples_per_symbol self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha fmin = -0.025 fmax = 0.025 if not _def_has_gr_digital: self.receiver=gr.mpsk_receiver_cc(arity, pi/4.0, self._costas_alpha, self._costas_beta, fmin, fmax, self._mm_mu, self._mm_gain_mu, self._mm_omega, self._mm_gain_omega, self._mm_omega_relative_limit) else: self.receiver=digital.mpsk_receiver_cc(arity, pi/4.0, 2*pi/150, fmin, fmax, self._mm_mu, self._mm_gain_mu, self._mm_omega, self._mm_gain_omega, self._mm_omega_relative_limit) #self.receiver.set_alpha(self._costas_alpha) #self.receiver.set_beta(self._costas_beta) # Perform Differential decoding on the constellation self.diffdec = digital.diff_phasor_cc() # take angle of the difference (in radians) self.to_float = blocks.complex_to_arg() # convert from radians such that signal is in -3/-1/+1/+3 self.rescale = blocks.multiply_const_ff( 1 / (pi / 4) ) if verbose: self._print_verbage() if log: self._setup_logging() # Connect & Initialize base class self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, self.diffdec, self.to_float, self.rescale, self)
def __init__(self): gr.top_block.__init__(self, "Tetra Rx Multi") options = self.get_options() self.src = blocks.file_source(gr.sizeof_gr_complex * 1, "/tmp/myout1.ch", False) ################################################## # Variables ################################################## self.srate_rx = srate_rx = options.sample_rate self.channels = srate_rx / 25000 self.srate_channel = 36000 self.afc_period = 15 self.afc_gain = 0.01 self.afc_channel = options.auto_tune or -1 self.afc_ppm_step = 100 self.debug = options.debug self.last_pwr = -100000 self.sig_det_period = 10 self.sig_det_bw = sig_det_bw = options.sig_detection_bw or srate_rx if self.sig_det_bw <= 1.: self.sig_det_bw *= srate_rx self.sig_det_threshold = options.sig_detection_threshold self.sig_det_channels = [] for ch in range(self.channels): if ch >= self.channels / 2: ch_ = (self.channels - ch - 1) else: ch_ = ch if (float(ch_) / self.channels * 2) <= (self.sig_det_bw / srate_rx): self.sig_det_channels.append(ch) self.channels = 10 ################################################## # RPC server ################################################## self.xmlrpc_server = SimpleXMLRPCServer.SimpleXMLRPCServer( ("localhost", options.listen_port), allow_none=True) self.xmlrpc_server.register_instance(self) threading.Thread(target=self.xmlrpc_server.serve_forever).start() ################################################## # Rx Blocks and connections ################################################## out_type, dst_path = options.output.split("://", 1) if out_type == "udp": dst_ip, dst_port = dst_path.split(':', 1) self.blocks_deinterleave_0 = blocks.deinterleave( gr.sizeof_gr_complex * 1, 1) self.squelch = [] self.digital_mpsk_receiver_cc = [] self.diff_phasor = [] self.complex_to_arg = [] self.multiply_const = [] self.add_const = [] self.float_to_uchar = [] self.map_bits = [] self.unpack_k_bits = [] self.blocks_sink = [] for ch in range(0, self.channels): mpsk = digital.mpsk_receiver_cc(4, math.pi / 4, math.pi / 100.0, -0.5, 0.5, 0.25, 0.001, 2, 0.001, 0.001) diff_phasor = digital.diff_phasor_cc() complex_to_arg = blocks.complex_to_arg(1) multiply_const = blocks.multiply_const_vff((2. / math.pi, )) add_const = blocks.add_const_vff((1.5, )) float_to_uchar = blocks.float_to_uchar() map_bits = digital.map_bb(([3, 2, 0, 1, 3])) unpack_k_bits = blocks.unpack_k_bits_bb(2) brmchannels = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 ] #brmchannels = [11,4,3,64,45,47,53,8,68,6,56,49,17,54,65,5,71,22,48,7,50] # itds kancl #brmchannels = [23,13,40,69,59,7,42,54,5,14,4,56,45,46,67,55,66,44,71,49,31,57,0,65,70] # doma - dole #brmchannels = [23,13,59,40,69,7,49,60,42,70,4,50,66,67,3,14,57,33,46,22,68,32,39,24,6,12,43,58,48,17,5,56,65,29,54,30,16,52,53,41,47,2,34,44,8] # doma - strecha #brmchannels = [67, 7, 23, 70] # doma - strecha - SDS #brmchannels = [67, 7, 23, 70,9,71,64,63,62,61,55,51,45,38,37,36,35,31,28,27,26,25,21,20,19,18,15,11,10,1,0] # doma - strecha - komplement if out_type == 'udp': sink = blocks.udp_sink(gr.sizeof_gr_char, dst_ip, int(dst_port) + ch, 1472, True) elif out_type == 'file': sink = blocks.file_sink(gr.sizeof_char, dst_path % ch, False) sink.set_unbuffered(True) else: raise ValueError("Invalid output URL '%s'" % options.output) print "connect %i" % ch if ch in brmchannels: self.connect( (self.blocks_deinterleave_0, ch), #(squelch, 0), (mpsk, 0), (diff_phasor, 0), (complex_to_arg, 0), (multiply_const, 0), (add_const, 0), (float_to_uchar, 0), (map_bits, 0), (unpack_k_bits, 0), (sink, 0)) self.digital_mpsk_receiver_cc.append(mpsk) self.diff_phasor.append(diff_phasor) self.complex_to_arg.append(complex_to_arg) self.multiply_const.append(multiply_const) self.add_const.append(add_const) self.float_to_uchar.append(float_to_uchar) self.map_bits.append(map_bits) self.unpack_k_bits.append(unpack_k_bits) self.blocks_sink.append(sink) self.connect((self.src, 0), (self.blocks_deinterleave_0, 0)) ################################################## # signal strenght identification ################################################## ''' self.pwr_probes = [] for ch in range(self.channels): pwr_probe = analog.probe_avg_mag_sqrd_c(0, 1./self.srate_channel) self.pwr_probes.append(pwr_probe) print "connect %i"%ch self.connect((self.blocks_deinterleave_0, ch), (pwr_probe, 0)) def _sig_det_probe(): while True: pwr = [self.pwr_probes[ch].level() for ch in range(self.channels) if ch in self.sig_det_channels] pwr = [10 * math.log10(p) for p in pwr if p > 0.] if not pwr: continue pwr = min(pwr) + self.sig_det_threshold print "power threshold target %f"%pwr if abs(pwr - self.last_pwr) > (self.sig_det_threshold / 2): for s in []: s.set_threshold(pwr) self.last_pwr = pwr time.sleep(self.sig_det_period) if self.sig_det_threshold is not None: self._sig_det_probe_thread = threading.Thread(target=_sig_det_probe) self._sig_det_probe_thread.daemon = True self._sig_det_probe_thread.start() ''' ################################################## # AFC blocks and connections ################################################## self.afc_selector = grc_blks2.selector( item_size=gr.sizeof_gr_complex, num_inputs=self.channels, num_outputs=1, input_index=0, output_index=0, ) self.afc_demod = analog.quadrature_demod_cf(self.srate_channel / (2 * math.pi)) samp_afc = self.srate_channel * self.afc_period / 2 self.afc_avg = blocks.moving_average_ff(samp_afc, 1. / samp_afc * self.afc_gain) self.afc_probe = blocks.probe_signal_f() def _afc_probe(): rt = 0.0 while True: time.sleep(self.afc_period) if self.afc_channel == -1: continue err = self.afc_probe.level() freq = err * self.afc_gain print "err: %f\tfreq: %f\trt %f" % (err, freq, rt) changed = False if err < -1: rt += 0.1 changed = True elif err > 1: rt -= 0.1 changed = True if changed: os.system("echo \"setrot %f\" | nc localhost 3333" % rt) self.afc_channel = 0 self._afc_err_thread = threading.Thread(target=_afc_probe) self._afc_err_thread.daemon = True self._afc_err_thread.start() for ch in range(self.channels): print "connect %i" % ch self.connect((self.blocks_deinterleave_0, ch), (self.afc_selector, ch)) self.connect((self.afc_selector, 0), (self.afc_demod, 0), (self.afc_avg, 0), (self.afc_probe, 0)) if self.afc_channel != -1: self.afc_selector.set_input_index(self.afc_channel)
def __init__(self): gr.top_block.__init__(self, "Modes Uf Rx Sigmf V2") Qt.QWidget.__init__(self) self.setWindowTitle("Modes Uf Rx Sigmf V2") qtgui.util.check_set_qss() try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "modes_uf_rx_sigmf_v2") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.sps = sps = 2 self.samp_rate = samp_rate = 8000000 self.rrc_taps = rrc_taps = firdes.root_raised_cosine( 1, 1, 0.5, 0.4, 32) self.rms_alpha = rms_alpha = 1e-6 self.rf_gain = rf_gain = 45 self.qt_thresh = qt_thresh = 110 self.es_thresh = es_thresh = 110 self.det_mult = det_mult = 2 self.det_avg_len = det_avg_len = 20 self.cons_offset = cons_offset = 5 self.burst_length = burst_length = 600 self.bit_thresh = bit_thresh = 5 self.avg_len = avg_len = 20 ################################################## # Blocks ################################################## self._rms_alpha_tool_bar = Qt.QToolBar(self) self._rms_alpha_tool_bar.addWidget(Qt.QLabel("rms_alpha" + ": ")) self._rms_alpha_line_edit = Qt.QLineEdit(str(self.rms_alpha)) self._rms_alpha_tool_bar.addWidget(self._rms_alpha_line_edit) self._rms_alpha_line_edit.returnPressed.connect( lambda: self.set_rms_alpha( eng_notation.str_to_num( str(self._rms_alpha_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._rms_alpha_tool_bar, 6, 3, 1, 1) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(3, 4): self.top_grid_layout.setColumnStretch(c, 1) self._qt_thresh_tool_bar = Qt.QToolBar(self) self._qt_thresh_tool_bar.addWidget(Qt.QLabel("qt_thresh" + ": ")) self._qt_thresh_line_edit = Qt.QLineEdit(str(self.qt_thresh)) self._qt_thresh_tool_bar.addWidget(self._qt_thresh_line_edit) self._qt_thresh_line_edit.returnPressed.connect( lambda: self.set_qt_thresh( eng_notation.str_to_num( str(self._qt_thresh_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._qt_thresh_tool_bar, 0, 2, 1, 2) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(2, 4): self.top_grid_layout.setColumnStretch(c, 1) self._es_thresh_tool_bar = Qt.QToolBar(self) self._es_thresh_tool_bar.addWidget(Qt.QLabel('ES Thresh' + ": ")) self._es_thresh_line_edit = Qt.QLineEdit(str(self.es_thresh)) self._es_thresh_tool_bar.addWidget(self._es_thresh_line_edit) self._es_thresh_line_edit.returnPressed.connect( lambda: self.set_es_thresh( eng_notation.str_to_num( str(self._es_thresh_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._es_thresh_tool_bar, 0, 5, 1, 1) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(5, 6): self.top_grid_layout.setColumnStretch(c, 1) self._det_mult_tool_bar = Qt.QToolBar(self) self._det_mult_tool_bar.addWidget(Qt.QLabel("det_mult" + ": ")) self._det_mult_line_edit = Qt.QLineEdit(str(self.det_mult)) self._det_mult_tool_bar.addWidget(self._det_mult_line_edit) self._det_mult_line_edit.returnPressed.connect( lambda: self.set_det_mult( eng_notation.str_to_num( str(self._det_mult_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._det_mult_tool_bar, 0, 6, 1, 2) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(6, 8): self.top_grid_layout.setColumnStretch(c, 1) self._det_avg_len_tool_bar = Qt.QToolBar(self) self._det_avg_len_tool_bar.addWidget(Qt.QLabel("det_avg_len" + ": ")) self._det_avg_len_line_edit = Qt.QLineEdit(str(self.det_avg_len)) self._det_avg_len_tool_bar.addWidget(self._det_avg_len_line_edit) self._det_avg_len_line_edit.returnPressed.connect( lambda: self.set_det_avg_len( int(str(self._det_avg_len_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._det_avg_len_tool_bar, 0, 9, 1, 1) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(9, 10): self.top_grid_layout.setColumnStretch(c, 1) self._cons_offset_tool_bar = Qt.QToolBar(self) self._cons_offset_tool_bar.addWidget(Qt.QLabel("cons_offset" + ": ")) self._cons_offset_line_edit = Qt.QLineEdit(str(self.cons_offset)) self._cons_offset_tool_bar.addWidget(self._cons_offset_line_edit) self._cons_offset_line_edit.returnPressed.connect( lambda: self.set_cons_offset( eng_notation.str_to_num( str(self._cons_offset_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._cons_offset_tool_bar, 0, 8, 1, 1) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(8, 9): self.top_grid_layout.setColumnStretch(c, 1) self._avg_len_tool_bar = Qt.QToolBar(self) self._avg_len_tool_bar.addWidget(Qt.QLabel("avg_len" + ": ")) self._avg_len_line_edit = Qt.QLineEdit(str(self.avg_len)) self._avg_len_tool_bar.addWidget(self._avg_len_line_edit) self._avg_len_line_edit.returnPressed.connect(lambda: self.set_avg_len( eng_notation.str_to_num( str(self._avg_len_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._avg_len_tool_bar, 0, 4, 1, 1) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 5): self.top_grid_layout.setColumnStretch(c, 1) self.vcc_es_tag_to_utc_0 = vcc.es_tag_to_utc(samp_rate) self.vcc_burst_snr_0 = vcc.burst_snr(25, 2) self.sigmf_source_0 = gr_sigmf.source( '/captures/adsb/20210127/MODE-S_2021-01-27T23:43:24.sigmf-data', "ci16" + ("_le" if sys.byteorder == "little" else "_be"), False) self._rf_gain_tool_bar = Qt.QToolBar(self) self._rf_gain_tool_bar.addWidget(Qt.QLabel("rf_gain" + ": ")) self._rf_gain_line_edit = Qt.QLineEdit(str(self.rf_gain)) self._rf_gain_tool_bar.addWidget(self._rf_gain_line_edit) self._rf_gain_line_edit.returnPressed.connect(lambda: self.set_rf_gain( eng_notation.str_to_num( str(self._rf_gain_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._rf_gain_tool_bar, 0, 0, 1, 2) for r in range(0, 1): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 2): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_time_sink_x_1 = qtgui.time_sink_f( burst_length / 2, #size samp_rate, #samp_rate "", #name 3 #number of inputs ) self.qtgui_time_sink_x_1.set_update_time(0.010) self.qtgui_time_sink_x_1.set_y_axis(-5, 20) self.qtgui_time_sink_x_1.set_y_label('Amplitude', "") self.qtgui_time_sink_x_1.enable_tags(-1, True) self.qtgui_time_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_AUTO, qtgui.TRIG_SLOPE_POS, qt_thresh, 1.0 / samp_rate * 100, 0, "") self.qtgui_time_sink_x_1.enable_autoscale(True) self.qtgui_time_sink_x_1.enable_grid(True) self.qtgui_time_sink_x_1.enable_axis_labels(True) self.qtgui_time_sink_x_1.enable_control_panel(False) self.qtgui_time_sink_x_1.enable_stem_plot(False) if not True: self.qtgui_time_sink_x_1.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue" ] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(3): if len(labels[i]) == 0: self.qtgui_time_sink_x_1.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_1.set_line_label(i, labels[i]) self.qtgui_time_sink_x_1.set_line_width(i, widths[i]) self.qtgui_time_sink_x_1.set_line_color(i, colors[i]) self.qtgui_time_sink_x_1.set_line_style(i, styles[i]) self.qtgui_time_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_1_win = sip.wrapinstance( self.qtgui_time_sink_x_1.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_1_win, 1, 0, 2, 4) for r in range(1, 3): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 4): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_time_sink_x_0_1 = qtgui.time_sink_f( burst_length / 2, #size samp_rate / 2, #samp_rate "soft chips", #name 3 #number of inputs ) self.qtgui_time_sink_x_0_1.set_update_time(0.10) self.qtgui_time_sink_x_0_1.set_y_axis(-1, 1) self.qtgui_time_sink_x_0_1.set_y_label('Amplitude', "") self.qtgui_time_sink_x_0_1.enable_tags(-1, True) self.qtgui_time_sink_x_0_1.set_trigger_mode(qtgui.TRIG_MODE_TAG, qtgui.TRIG_SLOPE_POS, 0, 0, 0, "es::event_type") self.qtgui_time_sink_x_0_1.enable_autoscale(True) self.qtgui_time_sink_x_0_1.enable_grid(False) self.qtgui_time_sink_x_0_1.enable_axis_labels(True) self.qtgui_time_sink_x_0_1.enable_control_panel(False) self.qtgui_time_sink_x_0_1.enable_stem_plot(False) if not True: self.qtgui_time_sink_x_0_1.disable_legend() labels = ['re', 'abs', 'mag', 'ph', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue" ] styles = [1, 2, 1, 1, 1, 1, 1, 1, 1, 1] markers = [0, -1, 0, -1, -1, -1, -1, -1, -1, -1] alphas = [1, 0.25, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(3): if len(labels[i]) == 0: self.qtgui_time_sink_x_0_1.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0_1.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0_1.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0_1.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0_1.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0_1.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0_1.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_1_win = sip.wrapinstance( self.qtgui_time_sink_x_0_1.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_1_win, 3, 0, 3, 5) for r in range(3, 6): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 5): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_time_raster_sink_x_0 = qtgui.time_raster_sink_b( samp_rate / 2, 20, 56, ([]), ([]), "", 1, ) self.qtgui_time_raster_sink_x_0.set_update_time(0.10) self.qtgui_time_raster_sink_x_0.set_intensity_range(-1, 1) self.qtgui_time_raster_sink_x_0.enable_grid(False) self.qtgui_time_raster_sink_x_0.enable_axis_labels(True) labels = ['', '', '', '', '', '', '', '', '', ''] colors = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_time_raster_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_time_raster_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_raster_sink_x_0.set_color_map(i, colors[i]) self.qtgui_time_raster_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_raster_sink_x_0_win = sip.wrapinstance( self.qtgui_time_raster_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_raster_sink_x_0_win, 3, 5, 3, 5) for r in range(3, 6): self.top_grid_layout.setRowStretch(r, 1) for c in range(5, 10): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_const_sink_x_0 = qtgui.const_sink_c( burst_length / 2, #size "", #name 1 #number of inputs ) self.qtgui_const_sink_x_0.set_update_time(0.010) self.qtgui_const_sink_x_0.set_y_axis(-2, 2) self.qtgui_const_sink_x_0.set_x_axis(-2, 2) self.qtgui_const_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, "") self.qtgui_const_sink_x_0.enable_autoscale(True) self.qtgui_const_sink_x_0.enable_grid(True) self.qtgui_const_sink_x_0.enable_axis_labels(True) if not True: self.qtgui_const_sink_x_0.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "red", "red", "red", "red", "red", "red", "red", "red" ] styles = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] markers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_const_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_const_sink_x_0.set_line_label(i, labels[i]) self.qtgui_const_sink_x_0.set_line_width(i, widths[i]) self.qtgui_const_sink_x_0.set_line_color(i, colors[i]) self.qtgui_const_sink_x_0.set_line_style(i, styles[i]) self.qtgui_const_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_const_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_const_sink_x_0_win = sip.wrapinstance( self.qtgui_const_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_const_sink_x_0_win, 1, 8, 2, 2) for r in range(1, 3): self.top_grid_layout.setRowStretch(r, 1) for c in range(8, 10): self.top_grid_layout.setColumnStretch(c, 1) self.pyqt_ctime_plot_0 = pyqt.ctime_plot('') self._pyqt_ctime_plot_0_win = self.pyqt_ctime_plot_0 self.top_grid_layout.addWidget(self._pyqt_ctime_plot_0_win, 1, 4, 2, 2) for r in range(1, 3): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 6): self.top_grid_layout.setColumnStretch(c, 1) self.pyqt_const_plot_0 = pyqt.const_plot(label='') self._pyqt_const_plot_0_win = self.pyqt_const_plot_0 self.top_grid_layout.addWidget(self._pyqt_const_plot_0_win, 1, 6, 2, 2) for r in range(1, 3): self.top_grid_layout.setRowStretch(r, 1) for c in range(6, 8): self.top_grid_layout.setColumnStretch(c, 1) self.low_pass_filter_0_0 = filter.fir_filter_ccf( 1, firdes.low_pass(1, samp_rate, 4e6, 250e3, firdes.WIN_BLACKMAN, 6.76)) self.fosphor_glfw_sink_c_0 = fosphor.glfw_sink_c() self.fosphor_glfw_sink_c_0.set_fft_window(window.WIN_BLACKMAN_hARRIS) self.fosphor_glfw_sink_c_0.set_frequency_range(0, samp_rate) self.es_trigger_edge_f_0 = es.trigger_edge_f(es_thresh, burst_length, burst_length / 3, gr.sizeof_gr_complex, 300) self.es_sink_0 = es.sink(1 * [gr.sizeof_gr_complex], 4, 64, 0, 2, 0) self.es_handler_pdu_0 = es.es_make_handler_pdu( es.es_handler_print.TYPE_C32) self.epy_block_1 = epy_block_1.uf_frame_sync(tag_name='sync', msg_len=112, samp_rate=samp_rate, sps=2) self.epy_block_0_0 = epy_block_0_0.uf_decode(msg_filter='All Messages', verbose=True) self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf( 2, math.pi / 200, (rrc_taps), 32, 16, 1.1, 1) self.digital_diff_phasor_cc_0 = digital.diff_phasor_cc() self.digital_costas_loop_cc_0 = digital.costas_loop_cc( math.pi / 50, 2, False) self.digital_correlate_access_code_tag_xx_0_0_1_2_2_0_0_0 = digital.correlate_access_code_tag_bb( '00011111000111000001', 3, 'sync') self.digital_binary_slicer_fb_0_0 = digital.binary_slicer_fb() self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex * 1, samp_rate * 2, True) self.blocks_sub_xx_2_0 = blocks.sub_ff(1) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_skiphead_0 = blocks.skiphead(gr.sizeof_float * 1, 1) self.blocks_rms_xx_1 = blocks.rms_cf(rms_alpha) self.blocks_pdu_to_tagged_stream_1 = blocks.pdu_to_tagged_stream( blocks.byte_t, 'packet_len') self.blocks_pdu_to_tagged_stream_0 = blocks.pdu_to_tagged_stream( blocks.complex_t, 'est_len') (self.blocks_pdu_to_tagged_stream_0).set_min_output_buffer(600) self.blocks_pdu_remove_0 = blocks.pdu_remove( pmt.intern("es::event_buffer")) self.blocks_multiply_const_xx_0 = blocks.multiply_const_cc(1.0 / 65536.0) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff( (-1 * det_mult, )) self.blocks_moving_average_xx_0_0 = blocks.moving_average_ff( int(det_avg_len), 1.0 / det_avg_len, 4000, 1) self.blocks_moving_average_xx_0 = blocks.moving_average_ff( int(avg_len), 1.0 / avg_len, 4000, 1) self.blocks_interleaved_short_to_complex_0 = blocks.interleaved_short_to_complex( True, False) self.blocks_complex_to_real_1_0_0 = blocks.complex_to_real(1) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.blocks_complex_to_arg_0 = blocks.complex_to_arg(1) self.blocks_char_to_float_0_1 = blocks.char_to_float(1, 1 / 10.0) self.blocks_add_const_vxx_0 = blocks.add_const_vff((cons_offset, )) self.blocks_abs_xx_0 = blocks.abs_ff(1) self._bit_thresh_tool_bar = Qt.QToolBar(self) self._bit_thresh_tool_bar.addWidget(Qt.QLabel("bit_thresh" + ": ")) self._bit_thresh_line_edit = Qt.QLineEdit(str(self.bit_thresh)) self._bit_thresh_tool_bar.addWidget(self._bit_thresh_line_edit) self._bit_thresh_line_edit.returnPressed.connect( lambda: self.set_bit_thresh( eng_notation.str_to_num( str(self._bit_thresh_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._bit_thresh_tool_bar, 6, 4, 1, 1) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 5): self.top_grid_layout.setColumnStretch(c, 1) self.analog_agc2_xx_0 = analog.agc2_cc(1e-1, 1e-2, 1.0, 1.0) self.analog_agc2_xx_0.set_max_gain(65536) self.ais_invert_0 = ais.invert() ################################################## # Connections ################################################## self.msg_connect((self.blocks_pdu_remove_0, 'pdus'), (self.vcc_burst_snr_0, 'in')) self.msg_connect((self.epy_block_0_0, 'out'), (self.blocks_pdu_to_tagged_stream_1, 'pdus')) self.msg_connect((self.epy_block_1, 'out'), (self.epy_block_0_0, 'in')) self.msg_connect((self.es_handler_pdu_0, 'pdus_out'), (self.blocks_pdu_remove_0, 'pdus')) self.msg_connect((self.es_trigger_edge_f_0, 'edge_event'), (self.es_handler_pdu_0, 'handle_event')) self.msg_connect((self.es_trigger_edge_f_0, 'which_stream'), (self.es_sink_0, 'schedule_event')) self.msg_connect((self.vcc_burst_snr_0, 'out'), (self.vcc_es_tag_to_utc_0, 'in')) self.msg_connect((self.vcc_es_tag_to_utc_0, 'out'), (self.blocks_pdu_to_tagged_stream_0, 'pdus')) self.msg_connect((self.vcc_es_tag_to_utc_0, 'out'), (self.pyqt_const_plot_0, 'cpdus')) self.msg_connect((self.vcc_es_tag_to_utc_0, 'out'), (self.pyqt_ctime_plot_0, 'cpdus')) self.connect( (self.ais_invert_0, 0), (self.digital_correlate_access_code_tag_xx_0_0_1_2_2_0_0_0, 0)) self.connect((self.analog_agc2_xx_0, 0), (self.blocks_complex_to_arg_0, 0)) self.connect((self.analog_agc2_xx_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.analog_agc2_xx_0, 0), (self.es_trigger_edge_f_0, 1)) self.connect((self.analog_agc2_xx_0, 0), (self.fosphor_glfw_sink_c_0, 0)) self.connect((self.blocks_abs_xx_0, 0), (self.blocks_moving_average_xx_0_0, 0)) self.connect((self.blocks_add_const_vxx_0, 0), (self.qtgui_time_sink_x_1, 2)) self.connect((self.blocks_char_to_float_0_1, 0), (self.qtgui_time_sink_x_0_1, 2)) self.connect((self.blocks_complex_to_arg_0, 0), (self.blocks_skiphead_0, 0)) self.connect((self.blocks_complex_to_arg_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.blocks_complex_to_arg_0, 0), (self.qtgui_time_sink_x_1, 1)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.blocks_complex_to_real_1_0_0, 0), (self.blocks_sub_xx_2_0, 0)) self.connect((self.blocks_complex_to_real_1_0_0, 0), (self.qtgui_time_sink_x_0_1, 0)) self.connect((self.blocks_interleaved_short_to_complex_0, 0), (self.blocks_multiply_const_xx_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.es_trigger_edge_f_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.qtgui_time_sink_x_1, 0)) self.connect((self.blocks_moving_average_xx_0_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.blocks_add_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_xx_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_pdu_to_tagged_stream_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.blocks_pdu_to_tagged_stream_1, 0), (self.qtgui_time_raster_sink_x_0, 0)) self.connect((self.blocks_rms_xx_1, 0), (self.blocks_sub_xx_2_0, 1)) self.connect((self.blocks_rms_xx_1, 0), (self.qtgui_time_sink_x_0_1, 1)) self.connect((self.blocks_skiphead_0, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.blocks_sub_xx_0, 0), (self.blocks_abs_xx_0, 0)) self.connect((self.blocks_sub_xx_2_0, 0), (self.digital_binary_slicer_fb_0_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.analog_agc2_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0_0, 0), (self.ais_invert_0, 0)) self.connect( (self.digital_correlate_access_code_tag_xx_0_0_1_2_2_0_0_0, 0), (self.blocks_char_to_float_0_1, 0)) self.connect( (self.digital_correlate_access_code_tag_xx_0_0_1_2_2_0_0_0, 0), (self.epy_block_1, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_diff_phasor_cc_0, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.qtgui_const_sink_x_0, 0)) self.connect((self.digital_diff_phasor_cc_0, 0), (self.blocks_complex_to_real_1_0_0, 0)) self.connect((self.digital_diff_phasor_cc_0, 0), (self.blocks_rms_xx_1, 0)) self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_costas_loop_cc_0, 0)) self.connect((self.es_trigger_edge_f_0, 0), (self.es_sink_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) self.connect((self.sigmf_source_0, 0), (self.blocks_interleaved_short_to_complex_0, 0))
def __init__(self): gr.top_block.__init__(self, "Psk31 Rx") Qt.QWidget.__init__(self) self.setWindowTitle("Psk31 Rx") qtgui.util.check_set_qss() try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "psk31_rx") try: if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): self.restoreGeometry(self.settings.value("geometry").toByteArray()) else: self.restoreGeometry(self.settings.value("geometry")) except: pass ################################################## # Variables ################################################## self.center_freq = center_freq = 441800000 self.samp_rate = samp_rate = 960000 self.psk_offset = psk_offset = 1000 self.psk_center = psk_center = center_freq + 141000 self.int_rate = int_rate = 48000 self.gain = gain = 10 self.audio_rate = audio_rate = 8000 ################################################## # Blocks ################################################## self._psk_offset_range = Range(0, 3000, 10, 1000, 200) self._psk_offset_win = RangeWidget(self._psk_offset_range, self.set_psk_offset, 'PSK offset', "counter_slider", float) self.top_grid_layout.addWidget(self._psk_offset_win) self._psk_center_range = Range(center_freq + 110000, center_freq + 150000, 1000, center_freq + 141000, 200) self._psk_center_win = RangeWidget(self._psk_center_range, self.set_psk_center, 'Tuning', "counter_slider", float) self.top_grid_layout.addWidget(self._psk_center_win) self._gain_range = Range(0, 50, 0.4, 10, 200) self._gain_win = RangeWidget(self._gain_range, self.set_gain, 'RX gain', "counter_slider", float) self.top_grid_layout.addWidget(self._gain_win) self.qtgui_waterfall_sink_x_2 = qtgui.waterfall_sink_f( 1024, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate / 120, #bw "", #name 1 #number of inputs ) self.qtgui_waterfall_sink_x_2.set_update_time(0.10) self.qtgui_waterfall_sink_x_2.enable_grid(False) self.qtgui_waterfall_sink_x_2.enable_axis_labels(True) self.qtgui_waterfall_sink_x_2.set_plot_pos_half(not False) labels = ['', '', '', '', '', '', '', '', '', ''] colors = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in range(1): if len(labels[i]) == 0: self.qtgui_waterfall_sink_x_2.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_waterfall_sink_x_2.set_line_label(i, labels[i]) self.qtgui_waterfall_sink_x_2.set_color_map(i, colors[i]) self.qtgui_waterfall_sink_x_2.set_line_alpha(i, alphas[i]) self.qtgui_waterfall_sink_x_2.set_intensity_range(-140, 10) self._qtgui_waterfall_sink_x_2_win = sip.wrapinstance(self.qtgui_waterfall_sink_x_2.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_waterfall_sink_x_2_win) self.qtgui_waterfall_sink_x_1 = qtgui.waterfall_sink_c( 1024, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate / 20, #bw "", #name 1 #number of inputs ) self.qtgui_waterfall_sink_x_1.set_update_time(0.10) self.qtgui_waterfall_sink_x_1.enable_grid(False) self.qtgui_waterfall_sink_x_1.enable_axis_labels(True) labels = ['', '', '', '', '', '', '', '', '', ''] colors = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in range(1): if len(labels[i]) == 0: self.qtgui_waterfall_sink_x_1.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_waterfall_sink_x_1.set_line_label(i, labels[i]) self.qtgui_waterfall_sink_x_1.set_color_map(i, colors[i]) self.qtgui_waterfall_sink_x_1.set_line_alpha(i, alphas[i]) self.qtgui_waterfall_sink_x_1.set_intensity_range(-140, 10) self._qtgui_waterfall_sink_x_1_win = sip.wrapinstance(self.qtgui_waterfall_sink_x_1.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_waterfall_sink_x_1_win) self.qtgui_waterfall_sink_x_0 = qtgui.waterfall_sink_c( 1024, #size firdes.WIN_BLACKMAN_hARRIS, #wintype center_freq, #fc samp_rate, #bw "", #name 1 #number of inputs ) self.qtgui_waterfall_sink_x_0.set_update_time(0.10) self.qtgui_waterfall_sink_x_0.enable_grid(False) self.qtgui_waterfall_sink_x_0.enable_axis_labels(True) labels = ['', '', '', '', '', '', '', '', '', ''] colors = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in range(1): if len(labels[i]) == 0: self.qtgui_waterfall_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_waterfall_sink_x_0.set_line_label(i, labels[i]) self.qtgui_waterfall_sink_x_0.set_color_map(i, colors[i]) self.qtgui_waterfall_sink_x_0.set_line_alpha(i, alphas[i]) self.qtgui_waterfall_sink_x_0.set_intensity_range(-140, 10) self._qtgui_waterfall_sink_x_0_win = sip.wrapinstance(self.qtgui_waterfall_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_waterfall_sink_x_0_win) self.qtgui_time_sink_x_1 = qtgui.time_sink_c( 1024, #size samp_rate / 120, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_1.set_update_time(0.10) self.qtgui_time_sink_x_1.set_y_axis(-1, 1) self.qtgui_time_sink_x_1.set_y_label('Amplitude', "") self.qtgui_time_sink_x_1.enable_tags(True) self.qtgui_time_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_1.enable_autoscale(False) self.qtgui_time_sink_x_1.enable_grid(False) self.qtgui_time_sink_x_1.enable_axis_labels(True) self.qtgui_time_sink_x_1.enable_control_panel(False) self.qtgui_time_sink_x_1.enable_stem_plot(False) labels = ['Signal 1', 'Signal 2', 'Signal 3', 'Signal 4', 'Signal 5', 'Signal 6', 'Signal 7', 'Signal 8', 'Signal 9', 'Signal 10'] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ['blue', 'red', 'green', 'black', 'cyan', 'magenta', 'yellow', 'dark red', 'dark green', 'dark blue'] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] for i in range(2): if len(labels[i]) == 0: if (i % 2 == 0): self.qtgui_time_sink_x_1.set_line_label(i, "Re{{Data {0}}}".format(i/2)) else: self.qtgui_time_sink_x_1.set_line_label(i, "Im{{Data {0}}}".format(i/2)) else: self.qtgui_time_sink_x_1.set_line_label(i, labels[i]) self.qtgui_time_sink_x_1.set_line_width(i, widths[i]) self.qtgui_time_sink_x_1.set_line_color(i, colors[i]) self.qtgui_time_sink_x_1.set_line_style(i, styles[i]) self.qtgui_time_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_1_win = sip.wrapinstance(self.qtgui_time_sink_x_1.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_1_win) self.qtgui_time_sink_x_0 = qtgui.time_sink_c( 1024, #size samp_rate / 120 / 16 / 16, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(0.10) self.qtgui_time_sink_x_0.set_y_axis(-1, 1) self.qtgui_time_sink_x_0.set_y_label('Amplitude', "") self.qtgui_time_sink_x_0.enable_tags(True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(False) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_axis_labels(True) self.qtgui_time_sink_x_0.enable_control_panel(False) self.qtgui_time_sink_x_0.enable_stem_plot(False) labels = ['Signal 1', 'Signal 2', 'Signal 3', 'Signal 4', 'Signal 5', 'Signal 6', 'Signal 7', 'Signal 8', 'Signal 9', 'Signal 10'] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ['blue', 'red', 'green', 'black', 'cyan', 'magenta', 'yellow', 'dark red', 'dark green', 'dark blue'] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] for i in range(2): if len(labels[i]) == 0: if (i % 2 == 0): self.qtgui_time_sink_x_0.set_line_label(i, "Re{{Data {0}}}".format(i/2)) else: self.qtgui_time_sink_x_0.set_line_label(i, "Im{{Data {0}}}".format(i/2)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_win) self.qtgui_number_sink_0 = qtgui.number_sink( gr.sizeof_float, 0, qtgui.NUM_GRAPH_HORIZ, 1 ) self.qtgui_number_sink_0.set_update_time(0.10) self.qtgui_number_sink_0.set_title("") labels = ['', '', '', '', '', '', '', '', '', ''] units = ['', '', '', '', '', '', '', '', '', ''] colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")] factor = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] for i in range(1): self.qtgui_number_sink_0.set_min(i, -1) self.qtgui_number_sink_0.set_max(i, 1) self.qtgui_number_sink_0.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_0.set_label(i, "Data {0}".format(i)) else: self.qtgui_number_sink_0.set_label(i, labels[i]) self.qtgui_number_sink_0.set_unit(i, units[i]) self.qtgui_number_sink_0.set_factor(i, factor[i]) self.qtgui_number_sink_0.enable_autoscale(False) self._qtgui_number_sink_0_win = sip.wrapinstance(self.qtgui_number_sink_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_number_sink_0_win) self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + '' ) self.osmosdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t()) self.osmosdr_source_0.set_sample_rate(samp_rate) self.osmosdr_source_0.set_center_freq(center_freq, 0) self.osmosdr_source_0.set_freq_corr(0, 0) self.osmosdr_source_0.set_gain(gain, 0) self.osmosdr_source_0.set_if_gain(20, 0) self.osmosdr_source_0.set_bb_gain(20, 0) self.osmosdr_source_0.set_antenna('', 0) self.osmosdr_source_0.set_bandwidth(0, 0) self.ham_varicode_rx_0 = ham.varicode_rx() self.freq_xlating_fir_filter_xxx_1 = filter.freq_xlating_fir_filter_ccc(16, firdes.low_pass(10, audio_rate, 120, 40, firdes.WIN_HAMMING, 6.76), psk_offset, audio_rate) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(samp_rate // int_rate, firdes.low_pass(1, samp_rate, 12000, 12000, firdes.WIN_HAMMING, 6.76), round(psk_center - center_freq,-3), samp_rate) self.digital_diff_phasor_cc_0 = digital.diff_phasor_cc() self.digital_costas_loop_cc_0 = digital.costas_loop_cc(5 * math.pi /100.0, 2, False) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_cc(16, 0.25*0.175*0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_char*1, 'psk31.txt', False) self.blocks_file_sink_0.set_unbuffered(True) self.blocks_complex_to_real_1 = blocks.complex_to_real(1) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.band_pass_filter_0 = filter.fir_filter_ccc( int_rate // audio_rate, firdes.complex_band_pass( 1, int_rate, 200, 2800, 200, firdes.WIN_HAMMING, 6.76)) self.audio_sink_0 = audio.sink(audio_rate, 'plughw:0,0', True) self.analog_agc_xx_0 = analog.agc_cc(1e-3, 0.1, 1.0) self.analog_agc_xx_0.set_max_gain(65536) ################################################## # Connections ################################################## self.connect((self.analog_agc_xx_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.analog_agc_xx_0, 0), (self.freq_xlating_fir_filter_xxx_1, 0)) self.connect((self.band_pass_filter_0, 0), (self.analog_agc_xx_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.audio_sink_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.qtgui_waterfall_sink_x_2, 0)) self.connect((self.blocks_complex_to_real_1, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.ham_varicode_rx_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_diff_phasor_cc_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_costas_loop_cc_0, 1), (self.qtgui_number_sink_0, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.qtgui_time_sink_x_1, 0)) self.connect((self.digital_diff_phasor_cc_0, 0), (self.blocks_complex_to_real_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.qtgui_waterfall_sink_x_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_1, 0), (self.digital_costas_loop_cc_0, 0)) self.connect((self.ham_varicode_rx_0, 0), (self.blocks_file_sink_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.qtgui_waterfall_sink_x_0, 0))
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-1", "--one-channel", action="store_true", default=False, help="software synthesized Q channel") parser.add_option("-a", "--agc", action="store_true", default=False, help="automatic gain control (overrides --gain)") parser.add_option("-c", "--calibration", type="eng_float", default=0, help="freq offset") parser.add_option("-d", "--debug", action="store_true", default=False, help="allow time at init to attach gdb") parser.add_option("-C", "--costas-alpha", type="eng_float", default=0.125, help="Costas alpha") parser.add_option("-g", "--gain", type="eng_float", default=1.0) parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file") parser.add_option("-I", "--imbe", action="store_true", default=False, help="output IMBE codewords") parser.add_option("-L", "--low-pass", type="eng_float", default=6.5e3, help="low pass cut-off", metavar="Hz") parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file") parser.add_option("-p", "--polarity", action="store_true", default=False, help="use reversed polarity") parser.add_option("-r", "--raw-symbols", type="string", default=None, help="dump decoded symbols to file") parser.add_option("-s", "--sample-rate", type="int", default=96000, help="input sample rate") parser.add_option("-t", "--tone-detect", action="store_true", default=False, help="use experimental tone detect algorithm") parser.add_option("-v", "--verbose", action="store_true", default=False, help="additional output") parser.add_option("-6", "--k6k", action="store_true", default=False, help="use 6K symbol rate") (options, args) = parser.parse_args() sample_rate = options.sample_rate if options.k6k: symbol_rate = 6000 else: symbol_rate = 4800 samples_per_symbol = sample_rate // symbol_rate IN = blocks.file_source(gr.sizeof_gr_complex, options.input_file) if options.one_channel: C2F = blocks.complex_to_float() F2C = blocks.float_to_complex() # osc./mixer for mixing signal down to approx. zero IF LO = analog.sig_source_c(sample_rate, analog.GR_COS_WAVE, options.calibration, 1.0, 0) MIXER = blocks.multiply_cc() # get signal into normalized range (-1.0 - +1.0) if options.agc: AMP = analog.feedforward_agc_cc(16, 1.0) else: AMP = blocks.multiply_const_cc(options.gain) lpf_taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, filter.firdes.WIN_HANN) decim_amt = 1 if options.tone_detect: if sample_rate != 96000: print "warning, only 96K has been tested." print "other rates may require theta to be reviewed/adjusted." step_size = 7.5e-8 theta = -4 # optimum timing sampling point cic_length = 48 DEMOD = op25_repeater.tdetect_cc(samples_per_symbol, step_size, theta, cic_length) else: # decim by 2 to get 48k rate samples_per_symbol /= 2 # for DECIM sample_rate /= 2 # for DECIM decim_amt = 2 # create Gardner/Costas loop # the loop will not work if the sample levels aren't normalized (above) timing_error_gain = 0.025 # loop error gain gain_omega = 0.25 * timing_error_gain * timing_error_gain alpha = options.costas_alpha beta = 0.125 * alpha * alpha fmin = -0.025 # fmin and fmax are in radians/s fmax = 0.025 DEMOD = op25_repeater.gardner_costas_cc(samples_per_symbol, timing_error_gain, gain_omega, alpha, beta, fmax, fmin) DECIM = filter.fir_filter_ccf(decim_amt, lpf_taps) # probably too much phase noise etc to attempt coherent demodulation # so we use differential DIFF = digital.diff_phasor_cc() # take angle of the phase difference (in radians) TOFLOAT = blocks.complex_to_arg() # convert from radians such that signal is in [-3, -1, +1, +3] RESCALE = blocks.multiply_const_ff(1 / (pi / 4.0)) # optional polarity reversal (should be unnec. - now autodetected) p = 1.0 if options.polarity: p = -1.0 POLARITY = blocks.multiply_const_ff(p) # hard decision at specified points levels = [-2.0, 0.0, 2.0, 4.0] SLICER = op25_repeater.fsk4_slicer_fb(levels) # assemble received frames and route to Wireshark via UDP hostname = "127.0.0.1" port = 23456 debug = 0 if options.verbose: debug = 255 do_imbe = False if options.imbe: do_imbe = True do_output = True # enable block's output stream do_msgq = False # msgq output not yet implemented msgq = gr.msg_queue(2) DECODER = op25_repeater.p25_frame_assembler(hostname, port, debug, do_imbe, do_output, do_msgq, msgq, False, False) OUT = blocks.file_sink(gr.sizeof_char, options.output_file) if options.one_channel: self.connect(IN, C2F, F2C, (MIXER, 0)) else: self.connect(IN, (MIXER, 0)) self.connect(LO, (MIXER, 1)) self.connect(MIXER, AMP, DECIM, DEMOD, DIFF, TOFLOAT, RESCALE, POLARITY, SLICER, DECODER, OUT) if options.raw_symbols: SINKC = blocks.file_sink(gr.sizeof_char, options.raw_symbols) self.connect(SLICER, SINKC) if options.debug: print 'Ready for GDB to attach (pid = %d)' % (os.getpid(), ) raw_input("Press 'Enter' to continue...")
def __init__(self, system, site_uuid, overseer_uuid): gr.top_block.__init__(self, "p25 receiver") #set globals self.is_locked = False self.system = system self.instance_uuid = '%s' % uuid.uuid4() self.log = logging.getLogger('overseer.p25_control_demod.%s' % self.instance_uuid) self.protocol_log = logging.getLogger('protocol.%s' % self.instance_uuid) self.log.info('Initializing instance: %s site: %s overseer: %s' % (self.instance_uuid, site_uuid, overseer_uuid)) self.site_uuid = site_uuid self.overseer_uuid = overseer_uuid self.control_channel = system['channels'][ system['default_control_channel']] self.control_channel_i = system['default_control_channel'] self.channel_identifier_table = {} try: self.modulation = system['modulation'] except: self.modulation = 'C4FM' self.channel_rate = 12500 symbol_rate = 4800 self.site_detail = {} self.site_detail['WACN ID'] = None self.site_detail['System ID'] = None self.site_detail['Control Channel'] = None self.site_detail['System Service Class'] = None self.site_detail['Site ID'] = None self.site_detail['RF Sub-system ID'] = None self.site_detail['RFSS Network Connection'] = None self.bad_messages = 0 self.total_messages = 0 self.quality = [] self.keep_running = True self.source = None # channel filter channel_rate = self.channel_rate * 2 self.control_prefilter = filter.freq_xlating_fir_filter_ccc( 1, (1, ), 0, channel_rate) # power squelch #power_squelch = gr.pwr_squelch_cc(squelch, 1e-3, 0, True) #self.connect(self.channel_filter, power_squelch) autotuneq = gr.msg_queue(2) self.demod_watcher = demod_watcher(self) self.symbol_deviation = 600.0 if self.modulation == 'C4FM': # FM demodulator fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = fm_demod = analog.quadrature_demod_cf( fm_demod_gain) moving_sum = blocks.moving_average_ff(10000, 1, 40000) subtract = blocks.sub_ff(1) divide_const = blocks.multiply_const_vff((0.0001, )) self.probe = blocks.probe_signal_f() self.connect(self.fm_demod, moving_sum, divide_const, self.probe) # symbol filter 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) demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, symbol_rate) elif self.modulation == 'CQPSK': # FM demodulator fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation) self.fm_demod = fm_demod = analog.quadrature_demod_cf( fm_demod_gain) moving_sum = blocks.moving_average_ff(10000, 1, 40000) subtract = blocks.sub_ff(1) divide_const = blocks.multiply_const_vff((0.0001, )) self.probe = blocks.probe_signal_f() self.connect(fm_demod, moving_sum, divide_const, self.probe) #self.resampler = filter.pfb.arb_resampler_ccf(float(48000)/float(channel_rate)) 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 omega = float(channel_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(channel_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] slicer = op25.fsk4_slicer_fb(levels) # frame decoder self.decodequeue = decodequeue = gr.msg_queue(1000) qsink = blocks.message_sink(gr.sizeof_char, self.decodequeue, False) self.decoder = decoder = repeater.p25_frame_assembler( '', 0, 0, False, True, True, autotuneq, False, False) if self.modulation == 'C4FM': self.connect(self.control_prefilter, fm_demod, symbol_filter, demod_fsk4, slicer, decoder, qsink) elif self.modulation == 'CQPSK': self.connect(self.resampler, self.agc, self.symbol_filter_c, self.clock, self.diffdec, self.to_float, self.rescale, slicer, decoder, qsink) ################################################## # Threads ################################################## self.connector = frontend_connector() self.client_redis = client_redis() self.redis_demod_publisher = redis_demod_publisher(parent_demod=self) quality_check_0 = threading.Thread(target=self.quality_check) quality_check_0.daemon = True quality_check_0.start() # Adjust the channel offset # self.tune_next_control_channel() #self.receive_engine() receive_engine = threading.Thread(target=self.receive_engine) receive_engine.daemon = True receive_engine.start()
def __init__(self): gr.top_block.__init__(self, "Tetra Rx Multi") options = self.get_options() ################################################## # Variables ################################################## self.srate_rx = srate_rx = options.sample_rate self.channels = srate_rx / 25000 self.srate_channel = 36000 self.afc_period = 5 self.afc_gain = 1. self.afc_channel = options.auto_tune or -1 self.afc_ppm_step = 100 self.debug = options.debug self.last_pwr = -100000 self.sig_det_period = 1 self.sig_det_bw = sig_det_bw = options.sig_detection_bw or srate_rx if self.sig_det_bw <= 1.: self.sig_det_bw *= srate_rx self.sig_det_threshold = options.sig_detection_threshold self.sig_det_channels = [] for ch in range(self.channels): if ch >= self.channels / 2: ch_ = (self.channels - ch - 1) else: ch_ = ch if (float(ch_) / self.channels * 2) <= (self.sig_det_bw / srate_rx): self.sig_det_channels.append(ch) ################################################## # RPC server ################################################## self.xmlrpc_server = SimpleXMLRPCServer.SimpleXMLRPCServer( ("localhost", options.listen_port), allow_none=True) self.xmlrpc_server.register_instance(self) threading.Thread(target=self.xmlrpc_server.serve_forever).start() ################################################## # Rx Blocks and connections ################################################## self.src = osmosdr.source(args=options.args) self.src.set_sample_rate(srate_rx) self.src.set_center_freq(options.frequency, 0) self.src.set_freq_corr(options.ppm, 0) self.src.set_dc_offset_mode(0, 0) self.src.set_iq_balance_mode(0, 0) if options.gain is not None: self.src.set_gain_mode(False, 0) self.src.set_gain(36, 0) else: self.src.set_gain_mode(True, 0) out_type, dst_path = options.output.split("://", 1) if out_type == "udp": dst_ip, dst_port = dst_path.split(':', 1) self.freq_xlating = freq_xlating_fft_filter_ccc(1, (1, ), 0, srate_rx) self.channelizer = pfb.channelizer_ccf( self.channels, (firdes.root_raised_cosine(1, srate_rx, 18000, 0.35, 1024)), 36. / 25., 100) self.squelch = [] self.digital_mpsk_receiver_cc = [] self.diff_phasor = [] self.complex_to_arg = [] self.multiply_const = [] self.add_const = [] self.float_to_uchar = [] self.map_bits = [] self.unpack_k_bits = [] self.blocks_sink = [] for ch in range(0, self.channels): squelch = analog.pwr_squelch_cc(0, 0.001, 0, True) mpsk = digital.mpsk_receiver_cc(4, math.pi / 4, math.pi / 100.0, -0.5, 0.5, 0.25, 0.001, 2, 0.001, 0.001) diff_phasor = digital.diff_phasor_cc() complex_to_arg = blocks.complex_to_arg(1) multiply_const = blocks.multiply_const_vff((2. / math.pi, )) add_const = blocks.add_const_vff((1.5, )) float_to_uchar = blocks.float_to_uchar() map_bits = digital.map_bb(([3, 2, 0, 1, 3])) unpack_k_bits = blocks.unpack_k_bits_bb(2) if out_type == 'udp': sink = blocks.udp_sink(gr.sizeof_gr_char, dst_ip, int(dst_port) + ch, 1472, True) elif out_type == 'file': sink = blocks.file_sink(gr.sizeof_char, dst_path % ch, False) sink.set_unbuffered(True) else: raise ValueError("Invalid output URL '%s'" % options.output) self.connect((self.channelizer, ch), (squelch, 0), (mpsk, 0), (diff_phasor, 0), (complex_to_arg, 0), (multiply_const, 0), (add_const, 0), (float_to_uchar, 0), (map_bits, 0), (unpack_k_bits, 0), (sink, 0)) self.squelch.append(squelch) self.digital_mpsk_receiver_cc.append(mpsk) self.diff_phasor.append(diff_phasor) self.complex_to_arg.append(complex_to_arg) self.multiply_const.append(multiply_const) self.add_const.append(add_const) self.float_to_uchar.append(float_to_uchar) self.map_bits.append(map_bits) self.unpack_k_bits.append(unpack_k_bits) self.blocks_sink.append(sink) self.connect((self.src, 0), (self.freq_xlating, 0), (self.channelizer, 0)) ################################################## # signal strenght identification ################################################## self.pwr_probes = [] for ch in range(self.channels): pwr_probe = analog.probe_avg_mag_sqrd_c(0, 1. / self.srate_channel) self.pwr_probes.append(pwr_probe) self.connect((self.channelizer, ch), (pwr_probe, 0)) def _sig_det_probe(): while True: pwr = [ self.pwr_probes[ch].level() for ch in range(self.channels) if ch in self.sig_det_channels ] pwr = [10 * math.log10(p) for p in pwr if p > 0.] if not pwr: continue pwr = min(pwr) + self.sig_det_threshold print "Power level for squelch % 5.1f" % pwr if abs(pwr - self.last_pwr) > (self.sig_det_threshold / 2): for s in self.squelch: s.set_threshold(pwr) self.last_pwr = pwr time.sleep(self.sig_det_period) if self.sig_det_threshold is not None: self._sig_det_probe_thread = threading.Thread( target=_sig_det_probe) self._sig_det_probe_thread.daemon = True self._sig_det_probe_thread.start() ################################################## # AFC blocks and connections ################################################## self.afc_selector = grc_blks2.selector( item_size=gr.sizeof_gr_complex, num_inputs=self.channels, num_outputs=1, input_index=0, output_index=0, ) self.afc_demod = analog.quadrature_demod_cf(self.srate_channel / (2 * math.pi)) samp_afc = self.srate_channel * self.afc_period / 2 self.afc_avg = blocks.moving_average_ff(samp_afc, 1. / samp_afc * self.afc_gain) self.afc_probe = blocks.probe_signal_f() def _afc_probe(): while True: time.sleep(self.afc_period) if self.afc_channel == -1: continue err = self.afc_probe.level() if abs(err) < self.afc_ppm_step: continue freq = self.freq_xlating.center_freq + err * self.afc_gain if self.debug: print "err: %f\tfreq: %f" % ( err, freq, ) self.freq_xlating.set_center_freq(freq) self._afc_err_thread = threading.Thread(target=_afc_probe) self._afc_err_thread.daemon = True self._afc_err_thread.start() for ch in range(self.channels): self.connect((self.channelizer, ch), (self.afc_selector, ch)) self.connect((self.afc_selector, 0), (self.afc_demod, 0), (self.afc_avg, 0), (self.afc_probe, 0)) if self.afc_channel != -1: self.afc_selector.set_input_index(self.afc_channel)
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()
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Psk31 Rx") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.center_freq = center_freq = 441000000 self.samp_rate = samp_rate = 960000 self.psk_offset = psk_offset = 1000 self.psk_center = psk_center = center_freq + 141000 self.int_rate = int_rate = 48000 self.gain = gain = 30 self.corr = corr = 0 self.audio_rate = audio_rate = 8000 ################################################## # Message Queues ################################################## blocks_message_sink_0_msgq_out = wxgui_termsink_0_msgq_in = gr.msg_queue( 2) ################################################## # Blocks ################################################## _psk_offset_sizer = wx.BoxSizer(wx.VERTICAL) self._psk_offset_text_box = forms.text_box( parent=self.GetWin(), sizer=_psk_offset_sizer, value=self.psk_offset, callback=self.set_psk_offset, label="PSK offset", converter=forms.float_converter(), proportion=0, ) self._psk_offset_slider = forms.slider( parent=self.GetWin(), sizer=_psk_offset_sizer, value=self.psk_offset, callback=self.set_psk_offset, minimum=0, maximum=3000, num_steps=300, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_psk_offset_sizer, 1, 0, 1, 2) _psk_center_sizer = wx.BoxSizer(wx.VERTICAL) self._psk_center_text_box = forms.text_box( parent=self.GetWin(), sizer=_psk_center_sizer, value=self.psk_center, callback=self.set_psk_center, label="Tuning", converter=forms.float_converter(), proportion=0, ) self._psk_center_slider = forms.slider( parent=self.GetWin(), sizer=_psk_center_sizer, value=self.psk_center, callback=self.set_psk_center, minimum=center_freq + 110000, maximum=center_freq + 150000, num_steps=40, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_psk_center_sizer, 0, 0, 1, 2) self.nb = self.nb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.nb.AddPage(grc_wxgui.Panel(self.nb), "960 kHz") self.nb.AddPage(grc_wxgui.Panel(self.nb), "48 kHz") self.nb.AddPage(grc_wxgui.Panel(self.nb), "4 kHz") self.nb.AddPage(grc_wxgui.Panel(self.nb), "I/Q scope") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Constellation") self.GridAdd(self.nb, 3, 0, 1, 2) _gain_sizer = wx.BoxSizer(wx.VERTICAL) self._gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, label='gain', converter=forms.float_converter(), proportion=0, ) self._gain_slider = forms.slider( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, minimum=0, maximum=49.6, num_steps=124, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_gain_sizer, 2, 0, 1, 1) _corr_sizer = wx.BoxSizer(wx.VERTICAL) self._corr_text_box = forms.text_box( parent=self.GetWin(), sizer=_corr_sizer, value=self.corr, callback=self.set_corr, label='corr', converter=forms.float_converter(), proportion=0, ) self._corr_slider = forms.slider( parent=self.GetWin(), sizer=_corr_sizer, value=self.corr, callback=self.set_corr, minimum=-150, maximum=150, num_steps=300, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_corr_sizer, 2, 1, 1, 1) self.wxgui_waterfallsink2_2 = waterfallsink2.waterfall_sink_f( self.nb.GetPage(2).GetWin(), baseband_freq=0, dynamic_range=30, ref_level=-40, ref_scale=2.0, sample_rate=audio_rate, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", win=window.blackmanharris, size=((800, 400)), ) self.nb.GetPage(2).Add(self.wxgui_waterfallsink2_2.win) def wxgui_waterfallsink2_2_callback(x, y): self.set_psk_offset(x) self.wxgui_waterfallsink2_2.set_callback( wxgui_waterfallsink2_2_callback) self.wxgui_waterfallsink2_1 = waterfallsink2.waterfall_sink_c( self.nb.GetPage(1).GetWin(), baseband_freq=psk_center, dynamic_range=30, ref_level=-30, ref_scale=2.0, sample_rate=int_rate, fft_size=2048, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", size=((800, 400)), ) self.nb.GetPage(1).Add(self.wxgui_waterfallsink2_1.win) self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c( self.nb.GetPage(0).GetWin(), baseband_freq=center_freq, dynamic_range=30, ref_level=-20, ref_scale=2.0, sample_rate=samp_rate, fft_size=2048, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", size=((800, 400)), ) self.nb.GetPage(0).Add(self.wxgui_waterfallsink2_0.win) def wxgui_waterfallsink2_0_callback(x, y): self.set_psk_center(x) self.wxgui_waterfallsink2_0.set_callback( wxgui_waterfallsink2_0_callback) self.wxgui_termsink_0 = termsink.termsink( parent=self.GetWin(), size=(500, 100), msgq=wxgui_termsink_0_msgq_in, ) self.Add(self.wxgui_termsink_0) self.wxgui_scopesink2_1 = scopesink2.scope_sink_c( self.nb.GetPage(4).GetWin(), title="Scope Plot", sample_rate=31.25, v_scale=0.4, v_offset=0, t_scale=0, ac_couple=False, xy_mode=True, num_inputs=1, trig_mode=wxgui.TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(4).Add(self.wxgui_scopesink2_1.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_c( self.nb.GetPage(3).GetWin(), title="Scope Plot", sample_rate=500, v_scale=0.4, v_offset=0, t_scale=0, ac_couple=False, xy_mode=True, num_inputs=1, trig_mode=wxgui.TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(3).Add(self.wxgui_scopesink2_0.win) self.wxgui_numbersink2_0 = numbersink2.number_sink_f( self.GetWin(), unit="Hz", minval=-500 / math.pi, maxval=500 / math.pi, factor=500 / math.pi, decimal_places=1, ref_level=0, sample_rate=500, number_rate=15, average=False, avg_alpha=None, label="Carrier tracking offset", peak_hold=False, show_gauge=True, ) self.Add(self.wxgui_numbersink2_0.win) self.osmosdr_source_0 = osmosdr.source(args="numchan=" + str(1) + " " + "") self.osmosdr_source_0.set_sample_rate(samp_rate) self.osmosdr_source_0.set_center_freq(center_freq, 0) self.osmosdr_source_0.set_freq_corr(corr, 0) self.osmosdr_source_0.set_dc_offset_mode(0, 0) self.osmosdr_source_0.set_iq_balance_mode(0, 0) self.osmosdr_source_0.set_gain_mode(0, 0) self.osmosdr_source_0.set_gain(gain, 0) self.osmosdr_source_0.set_if_gain(20, 0) self.osmosdr_source_0.set_bb_gain(20, 0) self.osmosdr_source_0.set_antenna("", 0) self.osmosdr_source_0.set_bandwidth(0, 0) self.ham_varicode_rx_0 = ham.varicode_rx() self.freq_xlating_fir_filter_xxx_1 = filter.freq_xlating_fir_filter_ccc( 16, (firdes.low_pass(10, audio_rate, 120, 40, firdes.WIN_HAMMING, 6.76)), psk_offset, audio_rate) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc( samp_rate / int_rate, (firdes.low_pass(1, samp_rate, 12000, 12000, firdes.WIN_HAMMING, 6.76)), round(psk_center - center_freq, -3), samp_rate) self.digital_diff_phasor_cc_0 = digital.diff_phasor_cc() self.digital_costas_loop_cc_0 = digital.costas_loop_cc( 5 * math.pi / 100.0, 2) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_cc( 16, 0.25 * 0.175 * 0.175, 0.5, 0.175, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_message_sink_0 = blocks.message_sink( gr.sizeof_char * 1, blocks_message_sink_0_msgq_out, True) self.blocks_complex_to_real_1 = blocks.complex_to_real(1) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.band_pass_filter_0 = filter.fir_filter_ccc( int_rate / audio_rate, firdes.complex_band_pass(1, int_rate, 200, 2800, 200, firdes.WIN_HAMMING, 6.76)) self.audio_sink_0 = audio.sink(audio_rate, "plughw:0,0", True) self.analog_agc_xx_0 = analog.agc_cc(1e-3, 0.1, 1.0) self.analog_agc_xx_0.set_max_gain(65536) ################################################## # Connections ################################################## self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_waterfallsink2_1, 0)) self.connect((self.osmosdr_source_0, 0), (self.wxgui_waterfallsink2_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.wxgui_waterfallsink2_2, 0)) self.connect((self.digital_costas_loop_cc_0, 1), (self.wxgui_numbersink2_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_1, 0), (self.digital_costas_loop_cc_0, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_diff_phasor_cc_0, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.ham_varicode_rx_0, 0), (self.blocks_message_sink_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.ham_varicode_rx_0, 0)) self.connect((self.blocks_complex_to_real_1, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.digital_diff_phasor_cc_0, 0), (self.blocks_complex_to_real_1, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.audio_sink_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.analog_agc_xx_0, 0)) self.connect((self.analog_agc_xx_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.analog_agc_xx_0, 0), (self.freq_xlating_fir_filter_xxx_1, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.wxgui_scopesink2_1, 0))