def __init__(self, bt=0.3, samples_per_symbol=2): gr.hier_block2.__init__( self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_char), gr.io_signature(1, 1, gr.sizeof_gr_complex) ) ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 # Turn it into NRZ data. self.unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) self.nrz = digital.chunks_to_symbols_bf([-1, 1], 1) # note could also invert bits here # Form Gaussian filter # Generate Gaussian response (Needs to be convolved with window below). self.gaussian_taps = gr.firdes.gaussian(1, samples_per_symbol, bt, ntaps) self.sqwave = (1,) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps), numpy.array(self.sqwave)) self.gaussian_filter = filter.interp_fir_filter_fff(samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-0.5,)) # CC430 RF core is inverted with respect to USRP for some reason self.invert = gr.multiply_const_vff((-1,)) # Connect & Initialize base class self.connect(self, self.unpack, self.nrz, self.invert, self.offset, self.gaussian_filter, self.fmmod, self)
def _setup_top_block(self): self.tb = gr.top_block() samp_rate = 96000 oversample = 10 center_freq = 868.280e6 # Radio receiver, initial downsampling args = str("nchan=1 rtl=%s,buffers=16,offset_tune=1" % self.device) osmosdr_source = osmosdr.source_c(args=args) osmosdr_source.set_sample_rate(samp_rate*oversample) osmosdr_source.set_center_freq(center_freq, 0) osmosdr_source.set_freq_corr(0, 0) osmosdr_source.set_gain_mode(1, 0) osmosdr_source.set_gain(0, 0) low_pass_filter = gr.fir_filter_ccf(oversample, firdes.low_pass(1, samp_rate*oversample, 90e3, 8e3, firdes.WIN_HAMMING, 6.76)) self.tb.connect((osmosdr_source, 0), (low_pass_filter, 0)) # Squelch self.noise_probe = gr.probe_avg_mag_sqrd_c(0, 1.0/samp_rate/1e2) self.squelch = gr.simple_squelch_cc(self.noise_level, 1) noise_probe_thread = threading.Thread(target=self._noise_probe_thread) noise_probe_thread.start() self.threads.append(noise_probe_thread) self.tb.connect((low_pass_filter, 0), (self.noise_probe, 0)) self.tb.connect((low_pass_filter, 0), (self.squelch, 0)) # FM demodulation quadrature_demod = gr.quadrature_demod_cf(1) self.tb.connect((self.squelch, 0), (quadrature_demod, 0)) # Binary slicing, transformation into capture-compatible format add_offset = gr.add_const_vff((-1e-3, )) binary_slicer = digital.binary_slicer_fb() char_to_float = gr.char_to_float(1, 1) multiply_const = gr.multiply_const_vff((255, )) float_to_uchar = gr.float_to_uchar() pipe_sink = gr.file_sink(gr.sizeof_char*1, self.pipe) pipe_sink.set_unbuffered(False) self.tb.connect((quadrature_demod, 0), (add_offset, 0)) self.tb.connect((add_offset, 0), (binary_slicer, 0)) self.tb.connect((binary_slicer, 0), (char_to_float, 0)) self.tb.connect((char_to_float, 0), (multiply_const, 0)) self.tb.connect((multiply_const, 0), (float_to_uchar, 0)) self.tb.connect((float_to_uchar, 0), (pipe_sink, 0))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.variable_slider_0 = variable_slider_0 = 30 self.samp_rate = samp_rate = 32000 ################################################## # Blocks ################################################## _variable_slider_0_sizer = wx.BoxSizer(wx.VERTICAL) self._variable_slider_0_text_box = forms.text_box( parent=self.GetWin(), sizer=_variable_slider_0_sizer, value=self.variable_slider_0, callback=self.set_variable_slider_0, label='variable_slider_0', converter=forms.float_converter(), proportion=0, ) self._variable_slider_0_slider = forms.slider( parent=self.GetWin(), sizer=_variable_slider_0_sizer, value=self.variable_slider_0, callback=self.set_variable_slider_0, minimum=0, maximum=100, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_variable_slider_0_sizer) self.sbfan_0 = sbfan.sbfan(1,0,0) self.plot_sink_0 = plot_sink.plot_sink_f( self.GetWin(), title="Scope Plot", vlen=1, decim=1, gsz=1000, zoom=0, ) self.Add(self.plot_sink_0.win) self.gr_sig_source_x_0 = gr.sig_source_f(samp_rate, gr.GR_SIN_WAVE, 1000, 30, 0) self.gr_delay_0 = gr.delay(gr.sizeof_float*1, 5) self.gr_add_const_vxx_0 = gr.add_const_vff((30, )) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 40) ################################################## # Connections ################################################## self.connect((self.const_source_x_0, 0), (self.sbfan_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_add_const_vxx_0, 0)) self.connect((self.sbfan_0, 0), (self.plot_sink_0, 0)) self.connect((self.gr_add_const_vxx_0, 0), (self.gr_delay_0, 0)) self.connect((self.gr_delay_0, 0), (self.sbfan_0, 1))
def __init__(self,k): gr.hier_block2.__init__(self,"BER Estimator", gr.io_signature(1,1,gr.sizeof_float), gr.io_signature(1,1,gr.sizeof_float)) self.add = gr.add_const_vff((-1, )) self.mult= gr.multiply_const_ff(-1/k) self.connect(self,self.add, self.mult,self)
def __init__(self, k): gr.hier_block2.__init__(self, "BER Estimator", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) self.add = gr.add_const_vff((-1, )) self.mult = gr.multiply_const_ff(-1 / k) self.connect(self, self.add, self.mult, self)
def __init__(self, bt = 0.3, samples_per_symbol = 2, ti_adj=False): gr.hier_block2.__init__(self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_char), gr.io_signature(1, 1, gr.sizeof_gr_complex)) self.sps = 2 self.bt = 0.35 self.mu = 0.5 self.gain_mu = 0.175 self.freq_error = 0.0 self.omega_relative_limit = 0.005 self.omega = self.sps * (1 + self.freq_error) self.gain_omega = .25 * self.gain_mu * self.gain_mu # critically damped ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 # Turn it into NRZ data. self.unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) self.nrz = digital.chunks_to_symbols_bf([-1, 1], 1) # note could also invert bits here # Form Gaussian filter # Generate Gaussian response (Needs to be convolved with window below). self.gaussian_taps = gr.firdes.gaussian(1, samples_per_symbol, bt, ntaps) self.sqwave = (1,) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) self.gaussian_filter = filter.interp_fir_filter_fff(samples_per_symbol, self.taps) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff(self.omega, self.gain_omega, self.mu, self.gain_mu, self.omega_relative_limit) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-.5, )) # CC430 RF core is inverted with respect to USRP for some reason self.invert = gr.multiply_const_vff((-1, )) # Connect & Initialize base class if ti_adj: self.connect(self, self.unpack, self.nrz, self.invert, self.offset, self.gaussian_filter, self.fmmod, self) else: self.connect(self, self.unpack, self.nrz, self.gaussian_filter, self.fmmod, self)
def __init__(self): gr.hier_block2.__init__(self,"BER Estimator", gr.io_signature(1,1,gr.sizeof_float), gr.io_signature(1,1,gr.sizeof_float)) #TODO Implement a polynomial block in C++ and approximate with polynomials #of arbitrary order self.add = gr.add_const_vff((-1, )) self.square = gr.multiply_ff() self.mult_lin = gr.multiply_const_ff(-0.20473967) self.mult_sq = gr.multiply_const_ff(1.5228658) self.sum = gr.add_ff() self.connect(self,self.add) self.connect(self.add,(self.square,0)) self.connect(self.add,(self.square,1)) self.connect(self.square,self.mult_sq,(self.sum,0)) self.connect(self.add,self.mult_lin,(self.sum,1)) self.connect(self.sum,self)
def __init__(self): gr.hier_block2.__init__(self, "BER Estimator", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) #TODO Implement a polynomial block in C++ and approximate with polynomials #of arbitrary order self.add = gr.add_const_vff((-1, )) self.square = gr.multiply_ff() self.mult_lin = gr.multiply_const_ff(-0.20473967) self.mult_sq = gr.multiply_const_ff(1.5228658) self.sum = gr.add_ff() self.connect(self, self.add) self.connect(self.add, (self.square, 0)) self.connect(self.add, (self.square, 1)) self.connect(self.square, self.mult_sq, (self.sum, 0)) self.connect(self.add, self.mult_lin, (self.sum, 1)) self.connect(self.sum, self)
def __init__(self, app, samp_rate, at, filename, repeat, sine, lc): ''' in: - app = object of type RXApp - samp_rate = sample rate in Hertz - at = attenuation factor - filename = filename - repeat = if True them reads in a loop the file - sine - lc = large carrier ''' gr.hier_block2.__init__(self, "RXData", gr.io_signature(0, 0, 0), gr.io_signature(1, 1, gr.sizeof_gr_complex)) # instance variables self.app = app if sine: self.fileSrc = gr.sig_source_f(samp_rate, gr.GR_SIN_WAVE, 1000, 1.0) self.addCte = None self.mulitplyCte = None print "i: signal = sine" else: if at == 0.0: self.fileSrc = gr.null_source(gr.sizeof_float*1) self.addCte = None self.mulitplyCte = None print "i: signal = null" else: self.fileSrc = gr.file_source(gr.sizeof_float*1, filename, repeat) self.addCte = gr.add_const_vff((lc, )) self.mulitplyCte = gr.multiply_const_vff((at, )) print "i: signal = " + filename # self.mulitplyCte = gr.multiply_const_vff((at, )) self.f2c = gr.float_to_complex(1) #EO instance variables self.__makeConnections()
def __init__(self): """ Hierarchical block for MSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__(self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) self.sps = 2 self.bt = 0.35 self.mu = 0.5 self.gain_mu = 0.175 self.freq_error = 0.0 self.omega_relative_limit = 0.005 self.omega = self.sps * (1 + self.freq_error) self.gain_omega = .25 * self.gain_mu * self.gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / self.sps self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.invert = gr.multiply_const_vff((-1, )) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-1.4, )) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff( self.omega, self.gain_omega, self.mu, self.gain_mu, self.omega_relative_limit) self.slicer = digital.binary_slicer_fb() self.connect(self, self.fmdemod, self.invert, self.clock_recovery, self.offset, self)
def __init__(self): gr.top_block.__init__(self, "MSK Demod Demo") # Variables self.samp_rate = samp_rate = 125e3 self.f_center = f_center = 868e6 self.bandwidth = bandwidth = 500e3 self.gain = gain = 5 self.decimation = decimation = 2 # Blocks self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(f_center, 0) self.uhd_usrp_source_0.set_gain(gain, 0) self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0) self.msk_demod = msk.msk_demod_cf() self.slicer = digital.binary_slicer_fb() self.slicer2 = digital.binary_slicer_fb() self.offset = gr.add_const_vff((0, )) self.sink = gr.vector_sink_b(1) self.f_sink = gr.vector_sink_f(1) self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log') # Connections self.connect(self.uhd_usrp_source_0, self.msk_demod, self.offset, self.slicer, self.sink) self.connect(self.offset, self.f_sink) self.connect(self.offset, self.slicer2, self.file_sink)
def __init__(self): """ Hierarchical block for MSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__( self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float) ) self.sps = 2 self.bt = 0.35 self.mu = 0.5 self.gain_mu = 0.175 self.freq_error = 0.0 self.omega_relative_limit = 0.005 self.omega = self.sps * (1 + self.freq_error) self.gain_omega = 0.25 * self.gain_mu * self.gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / self.sps self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.invert = gr.multiply_const_vff((-1,)) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-1.2,)) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff( self.omega, self.gain_omega, self.mu, self.gain_mu, self.omega_relative_limit ) self.slicer = digital.binary_slicer_fb() self.connect(self, self.fmdemod, self.invert, self.clock_recovery, self.offset, self)
def __init__(self, bt=0.3, samples_per_symbol=2): gr.hier_block2.__init__(self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_char), gr.io_signature(1, 1, gr.sizeof_gr_complex)) ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 # Turn it into NRZ data. self.unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) self.nrz = digital.chunks_to_symbols_bf( [-1, 1], 1) # note could also invert bits here # Form Gaussian filter # Generate Gaussian response (Needs to be convolved with window below). self.gaussian_taps = gr.firdes.gaussian(1, samples_per_symbol, bt, ntaps) self.sqwave = (1, ) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps), numpy.array(self.sqwave)) self.gaussian_filter = filter.interp_fir_filter_fff( samples_per_symbol, self.taps) # FM modulation self.fmmod = gr.frequency_modulator_fc(sensitivity) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-.5, )) # CC430 RF core is inverted with respect to USRP for some reason self.invert = gr.multiply_const_vff((-1, )) # Connect & Initialize base class self.connect(self, self.unpack, self.nrz, self.invert, self.offset, self.gaussian_filter, self.fmmod, self)
def __init__(self, sample_rate, ber_threshold=0, # Above which to do search ber_smoothing=0, # Alpha of BER smoother (0.01) ber_duration=0, # Length before trying next combo ber_sample_decimation=1, settling_period=0, pre_lock_duration=0, #ber_sample_skip=0 **kwargs): use_throttle = False base_duration = 1024 if sample_rate > 0: use_throttle = True base_duration *= 4 # Has to be high enough for block-delay if ber_threshold == 0: ber_threshold = 512 * 4 if ber_smoothing == 0: ber_smoothing = 0.01 if ber_duration == 0: ber_duration = base_duration * 2 # 1000ms if settling_period == 0: settling_period = base_duration * 1 # 500ms if pre_lock_duration == 0: pre_lock_duration = base_duration * 2 #1000ms print "Creating Auto-FEC:" print "\tsample_rate:\t\t", sample_rate print "\tber_threshold:\t\t", ber_threshold print "\tber_smoothing:\t\t", ber_smoothing print "\tber_duration:\t\t", ber_duration print "\tber_sample_decimation:\t", ber_sample_decimation print "\tsettling_period:\t", settling_period print "\tpre_lock_duration:\t", pre_lock_duration print "" self.sample_rate = sample_rate self.ber_threshold = ber_threshold #self.ber_smoothing = ber_smoothing self.ber_duration = ber_duration self.settling_period = settling_period self.pre_lock_duration = pre_lock_duration #self.ber_sample_skip = ber_sample_skip self.data_lock = threading.Lock() gr.hier_block2.__init__(self, "auto_fec", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Post MPSK-receiver complex input gr.io_signature3(3, 3, gr.sizeof_char, gr.sizeof_float, gr.sizeof_float)) # Decoded packed bytes, BER metric, lock self.input_watcher = auto_fec_input_watcher(self) default_xform = self.input_watcher.xform_lock self.gr_conjugate_cc_0 = gr.conjugate_cc() self.connect((self, 0), (self.gr_conjugate_cc_0, 0)) # Input self.blks2_selector_0 = grc_blks2.selector( item_size=gr.sizeof_gr_complex*1, num_inputs=2, num_outputs=1, input_index=default_xform.get_conjugation_index(), output_index=0, ) self.connect((self.gr_conjugate_cc_0, 0), (self.blks2_selector_0, 0)) self.connect((self, 0), (self.blks2_selector_0, 1)) # Input self.gr_multiply_const_vxx_3 = gr.multiply_const_vcc((0.707*(1+1j), )) self.connect((self.blks2_selector_0, 0), (self.gr_multiply_const_vxx_3, 0)) self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc((default_xform.get_rotation(), )) # phase_mult self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_multiply_const_vxx_2, 0)) self.gr_complex_to_float_0_0 = gr.complex_to_float(1) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_complex_to_float_0_0, 0)) self.gr_interleave_1 = gr.interleave(gr.sizeof_float*1) self.connect((self.gr_complex_to_float_0_0, 1), (self.gr_interleave_1, 1)) self.connect((self.gr_complex_to_float_0_0, 0), (self.gr_interleave_1, 0)) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((1, )) # invert self.connect((self.gr_interleave_1, 0), (self.gr_multiply_const_vxx_0, 0)) self.baz_delay_2 = baz.delay(gr.sizeof_float*1, default_xform.get_puncture_delay()) # delay_puncture self.connect((self.gr_multiply_const_vxx_0, 0), (self.baz_delay_2, 0)) self.depuncture_ff_0 = baz.depuncture_ff((_puncture_matrices[self.input_watcher.puncture_matrix][1])) # puncture_matrix self.connect((self.baz_delay_2, 0), (self.depuncture_ff_0, 0)) self.baz_delay_1 = baz.delay(gr.sizeof_float*1, default_xform.get_viterbi_delay()) # delay_viterbi self.connect((self.depuncture_ff_0, 0), (self.baz_delay_1, 0)) self.swap_ff_0 = baz.swap_ff(default_xform.get_viterbi_swap()) # swap_viterbi self.connect((self.baz_delay_1, 0), (self.swap_ff_0, 0)) self.gr_decode_ccsds_27_fb_0 = gr.decode_ccsds_27_fb() if use_throttle: print "==> Using throttle at sample rate:", self.sample_rate self.gr_throttle_0 = gr.throttle(gr.sizeof_float, self.sample_rate) self.connect((self.swap_ff_0, 0), (self.gr_throttle_0, 0)) self.connect((self.gr_throttle_0, 0), (self.gr_decode_ccsds_27_fb_0, 0)) else: self.connect((self.swap_ff_0, 0), (self.gr_decode_ccsds_27_fb_0, 0)) self.connect((self.gr_decode_ccsds_27_fb_0, 0), (self, 0)) # Output bytes self.gr_add_const_vxx_1 = gr.add_const_vff((-4096, )) self.connect((self.gr_decode_ccsds_27_fb_0, 1), (self.gr_add_const_vxx_1, 0)) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((-1, )) self.connect((self.gr_add_const_vxx_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self, 1)) # Output BER self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(ber_smoothing, 1) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.gr_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float, ber_sample_decimation) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0)) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) # Last param is const value if use_throttle: lock_throttle_rate = self.sample_rate // 16 print "==> Using lock throttle rate:", lock_throttle_rate self.gr_throttle_1 = gr.throttle(gr.sizeof_float, lock_throttle_rate) self.connect((self.const_source_x_0, 0), (self.gr_throttle_1, 0)) self.connect((self.gr_throttle_1, 0), (self, 2)) else: self.connect((self.const_source_x_0, 0), (self, 2)) self.msg_q = gr.msg_queue(2*256) # message queue that holds at most 2 messages, increase to speed up process self.msg_sink = gr.message_sink(gr.sizeof_float, self.msg_q, dont_block=0) # Block to speed up process self.connect((self.gr_keep_one_in_n_0, 0), self.msg_sink) self.input_watcher.start()
def __init__(self, freq_corr=0, N_id_1=134, avg_frames=1, N_id_2=0, decim=16): grc_wxgui.top_block_gui.__init__(self, title="Sss Corr2 Gui") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.freq_corr = freq_corr self.N_id_1 = N_id_1 self.avg_frames = avg_frames self.N_id_2 = N_id_2 self.decim = decim ################################################## # Variables ################################################## self.vec_half_frame = vec_half_frame = 30720 * 5 / decim self.samp_rate = samp_rate = 30720e3 / decim self.rot = rot = 0 self.noise_level = noise_level = 0 self.fft_size = fft_size = 2048 / decim ################################################## # Blocks ################################################## _rot_sizer = wx.BoxSizer(wx.VERTICAL) self._rot_text_box = forms.text_box( parent=self.GetWin(), sizer=_rot_sizer, value=self.rot, callback=self.set_rot, label='rot', converter=forms.float_converter(), proportion=0, ) self._rot_slider = forms.slider( parent=self.GetWin(), sizer=_rot_sizer, value=self.rot, callback=self.set_rot, minimum=0, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_rot_sizer) _noise_level_sizer = wx.BoxSizer(wx.VERTICAL) self._noise_level_text_box = forms.text_box( parent=self.GetWin(), sizer=_noise_level_sizer, value=self.noise_level, callback=self.set_noise_level, label='noise_level', converter=forms.float_converter(), proportion=0, ) self._noise_level_slider = forms.slider( parent=self.GetWin(), sizer=_noise_level_sizer, value=self.noise_level, callback=self.set_noise_level, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_noise_level_sizer) self.wxgui_scopesink2_0 = scopesink2.scope_sink_c( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=2, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.gr_vector_to_stream_1 = gr.vector_to_stream( gr.sizeof_gr_complex * 1, fft_size) self.gr_vector_to_stream_0_2 = gr.vector_to_stream( gr.sizeof_gr_complex * 1, fft_size) self.gr_vector_to_stream_0_1 = gr.vector_to_stream( gr.sizeof_gr_complex * 1, fft_size) self.gr_vector_to_stream_0_0 = gr.vector_to_stream( gr.sizeof_gr_complex * 1, fft_size) self.gr_vector_to_stream_0 = gr.vector_to_stream( gr.sizeof_float * 1, fft_size) self.gr_vector_source_x_0_0_0 = gr.vector_source_c( (gen_pss_fd(N_id_2, fft_size, False).get_data()), True, fft_size) self.gr_vector_source_x_0_0 = gr.vector_source_c( (gen_pss_fd(N_id_2, fft_size, False).get_data()), True, fft_size) self.gr_vector_source_x_0 = gr.vector_source_c( (gen_sss_fd(N_id_1, N_id_2, fft_size).get_sss(True)), True, fft_size) self.gr_stream_to_vector_0_0 = gr.stream_to_vector( gr.sizeof_gr_complex * 1, fft_size) self.gr_stream_to_vector_0 = gr.stream_to_vector( gr.sizeof_gr_complex * 1, fft_size) self.gr_repeat_0 = gr.repeat(gr.sizeof_float * 1, fft_size) self.gr_null_sink_0_0 = gr.null_sink(gr.sizeof_gr_complex * 1) self.gr_null_sink_0 = gr.null_sink(gr.sizeof_gr_complex * 1) self.gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, noise_level, 0) self.gr_multiply_xx_1 = gr.multiply_vcc(1) self.gr_multiply_xx_0 = gr.multiply_vcc(fft_size) self.gr_multiply_const_vxx_1 = gr.multiply_const_vcc((1 / 1500., )) self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc( (exp(rot * 2 * numpy.pi * 1j), )) self.gr_interleave_0 = gr.interleave(gr.sizeof_gr_complex * fft_size) self.gr_integrate_xx_0 = gr.integrate_ff(fft_size) self.gr_float_to_complex_0_0 = gr.float_to_complex(1) self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_file_source_0 = gr.file_source( gr.sizeof_gr_complex * 1, "/home/user/git/gr-lte/gr-lte/test/foo_pss0_sss_in.cfile", True) self.gr_fft_vxx_1 = gr.fft_vcc(fft_size, False, (window.blackmanharris(1024)), True, 1) self.gr_fft_vxx_0 = gr.fft_vcc(fft_size, True, (window.blackmanharris(1024)), True, 1) self.gr_divide_xx_0_1 = gr.divide_cc(1) self.gr_divide_xx_0_0 = gr.divide_ff(1) self.gr_divide_xx_0 = gr.divide_cc(1) self.gr_deinterleave_0 = gr.deinterleave(gr.sizeof_gr_complex * fft_size) self.gr_conjugate_cc_1 = gr.conjugate_cc() self.gr_conjugate_cc_0 = gr.conjugate_cc() self.gr_complex_to_mag_squared_0_0 = gr.complex_to_mag_squared(1) self.gr_complex_to_mag_squared_0 = gr.complex_to_mag_squared(fft_size) self.gr_add_xx_0 = gr.add_vcc(1) self.gr_add_const_vxx_0 = gr.add_const_vff((1, )) self.const_source_x_0_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) ################################################## # Connections ################################################## self.connect((self.gr_file_source_0, 0), (self.gr_stream_to_vector_0, 0)) self.connect((self.gr_conjugate_cc_0, 0), (self.gr_stream_to_vector_0_0, 0)) self.connect((self.gr_stream_to_vector_0_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_deinterleave_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_complex_to_mag_squared_0, 0)) self.connect((self.gr_complex_to_mag_squared_0, 0), (self.gr_vector_to_stream_0, 0)) self.connect((self.gr_vector_to_stream_0, 0), (self.gr_integrate_xx_0, 0)) self.connect((self.gr_integrate_xx_0, 0), (self.gr_repeat_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_vector_to_stream_0_0, 0)) self.connect((self.gr_vector_to_stream_0_1, 0), (self.gr_multiply_xx_1, 1)) self.connect((self.gr_divide_xx_0, 0), (self.gr_multiply_xx_1, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.gr_divide_xx_0, 1)) self.connect((self.gr_conjugate_cc_1, 0), (self.gr_divide_xx_0, 0)) self.connect((self.gr_deinterleave_0, 1), (self.gr_vector_to_stream_0_1, 0)) self.connect((self.gr_repeat_0, 0), (self.gr_float_to_complex_0, 0)) self.connect((self.const_source_x_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.gr_vector_to_stream_0_0, 0), (self.gr_conjugate_cc_1, 0)) self.connect((self.gr_vector_to_stream_0_0, 0), (self.gr_complex_to_mag_squared_0_0, 0)) self.connect((self.gr_complex_to_mag_squared_0_0, 0), (self.gr_divide_xx_0_0, 0)) self.connect((self.gr_repeat_0, 0), (self.gr_divide_xx_0_0, 1)) self.connect((self.gr_divide_xx_0_0, 0), (self.gr_add_const_vxx_0, 0)) self.connect((self.gr_add_const_vxx_0, 0), (self.gr_float_to_complex_0_0, 0)) self.connect((self.const_source_x_0_0, 0), (self.gr_float_to_complex_0_0, 1)) self.connect((self.gr_float_to_complex_0_0, 0), (self.gr_divide_xx_0_1, 1)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_divide_xx_0_1, 0)) self.connect((self.gr_stream_to_vector_0, 0), (self.gr_fft_vxx_0, 0)) self.connect((self.gr_fft_vxx_0, 0), (self.gr_deinterleave_0, 0)) self.connect((self.gr_vector_to_stream_0_2, 0), (self.gr_conjugate_cc_0, 0)) self.connect((self.gr_divide_xx_0_1, 0), (self.gr_null_sink_0, 0)) self.connect((self.gr_vector_source_x_0, 0), (self.gr_interleave_0, 1)) self.connect((self.gr_interleave_0, 0), (self.gr_fft_vxx_1, 0)) self.connect((self.gr_fft_vxx_1, 0), (self.gr_vector_to_stream_1, 0)) self.connect((self.gr_vector_source_x_0_0, 0), (self.gr_interleave_0, 0)) self.connect((self.gr_vector_source_x_0_0_0, 0), (self.gr_vector_to_stream_0_2, 0)) self.connect((self.gr_noise_source_x_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.gr_vector_to_stream_1, 0), (self.gr_add_xx_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_vector_to_stream_0_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.gr_null_sink_0_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_scopesink2_0, 1)) self.connect((self.gr_divide_xx_0_1, 0), (self.wxgui_scopesink2_0, 0))
def __init__(self, freq_corr=0, N_id_1=134, avg_frames=1, N_id_2=0, decim=16): grc_wxgui.top_block_gui.__init__(self, title="Sss Corr2 Gui") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.freq_corr = freq_corr self.N_id_1 = N_id_1 self.avg_frames = avg_frames self.N_id_2 = N_id_2 self.decim = decim ################################################## # Variables ################################################## self.vec_half_frame = vec_half_frame = 30720*5/decim self.samp_rate = samp_rate = 30720e3/decim self.rot = rot = 0 self.noise_level = noise_level = 0 self.fft_size = fft_size = 2048/decim ################################################## # Blocks ################################################## _rot_sizer = wx.BoxSizer(wx.VERTICAL) self._rot_text_box = forms.text_box( parent=self.GetWin(), sizer=_rot_sizer, value=self.rot, callback=self.set_rot, label='rot', converter=forms.float_converter(), proportion=0, ) self._rot_slider = forms.slider( parent=self.GetWin(), sizer=_rot_sizer, value=self.rot, callback=self.set_rot, minimum=0, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_rot_sizer) _noise_level_sizer = wx.BoxSizer(wx.VERTICAL) self._noise_level_text_box = forms.text_box( parent=self.GetWin(), sizer=_noise_level_sizer, value=self.noise_level, callback=self.set_noise_level, label='noise_level', converter=forms.float_converter(), proportion=0, ) self._noise_level_slider = forms.slider( parent=self.GetWin(), sizer=_noise_level_sizer, value=self.noise_level, callback=self.set_noise_level, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_noise_level_sizer) self.wxgui_scopesink2_0 = scopesink2.scope_sink_c( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=2, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.gr_vector_to_stream_1 = gr.vector_to_stream(gr.sizeof_gr_complex*1, fft_size) self.gr_vector_to_stream_0_2 = gr.vector_to_stream(gr.sizeof_gr_complex*1, fft_size) self.gr_vector_to_stream_0_1 = gr.vector_to_stream(gr.sizeof_gr_complex*1, fft_size) self.gr_vector_to_stream_0_0 = gr.vector_to_stream(gr.sizeof_gr_complex*1, fft_size) self.gr_vector_to_stream_0 = gr.vector_to_stream(gr.sizeof_float*1, fft_size) self.gr_vector_source_x_0_0_0 = gr.vector_source_c((gen_pss_fd(N_id_2, fft_size, False).get_data()), True, fft_size) self.gr_vector_source_x_0_0 = gr.vector_source_c((gen_pss_fd(N_id_2, fft_size, False).get_data()), True, fft_size) self.gr_vector_source_x_0 = gr.vector_source_c((gen_sss_fd( N_id_1, N_id_2, fft_size).get_sss(True)), True, fft_size) self.gr_stream_to_vector_0_0 = gr.stream_to_vector(gr.sizeof_gr_complex*1, fft_size) self.gr_stream_to_vector_0 = gr.stream_to_vector(gr.sizeof_gr_complex*1, fft_size) self.gr_repeat_0 = gr.repeat(gr.sizeof_float*1, fft_size) self.gr_null_sink_0_0 = gr.null_sink(gr.sizeof_gr_complex*1) self.gr_null_sink_0 = gr.null_sink(gr.sizeof_gr_complex*1) self.gr_noise_source_x_0 = gr.noise_source_c(gr.GR_GAUSSIAN, noise_level, 0) self.gr_multiply_xx_1 = gr.multiply_vcc(1) self.gr_multiply_xx_0 = gr.multiply_vcc(fft_size) self.gr_multiply_const_vxx_1 = gr.multiply_const_vcc((1/1500., )) self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc((exp(rot*2*numpy.pi*1j), )) self.gr_interleave_0 = gr.interleave(gr.sizeof_gr_complex*fft_size) self.gr_integrate_xx_0 = gr.integrate_ff(fft_size) self.gr_float_to_complex_0_0 = gr.float_to_complex(1) self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_file_source_0 = gr.file_source(gr.sizeof_gr_complex*1, "/home/user/git/gr-lte/gr-lte/test/foo_pss0_sss_in.cfile", True) self.gr_fft_vxx_1 = gr.fft_vcc(fft_size, False, (window.blackmanharris(1024)), True, 1) self.gr_fft_vxx_0 = gr.fft_vcc(fft_size, True, (window.blackmanharris(1024)), True, 1) self.gr_divide_xx_0_1 = gr.divide_cc(1) self.gr_divide_xx_0_0 = gr.divide_ff(1) self.gr_divide_xx_0 = gr.divide_cc(1) self.gr_deinterleave_0 = gr.deinterleave(gr.sizeof_gr_complex*fft_size) self.gr_conjugate_cc_1 = gr.conjugate_cc() self.gr_conjugate_cc_0 = gr.conjugate_cc() self.gr_complex_to_mag_squared_0_0 = gr.complex_to_mag_squared(1) self.gr_complex_to_mag_squared_0 = gr.complex_to_mag_squared(fft_size) self.gr_add_xx_0 = gr.add_vcc(1) self.gr_add_const_vxx_0 = gr.add_const_vff((1, )) self.const_source_x_0_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) ################################################## # Connections ################################################## self.connect((self.gr_file_source_0, 0), (self.gr_stream_to_vector_0, 0)) self.connect((self.gr_conjugate_cc_0, 0), (self.gr_stream_to_vector_0_0, 0)) self.connect((self.gr_stream_to_vector_0_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_deinterleave_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_complex_to_mag_squared_0, 0)) self.connect((self.gr_complex_to_mag_squared_0, 0), (self.gr_vector_to_stream_0, 0)) self.connect((self.gr_vector_to_stream_0, 0), (self.gr_integrate_xx_0, 0)) self.connect((self.gr_integrate_xx_0, 0), (self.gr_repeat_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_vector_to_stream_0_0, 0)) self.connect((self.gr_vector_to_stream_0_1, 0), (self.gr_multiply_xx_1, 1)) self.connect((self.gr_divide_xx_0, 0), (self.gr_multiply_xx_1, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.gr_divide_xx_0, 1)) self.connect((self.gr_conjugate_cc_1, 0), (self.gr_divide_xx_0, 0)) self.connect((self.gr_deinterleave_0, 1), (self.gr_vector_to_stream_0_1, 0)) self.connect((self.gr_repeat_0, 0), (self.gr_float_to_complex_0, 0)) self.connect((self.const_source_x_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.gr_vector_to_stream_0_0, 0), (self.gr_conjugate_cc_1, 0)) self.connect((self.gr_vector_to_stream_0_0, 0), (self.gr_complex_to_mag_squared_0_0, 0)) self.connect((self.gr_complex_to_mag_squared_0_0, 0), (self.gr_divide_xx_0_0, 0)) self.connect((self.gr_repeat_0, 0), (self.gr_divide_xx_0_0, 1)) self.connect((self.gr_divide_xx_0_0, 0), (self.gr_add_const_vxx_0, 0)) self.connect((self.gr_add_const_vxx_0, 0), (self.gr_float_to_complex_0_0, 0)) self.connect((self.const_source_x_0_0, 0), (self.gr_float_to_complex_0_0, 1)) self.connect((self.gr_float_to_complex_0_0, 0), (self.gr_divide_xx_0_1, 1)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_divide_xx_0_1, 0)) self.connect((self.gr_stream_to_vector_0, 0), (self.gr_fft_vxx_0, 0)) self.connect((self.gr_fft_vxx_0, 0), (self.gr_deinterleave_0, 0)) self.connect((self.gr_vector_to_stream_0_2, 0), (self.gr_conjugate_cc_0, 0)) self.connect((self.gr_divide_xx_0_1, 0), (self.gr_null_sink_0, 0)) self.connect((self.gr_vector_source_x_0, 0), (self.gr_interleave_0, 1)) self.connect((self.gr_interleave_0, 0), (self.gr_fft_vxx_1, 0)) self.connect((self.gr_fft_vxx_1, 0), (self.gr_vector_to_stream_1, 0)) self.connect((self.gr_vector_source_x_0_0, 0), (self.gr_interleave_0, 0)) self.connect((self.gr_vector_source_x_0_0_0, 0), (self.gr_vector_to_stream_0_2, 0)) self.connect((self.gr_noise_source_x_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.gr_vector_to_stream_1, 0), (self.gr_add_xx_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_vector_to_stream_0_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.gr_null_sink_0_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_scopesink2_0, 1)) self.connect((self.gr_divide_xx_0_1, 0), (self.wxgui_scopesink2_0, 0))
def __init__(self, devid="type=b100", rdsfile="rds_fifo", gain=35.0, freq=101.1e6, xmlport=13777, arate=int(48e3), mute=-15.0, ftune=0, ant="J1", subdev="A:0", ahw="pulse", deemph=75.0e-6, prenames='["UWRF","89.3","950","WEVR"]', prefreqs="[88.715e6,89.3e6,950.735e6,106.317e6]", volume=1.0): grc_wxgui.top_block_gui.__init__(self, title="Simple FM (Stereo) Receiver") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.devid = devid self.rdsfile = rdsfile self.gain = gain self.freq = freq self.xmlport = xmlport self.arate = arate self.mute = mute self.ftune = ftune self.ant = ant self.subdev = subdev self.ahw = ahw self.deemph = deemph self.prenames = prenames self.prefreqs = prefreqs self.volume = volume ################################################## # Variables ################################################## self.pthresh = pthresh = 350 self.preselect = preselect = eval(prefreqs)[0] self.pilot_level = pilot_level = 0 self.ifreq = ifreq = freq self.stpilotdet = stpilotdet = True if (pilot_level > pthresh) else False self.stereo = stereo = True self.rf_pwr_lvl = rf_pwr_lvl = 0 self.cur_freq = cur_freq = simple_fm_helper.freq_select(ifreq,preselect) self.vol = vol = volume self.variable_static_text_0 = variable_static_text_0 = 10.0*math.log(rf_pwr_lvl+1.0e-11)/math.log(10) self.tone_med = tone_med = 5 self.tone_low = tone_low = 5 self.tone_high = tone_high = 5 self.stereo_0 = stereo_0 = stpilotdet self.st_enabled = st_enabled = 1 if (stereo == True and pilot_level > pthresh) else 0 self.squelch_probe = squelch_probe = 0 self.sq_thresh = sq_thresh = mute self.samp_rate = samp_rate = 250e3 self.rtext_0 = rtext_0 = cur_freq self.record = record = False self.rdsrate = rdsrate = 25e3 self.osmo_taps = osmo_taps = firdes.low_pass(1.0,1.00e6,95e3,20e3,firdes.WIN_HAMMING,6.76) self.mod_reset = mod_reset = 0 self.igain = igain = gain self.fine = fine = ftune self.farate = farate = arate self.dm = dm = deemph self.discrim_dc = discrim_dc = 0 self.capture_file = capture_file = "capture.wav" self.asrate = asrate = 125e3 ################################################## # Blocks ################################################## _sq_thresh_sizer = wx.BoxSizer(wx.VERTICAL) self._sq_thresh_text_box = forms.text_box( parent=self.GetWin(), sizer=_sq_thresh_sizer, value=self.sq_thresh, callback=self.set_sq_thresh, label="Mute Level", converter=forms.float_converter(), proportion=0, ) self._sq_thresh_slider = forms.slider( parent=self.GetWin(), sizer=_sq_thresh_sizer, value=self.sq_thresh, callback=self.set_sq_thresh, minimum=-30.0, maximum=-5.0, num_steps=40, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_sq_thresh_sizer, 1, 5, 1, 1) self.input_power = gr.probe_avg_mag_sqrd_c(sq_thresh, 1.0/(samp_rate/10)) self.dc_level = gr.probe_signal_f() _vol_sizer = wx.BoxSizer(wx.VERTICAL) self._vol_text_box = forms.text_box( parent=self.GetWin(), sizer=_vol_sizer, value=self.vol, callback=self.set_vol, label="Volume", converter=forms.float_converter(), proportion=0, ) self._vol_slider = forms.slider( parent=self.GetWin(), sizer=_vol_sizer, value=self.vol, callback=self.set_vol, minimum=0, maximum=11, num_steps=110, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_vol_sizer, 0, 3, 1, 1) _tone_med_sizer = wx.BoxSizer(wx.VERTICAL) self._tone_med_text_box = forms.text_box( parent=self.GetWin(), sizer=_tone_med_sizer, value=self.tone_med, callback=self.set_tone_med, label="1Khz-4Khz", converter=forms.float_converter(), proportion=0, ) self._tone_med_slider = forms.slider( parent=self.GetWin(), sizer=_tone_med_sizer, value=self.tone_med, callback=self.set_tone_med, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_tone_med_sizer, 1, 3, 1, 1) _tone_low_sizer = wx.BoxSizer(wx.VERTICAL) self._tone_low_text_box = forms.text_box( parent=self.GetWin(), sizer=_tone_low_sizer, value=self.tone_low, callback=self.set_tone_low, label="0-1Khz", converter=forms.float_converter(), proportion=0, ) self._tone_low_slider = forms.slider( parent=self.GetWin(), sizer=_tone_low_sizer, value=self.tone_low, callback=self.set_tone_low, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_tone_low_sizer, 1, 2, 1, 1) _tone_high_sizer = wx.BoxSizer(wx.VERTICAL) self._tone_high_text_box = forms.text_box( parent=self.GetWin(), sizer=_tone_high_sizer, value=self.tone_high, callback=self.set_tone_high, label="4Khz-15Khz", converter=forms.float_converter(), proportion=0, ) self._tone_high_slider = forms.slider( parent=self.GetWin(), sizer=_tone_high_sizer, value=self.tone_high, callback=self.set_tone_high, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_tone_high_sizer, 1, 4, 1, 1) def _squelch_probe_probe(): while True: val = self.input_power.unmuted() try: self.set_squelch_probe(val) except AttributeError, e: pass time.sleep(1.0/(10)) _squelch_probe_thread = threading.Thread(target=_squelch_probe_probe) _squelch_probe_thread.daemon = True _squelch_probe_thread.start() self._record_check_box = forms.check_box( parent=self.GetWin(), value=self.record, callback=self.set_record, label="Record Audio", true=True, false=False, ) self.GridAdd(self._record_check_box, 2, 2, 1, 1) self.pilot_probe = gr.probe_signal_f() _fine_sizer = wx.BoxSizer(wx.VERTICAL) self._fine_text_box = forms.text_box( parent=self.GetWin(), sizer=_fine_sizer, value=self.fine, callback=self.set_fine, label="Fine Tuning", converter=forms.float_converter(), proportion=0, ) self._fine_slider = forms.slider( parent=self.GetWin(), sizer=_fine_sizer, value=self.fine, callback=self.set_fine, minimum=-50.0e3, maximum=50.e03, num_steps=400, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_fine_sizer, 1, 0, 1, 1) def _discrim_dc_probe(): while True: val = self.dc_level.level() try: self.set_discrim_dc(val) except AttributeError, e: pass time.sleep(1.0/(2.5)) _discrim_dc_thread = threading.Thread(target=_discrim_dc_probe) _discrim_dc_thread.daemon = True _discrim_dc_thread.start() self._capture_file_text_box = forms.text_box( parent=self.GetWin(), value=self.capture_file, callback=self.set_capture_file, label="Record Filename", converter=forms.str_converter(), ) self.GridAdd(self._capture_file_text_box, 2, 0, 1, 2) self.Main = self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.Main.AddPage(grc_wxgui.Panel(self.Main), "L/R") self.Main.AddPage(grc_wxgui.Panel(self.Main), "FM Demod Spectrum") self.Add(self.Main) self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c( self.GetWin(), baseband_freq=0, dynamic_range=100, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", ) self.Add(self.wxgui_waterfallsink2_0.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.Main.GetPage(0).GetWin(), title="Audio Channels (L and R)", sample_rate=farate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=2, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Rel. Audio Level", ) self.Main.GetPage(0).Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.Main.GetPage(1).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=asrate, fft_size=1024, fft_rate=6, average=True, avg_alpha=0.1, title="FM Demod Spectrum", peak_hold=False, ) self.Main.GetPage(1).Add(self.wxgui_fftsink2_0.win) self._variable_static_text_0_static_text = forms.static_text( parent=self.GetWin(), value=self.variable_static_text_0, callback=self.set_variable_static_text_0, label="RF Power ", converter=forms.float_converter(formatter=lambda x: "%4.1f" % x), ) self.GridAdd(self._variable_static_text_0_static_text, 0, 2, 1, 1) self._stereo_0_check_box = forms.check_box( parent=self.GetWin(), value=self.stereo_0, callback=self.set_stereo_0, label="Stereo Detect", true=True, false=False, ) self.GridAdd(self._stereo_0_check_box, 2, 5, 1, 1) self._stereo_check_box = forms.check_box( parent=self.GetWin(), value=self.stereo, callback=self.set_stereo, label="Stereo", true=True, false=False, ) self.GridAdd(self._stereo_check_box, 2, 4, 1, 1) self.rtl2832_source_0 = baz.rtl_source_c(defer_creation=True) self.rtl2832_source_0.set_verbose(True) self.rtl2832_source_0.set_vid(0x0) self.rtl2832_source_0.set_pid(0x0) self.rtl2832_source_0.set_tuner_name("") self.rtl2832_source_0.set_default_timeout(0) self.rtl2832_source_0.set_use_buffer(True) self.rtl2832_source_0.set_fir_coefficients(([])) if self.rtl2832_source_0.create() == False: raise Exception("Failed to create RTL2832 Source: rtl2832_source_0") self.rtl2832_source_0.set_sample_rate(1.0e6) self.rtl2832_source_0.set_frequency(cur_freq+200e3) self.rtl2832_source_0.set_auto_gain_mode(False) self.rtl2832_source_0.set_relative_gain(True) self.rtl2832_source_0.set_gain(gain) self._rtext_0_static_text = forms.static_text( parent=self.GetWin(), value=self.rtext_0, callback=self.set_rtext_0, label="CURRENT FREQUENCY>>", converter=forms.float_converter(), ) self.GridAdd(self._rtext_0_static_text, 0, 1, 1, 1) def _rf_pwr_lvl_probe(): while True: val = self.input_power.level() try: self.set_rf_pwr_lvl(val) except AttributeError, e: pass time.sleep(1.0/(2)) _rf_pwr_lvl_thread = threading.Thread(target=_rf_pwr_lvl_probe) _rf_pwr_lvl_thread.daemon = True _rf_pwr_lvl_thread.start() self._preselect_chooser = forms.radio_buttons( parent=self.GetWin(), value=self.preselect, callback=self.set_preselect, label='preselect', choices=eval(prefreqs), labels=eval(prenames), style=wx.RA_HORIZONTAL, ) self.GridAdd(self._preselect_chooser, 0, 4, 1, 1) def _pilot_level_probe(): while True: val = self.pilot_probe.level() try: self.set_pilot_level(val) except AttributeError, e: pass time.sleep(1.0/(5)) _pilot_level_thread = threading.Thread(target=_pilot_level_probe) _pilot_level_thread.daemon = True _pilot_level_thread.start() self.low_pass_filter_3 = gr.fir_filter_fff(1, firdes.low_pass( 3, asrate/500, 10, 3, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_2 = gr.fir_filter_fff(10, firdes.low_pass( 3, asrate/50, 100, 30, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_1 = gr.fir_filter_fff(10, firdes.low_pass( 3, asrate/5, 1e3, 200, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = gr.fir_filter_fff(5, firdes.low_pass( 3, asrate, 10e3, 2e3, firdes.WIN_HAMMING, 6.76)) _igain_sizer = wx.BoxSizer(wx.VERTICAL) self._igain_text_box = forms.text_box( parent=self.GetWin(), sizer=_igain_sizer, value=self.igain, callback=self.set_igain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._igain_slider = forms.slider( parent=self.GetWin(), sizer=_igain_sizer, value=self.igain, callback=self.set_igain, minimum=0, maximum=50, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_igain_sizer, 1, 1, 1, 1) _ifreq_sizer = wx.BoxSizer(wx.VERTICAL) self._ifreq_text_box = forms.text_box( parent=self.GetWin(), sizer=_ifreq_sizer, value=self.ifreq, callback=self.set_ifreq, label="Center Frequency", converter=forms.float_converter(), proportion=0, ) self._ifreq_slider = forms.slider( parent=self.GetWin(), sizer=_ifreq_sizer, value=self.ifreq, callback=self.set_ifreq, minimum=88.1e6, maximum=108.1e6, num_steps=200, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_ifreq_sizer, 0, 0, 1, 1) self.gr_wavfile_sink_0 = gr.wavfile_sink("/dev/null" if record == False else capture_file, 2, int(farate), 16) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_single_pole_iir_filter_xx_1 = gr.single_pole_iir_filter_ff(2.5/(asrate/500), 1) self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(1.0/(asrate/3), 1) self.gr_multiply_xx_1 = gr.multiply_vff(1) self.gr_multiply_xx_0_0 = gr.multiply_vff(1) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_multiply_const_vxx_3 = gr.multiply_const_vff((3.16e3 if st_enabled else 0, )) self.gr_multiply_const_vxx_2 = gr.multiply_const_vff((1.0 if st_enabled else 1.414, )) self.gr_multiply_const_vxx_1_0 = gr.multiply_const_vff((0 if st_enabled else 1, )) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((0 if squelch_probe == 0 else 1.0, )) self.gr_multiply_const_vxx_0_0 = gr.multiply_const_vff((vol*1.5*10.0, )) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((vol*1.5*10.0 if st_enabled else 0, )) self.gr_keep_one_in_n_0 = gr.keep_one_in_n(gr.sizeof_float*1, int(asrate/3)) self.gr_freq_xlating_fir_filter_xxx_0 = gr.freq_xlating_fir_filter_ccc(4, (osmo_taps), 200e3+fine+(-12e3*discrim_dc), 1.0e6) self.gr_fractional_interpolator_xx_0_0 = gr.fractional_interpolator_ff(0, asrate/farate) self.gr_fractional_interpolator_xx_0 = gr.fractional_interpolator_ff(0, asrate/farate) self.gr_fft_filter_xxx_1_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_high/10.0,asrate,3.5e3,15.0e3,5.0e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_1_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_med/10.0,asrate,1.0e3,4.0e3,2.0e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_1 = gr.fft_filter_fff(1, (firdes.low_pass(tone_low/10.0,asrate,1.2e3,500,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_0_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_high/10.0,asrate,3.5e3,13.5e3,3.5e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_med/10.0,asrate,1.0e3,4.0e3,2.0e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_0 = gr.fft_filter_fff(1, (firdes.low_pass(tone_low/10.0,asrate,1.2e3,500,firdes.WIN_HAMMING)), 1) self.gr_divide_xx_0 = gr.divide_ff(1) self.gr_agc_xx_1 = gr.agc_cc(1e-2, 0.35, 1.0, 5000) self.gr_add_xx_2_0 = gr.add_vff(1) self.gr_add_xx_2 = gr.add_vff(1) self.gr_add_xx_1 = gr.add_vff(1) self.gr_add_xx_0 = gr.add_vff(1) self.gr_add_const_vxx_0 = gr.add_const_vff((1.0e-7, )) self._dm_chooser = forms.radio_buttons( parent=self.GetWin(), value=self.dm, callback=self.set_dm, label="FM Deemphasis", choices=[75.0e-6, 50.0e-6], labels=["NA", "EU"], style=wx.RA_HORIZONTAL, ) self.GridAdd(self._dm_chooser, 0, 5, 1, 1) self.blks2_wfm_rcv_0 = blks2.wfm_rcv( quad_rate=samp_rate, audio_decimation=2, ) self.blks2_fm_deemph_0_0 = blks2.fm_deemph(fs=farate, tau=deemph) self.blks2_fm_deemph_0 = blks2.fm_deemph(fs=farate, tau=deemph) self.band_pass_filter_2_0 = gr.fir_filter_fff(1, firdes.band_pass( 20, asrate, 17.5e3, 17.9e3, 250, firdes.WIN_HAMMING, 6.76)) self.band_pass_filter_2 = gr.fir_filter_fff(1, firdes.band_pass( 10, asrate, 18.8e3, 19.2e3, 350, firdes.WIN_HAMMING, 6.76)) self.band_pass_filter_0_0 = gr.fir_filter_fff(1, firdes.band_pass( 1, asrate, 38e3-(15e3), 38e3+(15e3), 4.0e3, firdes.WIN_HAMMING, 6.76)) self.audio_sink_0 = audio.sink(int(farate), "" if ahw == "Default" else ahw, True) ################################################## # Connections ################################################## self.connect((self.gr_add_xx_1, 0), (self.gr_fractional_interpolator_xx_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.gr_fractional_interpolator_xx_0_0, 0)) self.connect((self.band_pass_filter_0_0, 0), (self.gr_multiply_xx_1, 0)) self.connect((self.gr_multiply_const_vxx_1_0, 0), (self.gr_add_xx_0, 0)) self.connect((self.band_pass_filter_2_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.band_pass_filter_2_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_multiply_xx_0_0, 0), (self.gr_divide_xx_0, 0)) self.connect((self.gr_divide_xx_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_add_const_vxx_0, 0)) self.connect((self.gr_add_const_vxx_0, 0), (self.gr_divide_xx_0, 1)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0)) self.connect((self.gr_keep_one_in_n_0, 0), (self.pilot_probe, 0)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_1, 2)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_0_0, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_add_xx_1, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_sub_xx_0, 0)) self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_sub_xx_0, 1)) self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_add_xx_1, 1)) self.connect((self.gr_fractional_interpolator_xx_0, 0), (self.gr_multiply_const_vxx_0_0, 0)) self.connect((self.gr_fractional_interpolator_xx_0_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_1, 1)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0, 0)) self.connect((self.gr_fft_filter_xxx_1, 0), (self.gr_add_xx_2, 0)) self.connect((self.gr_fft_filter_xxx_1_0, 0), (self.gr_add_xx_2, 1)) self.connect((self.gr_fft_filter_xxx_1_0_0, 0), (self.gr_add_xx_2, 2)) self.connect((self.gr_add_xx_2, 0), (self.gr_multiply_const_vxx_2, 0)) self.connect((self.gr_add_xx_2_0, 0), (self.gr_multiply_const_vxx_3, 0)) self.connect((self.gr_fft_filter_xxx_0, 0), (self.gr_add_xx_2_0, 0)) self.connect((self.gr_fft_filter_xxx_0_0, 0), (self.gr_add_xx_2_0, 1)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0_0, 0)) self.connect((self.gr_fft_filter_xxx_0_0_0, 0), (self.gr_add_xx_2_0, 2)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0_0_0, 0)) self.connect((self.blks2_fm_deemph_0, 0), (self.gr_multiply_const_vxx_1_0, 0)) self.connect((self.blks2_fm_deemph_0, 0), (self.gr_wavfile_sink_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1_0_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.blks2_fm_deemph_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.audio_sink_0, 1)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_fm_deemph_0_0, 0)) self.connect((self.blks2_fm_deemph_0_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_0_0, 1)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_2, 0)) self.connect((self.blks2_fm_deemph_0, 0), (self.audio_sink_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_2_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_0_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.gr_wavfile_sink_0, 1)) self.connect((self.blks2_fm_deemph_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.wxgui_scopesink2_0, 1)) self.connect((self.blks2_wfm_rcv_0, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_agc_xx_1, 0), (self.blks2_wfm_rcv_0, 0)) self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.gr_agc_xx_1, 0)) self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.input_power, 0)) self.connect((self.blks2_wfm_rcv_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.low_pass_filter_1, 0)) self.connect((self.low_pass_filter_1, 0), (self.low_pass_filter_2, 0)) self.connect((self.low_pass_filter_2, 0), (self.low_pass_filter_3, 0)) self.connect((self.gr_single_pole_iir_filter_xx_1, 0), (self.dc_level, 0)) self.connect((self.low_pass_filter_3, 0), (self.gr_single_pole_iir_filter_xx_1, 0)) self.connect((self.rtl2832_source_0, 0), (self.gr_freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_waterfallsink2_0, 0))
def __init__(self, bt = 0.3, samples_per_symbol = 2, ti_adj=False, magic_num=0): """ Hierarchical block for MSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__(self, "msk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) self.sps = 2 self.bt = 0.35 self.mu = 0.5 self.gain_mu = 0.175 self.freq_error = 0.0 self.omega_relative_limit = 0.005 self.omega = self.sps * (1 + self.freq_error) self.gain_omega = .25 * self.gain_mu * self.gain_mu # critically damped # Demodulate FM sensitivity = (pi / 2) / self.sps self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.invert = gr.multiply_const_vff((-1, )) # TODO: this is hardcoded, how to figure out this value? self.offset = gr.add_const_vff((-1.2, )) self.offset2 = gr.add_const_vff((magic_num, )) self.nfilts = nfilts = 32 self.sps = sps = 2 self.rrc_taps = rrc_taps = filter.firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), 0.35, 11*sps*nfilts) self.pfb = digital.pfb_clock_sync_ccf(sps, 2*3.14/100.0, (rrc_taps), nfilts, nfilts/2, 1.5, 1) # the clock recovery block tracks the symbol clock and resamples as needed. # the output of the block is a stream of soft symbols (float) self.clock_recovery = digital.clock_recovery_mm_ff(self.omega, self.gain_omega, self.mu, self.gain_mu, self.omega_relative_limit) ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 # Form Gaussian filter # Generate Gaussian response (Needs to be convolved with window below). self.gaussian_taps = gr.firdes.gaussian(1, samples_per_symbol, bt, ntaps) self.sqwave = (1,) * samples_per_symbol # rectangular window self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) self.gaussian_filter = filter.fir_filter_ccc(samples_per_symbol, self.taps) self.slicer = digital.binary_slicer_fb() if ti_adj: self.connect(self, self.fmdemod, self.invert, self.clock_recovery, self.offset, self) else: self.connect(self, self.gaussian_filter, self.fmdemod, self.clock_recovery, self.offset2, self)
def setUp (self): self.tb = gr.top_block () # Read in successfully decoded live data from Matlab linf=open('/home/demel/exchange/matlab_d.txt') lintu=range(120) for i in lintu: lintu[i]=float(linf.readline()) #print lintu # source for live data self.srcl = gr.vector_source_f(lintu,False,120) # Read in .txt file with example MIB encoded + CRC checksum inf=open('/home/demel/exchange/crc.txt') self.intu=range(40) for i in self.intu: self.intu[i]=float(inf.readline()) #inf=open('/home/demel/exchange/matlab_d.txt') #intu=range(120) #for i in range(120): # intu[i]=float(inf.readline()) # Source and conversions self.src = gr.vector_source_f(self.intu,False,40) self.conv = gr.float_to_char(40,1) # Resize vector with repetition of last part # Vector to stream for encoder my_map1=range(46) for i in range(40): my_map1[i+6]=i for i in range(6): my_map1[i]=i+40 self.map1 = lte.vector_resize_vbvb(my_map1,40,46) self.vtos = gr.vector_to_stream(1*gr.sizeof_char,46) # Encoding of input data self.fsm = trellis.fsm(1,3,[91,121,117]) self.enc = trellis.encoder_bb(self.fsm,0) # unpack packed bits from encoder self.unp = gr.unpack_k_bits_bb(3) # stream to vector self.stov = gr.stream_to_vector(1*gr.sizeof_char,138) # Remove first part which contains tail-biting init stuff map2 = range(120) for i in map2: map2[i]= i+18 self.map2 = lte.vector_resize_vbvb(map2,138,120) # conversion from char to float to match input of decoder self.conv2= gr.char_to_float(120,1) ############################################### # From here on only "receiver side" processing ############################################### # like QPSK demodulation: NRZ coding. vec2=range(120) for i in vec2: vec2[i]=float(-2.0) self.mult = gr.multiply_const_vff(vec2) vec=range(120) for i in vec: vec[i]=1 self.add = gr.add_const_vff(vec) # this is the actual unit under test self.vit = lte.viterbi_vfvb() # Sinks self.snk = gr.vector_sink_b(40) self.snk2 = gr.vector_sink_f(120) # connecting blocks self.tb.connect(self.src,self.conv,self.map1,self.vtos,self.enc,self.unp) self.tb.connect(self.unp,self.stov,self.map2,self.conv2) self.tb.connect(self.conv2,self.mult,self.add) self.tb.connect(self.srcl,self.vit,self.snk) self.tb.connect(self.add,self.snk2)
def test_add_const_vff_one(self): src_data = (1.0,) op = gr.add_const_vff((2.0,)) exp_data = (3.0,) self.help_const_ff(src_data, exp_data, op)
def test_add_const_vff_five(self): src_data = (1.0, 2.0, 3.0, 4.0, 5.0) op = gr.add_const_vff((6.0, 7.0, 8.0, 9.0, 10.0)) exp_data = (7.0, 9.0, 11.0, 13.0, 15.0) self.help_const_ff(src_data, exp_data, op)
def __init__(self, subc, vlen, ss): gr.hier_block2.__init__( self, "new_snr_estimator", gr.io_signature(2, 2, gr.sizeof_gr_complex * vlen), #gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float*vlen/ss*(ss-1))) gr.io_signature2(2, 2, gr.sizeof_float * vlen, gr.sizeof_float)) print "Created Milan's SINR estimator" trigger = [0] * vlen trigger[0] = 1 v = range(vlen / ss) ones_ind = map(lambda z: z * ss, v) skip2_pr0 = skip(gr.sizeof_gr_complex, vlen) skip2_pr1 = skip(gr.sizeof_gr_complex, vlen) for x in ones_ind: skip2_pr0.skip(x) skip2_pr1.skip(x) #print "skipped ones",ones_ind v2s_pr0 = gr.vector_to_stream(gr.sizeof_gr_complex, vlen) v2s_pr1 = gr.vector_to_stream(gr.sizeof_gr_complex, vlen) s2v2_pr0 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss * (ss - 1)) trigger_src_2_pr0 = gr.vector_source_b(trigger, True) s2v2_pr1 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss * (ss - 1)) trigger_src_2_pr1 = gr.vector_source_b(trigger, True) mag_sq_zeros_pr0 = gr.complex_to_mag_squared(vlen / ss * (ss - 1)) mag_sq_zeros_pr1 = gr.complex_to_mag_squared(vlen / ss * (ss - 1)) filt_zeros_pr0 = gr.single_pole_iir_filter_ff(0.01, vlen / ss * (ss - 1)) filt_zeros_pr1 = gr.single_pole_iir_filter_ff(0.01, vlen / ss * (ss - 1)) v1 = vlen / ss * (ss - 1) vevc1 = [-1] * v1 neg_nomin_z = gr.multiply_const_vff(vevc1) div_z = gr.divide_ff(vlen / ss * (ss - 1)) on_zeros = gr.add_const_vff(vevc1) sum_zeros = add_vff(vlen / ss * (ss - 1)) # For average sum_all = vector_sum_vff(vlen) mult = gr.multiply_const_ff(1. / vlen) scsnr_db_av = gr.nlog10_ff(10, 1, 0) filt_end_av = gr.single_pole_iir_filter_ff(0.1) self.connect((self, 0), v2s_pr0, skip2_pr0, s2v2_pr0, mag_sq_zeros_pr0, filt_zeros_pr0) self.connect(trigger_src_2_pr0, (skip2_pr0, 1)) self.connect((self, 1), v2s_pr1, skip2_pr1, s2v2_pr1, mag_sq_zeros_pr1, filt_zeros_pr1) self.connect(trigger_src_2_pr1, (skip2_pr1, 1)) # On zeros self.connect(filt_zeros_pr1, (sum_zeros, 0)) self.connect(filt_zeros_pr0, neg_nomin_z, (sum_zeros, 1)) self.connect(sum_zeros, div_z) self.connect(filt_zeros_pr0, (div_z, 1)) scsnr_db = gr.nlog10_ff(10, vlen, 0) filt_end = gr.single_pole_iir_filter_ff(0.1, vlen) dd = [] for i in range(vlen / ss): dd.extend([i * ss]) #print dd interpolator = sinr_interpolator(vlen, ss, dd) self.connect(div_z, interpolator, filt_end, scsnr_db, self) self.connect(interpolator, sum_all, mult, scsnr_db_av, filt_end_av, (self, 1))
def __init__(self, subc, vlen, ss): gr.hier_block2.__init__(self, "new_snr_estimator", gr.io_signature(2,2,gr.sizeof_gr_complex*vlen), #gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float*vlen/ss*(ss-1))) gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float)) print "Created Milan's SINR estimator" trigger = [0]*vlen trigger[0] = 1 v = range (vlen/ss) ones_ind= map(lambda z: z*ss,v) skip2_pr0 = skip(gr.sizeof_gr_complex,vlen) skip2_pr1 = skip(gr.sizeof_gr_complex,vlen) for x in ones_ind: skip2_pr0.skip(x) skip2_pr1.skip(x) #print "skipped ones",ones_ind v2s_pr0 = gr.vector_to_stream(gr.sizeof_gr_complex,vlen) v2s_pr1 = gr.vector_to_stream(gr.sizeof_gr_complex,vlen) s2v2_pr0 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1)) trigger_src_2_pr0 = gr.vector_source_b(trigger,True) s2v2_pr1 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1)) trigger_src_2_pr1 = gr.vector_source_b(trigger,True) mag_sq_zeros_pr0 = gr.complex_to_mag_squared(vlen/ss*(ss-1)) mag_sq_zeros_pr1 = gr.complex_to_mag_squared(vlen/ss*(ss-1)) filt_zeros_pr0 = gr.single_pole_iir_filter_ff(0.01,vlen/ss*(ss-1)) filt_zeros_pr1 = gr.single_pole_iir_filter_ff(0.01,vlen/ss*(ss-1)) v1 = vlen/ss*(ss-1) vevc1 =[-1]*v1 neg_nomin_z = gr.multiply_const_vff(vevc1) div_z=gr.divide_ff(vlen/ss*(ss-1)) on_zeros = gr.add_const_vff(vevc1) sum_zeros = add_vff(vlen/ss*(ss-1)) # For average sum_all = vector_sum_vff(vlen) mult = gr.multiply_const_ff(1./vlen) scsnr_db_av = gr.nlog10_ff(10,1,0) filt_end_av = gr.single_pole_iir_filter_ff(0.1) self.connect((self,0),v2s_pr0,skip2_pr0,s2v2_pr0,mag_sq_zeros_pr0,filt_zeros_pr0) self.connect(trigger_src_2_pr0,(skip2_pr0,1)) self.connect((self,1),v2s_pr1,skip2_pr1,s2v2_pr1,mag_sq_zeros_pr1,filt_zeros_pr1) self.connect(trigger_src_2_pr1,(skip2_pr1,1)) # On zeros self.connect(filt_zeros_pr1,(sum_zeros,0)) self.connect(filt_zeros_pr0,neg_nomin_z,(sum_zeros,1)) self.connect(sum_zeros,div_z) self.connect(filt_zeros_pr0,(div_z,1)) scsnr_db = gr.nlog10_ff(10,vlen,0) filt_end = gr.single_pole_iir_filter_ff(0.1,vlen) dd = [] for i in range (vlen/ss): dd.extend([i*ss]) #print dd interpolator = sinr_interpolator(vlen, ss,dd) self.connect(div_z,interpolator,filt_end,scsnr_db,self) self.connect(interpolator,sum_all,mult,scsnr_db_av,filt_end_av,(self,1))
def test_add_const_vff_one(self): src_data = (1.0, ) op = gr.add_const_vff((2.0, )) exp_data = (3.0, ) self.help_const_ff(src_data, exp_data, op)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="USRP LRIT Receiver") ################################################## # Variables ################################################## self.config_filename = config_filename = "usrp_rx_lrit.cfg" self._saved_decim_config = ConfigParser.ConfigParser() self._saved_decim_config.read(config_filename) try: saved_decim = self._saved_decim_config.getint("main", "decim") except: saved_decim = 160 self.saved_decim = saved_decim self.decim = decim = saved_decim self.symbol_rate = symbol_rate = 293e3 self._saved_gain_mu_config = ConfigParser.ConfigParser() self._saved_gain_mu_config.read(config_filename) try: saved_gain_mu = self._saved_gain_mu_config.getfloat("main", "gain_mu") except: saved_gain_mu = 0.005 self.saved_gain_mu = saved_gain_mu self._saved_gain_config = ConfigParser.ConfigParser() self._saved_gain_config.read(config_filename) try: saved_gain = self._saved_gain_config.getfloat("main", "gain") except: saved_gain = 33 self.saved_gain = saved_gain self._saved_freq_config = ConfigParser.ConfigParser() self._saved_freq_config.read(config_filename) try: saved_freq = self._saved_freq_config.getfloat("main", "freq") except: saved_freq = 137e6 self.saved_freq = saved_freq self._saved_costas_alpha_config = ConfigParser.ConfigParser() self._saved_costas_alpha_config.read(config_filename) try: saved_costas_alpha = self._saved_costas_alpha_config.getfloat("main", "costas_alpha") except: saved_costas_alpha = 0.005 self.saved_costas_alpha = saved_costas_alpha self.samp_rate = samp_rate = 64e6/decim self.sps = sps = samp_rate/symbol_rate self.gain_mu = gain_mu = saved_gain_mu self.gain = gain = saved_gain self.freq = freq = saved_freq self.costas_alpha = costas_alpha = saved_costas_alpha ################################################## # Notebooks ################################################## self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.displays.AddPage(grc_wxgui.Panel(self.displays), "USRP RX") self.displays.AddPage(grc_wxgui.Panel(self.displays), "Costas Output") self.GridAdd(self.displays, 2, 0, 1, 3) ################################################## # Controls ################################################## self._decim_text_box = forms.text_box( parent=self.GetWin(), value=self.decim, callback=self.set_decim, label="Decim", converter=forms.int_converter(), ) self.GridAdd(self._decim_text_box, 0, 0, 1, 1) _gain_mu_sizer = wx.BoxSizer(wx.VERTICAL) self._gain_mu_text_box = forms.text_box( parent=self.GetWin(), sizer=_gain_mu_sizer, value=self.gain_mu, callback=self.set_gain_mu, label="Gain Mu", converter=forms.float_converter(), proportion=0, ) self._gain_mu_slider = forms.slider( parent=self.GetWin(), sizer=_gain_mu_sizer, value=self.gain_mu, callback=self.set_gain_mu, minimum=0, maximum=0.5, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_gain_mu_sizer, 1, 1, 1, 1) _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=115, num_steps=115, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_gain_sizer, 0, 1, 1, 1) _freq_sizer = wx.BoxSizer(wx.VERTICAL) self._freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_freq_sizer, value=self.freq, callback=self.set_freq, label="Frequency", converter=forms.float_converter(), proportion=0, ) self._freq_slider = forms.slider( parent=self.GetWin(), sizer=_freq_sizer, value=self.freq, callback=self.set_freq, minimum=135e6, maximum=139e6, num_steps=400, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_freq_sizer, 0, 2, 1, 1) _costas_alpha_sizer = wx.BoxSizer(wx.VERTICAL) self._costas_alpha_text_box = forms.text_box( parent=self.GetWin(), sizer=_costas_alpha_sizer, value=self.costas_alpha, callback=self.set_costas_alpha, label="Costas Alpha", converter=forms.float_converter(), proportion=0, ) self._costas_alpha_slider = forms.slider( parent=self.GetWin(), sizer=_costas_alpha_sizer, value=self.costas_alpha, callback=self.set_costas_alpha, minimum=0, maximum=0.5, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_costas_alpha_sizer, 1, 0, 1, 1) ################################################## # Blocks ################################################## self.gr_add_const_vxx_0 = gr.add_const_vff((48.0, )) self.gr_agc_xx_0 = gr.agc_cc(1e-6, 1.0, 1.0/32767.0, 1.0) self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() self.gr_char_to_float_0 = gr.char_to_float() self.gr_complex_to_real_0 = gr.complex_to_real(1) self.gr_file_sink_0 = gr.file_sink(gr.sizeof_char*1, "bits.dat") self.gr_file_source_0 = gr.file_source(gr.sizeof_gr_complex*1, "lrit.dat", False) self.gr_float_to_char_0 = gr.float_to_char() self.gr_mpsk_receiver_cc_0 = gr.mpsk_receiver_cc(2, 0, costas_alpha, costas_alpha*costas_alpha/4.0, -0.05, 0.05, 0.5, gain_mu, sps, gain_mu*gain_mu/4.0, 0.05) self.gr_probe_mpsk_snr_c_0 = grc_blks2.probe_mpsk_snr_c( type='snr', alpha=0.0001, probe_rate=10, ) self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex*1, samp_rate) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.displays.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=10, y_divs=10, ref_level=50, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=False, avg_alpha=None, title="Spectrum", peak_hold=False, ) self.displays.GetPage(0).GridAdd(self.wxgui_fftsink2_0.win, 0, 0, 1, 1) self.wxgui_numbersink2_0 = numbersink2.number_sink_f( self.displays.GetPage(1).GetWin(), unit="dB", minval=0, maxval=30, factor=1.0, decimal_places=1, ref_level=0, sample_rate=10, number_rate=10, average=False, avg_alpha=None, label="SNR", peak_hold=False, show_gauge=True, ) self.displays.GetPage(1).GridAdd(self.wxgui_numbersink2_0.win, 2, 0, 1, 1) self.wxgui_scopesink2_0 = scopesink2.scope_sink_c( self.displays.GetPage(0).GetWin(), title="Waveform", sample_rate=samp_rate, v_scale=0.5, t_scale=20.0/samp_rate, ac_couple=False, xy_mode=True, num_inputs=1, ) self.displays.GetPage(0).GridAdd(self.wxgui_scopesink2_0.win, 1, 0, 1, 1) self.wxgui_scopesink2_1 = scopesink2.scope_sink_c( self.displays.GetPage(1).GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=0.4, t_scale=20.0/samp_rate, ac_couple=False, xy_mode=True, num_inputs=1, ) self.displays.GetPage(1).GridAdd(self.wxgui_scopesink2_1.win, 0, 0, 1, 1) ################################################## # Connections ################################################## self.connect((self.gr_agc_xx_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.gr_file_source_0, 0), (self.gr_throttle_0, 0)) self.connect((self.gr_throttle_0, 0), (self.gr_agc_xx_0, 0)) self.connect((self.gr_probe_mpsk_snr_c_0, 0), (self.wxgui_numbersink2_0, 0)) self.connect((self.gr_mpsk_receiver_cc_0, 0), (self.gr_probe_mpsk_snr_c_0, 0)) self.connect((self.gr_agc_xx_0, 0), (self.gr_mpsk_receiver_cc_0, 0)) self.connect((self.gr_mpsk_receiver_cc_0, 0), (self.wxgui_scopesink2_1, 0)) self.connect((self.gr_agc_xx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_mpsk_receiver_cc_0, 0), (self.gr_complex_to_real_0, 0)) self.connect((self.gr_complex_to_real_0, 0), (self.gr_binary_slicer_fb_0, 0)) self.connect((self.gr_binary_slicer_fb_0, 0), (self.gr_char_to_float_0, 0)) self.connect((self.gr_char_to_float_0, 0), (self.gr_add_const_vxx_0, 0)) self.connect((self.gr_add_const_vxx_0, 0), (self.gr_float_to_char_0, 0)) self.connect((self.gr_float_to_char_0, 0), (self.gr_file_sink_0, 0))
def __init__( self, sample_rate, ber_threshold=0, # Above which to do search ber_smoothing=0, # Alpha of BER smoother (0.01) ber_duration=0, # Length before trying next combo ber_sample_decimation=1, settling_period=0, pre_lock_duration=0, #ber_sample_skip=0 **kwargs): use_throttle = False base_duration = 1024 if sample_rate > 0: use_throttle = True base_duration *= 4 # Has to be high enough for block-delay if ber_threshold == 0: ber_threshold = 512 * 4 if ber_smoothing == 0: ber_smoothing = 0.01 if ber_duration == 0: ber_duration = base_duration * 2 # 1000ms if settling_period == 0: settling_period = base_duration * 1 # 500ms if pre_lock_duration == 0: pre_lock_duration = base_duration * 2 #1000ms print "Creating Auto-FEC:" print "\tsample_rate:\t\t", sample_rate print "\tber_threshold:\t\t", ber_threshold print "\tber_smoothing:\t\t", ber_smoothing print "\tber_duration:\t\t", ber_duration print "\tber_sample_decimation:\t", ber_sample_decimation print "\tsettling_period:\t", settling_period print "\tpre_lock_duration:\t", pre_lock_duration print "" self.sample_rate = sample_rate self.ber_threshold = ber_threshold #self.ber_smoothing = ber_smoothing self.ber_duration = ber_duration self.settling_period = settling_period self.pre_lock_duration = pre_lock_duration #self.ber_sample_skip = ber_sample_skip self.data_lock = threading.Lock() gr.hier_block2.__init__( self, "auto_fec", gr.io_signature( 1, 1, gr.sizeof_gr_complex), # Post MPSK-receiver complex input gr.io_signature3( 3, 3, gr.sizeof_char, gr.sizeof_float, gr.sizeof_float)) # Decoded packed bytes, BER metric, lock self.input_watcher = auto_fec_input_watcher(self) default_xform = self.input_watcher.xform_lock self.gr_conjugate_cc_0 = gr.conjugate_cc() self.connect((self, 0), (self.gr_conjugate_cc_0, 0)) # Input self.blks2_selector_0 = grc_blks2.selector( item_size=gr.sizeof_gr_complex * 1, num_inputs=2, num_outputs=1, input_index=default_xform.get_conjugation_index(), output_index=0, ) self.connect((self.gr_conjugate_cc_0, 0), (self.blks2_selector_0, 0)) self.connect((self, 0), (self.blks2_selector_0, 1)) # Input self.gr_multiply_const_vxx_3 = gr.multiply_const_vcc( (0.707 * (1 + 1j), )) self.connect((self.blks2_selector_0, 0), (self.gr_multiply_const_vxx_3, 0)) self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc( (default_xform.get_rotation(), )) # phase_mult self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_multiply_const_vxx_2, 0)) self.gr_complex_to_float_0_0 = gr.complex_to_float(1) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_complex_to_float_0_0, 0)) self.gr_interleave_1 = gr.interleave(gr.sizeof_float * 1) self.connect((self.gr_complex_to_float_0_0, 1), (self.gr_interleave_1, 1)) self.connect((self.gr_complex_to_float_0_0, 0), (self.gr_interleave_1, 0)) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((1, )) # invert self.connect((self.gr_interleave_1, 0), (self.gr_multiply_const_vxx_0, 0)) self.baz_delay_2 = baz.delay( gr.sizeof_float * 1, default_xform.get_puncture_delay()) # delay_puncture self.connect((self.gr_multiply_const_vxx_0, 0), (self.baz_delay_2, 0)) self.depuncture_ff_0 = baz.depuncture_ff( (_puncture_matrices[self.input_watcher.puncture_matrix][1] )) # puncture_matrix self.connect((self.baz_delay_2, 0), (self.depuncture_ff_0, 0)) self.baz_delay_1 = baz.delay( gr.sizeof_float * 1, default_xform.get_viterbi_delay()) # delay_viterbi self.connect((self.depuncture_ff_0, 0), (self.baz_delay_1, 0)) self.swap_ff_0 = baz.swap_ff( default_xform.get_viterbi_swap()) # swap_viterbi self.connect((self.baz_delay_1, 0), (self.swap_ff_0, 0)) self.gr_decode_ccsds_27_fb_0 = gr.decode_ccsds_27_fb() if use_throttle: print "==> Using throttle at sample rate:", self.sample_rate self.gr_throttle_0 = gr.throttle(gr.sizeof_float, self.sample_rate) self.connect((self.swap_ff_0, 0), (self.gr_throttle_0, 0)) self.connect((self.gr_throttle_0, 0), (self.gr_decode_ccsds_27_fb_0, 0)) else: self.connect((self.swap_ff_0, 0), (self.gr_decode_ccsds_27_fb_0, 0)) self.connect((self.gr_decode_ccsds_27_fb_0, 0), (self, 0)) # Output bytes self.gr_add_const_vxx_1 = gr.add_const_vff((-4096, )) self.connect((self.gr_decode_ccsds_27_fb_0, 1), (self.gr_add_const_vxx_1, 0)) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((-1, )) self.connect((self.gr_add_const_vxx_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self, 1)) # Output BER self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff( ber_smoothing, 1) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.gr_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float, ber_sample_decimation) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0)) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) # Last param is const value if use_throttle: lock_throttle_rate = self.sample_rate // 16 print "==> Using lock throttle rate:", lock_throttle_rate self.gr_throttle_1 = gr.throttle(gr.sizeof_float, lock_throttle_rate) self.connect((self.const_source_x_0, 0), (self.gr_throttle_1, 0)) self.connect((self.gr_throttle_1, 0), (self, 2)) else: self.connect((self.const_source_x_0, 0), (self, 2)) self.msg_q = gr.msg_queue( 2 * 256 ) # message queue that holds at most 2 messages, increase to speed up process self.msg_sink = gr.message_sink( gr.sizeof_float, self.msg_q, dont_block=0) # Block to speed up process self.connect((self.gr_keep_one_in_n_0, 0), self.msg_sink) self.input_watcher.start()