def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 48000 ################################################## # Blocks ################################################## self.rational_resampler_xxx_1 = filter.rational_resampler_fff( interpolation=4160, decimation=4800, taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0 = filter.rational_resampler_fff( interpolation=9600, decimation=samp_rate, taps=None, fractional_bw=None, ) self.blocks_wavfile_source_0 = blocks.wavfile_source(sys.argv[1], False) self.blocks_skiphead_0 = blocks.skiphead(gr.sizeof_float*1, 1) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((255, )) self.blocks_keep_one_in_n_1 = blocks.keep_one_in_n(gr.sizeof_float*1, 2) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float*1, 2) self.blocks_float_to_uchar_0 = blocks.float_to_uchar() self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_char*1, sys.argv[1]+".gray", False) self.blocks_file_sink_0.set_unbuffered(False) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.band_pass_filter_0 = filter.fir_filter_fff(1, firdes.band_pass( 1, samp_rate, 500, 4200, 2000, firdes.WIN_HAMMING, 6.76)) ################################################## # Connections ################################################## self.connect((self.blocks_wavfile_source_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_skiphead_0, 0)) self.connect((self.blocks_skiphead_0, 0), (self.blocks_keep_one_in_n_1, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_keep_one_in_n_1, 0), (self.blocks_float_to_complex_0, 1)) self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.blocks_complex_to_mag_0, 0), (self.rational_resampler_xxx_1, 0)) self.connect((self.rational_resampler_xxx_1, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.blocks_float_to_uchar_0, 0)) self.connect((self.blocks_float_to_uchar_0, 0), (self.blocks_file_sink_0, 0))
def __init__(self, fft_len, sample_rate, tune_freq, average, rate, width, height): gr.hier_block2.__init__(self, "ascii plot", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) self.fft_len = fft_len self.sample_rate = sample_rate self.average = average self.tune_freq = tune_freq self.rate = rate if width == 0 and height == 0: rows, columns = os.popen('stty size', 'r').read().split() self.height = int(rows) - 5 self.width = int(columns) / 2 - 10 else: self.height = height self.width = width self.msgq = gr.msg_queue(2) #######BLOCKS##### self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n( gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate / self.fft_len / self.rate))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, (), True) self.c2mag2 = blocks.complex_to_mag_squared(self.fft_len) self.avg = grfilter.single_pole_iir_filter_ff(self.average, self.fft_len) self.log = blocks.nlog10_ff( 10, self.fft_len, -10 * math.log10(self.fft_len) # Adjust for number of bins - 10 * math.log10(self.sample_rate)) # Adjust for sample rate self.sink = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq, True) #register message out to other blocks self.message_port_register_hier_out("pkt_out") #packet generator self.packet_generator = of.chat_blocks.chat_sender() #####CONNECTIONS#### self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag2, self.avg, self.log, self.sink) #MSG output self.msg_connect(self.packet_generator, "out", self, "pkt_out") ####THREADS#### self._ascii_plotter = ascii_plotter(self.width, self.height, self.tune_freq, self.sample_rate, self.fft_len) self._main = main_thread(self.msgq, self._ascii_plotter, self.packet_generator)
def __init__(self, interpolation=36, decimation=125): gr.hier_block2.__init__(self, "indri_smartnet_control_channel", gr.io_signature(1,1,gr.sizeof_float), gr.io_signature(1,1,1)) # Figure out where zero should be, despite RTL-SDR drift avglen = 1000 # should be big enough to catch drifts offset = blocks.moving_average_ff(avglen, 1.0/avglen, 40*avglen) differential = blocks.sub_ff() self.connect(self, (differential,0)) self.connect(self, offset) self.connect(offset, (differential,1)) # sample off the offsets to adjust tuning offset_sampler = blocks.keep_one_in_n(gr.sizeof_float, 10*avglen) offset_mag_block = blocks.probe_signal_f() self.offset_mag = offset_mag_block self.connect(offset, offset_sampler, offset_mag_block) rational_resampler = gr_filter.rational_resampler_fff( interpolation=interpolation, decimation=decimation, taps=None, fractional_bw=0.45, ) slicer = digital.binary_slicer_fb() self.connect(differential, rational_resampler, slicer, self)
def __init__(self, fft_size=2048, decim=100): gr.hier_block2.__init__( self, "RA:FFT", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_float*fft_size), ) ################################################## # Parameters ################################################## self.fft_size = fft_size self.decim = decim ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(1.0/decim, fft_size) self.fft_vxx_0 = fft.fft_vcc(fft_size, True, (window.blackmanharris(1024)), True, 1) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, fft_size) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff(([1.0/fft_size]*fft_size)) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float*fft_size, decim) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(fft_size) ################################################## # Connections ################################################## self.connect((self.blocks_multiply_const_vxx_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.fft_vxx_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self, 0))
def __init__(self, N=512 , NW=3 , K=5, weighting='adaptive', fftshift=False, samp_rate = 1, rate = 10): gr.hier_block2.__init__(self, "mtm", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float*N)) self.check_parameters(N, NW, K) self.s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, N) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * N, max(1, int(samp_rate/N/rate))) self.connect(self, self.s2v, self.one_in_n) dpss = specest_gendpss.gendpss(N=N, NW=NW, K=K) self.mtm = [eigenspectrum(dpss.dpssarray[i], fftshift) for i in xrange(K)] if weighting == 'adaptive': self.sum = specest_swig.adaptiveweighting_vff(N, dpss.lambdas) self.connect_mtm(K) self.connect(self.sum, self) elif weighting == 'unity': self.sum = blocks.add_ff(N) self.divide = blocks.multiply_const_vff([1./K]*N) self.connect_mtm(K) self.connect(self.sum, self.divide, self) elif weighting == 'eigenvalues': self.eigvalmulti = [] self.lambdasum = 0 for i in xrange(K): self.eigvalmulti.append(blocks.multiply_const_vff([dpss.lambdas[i]]*N)) self.lambdasum += dpss.lambdas[i] self.divide = blocks.multiply_const_vff([1./self.lambdasum]*N) self.sum = blocks.add_ff(N) #self.connect_mtm(K) self.connect_mtm_eig(K) self.connect(self.sum, self.divide, self) else: raise ValueError, 'weighting-type should be: adaptive, unity or eigenvalues'
def __init__(self, fft_len, rate, sample_rate): gr.hier_block2.__init__(self, "psd_logger", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0,0,0)) self.fft_len = fft_len self.rate = rate self.sample_rate = sample_rate self.msgq = gr.msg_queue(2) self.log_file = open('/tmp/psd_log'+'-'+ time.strftime("%y%m%d") + '-' + time.strftime("%H%M%S"),'w') self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate/self.fft_len/self.rate))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, mywindow) power = 0 for tap in mywindow: power += tap*tap self.c2mag = blocks.complex_to_mag(self.fft_len) self.sink = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq, True) self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.sink) self._watcher = _queue_watcher(self.msgq, self.log_file)
def __init__(self, fft_len, rate, sample_rate): gr.hier_block2.__init__(self, "psd_logger", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) self.fft_len = fft_len self.rate = rate self.sample_rate = sample_rate self.msgq = gr.msg_queue(2) self.log_file = open( '/tmp/psd_log' + '-' + time.strftime("%y%m%d") + '-' + time.strftime("%H%M%S"), 'w') self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n( gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate / self.fft_len / self.rate))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, mywindow) power = 0 for tap in mywindow: power += tap * tap self.c2mag = blocks.complex_to_mag(self.fft_len) self.sink = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq, True) self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.sink) self._watcher = _queue_watcher(self.msgq, self.log_file)
def __init__(self, fft_len, sample_rate, tune_freq, average, rate, length, height): gr.hier_block2.__init__(self, "ascii plot", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0,0,0)) self.fft_len = fft_len self.sample_rate = sample_rate self.average = average self.tune_freq = tune_freq self.rate = rate self.length = length self.height = height self.msgq = gr.msg_queue(2) #######BLOCKS##### self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate/self.fft_len/self.rate))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, (), True) self.c2mag2 = blocks.complex_to_mag_squared(self.fft_len) self.avg = grfilter.single_pole_iir_filter_ff(1.0, self.fft_len) self.log = blocks.nlog10_ff(10, self.fft_len, -10*math.log10(self.fft_len) # Adjust for number of bins -10*math.log10(self.sample_rate)) # Adjust for sample rate self.sink = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq, True) #####CONNECTIONS#### self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag2, self.avg, self.log, self.sink) self._main = main_thread(self.msgq, self.fft_len, self.sample_rate, self.tune_freq, self.length, self.height)
def __init__(self, integ=1, samp_rate=1, det_rate=1): gr.hier_block2.__init__( self, "Total Power Radiometer", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_float * 1), ) ################################################## # Parameters ################################################## self.integ = integ self.samp_rate = samp_rate self.det_rate = det_rate ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( 1.0 / ((samp_rate * integ) / 2.0), 1) (self.single_pole_iir_filter_xx_0).set_processor_affinity([1]) self.blocks_keep_one_in_n_4 = blocks.keep_one_in_n( gr.sizeof_float * 1, samp_rate / det_rate) self.blocks_complex_to_mag_squared_1 = blocks.complex_to_mag_squared(1) ################################################## # Connections ################################################## self.connect((self.blocks_complex_to_mag_squared_1, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_keep_one_in_n_4, 0), (self, 0)) self.connect((self, 0), (self.blocks_complex_to_mag_squared_1, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_4, 0))
def __init__(self): gr.top_block.__init__(self, "Gotenna Rx Usrp") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 32000000 self.fsk_deviation_hz = fsk_deviation_hz = 12500 self.chan_spacing = chan_spacing = 500000 self.baud_rate = baud_rate = 24000 ################################################## # Blocks ################################################## self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(("", '')), uhd.stream_args( cpu_format="fc32", args='', channels=list(range(0,1)), ), ) self.uhd_usrp_source_0.set_center_freq(915000000, 0) self.uhd_usrp_source_0.set_gain(5, 0) self.uhd_usrp_source_0.set_antenna('TX/RX', 0) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec()) self.rational_resampler_xxx_0 = filter.rational_resampler_fff( interpolation=1, decimation=4, taps=None, fractional_bw=None) self.gotenna_sink = gotenna_sink.blk() self.digital_symbol_sync_xx_0 = digital.symbol_sync_ff( digital.TED_DANDREA_AND_MENGALI_GEN_MSK, float(chan_spacing) / baud_rate / 4, 0.05, 1.5, 1.0, 0.001 * float(chan_spacing) / baud_rate / 4, 1, digital.constellation_bpsk().base(), digital.IR_MMSE_8TAP, 128, []) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_gr_complex*1, samp_rate // chan_spacing) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(chan_spacing/(2*math.pi*fsk_deviation_hz)) ################################################## # Connections ################################################## self.connect((self.analog_quadrature_demod_cf_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.gotenna_sink, 0)) self.connect((self.digital_symbol_sync_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.digital_symbol_sync_xx_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.blocks_keep_one_in_n_0, 0))
def __init__(self, block_size, one_in, item_size=gr.sizeof_gr_complex, vector_output=False): logger.info('%s will reduce stream to %3.0f%%.' % (self.__class__.__name__, 100.0 / one_in)) out_sig_item_size = item_size * (block_size if vector_output else 1) gr.hier_block2.__init__(self, self.__class__.__name__, gr.io_signature(1, 1, item_size), gr.io_signature(1, 1, out_sig_item_size)) self.s2v = blocks.stream_to_vector(item_size, block_size) self.keeper = blocks.keep_one_in_n(item_size * block_size, one_in) self.connect(self, self.s2v, self.keeper) if vector_output: self.connect(self.keeper, self) else: self.v2s = blocks.vector_to_stream(item_size, block_size) self.connect(self.keeper, self.v2s, self)
def __init__(self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fft_size=512, fft_rate=default_fft_rate, average=False, avg_alpha=None, title='', size=default_fftsink_size, **kwargs): gr.hier_block2.__init__(self, "waterfall_sink_f", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(0,0,0)) waterfall_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title) self.s2p = blocks.stream_to_vector(gr.sizeof_float, self.fft_size) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_float * self.fft_size, max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) mywindow = window.blackmanharris(self.fft_size) self.fft = fft.fft_vfc(self.fft_size, True, mywindow) self.c2mag = blocks.complex_to_mag(self.fft_size) self.avg = filter.single_pole_iir_filter_ff(1.0, self.fft_size) self.log = blocks.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) self.sink = blocks.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink) self.win = waterfall_window(self, parent, size=size) self.set_average(self.average)
def __init__(self): gr.top_block.__init__(self) usage = "%prog: [options] samples_file" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-m", "--dab-mode", type="int", default=1, help="DAB mode [default=%default]") parser.add_option('-u', '--usrp-source', action="store_true", default=False, help="Samples from USRP (-> resample from 2 MSPS to 2.048 MSPS)") (options, args) = parser.parse_args () dp = dab.dab_parameters(options.dab_mode) filename = args[0] self.src = blocks.file_source(gr.sizeof_gr_complex, filename, False) self.resample = blocks.rational_resampler_ccc(2048,2000) self.rate_detect_ns = dab.detect_null.detect_null(dp.ns_length, False) self.rate_estimator = dab.blocks.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length) self.decimate = blocks.keep_one_in_n(gr.sizeof_float, dp.frame_length) self.ignore_first = blocks.skiphead(gr.sizeof_float, 1) self.sink = blocks.vector_sink_f() if options.usrp_source: self.connect(self.src, self.resample, self.rate_detect_ns, self.rate_estimator, self.decimate, self.ignore_first, self.sink) else: self.connect(self.src, self.rate_detect_ns, self.rate_estimator, self.decimate, self.ignore_first, self.sink)
def __init__(self, sample_rate, fac_size, fac_rate): gr.hier_block2.__init__(self, "fast_autocorrelator_c", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) # Parameters self.sample_rate = sample_rate self.fac_size = fac_size self.fac_rate = fac_rate self.window = () # Block Objects For Float Fast Autocorrelator self.stream_to_vector = blocks.stream_to_vector( gr.sizeof_float, fac_size) self.keep_one_in_n = blocks.keep_one_in_n( gr.sizeof_float * fac_size, max(1, int(sample_rate / fac_size / fac_rate))) self.fac_fft = fft.fft_vfc(fac_size, True, self.window) self.complex_to_mag = blocks.complex_to_mag(fac_size) self.fac_complex_to_mag = blocks.complex_to_mag(fac_size) self.nlog10_ff = blocks.nlog10_ff(20, fac_size, -20 * math.log10(fac_size)) self.single_pole_iir_filter_ff = filter.single_pole_iir_filter_ff( 1, fac_size) self.fft_vfc = fft.fft_vfc(fac_size, True, self.window) self.vector_to_stream = blocks.vector_to_stream( gr.sizeof_float, self.fac_size) # Connections for Auto Correlator self.connect(self, self.stream_to_vector, self.keep_one_in_n, self.fft_vfc, self.complex_to_mag, self.fac_fft, self.fac_complex_to_mag, self.single_pole_iir_filter_ff, self.nlog10_ff, self.vector_to_stream, self)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 44100 ################################################## # Blocks ################################################## self.wxgui_numbersink2_0 = numbersink2.number_sink_f( self.GetWin(), unit="Hz", minval=50, maxval=280, factor=1, decimal_places=2, ref_level=0, sample_rate=samp_rate, number_rate=15, average=False, avg_alpha=None, label="Number Plot", peak_hold=False, show_gauge=True, ) self.Add(self.wxgui_numbersink2_0.win) self.blocks_moving_average_xx_0 = blocks.moving_average_ff( samp_rate / 50, 25 / pi, 200) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, 10) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.band_pass_filter_0 = filter.fir_filter_ccc( 1, firdes.complex_band_pass(1, samp_rate, 60, 255, 100, firdes.WIN_BLACKMAN, 6.76)) self.audio_source_0 = audio.source(samp_rate, "default", True) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf( 200 * 2.0 * pi / samp_rate, 260 * 2.0 * pi / samp_rate, 60 * 2.0 * pi / samp_rate) ################################################## # Connections ################################################## self.connect((self.blocks_moving_average_xx_0, 0), (self.wxgui_numbersink2_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.audio_source_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_moving_average_xx_0, 0))
def __init__(self, ebno_db=0, min_errors=100, samp_per_sym=1): gr.top_block.__init__(self, "BER 4FSK ") ################################################## # Parameters ################################################## self.ebno_db = ebno_db self.min_errors = min_errors self.samp_per_sym = samp_per_sym ################################################## # Variables ################################################## self.symb_rate = symb_rate = 4800 self.bits_per_sym = bits_per_sym = 1 self.bit_rate = bit_rate = float(symb_rate)*bits_per_sym self.average_power = average_power = 1.0 self.ebno = ebno = 10**(ebno_db/10.0) self.eb = eb = average_power/bit_rate self.samp_rate = samp_rate = symb_rate*samp_per_sym self.no = no = eb/ebno self.noise_variance = noise_variance = no*samp_rate/2.0 ################################################## # Blocks ################################################## self.sample_counter = sample_counter() self.probe_avg_power = analog.probe_avg_mag_sqrd_f(0, 1) self.pack_rx_bits = blocks.pack_k_bits_bb(8) self.pack_msg_bits = blocks.pack_k_bits_bb(8) self.glfsr = digital.glfsr_source_b(8, True, 0, 1) self.four_level_symbol_mapper_0 = four_level_symbol_mapper( symbol_map=[-1,1], ) self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bf(([-1,1]), 1) self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float*1, samp_per_sym) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float*1, samp_per_sym) self.blocks_add_xx_0 = blocks.add_vff(1) self.ber_sink = blocks.vector_sink_f(1) self.ber_measure = fec.ber_bf(True, min_errors, -7.0) self.analog_fastnoise_source_x_0 = analog.fastnoise_source_f(analog.GR_GAUSSIAN, math.sqrt(noise_variance), 0, 8192) ################################################## # Connections ################################################## self.connect((self.analog_fastnoise_source_x_0, 0), (self.blocks_add_xx_0, 1)) self.connect((self.ber_measure, 0), (self.ber_sink, 0)) self.connect((self.blocks_add_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.four_level_symbol_mapper_0, 0)) self.connect((self.blocks_repeat_0, 0), (self.blocks_add_xx_0, 0)) self.connect((self.blocks_repeat_0, 0), (self.probe_avg_power, 0)) self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.blocks_repeat_0, 0)) self.connect((self.four_level_symbol_mapper_0, 0), (self.sample_counter, 0)) self.connect((self.glfsr, 0), (self.digital_chunks_to_symbols_xx_0, 0)) self.connect((self.glfsr, 0), (self.pack_msg_bits, 0)) self.connect((self.pack_msg_bits, 0), (self.ber_measure, 0)) self.connect((self.pack_rx_bits, 0), (self.ber_measure, 1)) self.connect((self.sample_counter, 0), (self.pack_rx_bits, 0))
def test_001(self): src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) expected_data = (5, 10) src = blocks.vector_source_b(src_data); op = blocks.keep_one_in_n(gr.sizeof_char, 5) dst = blocks.vector_sink_b() self.tb.connect(src, op, dst) self.tb.run() self.assertEqual(dst.data(), expected_data)
def __init__(self, fft_len, sample_rate, average, rate, max_tu, data_precision): gr.hier_block2.__init__(self, "ascii plot", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) self.fft_len = fft_len self.sample_rate = sample_rate self.average = average self.rate = rate self.max_tu = max_tu - 2 #reserve two bytes for segmentation self.data_precision = data_precision if data_precision: print '32bit FFT in use (more bandwidth and precision)' else: print '8bit FFT in use (less bandwidth and precision)' self.msgq = gr.msg_queue(2) #######BLOCKS##### self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n( gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate / self.fft_len / self.rate))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, mywindow, True) self.c2mag2 = blocks.complex_to_mag_squared(self.fft_len) self.avg = grfilter.single_pole_iir_filter_ff(self.average, self.fft_len) self.log = blocks.nlog10_ff( 10, self.fft_len, -10 * math.log10(self.fft_len) # Adjust for number of bins - 10 * math.log10(self.sample_rate)) # Adjust for sample rate self.sink = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq, True) #register message out to other blocks self.message_port_register_hier_out("pdus") self._packet_source = packet_source() #####CONNECTIONS#### self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag2, self.avg, self.log, self.sink) self.msg_connect(self._packet_source, "out", self, "pdus") ####THREADS#### self._main = main_thread(self.msgq, self._packet_source, self.max_tu, self.fft_len, self.data_precision)
def __init__(self, filename, filesize=100e6): gr.hier_block2.__init__( self, "Ramdisk File Sink", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signaturev(4, 4, [ gr.sizeof_float * 1, gr.sizeof_float * 1, gr.sizeof_float * 1, gr.sizeof_float * 1 ]), ) ################################################## # Variables ################################################## mem = psutil.virtual_memory() self.filesize = int(min(mem.free - 500e6, filesize)) print "Actual file size: " + str(filesize) print "Set file size: " + str(self.filesize) self.filename = filename # Create RAMDISK subprocess.call(shlex.split("sudo mkdir /tmp/ramdisk")) subprocess.call( shlex.split("sudo mount -t tmpfs -o size=" + str(int(self.filesize)) + " none /tmp/ramdisk")) username = getpass.getuser() subprocess.call( shlex.split("sudo chown -R " + username + ":" + username + " /tmp/ramdisk")) ################################################## # Blocks ################################################## self.decim = blocks.keep_one_in_n(gr.sizeof_gr_complex * 1, int(self.filesize / 8 / 100)) self.file_meta_sink = blocks.file_meta_sink( gr.sizeof_gr_complex * 1, "/tmp/ramdisk/capture.dat", 1, 1, blocks.GR_FILE_FLOAT, True, 1000000, "", True) self.file_meta_sink.set_unbuffered(False) self.ctrl_progress = ctrl_progress(filename=filename, filesize=self.filesize, filesink=self.file_meta_sink) ################################################## # Connections ################################################## self.connect((self, 0), (self.file_meta_sink, 0)) self.connect((self, 0), (self.decim, 0)) self.connect((self.decim, 0), (self.ctrl_progress, 0)) self.connect((self.ctrl_progress, 0), (self, 0)) self.connect((self.ctrl_progress, 1), (self, 1)) self.connect((self.ctrl_progress, 2), (self, 2)) self.connect((self.ctrl_progress, 3), (self, 3))
def __init__(self): gr.top_block.__init__(self, type(self).__name__) OptionalDriverMixin.__init__(self) # replace this with actual demodulator # this just proves there is data. mind the dc offset. sink = audio.sink(device_name='', sampling_rate=48000) decim = blocks.keep_one_in_n(gr.sizeof_gr_complex, 167) demod = blocks.complex_to_real() self.connect(decim, demod, sink) self.driver = blocks.vector_source_c([]) self.driver_connection = (self.driver, decim) self.connect(*self.driver_connection)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 44100 ################################################## # Blocks ################################################## self.wxgui_numbersink2_0 = numbersink2.number_sink_f( self.GetWin(), unit="Hz", minval=50, maxval=280, factor=1, decimal_places=2, ref_level=0, sample_rate=samp_rate, number_rate=15, average=False, avg_alpha=None, label="Number Plot", peak_hold=False, show_gauge=True, ) self.Add(self.wxgui_numbersink2_0.win) self.blocks_moving_average_xx_0 = blocks.moving_average_ff(samp_rate / 50, 25 / pi, 200) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float * 1, 10) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.band_pass_filter_0 = filter.fir_filter_ccc( 1, firdes.complex_band_pass(1, samp_rate, 60, 255, 100, firdes.WIN_BLACKMAN, 6.76) ) self.audio_source_0 = audio.source(samp_rate, "default", True) self.analog_pll_freqdet_cf_0 = analog.pll_freqdet_cf( 200 * 2.0 * pi / samp_rate, 260 * 2.0 * pi / samp_rate, 60 * 2.0 * pi / samp_rate ) ################################################## # Connections ################################################## self.connect((self.blocks_moving_average_xx_0, 0), (self.wxgui_numbersink2_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.analog_pll_freqdet_cf_0, 0)) self.connect((self.audio_source_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.analog_pll_freqdet_cf_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_moving_average_xx_0, 0))
def __init__(self, N=512 , NW=3 , K=5, fftshift=False, samp_rate = 1, rate = 10): gr.hier_block2.__init__(self, "loeve", gr.io_signature(2, 2, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float*N)) self.check_parameters(N, NW, K) self.s2v1 = blocks.stream_to_vector(gr.sizeof_gr_complex, N) self.s2v2 = blocks.stream_to_vector(gr.sizeof_gr_complex, N) self.one_in_n1 = blocks.keep_one_in_n(gr.sizeof_gr_complex * N, max(1, int(samp_rate/N/rate))) self.one_in_n2 = blocks.keep_one_in_n(gr.sizeof_gr_complex * N, max(1, int(samp_rate/N/rate))) self.connect((self, 0), self.s2v1, self.one_in_n1) self.connect((self, 1), self.s2v2, self.one_in_n2) dpss = specest_gendpss.gendpss(N=N, NW=NW, K=K) self.mtm1 = [eigenspectrum(dpss.dpssarray[i], fftshift) for i in xrange(K)] self.mtm2 = [eigenspectrum(dpss.dpssarray[i], fftshift) for i in xrange(K)] self.multipliers = [blocks.multiply_vcc(N) for i in xrange(K)] self.sum = blocks.add_vcc(N) self.divide = blocks.multiply_const_vcc([1./K]*N) self.c2mag = blocks.complex_to_mag_squared(N) self.connect_loeve(K) self.connect(self.sum, self.divide, self.c2mag, self)
def __init__(self): gr.top_block.__init__(self, "Gsm Meta Capture") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 1e6 ################################################## # Blocks ################################################## self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(("", "")), 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(906.2e6, 0) self.uhd_usrp_source_0.set_gain(10, 0) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( .0001, 1) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, 13300) self.blocks_file_meta_sink_0 = blocks.file_meta_sink( gr.sizeof_float * 1, "meta_signal.bin", samp_rate, 1, blocks.GR_FILE_FLOAT, False, 10, "", False) self.blocks_file_meta_sink_0.set_unbuffered(False) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.band_pass_filter_0 = filter.fir_filter_ccf( 1, firdes.band_pass(1, samp_rate, 100e3, 300e3, 200, firdes.WIN_HAMMING, 6.76)) ################################################## # Connections ################################################## self.connect((self.band_pass_filter_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_file_meta_sink_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.band_pass_filter_0, 0))
def __init__(self): gr.top_block.__init__(self, "Elster Rx Nogui") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 2400000 self.rx_gain = rx_gain = 45 self.corr = corr = 0 self.channel_rate = channel_rate = 400000 self.channel_decimation = channel_decimation = 4 self.center_freq = center_freq = 904600000 ################################################## # Blocks ################################################## 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(rx_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.low_pass_filter_1 = filter.fir_filter_fff(channel_decimation, firdes.low_pass( 1, channel_rate, 20000, 5000, firdes.WIN_HAMMING, 6.76)) self.elster_packetize_0 = elster.packetize(1) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(channel_rate * 56.48E-6 / 2 / channel_decimation, 0.25*(0.05*0.05), 0.5, 0.05, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_gr_complex*1, samp_rate/channel_rate) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(-channel_rate/(115000*2*3.1416)) ################################################## # Connections ################################################## self.connect((self.osmosdr_source_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.low_pass_filter_1, 0)) self.connect((self.low_pass_filter_1, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.elster_packetize_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0))
def __init__(self, fft_len, sens_per_sec, sample_rate, channel_space = 1, search_bw = 1, thr_leveler = 10, tune_freq = 0, alpha_avg = 1, test_duration = 1, period = 3600, trunc_band = 1, verbose = False, peak_alpha = 0, subject_channels = []): gr.hier_block2.__init__(self, "flank detector", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0,0,0)) self.fft_len = fft_len #lenght of the fft for spectral analysis self.sens_per_sec = sens_per_sec #number of measurements per second (decimates) self.sample_rate = sample_rate self.channel_space = channel_space #channel space for analysis self.search_bw = search_bw #search bandwidth within each channel self.thr_leveler = thr_leveler #leveler factor for noise floor / threshold comparison self.tune_freq = tune_freq #center frequency self.threshold = 0 #actual value of the threshold self.alpha_avg = alpha_avg #averaging factor for noise level between consecutive measurements self.peak_alpha = peak_alpha #averaging factor for peak level between consecutive measurements self.subject_channels = subject_channels #channels whose flancks will be analysed self.msgq0 = gr.msg_queue(2) #######BLOCKS##### self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate/self.fft_len/self.sens_per_sec))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, (), True) self.c2mag2 = blocks.complex_to_mag_squared(self.fft_len) self.multiply = blocks.multiply_const_vff(np.array([1.0/float(self.fft_len**2)]*fft_len)) self.sink0 = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq0, True) #####CONNECTIONS#### self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag2, self.multiply, self.sink0) #start periodic logging self._logger = logger(period, test_duration) #self._logger = None #Watchers #statistics and power self._watcher0 = _queue0_watcher(self.msgq0, sens_per_sec, self.tune_freq, self.channel_space, self.search_bw, self.fft_len, self.sample_rate, self.thr_leveler, self.alpha_avg, test_duration, trunc_band, verbose, peak_alpha, subject_channels, self._logger)
def __init__(self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fft_size=512, fft_rate=default_fft_rate, average=False, avg_alpha=None, title='', size=default_fftsink_size, **kwargs): gr.hier_block2.__init__(self, "waterfall_sink_f", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(0, 0, 0)) waterfall_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title) self.s2p = blocks.stream_to_vector(gr.sizeof_float, self.fft_size) self.one_in_n = blocks.keep_one_in_n( gr.sizeof_float * self.fft_size, max(1, int(self.sample_rate / self.fft_size / self.fft_rate))) mywindow = window.blackmanharris(self.fft_size) self.fft = fft.fft_vfc(self.fft_size, True, mywindow) self.c2mag = blocks.complex_to_mag(self.fft_size) self.avg = filter.single_pole_iir_filter_ff(1.0, self.fft_size) self.log = blocks.nlog10_ff(20, self.fft_size, -20 * math.log10(self.fft_size)) self.sink = blocks.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag, self.avg, self.log, self.sink) self.win = waterfall_window(self, parent, size=size) self.set_average(self.average)
def __init__(self, parent, baseband_freq=0, ref_scale=2.0, y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512, fft_rate=default_fft_rate, average=False, avg_alpha=None, title='', size=default_fftsink_size, peak_hold=False, use_persistence=False, persist_alpha=0.2, **kwargs): gr.hier_block2.__init__(self, "fft_sink_c", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0,0,0)) fft_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, y_per_div=y_per_div, y_divs=y_divs, ref_level=ref_level, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold, use_persistence=use_persistence, persist_alpha=persist_alpha) self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size, max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) mywindow = window.blackmanharris(self.fft_size) self.fft = fft.fft_vcc(self.fft_size, True, mywindow) power = 0 for tap in mywindow: power += tap*tap self.c2magsq = blocks.complex_to_mag_squared(self.fft_size) self.avg = grfilter.single_pole_iir_filter_ff(1.0, self.fft_size) # FIXME We need to add 3dB to all bins but the DC bin self.log = blocks.nlog10_ff(10, self.fft_size, -20*math.log10(self.fft_size) # Adjust for number of bins -10*math.log10(power/self.fft_size) # Adjust for windowing loss -20*math.log10(ref_scale/2)) # Adjust for reference scale self.sink = blocks.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2magsq, self.avg, self.log, self.sink) self.win = fft_window(self, parent, size=size) self.set_average(self.average) self.set_use_persistence(self.use_persistence) self.set_persist_alpha(self.persist_alpha) self.set_peak_hold(self.peak_hold)
def __init__(self, fft_size=2048, decim=100): gr.hier_block2.__init__( self, "RA:FFT", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_float * fft_size), ) ################################################## # Parameters ################################################## self.fft_size = fft_size self.decim = decim ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( 1.0 / decim, fft_size) self.fft_vxx_0 = fft.fft_vcc(fft_size, True, (window.blackmanharris(1024)), True, 1) self.blocks_stream_to_vector_0 = blocks.stream_to_vector( gr.sizeof_gr_complex * 1, fft_size) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff( ([1.0 / fft_size] * fft_size)) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * fft_size, decim) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared( fft_size) ################################################## # Connections ################################################## self.connect((self.blocks_multiply_const_vxx_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.fft_vxx_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self, 0))
def __init__(self, block_len, n, uhd_src_active, file_rec_samp_rate): gr.hier_block2.__init__(self, "decimator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_gr_complex)) if(uhd_src_active == True): self.stv = blocks.stream_to_vector(gr.sizeof_gr_complex, block_len) self.decim = blocks.keep_one_in_n(block_len * gr.sizeof_gr_complex, n) self. vts = blocks.vector_to_stream(gr.sizeof_gr_complex, block_len) self.connect(self, self.stv) self.connect(self.stv, self.decim) self.connect(self.decim, self.vts) self.connect(self.vts, self) else: self.throttle = blocks.throttle(gr.sizeof_gr_complex, file_rec_samp_rate) self.connect(self, self.throttle) self.connect(self.throttle, self)
def __init__(self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fac_size=512, fac_rate=default_fac_rate, average=False, avg_alpha=None, title='', size=default_facsink_size, peak_hold=False): fac_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fac_size=fac_size, fac_rate=fac_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold) s2p = blocks.stream_to_vector(gr.sizeof_float, self.fac_size) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_float * self.fac_size, max(1, int(self.sample_rate/self.fac_size/self.fac_rate))) # windowing removed... #fac = gr.fft_vfc(self.fac_size, True, ()) fac = fft.fft_vfc(self.fac_size, True, ()) c2mag = blocks.complex_to_mag(self.fac_size) self.avg = filter.single_pole_iir_filter_ff_make(1.0, self.fac_size) fac_fac = fft.fft_vfc(self.fac_size, True, ()) fac_c2mag = blocks.complex_to_mag_make(fac_size) # FIXME We need to add 3dB to all bins but the DC bin log = blocks.nlog10_ff_make(20, self.fac_size, -20*math.log10(self.fac_size) ) sink = blocks.message_sink(gr.sizeof_float * self.fac_size, self.msgq, True) self.connect(s2p, self.one_in_n, fac, c2mag, fac_fac, fac_c2mag, self.avg, log, sink) # gr.hier_block.__init__(self, fg, s2p, sink) self.win = fac_window(self, parent, size=size) self.set_average(self.average) self.wxgui_connect(self, s2p)
def __init__(self, mode, input_rate=0, context=None): assert input_rate > 0 self.__input_rate = input_rate gr.hier_block2.__init__( self, type(self).__name__, gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) channel_filter = self.__make_channel_filter() self.__text = u'' self.__char_queue = gr.msg_queue(limit=100) self.__char_sink = blocks.message_sink(gr.sizeof_char, self.__char_queue, True) # The output of the channel filter is oversampled so we don't need to # interpolate for the audio monitor. So we'll downsample before going into # the demodulator. samp_per_sym = 8 downsample = self.__demod_rate / samp_per_sym / self.__symbol_rate assert downsample % 1 == 0 downsample = int(downsample) self.connect( self, channel_filter, blocks.keep_one_in_n(gr.sizeof_gr_complex, downsample), psk31_coherent_demodulator_cc(samp_per_sym=samp_per_sym), psk31_constellation_decoder_cb( varicode_decode=True, differential_decode=True), self.__char_sink) self.connect( channel_filter, blocks.rotator_cc(rotator_inc(self.__demod_rate, self.__audio_frequency)), blocks.complex_to_real(vlen=1), analog.agc2_ff( reference=dB(-10), attack_rate=8e-1, decay_rate=8e-1), self)
def __init__(self, sample_rate, fac_size, fac_decimation, useDB): gr.hier_block2.__init__( self, "AutoCorrelator", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float * fac_size)) # Output signature self.fac_size = fac_size self.fac_decimation = fac_decimation self.sample_rate = sample_rate streamToVec = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fac_size) # Make sure N is at least 1 decimation = int(self.sample_rate / self.fac_size / self.fac_decimation) self.one_in_n = blocks.keep_one_in_n( gr.sizeof_gr_complex * self.fac_size, max(1, decimation)) # FFT Note: No windowing. fac = fft.fft_vcc(self.fac_size, True, ()) complex2Mag = blocks.complex_to_mag(self.fac_size) self.avg = filter.single_pole_iir_filter_ff_make(1.0, self.fac_size) fac_fac = fft.fft_vfc(self.fac_size, True, ()) fac_c2mag = blocks.complex_to_mag_make(fac_size) # There's a note in Baz's block about needing to add 3 dB to each bin but the DC bin, however it was never implemented n = 20 k = -20 * math.log10(self.fac_size) log = blocks.nlog10_ff_make(n, self.fac_size, k) if useDB: self.connect(self, streamToVec, self.one_in_n, fac, complex2Mag, fac_fac, fac_c2mag, self.avg, log, self) else: self.connect(self, streamToVec, self.one_in_n, fac, complex2Mag, fac_fac, fac_c2mag, self.avg, self)
def __init__(self, fft_len, sample_rate, tune_freq, average, rate, width, height): gr.hier_block2.__init__(self, "ascii plot", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) self.fft_len = fft_len self.sample_rate = sample_rate self.average = average self.tune_freq = tune_freq self.rate = rate self.width = width self.height = height self.msgq = gr.msg_queue(2) #######BLOCKS##### self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_len) self.one_in_n = blocks.keep_one_in_n( gr.sizeof_gr_complex * self.fft_len, max(1, int(self.sample_rate / self.fft_len / self.rate))) mywindow = window.blackmanharris(self.fft_len) self.fft = fft.fft_vcc(self.fft_len, True, (), True) self.c2mag2 = blocks.complex_to_mag_squared(self.fft_len) self.avg = grfilter.single_pole_iir_filter_ff(1.0, self.fft_len) self.log = blocks.nlog10_ff( 10, self.fft_len, -10 * math.log10(self.fft_len) # Adjust for number of bins - 10 * math.log10(self.sample_rate)) # Adjust for sample rate self.sink = blocks.message_sink(gr.sizeof_float * self.fft_len, self.msgq, True) #####CONNECTIONS#### self.connect(self, self.s2p, self.one_in_n, self.fft, self.c2mag2, self.avg, self.log, self.sink) self._main = main_thread(self.msgq, self.fft_len, self.sample_rate, self.tune_freq, self.width, self.height)
def __init__(self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fac_size=512, fac_rate=default_fac_rate, average=False, avg_alpha=None, title='', size=default_facsink_size, peak_hold=False): fac_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fac_size=fac_size, fac_rate=fac_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold) s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fac_size) self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * self.fac_size, max(1, int(self.sample_rate/self.fac_size/self.fac_rate))) # windowing removed ... fac = fft.fft_vcc(self.fac_size, True, ()) c2mag = blocks.complex_to_mag_make(fac_size) # Things go off into the weeds if we try for an inverse FFT so a forward FFT will have to do... fac_fac = fft.fft_vfc(self.fac_size, True, ()) fac_c2mag = blocks.complex_to_mag_make(fac_size) self.avg = filter.single_pole_iir_filter_ff_make(1.0, fac_size) log = blocks.nlog10_ff_make(20, self.fac_size, -20*math.log10(self.fac_size) ) # - 20*math.log10(norm) ) # - self.avg[0] ) sink = blocks.message_sink_make(gr.sizeof_float * fac_size, self.msgq, True) self.connect(s2p, self.one_in_n, fac, c2mag, fac_fac, fac_c2mag, self.avg, log, sink) # gr.hier_block2.__init__(self, fg, s2p, sink) self.win = fac_window(self, parent, size=size) self.set_average(self.average) self.wxgui_connect(self, s2p)
def __init__(self, mode, input_rate=0, context=None): assert input_rate > 0 self.__input_rate = input_rate gr.hier_block2.__init__( self, type(self).__name__, gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) channel_filter = self.__make_channel_filter() self.__char_queue = gr.msg_queue(limit=100) self.__char_sink = blocks.message_sink(gr.sizeof_char, self.__char_queue, True) # The output of the channel filter is oversampled so we don't need to # interpolate for the audio monitor. So we'll downsample before going into # the demodulator. samp_per_sym = 8 downsample = self.__demod_rate / samp_per_sym / self.__symbol_rate assert downsample % 1 == 0 downsample = int(downsample) self.connect( self, channel_filter, blocks.keep_one_in_n(gr.sizeof_gr_complex, downsample), psk31_coherent_demodulator_cc(samp_per_sym=samp_per_sym), psk31_constellation_decoder_cb( varicode_decode=True, differential_decode=True), self.__char_sink) self.connect( channel_filter, blocks.rotator_cc(rotator_inc(self.__demod_rate, self.__audio_frequency)), blocks.complex_to_real(vlen=1), analog.agc2_ff( reference=dB(-10), attack_rate=8e-1, decay_rate=8e-1), self)
def __init__(self, item_size, sample_rate, vec_rate, vec_len): """ Create the block chain. Args: item_size: the number of bytes per sample sample_rate: the rate of incoming samples vec_rate: the rate of outgoing vectors (same units as sample_rate) vec_len: the length of the outgoing vectors in items """ self._vec_rate = vec_rate self._vec_len = vec_len self._sample_rate = sample_rate gr.hier_block2.__init__(self, "stream_to_vector_decimator", gr.io_signature(1, 1, item_size), # Input signature gr.io_signature(1, 1, item_size*vec_len)) # Output signature s2v = blocks.stream_to_vector(item_size, vec_len) self.one_in_n = blocks.keep_one_in_n(item_size*vec_len, 1) self._update_decimator() self.connect(self, s2v, self.one_in_n, self)
def __init__(self): gr.top_block.__init__(self) usage = "%prog: [options] samples_file" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-m", "--dab-mode", type="int", default=1, help="DAB mode [default=%default]") parser.add_option( '-u', '--usrp-source', action="store_true", default=False, help="Samples from USRP (-> resample from 2 MSPS to 2.048 MSPS)") (options, args) = parser.parse_args() dp = grdab.dab_parameters(options.dab_mode) filename = args[0] self.src = blocks.file_source(gr.sizeof_gr_complex, filename, False) self.resample = blocks.rational_resampler_ccc(2048, 2000) self.rate_detect_ns = grdab.detect_null.detect_null( dp.ns_length, False) self.rate_estimator = grdab.blocks.estimate_sample_rate_bf( dp.sample_rate, dp.frame_length) self.decimate = blocks.keep_one_in_n(gr.sizeof_float, dp.frame_length) self.ignore_first = blocks.skiphead(gr.sizeof_float, 1) self.sink = blocks.vector_sink_f() if options.usrp_source: self.connect(self.src, self.resample, self.rate_detect_ns, self.rate_estimator, self.decimate, self.ignore_first, self.sink) else: self.connect(self.src, self.rate_detect_ns, self.rate_estimator, self.decimate, self.ignore_first, self.sink)
def __init__(self): gr.top_block.__init__(self, "Gsm Meta Capture") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 1e6 ################################################## # Blocks ################################################## self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(("", "")), 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(906.2e6, 0) self.uhd_usrp_source_0.set_gain(10, 0) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(.0001, 1) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float*1, 13300) self.blocks_file_meta_sink_0 = blocks.file_meta_sink(gr.sizeof_float*1, "meta_signal.bin", samp_rate, 1, blocks.GR_FILE_FLOAT, False, 10, "", False) self.blocks_file_meta_sink_0.set_unbuffered(False) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.band_pass_filter_0 = filter.fir_filter_ccf(1, firdes.band_pass( 1, samp_rate, 100e3, 300e3, 200, firdes.WIN_HAMMING, 6.76)) ################################################## # Connections ################################################## self.connect((self.band_pass_filter_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_file_meta_sink_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.band_pass_filter_0, 0))
def _connect_rds_flow(self): xlate_bandwidth = 100000 audio_decim = 5 sample_rate = self._sample_rate baseband_rate = sample_rate / self.bb_decim freq_offset = 0 cosine_filter = grf.fir_filter_ccf( 1, firdes.root_raised_cosine(1, baseband_rate / audio_decim, 2375, 1, 100)) fir0 = grf.freq_xlating_fir_filter_ccc( 1, firdes.low_pass(1, sample_rate, xlate_bandwidth, 100000), freq_offset, sample_rate) fir1 = grf.freq_xlating_fir_filter_fcc( audio_decim, firdes.low_pass(2500.0, baseband_rate, 2.4e3, 2e3, firdes.WIN_HAMMING), 57e3, baseband_rate) mpsk_receiver = digital.mpsk_receiver_cc( 2, 0, cmath.pi / 100.0, -0.06, 0.06, 0.5, 0.05, baseband_rate / audio_decim / 2375.0, 0.001, 0.005) complex_to_real = blocks.complex_to_real(1) binary_slicer = digital.binary_slicer_fb() keep_one_in_2 = blocks.keep_one_in_n(gr.sizeof_char * 1, 2) diff_decoder = digital.diff_decoder_bb(2) self.connect(self.rtlsdr_source, fir0, self.wfm_rcv_rds, fir1, cosine_filter, mpsk_receiver, complex_to_real, binary_slicer, keep_one_in_2, diff_decoder, self.rds_decoder) # RDS Decoder -> RDS Parser -> RDS Adapter self.msg_connect(self.rds_decoder, b'out', self.rds_parser, b'in') self.msg_connect(self.rds_parser, b'out', self.rds_adapter, b'in')
def __init__(self, item_size, sample_rate, vec_rate, vec_len): """ Create the block chain. Args: item_size: the number of bytes per sample sample_rate: the rate of incoming samples vec_rate: the rate of outgoing vectors (same units as sample_rate) vec_len: the length of the outgoing vectors in items """ self._vec_rate = vec_rate self._vec_len = vec_len self._sample_rate = sample_rate gr.hier_block2.__init__( self, "stream_to_vector_decimator", gr.io_signature(1, 1, item_size), # Input signature gr.io_signature(1, 1, item_size * vec_len)) # Output signature s2v = blocks.stream_to_vector(item_size, vec_len) self.one_in_n = blocks.keep_one_in_n(item_size * vec_len, 1) self._update_decimator() self.connect(self, s2v, self.one_in_n, self)
def save_spectral_power(self, filepath, fft_len=2048, int_time=5, samp_rate=None, eq_file=None): """ Save the integrated spectrum from the telescope at regular intervals to an ASCI file Parameters ---------- filepath : str The path to the file where the results should be output. fft_len : int The number of bins which the spectrum should be made of (i.e. the length of the FFT transform.) Defaults to 2048. int_time : float The number of seconds over which each output sample is integrated. Defaults to 5 seconds. samp_rate : int The input sample rate of the data. This defaults to the sample rate of the ettus device, which should be fine for most (all?!) circumstances. eq_file : str The file containing the equalisation profile. This defaults to the the profile used in the rest of the module. """ if not samp_rate: samp_rate = self.samp_rate if not eq_file: eq_file = self.eq_file self.specflatfile = specflatfile(fft_len=2**11,fft_size=2**11,flat_file=eq_file,samp_rate=samp_rate) self.integrator = srt_integrator(fft_len=fft_len, int_time=int_time, reset_flag=0, samp_rate=samp_rate) self.blocks_keep_one_in_n = blocks.keep_one_in_n(gr.sizeof_float*fft_len, int_time*int(samp_rate/fft_len)) self.blocks_null = blocks.null_sink(gr.sizeof_float*fft_len) self.asci_sink = spectroscopy.asci_sink(fft_len, filepath) self.connect((self.rx_con, 0), (self.specflatfile, 0)) self.connect((self.specflatfile, 0), (self.integrator, 0)) self.connect((self.integrator,0), (self.blocks_null, 0)) self.connect((self.integrator, 1), (self.blocks_keep_one_in_n, 0)) self.connect((self.blocks_keep_one_in_n, 0), (self.asci_sink, 0))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Intensity Interferometer") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 250e3 self.magnitude = magnitude = 0.05 self.integ = integ = 1 self.beat = beat = 1 ################################################## # Blocks ################################################## _magnitude_sizer = wx.BoxSizer(wx.VERTICAL) self._magnitude_text_box = forms.text_box( parent=self.GetWin(), sizer=_magnitude_sizer, value=self.magnitude, callback=self.set_magnitude, label="Magnitude", converter=forms.float_converter(), proportion=0, ) self._magnitude_slider = forms.slider( parent=self.GetWin(), sizer=_magnitude_sizer, value=self.magnitude, callback=self.set_magnitude, minimum=0.05, maximum=0.5, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_magnitude_sizer) _integ_sizer = wx.BoxSizer(wx.VERTICAL) self._integ_text_box = forms.text_box( parent=self.GetWin(), sizer=_integ_sizer, value=self.integ, callback=self.set_integ, label="Integration Time (Sec)", converter=forms.float_converter(), proportion=0, ) self._integ_slider = forms.slider( parent=self.GetWin(), sizer=_integ_sizer, value=self.integ, callback=self.set_integ, minimum=1, maximum=30, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_integ_sizer) _beat_sizer = wx.BoxSizer(wx.VERTICAL) self._beat_text_box = forms.text_box( parent=self.GetWin(), sizer=_beat_sizer, value=self.beat, callback=self.set_beat, label="Beat Frequency (kHz)", converter=forms.float_converter(), proportion=0, ) self._beat_slider = forms.slider( parent=self.GetWin(), sizer=_beat_sizer, value=self.beat, callback=self.set_beat, minimum=1, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_beat_sizer) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="2nd detector power level", sample_rate=2, v_scale=0, v_offset=0, t_scale=450, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_STRIPCHART, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate / 10, fft_size=1024, fft_rate=8, average=True, avg_alpha=0.1, title="First Detector Spectrum", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( 1.0 / ((samp_rate / 10) * integ), 1) self.low_pass_filter_0 = gr.fir_filter_fff( int(samp_rate / 25e3), firdes.low_pass(1, samp_rate, 11e3, 2.5e3, firdes.WIN_HAMMING, 6.76)) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float * 1, samp_rate) self.blocks_multiply_xx_0 = blocks.multiply_vff(1) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, int(samp_rate / 20)) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.blocks_add_xx_0 = blocks.add_vcc(1) self.band_pass_filter_0 = gr.fir_filter_fff( 1, firdes.band_pass(1, samp_rate / 10, (beat * 1000) - 100, (beat * 1000) + 100, 50, firdes.WIN_HAMMING, 6.76)) self.analog_sig_source_x_0_0 = analog.sig_source_c( samp_rate, analog.GR_COS_WAVE, 122e3, magnitude, 0) self.analog_sig_source_x_0 = analog.sig_source_c( samp_rate, analog.GR_COS_WAVE, 122e3 - (beat * 1000), magnitude, 0) self.analog_noise_source_x_0 = analog.noise_source_c( analog.GR_GAUSSIAN, 0.2, 0) ################################################## # Connections ################################################## self.connect((self.analog_noise_source_x_0, 0), (self.blocks_add_xx_0, 2)) self.connect((self.analog_sig_source_x_0_0, 0), (self.blocks_add_xx_0, 1)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_add_xx_0, 0)) self.connect((self.blocks_add_xx_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.band_pass_filter_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.low_pass_filter_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0))
def __init__(self, samp_rate=2e6): grc_wxgui.top_block_gui.__init__( self, title="Amplitude calibration tool for USRP, v 0.2") ######################################################## # TODO: See if there's a sensible way to package an icon # with this program, rather than rely on some # particular Gnu Radio user's installation. # # _icon_path = "/home/dave/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png" # self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ######################################################## ################################################## # Parameters # # TODO: Add enough parameters, and the right ones, # that the program will come up with sliders # set conveniently for the user. # When step-sweep support is implemented, we # want to be able to run even w/o the GUI. ################################################## self.samp_rate = samp_rate ################################################## # Variables ################################################## self.usrp_gain_slider = usrp_gain_slider = 20 self.usrp_freq_offset_slider = usrp_freq_offset_slider = -100000 self.input_signal_power = input_signal_power = -50 self.input_freq_slider = input_freq_slider = 1e9 self.cal_file = None ################################################## # Blocks ################################################## self._input_rowhdr_text_box = wx.StaticText( self.GetWin(), label='\nReference Signal:\n') font = self._input_rowhdr_text_box.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self._input_rowhdr_text_box.SetFont(font) self.GridAdd(self._input_rowhdr_text_box, 1, 1, 1, 1) _input_freq_slider_sizer = wx.BoxSizer(wx.VERTICAL) self._input_freq_slider_text_box = forms.text_box( parent=self.GetWin(), sizer=_input_freq_slider_sizer, value=self.input_freq_slider, callback=self.set_input_freq_slider, label='RF input frequency (Hz)', converter=forms.float_converter(), proportion=0, ) self._input_freq_slider_slider = forms.slider( parent=self.GetWin(), sizer=_input_freq_slider_sizer, value=self.input_freq_slider, callback=self.set_input_freq_slider, minimum=10e6, maximum=6000e6, num_steps=20, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_input_freq_slider_sizer, 1, 2, 1, 3) _input_signal_power_sizer = wx.BoxSizer(wx.VERTICAL) self._input_signal_power_text_box = forms.text_box( parent=self.GetWin(), sizer=_input_signal_power_sizer, value=self.input_signal_power, callback=self.set_input_signal_power, label='Input signal power (dBm)', converter=forms.float_converter(), proportion=0, ) self._input_signal_power_slider = forms.slider( parent=self.GetWin(), sizer=_input_signal_power_sizer, value=self.input_signal_power, callback=self.set_input_signal_power, minimum=-70, maximum=-20, num_steps=50, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_input_signal_power_sizer, 1, 5, 1, 2) self._row_spacer_1 = wx.StaticText(self.GetWin(), label="\n") self.GridAdd(self._row_spacer_1, 2, 1, 1, 6) self._sdr_rowhdr_text_box = wx.StaticText(self.GetWin(), label='HackRF:') font = self._sdr_rowhdr_text_box.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self._sdr_rowhdr_text_box.SetFont(font) self.GridAdd(self._sdr_rowhdr_text_box, 3, 1, 1, 1) _usrp_freq_offset_slider_sizer = wx.BoxSizer(wx.VERTICAL) self._usrp_freq_offset_slider_text_box = forms.text_box( parent=self.GetWin(), sizer=_usrp_freq_offset_slider_sizer, value=self.usrp_freq_offset_slider, callback=self.set_usrp_freq_offset_slider, label='Freq offset', converter=forms.float_converter(), proportion=0, ) self._usrp_freq_offset_slider_slider = forms.slider( parent=self.GetWin(), sizer=_usrp_freq_offset_slider_sizer, value=self.usrp_freq_offset_slider, callback=self.set_usrp_freq_offset_slider, minimum=-200000, maximum=200000, num_steps=5, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_usrp_freq_offset_slider_sizer, 3, 2, 1, 3) _usrp_gain_slider_sizer = wx.BoxSizer(wx.VERTICAL) self._usrp_gain_slider_text_box = forms.text_box( parent=self.GetWin(), sizer=_usrp_gain_slider_sizer, value=self.usrp_gain_slider, callback=self.set_usrp_gain_slider, label='Gain (dB) !!!8dB step!!!', converter=forms.float_converter(), proportion=0, ) self._usrp_gain_slider_slider = forms.slider( parent=self.GetWin(), sizer=_usrp_gain_slider_sizer, value=self.usrp_gain_slider, callback=self.set_usrp_gain_slider, minimum=0, maximum=38, num_steps=38, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_usrp_gain_slider_sizer, 3, 5, 1, 2) self._row_spacer_2 = wx.StaticText(self.GetWin(), label="") self.GridAdd(self._row_spacer_2, 4, 1, 1, 6) self.wxgui_numbersink2_0_0 = numbersink2.number_sink_f( self.GetWin(), unit='dBFS', minval=-100, maxval=10, factor=1.0, decimal_places=0, ref_level=0, sample_rate=samp_rate / 10, number_rate=10, average=False, avg_alpha=None, label='Output power (digital)', peak_hold=False, show_gauge=True, ) self.GridAdd(self.wxgui_numbersink2_0_0.win, 5, 1, 1, 2) self.wxgui_numbersink2_0_0_1 = numbersink2.number_sink_f( self.GetWin(), unit='dB', minval=-20, maxval=80, factor=1.0, decimal_places=0, ref_level=0, sample_rate=samp_rate / 10, number_rate=10, average=False, avg_alpha=None, label='Power conversion value\n(output dbFS -> input dBm + gain)', peak_hold=False, show_gauge=True, ) self.GridAdd(self.wxgui_numbersink2_0_0_1.win, 5, 4, 1, 3) self.data_capture_button = forms.single_button( parent=self.GetWin(), label="Capture this data point", callback=self.checkbox_event, style=wx.BU_EXACTFIT, ) font = self.data_capture_button._button.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self.data_capture_button._button.SetFont(font) self.GridAdd(self.data_capture_button, 6, 4, 1, 1) self._wrapup_text_box_1 = wx.StaticText( self.GetWin(), label='\n USRP LO freq:\n', ) font = self._wrapup_text_box_1.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self._wrapup_text_box_1.SetFont(font) self.GridAdd(self._wrapup_text_box_1, 6, 5, 1, 1) self._wrapup_text_box_1.SetLabel("\n USRP LO freq: {0:.0f}\n".format( self.input_freq_slider + self.usrp_freq_offset_slider)) self._wrapup_text_box_2 = wx.StaticText( self.GetWin(), label='\n\n', ) self.GridAdd(self._wrapup_text_box_2, 6, 6, 1, 1) 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( input_freq_slider + usrp_freq_offset_slider, 0) self.osmosdr_source_0.set_freq_corr(0, 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(False, 0) self.osmosdr_source_0.set_gain(0, 0) self.osmosdr_source_0.set_if_gain(usrp_gain_slider, 0) self.osmosdr_source_0.set_bb_gain(0, 0) self.osmosdr_source_0.set_antenna('', 0) self.osmosdr_source_0.set_bandwidth(samp_rate, 0) self.u = self.osmosdr_source_0 self.u_mboard_serial = "" self.u_dboard_serial = "" self.u_dboard_id = "" self.u_dboard_id = "" self._sdr_rowhdr_text_box.SetLabel( "USRP serial # {0:s} \n{1:s} serial # {2:s} ".format( self.u_mboard_serial, self.u_dboard_id, self.u_dboard_serial)) self.single_pole_iir_filter_xx_1_0 = filter.single_pole_iir_filter_ff( 1.0 / ((0.1) * samp_rate), 1) self.low_pass_filter_0 = filter.fir_filter_ccf( 1, firdes.low_pass(1, samp_rate, samp_rate / 5, samp_rate / 10, firdes.WIN_HAMMING, 6.76)) self.dc_blocker_xx_0 = filter.dc_blocker_cc(1000, True) self.blocks_tag_debug_0 = blocks.tag_debug(gr.sizeof_gr_complex * 1, '', "") self.blocks_tag_debug_0.set_display(True) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_nlog10_ff_0_0 = blocks.nlog10_ff(10, 1, 0) self.blocks_keep_one_in_n_0_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, 10) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, 10) self.blocks_complex_to_mag_squared_0_0 = blocks.complex_to_mag_squared( 1) self.analog_const_source_x_0 = analog.sig_source_f( 0, analog.GR_CONST_WAVE, 0, 0, input_signal_power + usrp_gain_slider) ################################################## # Connections ################################################## self.connect((self.analog_const_source_x_0, 0), (self.blocks_keep_one_in_n_0_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0_0, 0), (self.single_pole_iir_filter_xx_1_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.wxgui_numbersink2_0_0, 0)) self.connect((self.blocks_keep_one_in_n_0_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.blocks_nlog10_ff_0_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.wxgui_numbersink2_0_0_1, 0)) self.connect((self.dc_blocker_xx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.blocks_complex_to_mag_squared_0_0, 0)) self.connect((self.single_pole_iir_filter_xx_1_0, 0), (self.blocks_nlog10_ff_0_0, 0)) self.connect((self.u, 0), (self.blocks_tag_debug_0, 0)) self.connect((self.u, 0), (self.dc_blocker_xx_0, 0))
def __init__( self, options, log = False ): ## Read configuration config = station_configuration() fft_length = config.fft_length cp_length = config.cp_length block_header = config.training_data data_subc = config.data_subcarriers virtual_subc = config.virtual_subcarriers total_subc = config.subcarriers block_length = config.block_length frame_length = config.frame_length dc_null = config.dc_null L = block_header.mm_periodic_parts ## Set Input/Output signature gr.hier_block2.__init__( self, "ofdm_inner_receiver", gr.io_signature( 1, 1, gr.sizeof_gr_complex ), gr.io_signaturev( 4, 4, [gr.sizeof_gr_complex * total_subc, # OFDM blocks gr.sizeof_char, # Frame start gr.sizeof_float * total_subc, gr.sizeof_float] ) ) # Normalized |CTF|^2 ## Input and output ports self.input = rx_input = self out_ofdm_blocks = ( self, 0 ) out_frame_start = ( self, 1 ) out_disp_ctf = ( self, 2 ) out_disp_cfo = ( self, 3 ) ## pre-FFT processing if options.ideal is False and options.ideal2 is False: if options.old_receiver is False: ## Compute autocorrelations for S&C preamble ## and cyclic prefix self._sc_metric = sc_metric = autocorrelator( fft_length/2, fft_length/2 ) self._gi_metric = gi_metric = autocorrelator( fft_length, cp_length ) self.connect( rx_input, sc_metric ) self.connect( rx_input, gi_metric ) ## Sync. Output contains OFDM blocks sync = ofdm.time_sync( fft_length, cp_length ) self.connect( rx_input, ( sync, 0 ) ) self.connect( sc_metric, ( sync, 1 ) ) self.connect( gi_metric, ( sync, 2 ) ) ofdm_blocks = ( sync, 0 ) frame_start = ( sync, 1 ) #log_to_file( self, ( sync, 1 ), "data/peak_detector.char" ) else: #Testing old/new metric self.tm = schmidl.recursive_timing_metric(fft_length) self.connect( self.input, self.tm) #log_to_file( self, self.tm, "data/rec_sc_metric_ofdm.float" ) timingmetric_shift = -2#int(-cp_length/4)# 0#-2 #int(-cp_length * 0.8) tmfilter = filter.fft_filter_fff(1, [1./cp_length]*cp_length) self.connect( self.tm, tmfilter ) self.tm = tmfilter self._pd_thres = 0.3 self._pd_lookahead = fft_length / 2 # empirically chosen peak_detector = ofdm.peak_detector_02_fb(self._pd_lookahead, self._pd_thres) self.connect(self.tm, peak_detector) #log_to_file( self, peak_detector, "data/rec_peak_detector.char" ) frame_start = [0]*frame_length frame_start[0] = 1 frame_start = self.frame_trigger_old = blocks.vector_source_b(frame_start,True) delayed_timesync = blocks.delay(gr.sizeof_char, (frame_length-1)*block_length + timingmetric_shift) self.connect( peak_detector, delayed_timesync ) self.block_sampler = ofdm.vector_sampler(gr.sizeof_gr_complex,block_length*frame_length) self.discard_cp = ofdm.vector_mask(block_length,cp_length,fft_length,[]) self.connect(self.input,self.block_sampler) self.connect(delayed_timesync,(self.block_sampler,1)) # TODO: dynamic solution vt2s = blocks.vector_to_stream(gr.sizeof_gr_complex*block_length, frame_length) self.connect(self.block_sampler,vt2s,self.discard_cp) #terminate_stream(self,ofdm_blocks) ofdm_blocks = self.discard_cp # else: # serial_to_parallel = blocks.stream_to_vector(gr.sizeof_gr_complex,block_length) # discard_cp = ofdm.vector_mask(block_length,cp_length,fft_length,[]) # ofdm_blocks = discard_cp # self.connect( rx_input, serial_to_parallel, discard_cp ) # frame_start = [0]*frame_length # frame_start[0] = 1 # frame_start = blocks.vector_source_b(frame_start,True) # # print "Disabled time synchronization stage" ## Compute autocorrelations for S&C preamble ## and cyclic prefix #log_to_file( self, sc_metric, "data/sc_metric_ofdm.float" ) #log_to_file(self, frame_start, "data/frame_start.compl") # log_to_file(self,ofdm_blocks,"data/ofdm_blocks_original.compl") if options.disable_time_sync or options.ideal or options.ideal2: if options.ideal is False and options.ideal2 is False: terminate_stream(self, ofdm_blocks) terminate_stream(self, frame_start) serial_to_parallel = blocks.stream_to_vector(gr.sizeof_gr_complex,block_length) discard_cp = ofdm.vector_mask_dc_null(block_length,cp_length,fft_length,dc_null, []) ofdm_blocks = discard_cp self.connect( rx_input, serial_to_parallel, discard_cp ) frame_start = [0]*frame_length frame_start[0] = 1 frame_start = blocks.vector_source_b(frame_start,True) print "Disabled time synchronization stage" print"\t\t\t\t\tframe_length = ",frame_length if options.ideal is False and options.ideal2 is False: ## Extract preamble, feed to Morelli & Mengali frequency offset estimator assert( block_header.mm_preamble_pos == 0 ) morelli_foe = ofdm.mm_frequency_estimator( fft_length, L,1,0 ) sampler_preamble = ofdm.vector_sampler( gr.sizeof_gr_complex * fft_length, 1 ) self.connect( ofdm_blocks, ( sampler_preamble, 0 ) ) self.connect( frame_start, ( sampler_preamble, 1 ) ) self.connect( sampler_preamble, morelli_foe ) freq_offset = morelli_foe ## Adaptive LMS FIR filtering of frequency offset lms_fir = ofdm.lms_fir_ff( 20, 1e-3 ) # TODO: verify parameter choice self.connect( freq_offset, lms_fir ) freq_offset = lms_fir #self.zmq_probe_freqoff = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5557") self.connect(lms_fir, blocks.keep_one_in_n(gr.sizeof_float,20) ,out_disp_cfo) else: self.connect(blocks.vector_source_f ([1]) ,out_disp_cfo) #log_to_file(self, lms_fir, "data/lms_fir.float") if options.disable_freq_sync or options.ideal or options.ideal2: if options.ideal is False and options.ideal2 is False: terminate_stream(self, freq_offset) freq_offset = blocks.vector_source_f([0.0],True) print "Disabled frequency synchronization stage" if options.ideal is False and options.ideal2 is False: ## Correct frequency shift, feed-forward structure frequency_shift = ofdm.frequency_shift_vcc( fft_length, -1.0/fft_length, cp_length ) self.connect( ofdm_blocks, ( frequency_shift, 0 ) ) self.connect( freq_offset, ( frequency_shift, 1 ) ) self.connect( frame_start, ( frequency_shift, 2 ) ) ofdm_blocks = frequency_shift ## FFT fft = fft_blocks.fft_vcc( fft_length, True, [], True ) self.connect( ofdm_blocks, fft ) ofdm_blocks = fft #log_to_file( self, fft, "data/compen.float" ) ## Remove virtual subcarriers if fft_length > data_subc: subcarrier_mask = ofdm.vector_mask_dc_null( fft_length, virtual_subc/2, total_subc, dc_null, [] ) self.connect( ofdm_blocks, subcarrier_mask ) ofdm_blocks = subcarrier_mask #log_to_file(self, ofdm_blocks, "data/vec_mask.compl") ## Least Squares estimator for channel transfer function (CTF) if options.logcir: log_to_file( self, ofdm_blocks, "data/OFDM_Blocks.compl" ) inv_preamble_fd = numpy.array( block_header.pilotsym_fd[ block_header.channel_estimation_pilot[0] ] ) inv_preamble_fd = numpy.concatenate([inv_preamble_fd[:total_subc/2],inv_preamble_fd[total_subc/2+dc_null:]]) #print "Channel estimation pilot: ", inv_preamble_fd inv_preamble_fd = 1. / inv_preamble_fd LS_channel_estimator0 = ofdm.multiply_const_vcc( list( inv_preamble_fd ) ) self.connect( ofdm_blocks, LS_channel_estimator0, gr.null_sink(gr.sizeof_gr_complex*total_subc)) log_to_file( self, LS_channel_estimator0, "data/OFDM_Blocks_eq.compl" ) ## post-FFT processing ## extract channel estimation preamble from frame if options.ideal is False and options.ideal2 is False: chest_pre_trigger = blocks.delay( gr.sizeof_char, 1) sampled_chest_preamble = ofdm.vector_sampler( gr.sizeof_gr_complex * total_subc, 1) self.connect( frame_start, chest_pre_trigger ) self.connect( chest_pre_trigger, ( sampled_chest_preamble, 1 ) ) self.connect( ofdm_blocks, ( sampled_chest_preamble, 0 ) ) ## Least Squares estimator for channel transfer function (CTF) inv_preamble_fd = numpy.array( block_header.pilotsym_fd[ block_header.channel_estimation_pilot[0] ] ) inv_preamble_fd = numpy.concatenate([inv_preamble_fd[:total_subc/2],inv_preamble_fd[total_subc/2+dc_null:]]) #print "Channel estimation pilot: ", inv_preamble_fd inv_preamble_fd = 1. / inv_preamble_fd LS_channel_estimator = ofdm.multiply_const_vcc( list( inv_preamble_fd ) ) self.connect( sampled_chest_preamble, LS_channel_estimator ) estimated_CTF = LS_channel_estimator if options.logcir: log_to_file( self, sampled_chest_preamble, "data/PREAM.compl" ) if not options.disable_ctf_enhancer: if options.logcir: ifft1 = fft_blocks.fft_vcc(total_subc,False,[],True) self.connect( estimated_CTF, ifft1,gr.null_sink(gr.sizeof_gr_complex*total_subc)) summ1 = ofdm.vector_sum_vcc(total_subc) c2m =gr.complex_to_mag(total_subc) self.connect( estimated_CTF,summ1 ,gr.null_sink(gr.sizeof_gr_complex)) self.connect( estimated_CTF, c2m,gr.null_sink(gr.sizeof_float*total_subc)) log_to_file( self, ifft1, "data/CIR1.compl" ) log_to_file( self, summ1, "data/CTFsumm1.compl" ) log_to_file( self, estimated_CTF, "data/CTF1.compl" ) log_to_file( self, c2m, "data/CTFmag1.float" ) ## MSE enhancer ctf_mse_enhancer = ofdm.CTF_MSE_enhancer( total_subc, cp_length + cp_length) self.connect( estimated_CTF, ctf_mse_enhancer ) # log_to_file( self, ctf_mse_enhancer, "data/ctf_mse_enhancer_original.compl") #ifft3 = fft_blocks.fft_vcc(total_subc,False,[],True) #null_noise = ofdm.noise_nulling(total_subc, cp_length + cp_length) #ctf_mse_enhancer = fft_blocks.fft_vcc(total_subc,True,[],True) #ctf_mse_enhancer = ofdm.vector_mask( fft_length, virtual_subc/2, # total_subc, [] ) #self.connect( estimated_CTF, ifft3,null_noise,ctf_mse_enhancer ) estimated_CTF = ctf_mse_enhancer print "Disabled CTF MSE enhancer" if options.logcir: ifft2 = fft_blocks.fft_vcc(total_subc,False,[],True) self.connect( estimated_CTF, ifft2,gr.null_sink(gr.sizeof_gr_complex*total_subc)) summ2 = ofdm.vector_sum_vcc(total_subc) c2m2 =gr.complex_to_mag(total_subc) self.connect( estimated_CTF,summ2 ,gr.null_sink(gr.sizeof_gr_complex)) self.connect( estimated_CTF, c2m2,gr.null_sink(gr.sizeof_float*total_subc)) log_to_file( self, ifft2, "data/CIR2.compl" ) log_to_file( self, summ2, "data/CTFsumm2.compl" ) log_to_file( self, estimated_CTF, "data/CTF2.compl" ) log_to_file( self, c2m2, "data/CTFmag2.float" ) ## Postprocess the CTF estimate ## CTF -> inverse CTF (for equalizer) ## CTF -> norm |.|^2 (for CTF display) ctf_postprocess = ofdm.postprocess_CTF_estimate( total_subc ) self.connect( estimated_CTF, ctf_postprocess ) inv_estimated_CTF = ( ctf_postprocess, 0 ) disp_CTF = ( ctf_postprocess, 1 ) # if options.disable_equalization or options.ideal: # terminate_stream(self, inv_estimated_CTF) # inv_estimated_CTF_vec = blocks.vector_source_c([1.0/fft_length*math.sqrt(total_subc)]*total_subc,True,total_subc) # inv_estimated_CTF_str = blocks.vector_to_stream(gr.sizeof_gr_complex, total_subc) # self.inv_estimated_CTF_mul = ofdm.multiply_const_ccf( 1.0/config.rms_amplitude ) # #inv_estimated_CTF_mul.set_k(1.0/config.rms_amplitude) # inv_estimated_CTF = blocks.stream_to_vector(gr.sizeof_gr_complex, total_subc) # self.connect( inv_estimated_CTF_vec, inv_estimated_CTF_str, self.inv_estimated_CTF_mul, inv_estimated_CTF) # print "Disabled equalization stage" ''' ## LMS Phase tracking ## Track residual frequency offset and sampling clock frequency offset nondata_blocks = [] for i in range(config.frame_length): if i in config.training_data.pilotsym_pos: nondata_blocks.append(i) print"\t\t\t\t\tnondata_blocks=",nondata_blocks pilot_subc = block_header.pilot_tones pilot_subcarriers = block_header.pilot_subc_sym print "PILOT SUBCARRIERS: ", pilot_subcarriers phase_tracking = ofdm.lms_phase_tracking_03( total_subc, pilot_subc, nondata_blocks, pilot_subcarriers,0 ) self.connect( ofdm_blocks, ( phase_tracking, 0 ) ) self.connect( inv_estimated_CTF, ( phase_tracking, 1 ) ) self.connect( frame_start, ( phase_tracking, 2 ) ) ## if options.scatter_plot_before_phase_tracking: self.before_phase_tracking = equalizer if options.disable_phase_tracking or options.ideal: terminate_stream(self, phase_tracking) print "Disabled phase tracking stage" else: ofdm_blocks = phase_tracking ''' ## Channel Equalizer if options.disable_equalization or options.ideal or options.ideal2: print "Disabled equalization stage" if options.ideal is False and options.ideal2 is False: terminate_stream(self, inv_estimated_CTF) else: equalizer = ofdm.channel_equalizer( total_subc ) self.connect( ofdm_blocks, ( equalizer, 0 ) ) self.connect( inv_estimated_CTF, ( equalizer, 1 ) ) self.connect( frame_start, ( equalizer, 2 ) ) ofdm_blocks = equalizer #log_to_file(self, equalizer,"data/equalizer_siso.compl") #log_to_file(self, ofdm_blocks, "data/equalizer.compl") ## LMS Phase tracking ## Track residual frequency offset and sampling clock frequency offset if options.ideal is False and options.ideal2 is False: nondata_blocks = [] for i in range(config.frame_length): if i in config.training_data.pilotsym_pos: nondata_blocks.append(i) print"\t\t\t\t\tnondata_blocks=",nondata_blocks pilot_subc = block_header.pilot_tones pilot_subcarriers = block_header.pilot_subc_sym print "PILOT SUBCARRIERS: ", pilot_subcarriers phase_tracking2 = ofdm.lms_phase_tracking_dc_null( total_subc, pilot_subc, nondata_blocks, pilot_subcarriers, dc_null ) self.connect( ofdm_blocks, ( phase_tracking2, 0 ) ) self.connect( frame_start, ( phase_tracking2, 1 ) ) ## if options.disable_phase_tracking or options.ideal or options.ideal2: if options.ideal is False and options.ideal2 is False: terminate_stream(self, phase_tracking2) print "Disabled phase tracking stage" else: ofdm_blocks = phase_tracking2 if options.scatter_plot_before_phase_tracking: self.before_phase_tracking = equalizer ## Output connections self.connect( ofdm_blocks, out_ofdm_blocks ) self.connect( frame_start, out_frame_start ) if options.ideal is False and options.ideal2 is False: self.connect( disp_CTF, out_disp_ctf ) else: self.connect( blocks.vector_source_f([1.0]*total_subc),blocks.stream_to_vector(gr.sizeof_float,total_subc), out_disp_ctf ) if log: log_to_file( self, sc_metric, "data/sc_metric.float" ) log_to_file( self, gi_metric, "data/gi_metric.float" ) log_to_file( self, morelli_foe, "data/morelli_foe.float" ) log_to_file( self, lms_fir, "data/lms_fir.float" ) log_to_file( self, sampler_preamble, "data/preamble.compl" ) log_to_file( self, sync, "data/sync.compl" ) log_to_file( self, frequency_shift, "data/frequency_shift.compl" ) log_to_file( self, fft, "data/fft.compl") log_to_file( self, fft, "data/fft.float", mag=True ) if vars().has_key( 'subcarrier_mask' ): log_to_file( self, subcarrier_mask, "data/subcarrier_mask.compl" ) log_to_file( self, ofdm_blocks, "data/ofdm_blocks_out.compl" ) log_to_file( self, frame_start, "data/frame_start.float", char_to_float=True ) log_to_file( self, sampled_chest_preamble, "data/sampled_chest_preamble.compl" ) log_to_file( self, LS_channel_estimator, "data/ls_channel_estimator.compl" ) log_to_file( self, LS_channel_estimator, "data/ls_channel_estimator.float", mag=True ) if "ctf_mse_enhancer" in locals(): log_to_file( self, ctf_mse_enhancer, "data/ctf_mse_enhancer.compl" ) log_to_file( self, ctf_mse_enhancer, "data/ctf_mse_enhancer.float", mag=True ) log_to_file( self, (ctf_postprocess,0), "data/inc_estimated_ctf.compl" ) log_to_file( self, (ctf_postprocess,1), "data/disp_ctf.float" ) log_to_file( self, equalizer, "data/equalizer.compl" ) log_to_file( self, equalizer, "data/equalizer.float", mag=True ) log_to_file( self, phase_tracking, "data/phase_tracking.compl" )
def __init__(self, options): gr.hier_block2.__init__( self, "fbmc_transmit_path", gr.io_signature(0, 0, 0), gr.io_signature(1, 1, gr.sizeof_gr_complex) ) common_options.defaults(options) config = self.config = station_configuration() config.data_subcarriers = options.subcarriers config.cp_length = 0 config.frame_data_blocks = options.data_blocks config._verbose = options.verbose config.fft_length = options.fft_length config.dc_null = options.dc_null config.training_data = default_block_header(config.data_subcarriers, config.fft_length, config.dc_null, options) config.coding = options.coding config.fbmc = options.fbmc config.adaptive_fbmc = options.adaptive_fbmc config.frame_id_blocks = 1 # FIXME # digital rms amplitude sent to USRP rms_amp = options.rms_amplitude self._options = copy.copy(options) config.block_length = config.fft_length + config.cp_length config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks config.frame_length = config.training_data.fbmc_no_preambles + 2 * config.frame_data_part config.subcarriers = config.data_subcarriers + config.training_data.pilot_subcarriers config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null # default values if parameters not set if rms_amp is None: rms_amp = math.sqrt(config.subcarriers) config.rms_amplitude = rms_amp # check some bounds if config.fft_length < config.subcarriers: raise SystemError, "Subcarrier number must be less than FFT length" if config.fft_length < config.cp_length: raise SystemError, "Cyclic prefix length must be less than FFT length" ## shortcuts blen = config.block_length flen = config.frame_length dsubc = config.data_subcarriers vsubc = config.virtual_subcarriers # Adaptive Transmitter Concept used_id_bits = config.used_id_bits = 8 # TODO: no constant in source code rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits # BPSK if config.data_subcarriers % used_id_bits <> 0: raise SystemError, "Data subcarriers need to be multiple of %d" % (used_id_bits) ## Allocation Control self.allocation_src = allocation_src( config.data_subcarriers, config.frame_data_blocks, config.coding, "tcp://*:3333", "tcp://" + options.rx_hostname + ":3322", ) if options.static_allocation: # DEBUG # how many bits per subcarrier if options.coding: mode = 1 # Coding mode 1-9 bitspermode = [0.5, 1, 1.5, 2, 3, 4, 4.5, 5, 6] # Information bits per mode modulbitspermode = [1, 2, 2, 4, 4, 6, 6, 6, 8] # Coding bits per mode bitcount_vec = [(int)(config.data_subcarriers * config.frame_data_blocks * bitspermode[mode - 1])] modul_bitcount_vec = [config.data_subcarriers * config.frame_data_blocks * modulbitspermode[mode - 1]] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) modul_bitcount_src = blocks.vector_source_i(modul_bitcount_vec, True, 1) bitloading = mode else: bitloading = 1 bitcount_vec = [config.data_subcarriers * config.frame_data_blocks * bitloading] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) modul_bitcount_src = bitcount_src # id's for frames id_vec = range(0, 256) id_src = blocks.vector_source_s(id_vec, True, 1) # bitloading for ID symbol and then once for data symbols # bitloading_vec = [1]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2) test_allocation = ( [bitloading] * (int)(config.data_subcarriers / 8) + [0] * (int)(config.data_subcarriers / 4 * 3) + [bitloading] * (int)(config.data_subcarriers / 8) ) # bitloading_vec = [1]*dsubc+[bitloading]*dsubc bitloading_vec = [1] * dsubc + test_allocation bitloading_src = blocks.vector_source_b(bitloading_vec, True, dsubc) # bitcount for frames # bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading] bitcount_vec = [config.frame_data_blocks * sum(test_allocation)] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) # power loading, here same for all symbols power_vec = ( [1] * (int)(config.data_subcarriers / 8) + [0] * (int)(config.data_subcarriers / 4 * 3) + [1] * (int)(config.data_subcarriers / 8) ) power_src = blocks.vector_source_f(power_vec, True, dsubc) # mux control stream to mux id and data bits mux_vec = [0] * dsubc + [1] * bitcount_vec[0] mux_ctrl = blocks.vector_source_b(mux_vec, True, 1) else: id_src = (self.allocation_src, 0) bitcount_src = (self.allocation_src, 4) bitloading_src = (self.allocation_src, 2) power_src = (self.allocation_src, 1) if options.coding: modul_bitcount_src = (self.allocation_src, 5) else: modul_bitcount_src = bitcount_src mux_ctrl = ofdm.tx_mux_ctrl(dsubc) self.connect(modul_bitcount_src, mux_ctrl) # Initial allocation self.allocation_src.set_allocation([4] * config.data_subcarriers, [1] * config.data_subcarriers) if options.benchmarking: self.allocation_src.set_allocation([4] * config.data_subcarriers, [1] * config.data_subcarriers) if options.lab_special_case: self.allocation_src.set_allocation( [0] * (config.data_subcarriers / 4) + [2] * (config.data_subcarriers / 2) + [0] * (config.data_subcarriers / 4), [1] * config.data_subcarriers, ) if options.log: log_to_file(self, id_src, "data/id_src.short") log_to_file(self, bitcount_src, "data/bitcount_src.int") log_to_file(self, bitloading_src, "data/bitloading_src.char") log_to_file(self, power_src, "data/power_src.cmplx") ## GUI probe output zmq_probe_bitloading = zeromq.pub_sink(gr.sizeof_char, dsubc, "tcp://*:4445") # also skip ID symbol bitloading with keep_one_in_n (side effect) # factor 2 for bitloading because we have two vectors per frame, one for id symbol and one for all payload/data symbols # factor config.frame_data_part for power because there is one vector per ofdm symbol per frame self.connect(bitloading_src, blocks.keep_one_in_n(gr.sizeof_char * dsubc, 2 * 40), zmq_probe_bitloading) zmq_probe_power = zeromq.pub_sink(gr.sizeof_float, dsubc, "tcp://*:4444") # self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_gr_complex*dsubc,40), blocks.complex_to_real(dsubc), zmq_probe_power) self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_float * dsubc, 40), zmq_probe_power) ## Workaround to avoid periodic structure seed(1) whitener_pn = [randint(0, 1) for i in range(used_id_bits * rep_id_bits)] ## ID Encoder id_enc = self._id_encoder = repetition_encoder_sb(used_id_bits, rep_id_bits, whitener_pn) self.connect(id_src, id_enc) if options.log: id_enc_f = gr.char_to_float() self.connect(id_enc, id_enc_f) log_to_file(self, id_enc_f, "data/id_enc_out.float") ## Reference Data Source ber_ref_src = ber_reference_source(self._options) self.connect(id_src, (ber_ref_src, 0)) self.connect(bitcount_src, (ber_ref_src, 1)) if options.log: log_to_file(self, ber_ref_src, "data/ber_rec_src_tx.char") if options.log: log_to_file(self, btrig, "data/bitmap_trig.char") ## Frame Trigger ftrig_stream = [1] + [0] * (config.frame_data_part - 1) ftrig = self._frame_trigger = blocks.vector_source_b(ftrig_stream, True) ## Data Multiplexer # Input 0: control stream # Input 1: encoded ID stream # Inputs 2..n: data streams dmux = self._data_multiplexer = stream_controlled_mux_b() self.connect(mux_ctrl, (dmux, 0)) self.connect(id_enc, (dmux, 1)) if options.coding: fo = trellis.fsm(1, 2, [91, 121]) encoder = self._encoder = trellis.encoder_bb(fo, 0) unpack = self._unpack = blocks.unpack_k_bits_bb(2) self.connect(ber_ref_src, encoder, unpack) if options.interleave: int_object = trellis.interleaver(2000, 666) interlv = trellis.permutation(int_object.K(), int_object.INTER(), 1, gr.sizeof_char) if not options.nopunct: bmaptrig_stream_puncturing = [1] + [0] * (config.frame_data_blocks / 2 - 1) btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b( bmaptrig_stream_puncturing, True ) puncturing = self._puncturing = puncture_bb(config.data_subcarriers) self.connect(bitloading_src, (puncturing, 1)) self.connect(self._bitmap_trigger_puncturing, (puncturing, 2)) self.connect(unpack, puncturing) last_block = puncturing if options.interleave: self.connect(last_block, interlv) last_block = interlv if options.benchmarking: self.connect(last_block, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(last_block, (dmux, 2)) else: if options.benchmarking: self.connect(unpack, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(unpack, (dmux, 2)) else: if options.benchmarking: self.connect(ber_ref_src, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(ber_ref_src, (dmux, 2)) if options.log: dmux_f = gr.char_to_float() self.connect(dmux, dmux_f) log_to_file(self, dmux_f, "data/dmux_out.float") ## Modulator mod = self._modulator = generic_mapper_bcv(config.data_subcarriers, config.coding, config.frame_data_part) self.connect(dmux, (mod, 0)) self.connect(bitloading_src, (mod, 1)) if options.log: log_to_file(self, mod, "data/mod_out.compl") modi = blocks.complex_to_imag(config.data_subcarriers) modr = blocks.complex_to_real(config.data_subcarriers) self.connect(mod, modi) self.connect(mod, modr) log_to_file(self, modi, "data/mod_imag_out.float") log_to_file(self, modr, "data/mod_real_out.float") ## Power allocator pa = self._power_allocator = multiply_frame_fc(config.frame_data_part, config.data_subcarriers) self.connect(mod, (pa, 0)) self.connect(power_src, (pa, 1)) if options.log: log_to_file(self, pa, "data/pa_out.compl") if options.fbmc: psubc = pa else: psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter() self.connect(pa, psubc) if options.log: log_to_file(self, psubc, "data/psubc_out.compl") subcarriers = config.subcarriers # fbmc_pblocks_timing = self._fbmc_timing_pilot_block_inserter = fbmc_timing_pilot_block_inserter(5,False) oqam_prep = self._oqam_prep = fbmc_oqam_preprocessing_vcvc(config.subcarriers, 0, 0) self.connect(psubc, oqam_prep) fbmc_pblocks = self._fbmc_pilot_block_inserter = fbmc_pilot_block_inserter(5, False) self.connect(oqam_prep, fbmc_pblocks) # log_to_file(self, fbmc_pblocks, "data/fbmc_pblocks_out.compl") # fbmc_insert_pream = self._fbmc_insert_pream = fbmc_insert_preamble_vcvc(M, syms_per_frame, preamble) # log_to_file(self, oqam_prep, "data/oqam_prep.compl") # log_to_file(self, psubc, "data/psubc_out.compl") # fbmc_pblocks = fbmc_pblocks_timing # log_to_file(self, fbmc_pblocks, "data/fbmc_pblocks_out.compl") beta_mult = self._beta_mult = fbmc_beta_multiplier_vcvc(config.subcarriers, 4, 4 * config.fft_length - 1, 0) self.connect(fbmc_pblocks, beta_mult) log_to_file(self, beta_mult, "data/beta_mult.compl") ## Add virtual subcarriers if config.fft_length > subcarriers: vsubc = self._virtual_subcarrier_extender = vector_padding_dc_null( config.subcarriers, config.fft_length, config.dc_null ) self.connect(beta_mult, vsubc) else: vsubc = self._virtual_subcarrier_extender = beta_mult if options.log: log_to_file(self, vsubc, "data/vsubc_out.compl") ## IFFT, no window, block shift ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [], True) self.connect(vsubc, ifft) if options.log: log_to_file(self, ifft, "data/ifft_out.compl") # FBMC separate stream + filterbanks separate_oqam = self._separate_oqam = fbmc_separate_vcvc(config.fft_length, 2) poly_netw_1 = self._poly_netw_1 = fbmc_polyphase_network_vcvc( config.fft_length, 4, 4 * config.fft_length - 1, False ) poly_netw_2 = self._poly_netw_2 = fbmc_polyphase_network_vcvc( config.fft_length, 4, 4 * config.fft_length - 1, False ) overlap_p2s = self._overlap_p2s = fbmc_overlapping_parallel_to_serial_vcc(config.fft_length) self.connect(ifft, (separate_oqam, 0), poly_netw_1) self.connect((separate_oqam, 1), poly_netw_2) self.connect(poly_netw_1, (overlap_p2s, 0)) self.connect(poly_netw_2, (overlap_p2s, 1)) ## Pilot blocks (preambles) # pblocks = self._pilot_block_inserter = pilot_block_inserter2(5,False) # self.connect( overlap_p2s, blocks.stream_to_vector(gr.sizeof_gr_complex,config.fft_length/2), pblocks ) # log_to_file(self, pblocks, "data/fbmc_pilot_block_ins_out.compl") if options.log: log_to_file(self, pblocks, "data/pilot_block_ins_out.compl") ## Cyclic Prefix # cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length, # config.block_length) # cp= blocks.vector_to_stream(gr.sizeof_gr_complex, config.fft_length/2) # self.connect(pblocks, cp ) # self.connect( overlap_p2s,blocks.stream_to_vector(gr.sizeof_gr_complex,config.fft_length/2), cp ) lastblock = overlap_p2s if options.log: log_to_file(self, overlap_p2s, "data/overlap_p2s_out.compl") # Digital Amplifier for resource allocation if config.adaptive_fbmc: rep = blocks.repeat(gr.sizeof_gr_complex, config.frame_length * config.block_length) amp = blocks.multiply_cc() self.connect(lastblock, (amp, 0)) self.connect((self.allocation_src, 3), rep, (amp, 1)) lastblock = amp else: self.connect((self.allocation_src, 3), blocks.null_sink(gr.sizeof_gr_complex)) ## Digital Amplifier # amp = self._amplifier = gr.multiply_const_cc(1) amp = self._amplifier = ofdm.multiply_const_ccf(1.0) self.connect(lastblock, amp) self.set_rms_amplitude(rms_amp) # log_to_file(self, amp, "data/amp_tx_out.compl") if options.log: log_to_file(self, amp, "data/amp_tx_out.compl") ## Tx parameters bandwidth = options.bandwidth or 2e6 bits = 8 * config.data_subcarriers * config.frame_data_blocks # max. QAM256 samples_per_frame = config.frame_length * config.block_length tb = samples_per_frame / bandwidth # set dummy carrier frequency if none available due to baseband mode if options.tx_freq is None: options.tx_freq = 0.0 self.tx_parameters = { "carrier_frequency": options.tx_freq / 1e9, "fft_size": config.fft_length, "cp_size": config.cp_length, "subcarrier_spacing": options.bandwidth / config.fft_length / 1e3, "data_subcarriers": config.data_subcarriers, "bandwidth": options.bandwidth / 1e6, "frame_length": config.frame_length, "symbol_time": (config.cp_length + config.fft_length) / options.bandwidth * 1e6, "max_data_rate": (bits / tb) / 1e6, } ## Setup Output self.connect(amp, self) # Display some information about the setup if config._verbose: self._print_verbage()
def __init__(self, options): gr.hier_block2.__init__(self, "fbmc_receive_path", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(0,0,0)) print "This is FBMC receive path 1x1" common_options.defaults(options) config = self.config = station_configuration() config.data_subcarriers = dsubc = options.subcarriers config.cp_length = 0 config.frame_data_blocks = options.data_blocks config._verbose = options.verbose #TODO: update config.fft_length = options.fft_length config.dc_null = options.dc_null config.training_data = default_block_header(dsubc, config.fft_length,config.dc_null,options) config.coding = options.coding config.ber_window = options.ber_window config.periodic_parts = 8 config.frame_id_blocks = 1 # FIXME self._options = copy.copy(options) #FIXME: do we need this? config.fbmc = options.fbmc config.block_length = config.fft_length + config.cp_length config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks config.frame_length = config.training_data.fbmc_no_preambles + 2*config.frame_data_part config.postpro_frame_length = config.frame_data_part + \ config.training_data.no_pilotsyms config.subcarriers = dsubc + \ config.training_data.pilot_subcarriers config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null total_subc = config.subcarriers # check some bounds if config.fft_length < config.subcarriers: raise SystemError, "Subcarrier number must be less than FFT length" if config.fft_length < config.cp_length: raise SystemError, "Cyclic prefix length must be less than FFT length" #self.input = gr.kludge_copy(gr.sizeof_gr_complex) #self.connect( self, self.input ) self.input = self self.ideal = options.ideal self.ideal2 = options.ideal2 ## Inner receiver ## Timing & Frequency Synchronization ## Channel estimation + Equalization ## Phase Tracking for sampling clock frequency offset correction inner_receiver = self.inner_receiver = fbmc_inner_receiver( options, options.log ) self.connect( self.input, inner_receiver ) ofdm_blocks = ( inner_receiver, 2 ) frame_start = ( inner_receiver, 1 ) disp_ctf = ( inner_receiver, 0 ) #self.snr_est_preamble = ( inner_receiver, 3 ) #terminate_stream(self,snr_est_preamble) disp_cfo = ( inner_receiver, 3 ) if self.ideal is False and self.ideal2 is False: self.zmq_probe_freqoff = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5557") self.connect(disp_cfo, self.zmq_probe_freqoff) else: self.connect(disp_cfo, blocks.null_sink(gr.sizeof_float)) # for ID decoder used_id_bits = config.used_id_bits = 8 #TODO: constant in source code! rep_id_bits = config.rep_id_bits = dsubc/used_id_bits #BPSK if options.log: print "rep_id_bits %d" % (rep_id_bits) if dsubc % used_id_bits <> 0: raise SystemError,"Data subcarriers need to be multiple of 10" ## Workaround to avoid periodic structure seed(1) whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)] ## NOTE!!! BIG HACK!!! ## first preamble ain't equalized .... ## for Milan's SNR estimator ## Outer Receiver ## Make new inner receiver compatible with old outer receiver ## FIXME: renew outer receiver self.ctf = disp_ctf #frame_sampler = ofdm_frame_sampler(options) frame_sampler = fbmc_frame_sampler(options) self.connect( ofdm_blocks, frame_sampler) self.connect( frame_start, (frame_sampler,1) ) # # ft = [0] * config.frame_length # ft[0] = 1 # # # The next block ensures that only complete frames find their way into # # the old outer receiver. The dynamic frame start trigger is hence # # replaced with a static one, fixed to the frame length. # # frame_sampler = ofdm.vector_sampler( gr.sizeof_gr_complex * total_subc, # config.frame_length ) # self.symbol_output = blocks.vector_to_stream( gr.sizeof_gr_complex * total_subc, # config.frame_length ) # delayed_frame_start = blocks.delay( gr.sizeof_char, config.frame_length - 1 ) # damn_static_frame_trigger = blocks.vector_source_b( ft, True ) # # if options.enable_erasure_decision: # frame_gate = vector_sampler( # gr.sizeof_gr_complex * total_subc * config.frame_length, 1 ) # self.connect( ofdm_blocks, frame_sampler, frame_gate, # self.symbol_output ) # else: # self.connect( ofdm_blocks, frame_sampler, self.symbol_output ) # # self.connect( frame_start, delayed_frame_start, ( frame_sampler, 1 ) ) if options.enable_erasure_decision: frame_gate = frame_sampler.frame_gate self.symbol_output = frame_sampler orig_frame_start = frame_start frame_start = (frame_sampler,1) self.frame_trigger = frame_start #terminate_stream(self, self.frame_trigger) ## Pilot block filter pb_filt = self._pilot_block_filter = fbmc_pilot_block_filter() self.connect(self.symbol_output,pb_filt) self.connect(self.frame_trigger,(pb_filt,1)) self.frame_data_trigger = (pb_filt,1) #self.symbol_output = pb_filt #if options.log: #log_to_file(self, pb_filt, "data/pb_filt_out.compl") if config.fbmc: pda_in = pb_filt else: ## Pilot subcarrier filter ps_filt = self._pilot_subcarrier_filter = pilot_subcarrier_filter() self.connect(self.symbol_output,ps_filt) if options.log: log_to_file(self, ps_filt, "data/ps_filt_out.compl") pda_in = ps_filt ## Workaround to avoid periodic structure # for ID decoder seed(1) whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)] if not options.enable_erasure_decision: ## ID Block Filter # Filter ID block, skip data blocks id_bfilt = self._id_block_filter = vector_sampler( gr.sizeof_gr_complex * dsubc, 1 ) if not config.frame_id_blocks == 1: raise SystemExit, "# ID Blocks > 1 not supported" self.connect( pda_in , id_bfilt ) self.connect( self.frame_data_trigger, ( id_bfilt, 1 ) ) # trigger #log_to_file( self, id_bfilt, "data/id_bfilt.compl" ) ## ID Demapper and Decoder, soft decision self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( dsubc, used_id_bits, whitener_pn ) self.connect( id_bfilt, self.id_dec ) print "Using coded BPSK soft decoder for ID detection" else: # options.enable_erasure_decision: id_bfilt = self._id_block_filter = vector_sampler( gr.sizeof_gr_complex * total_subc, config.frame_id_blocks ) id_bfilt_trig_delay = 0 for x in range( config.frame_length ): if x in config.training_data.pilotsym_pos: id_bfilt_trig_delay += 1 else: break print "Position of ID block within complete frame: %d" %(id_bfilt_trig_delay) assert( id_bfilt_trig_delay > 0 ) # else not supported id_bfilt_trig = blocks.delay( gr.sizeof_char, id_bfilt_trig_delay ) self.connect( ofdm_blocks, id_bfilt ) self.connect( orig_frame_start, id_bfilt_trig, ( id_bfilt, 1 ) ) self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( total_subc, used_id_bits, whitener_pn, config.training_data.shifted_pilot_tones ) self.connect( id_bfilt, self.id_dec ) print "Using coded BPSK soft decoder for ID detection" # The threshold block either returns 1.0 if the llr-value from the # id decoder is below the threshold, else 0.0. Hence we convert this # into chars, 0 and 1, and use it as trigger for the sampler. min_llr = ( self.id_dec, 1 ) erasure_threshold = gr.threshold_ff( 10.0, 10.0, 0 ) # FIXME is it the optimal threshold? erasure_dec = gr.float_to_char() id_gate = vector_sampler( gr.sizeof_short, 1 ) ctf_gate = vector_sampler( gr.sizeof_float * total_subc, 1 ) self.connect( self.id_dec , id_gate ) self.connect( self.ctf, ctf_gate ) self.connect( min_llr, erasure_threshold, erasure_dec ) self.connect( erasure_dec, ( frame_gate, 1 ) ) self.connect( erasure_dec, ( id_gate, 1 ) ) self.connect( erasure_dec, ( ctf_gate, 1 ) ) self.id_dec = self._id_decoder = id_gate self.ctf = ctf_gate print "Erasure decision for IDs is enabled" if options.log: id_dec_f = gr.short_to_float() self.connect(self.id_dec,id_dec_f) log_to_file(self, id_dec_f, "data/id_dec_out.float") if options.log: log_to_file(self, id_bfilt, "data/id_blockfilter_out.compl") # TODO: refactor names if options.log: map_src_f = gr.char_to_float(dsubc) self.connect(map_src,map_src_f) log_to_file(self, map_src_f, "data/map_src_out.float") ## Allocation Control if options.static_allocation: #DEBUG if options.coding: mode = 1 # Coding mode 1-9 bitspermode = [0.5,1,1.5,2,3,4,4.5,5,6] # Information bits per mode bitcount_vec = [(int)(config.data_subcarriers*config.frame_data_blocks*bitspermode[mode-1])] bitloading = mode else: bitloading = 1 bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading] #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks] self.bitcount_src = blocks.vector_source_i(bitcount_vec,True,1) # 0s for ID block, then data #bitloading_vec = [0]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2) bitloading_vec = [0]*dsubc+[bitloading]*dsubc bitloading_src = blocks.vector_source_b(bitloading_vec,True,dsubc) power_vec = [1]*config.data_subcarriers power_src = blocks.vector_source_f(power_vec,True,dsubc) else: self.allocation_buffer = ofdm.allocation_buffer(config.data_subcarriers, config.frame_data_blocks, "tcp://"+options.tx_hostname+":3333",config.coding) self.bitcount_src = (self.allocation_buffer,0) bitloading_src = (self.allocation_buffer,1) power_src = (self.allocation_buffer,2) self.connect(self.id_dec, self.allocation_buffer) if options.benchmarking: self.allocation_buffer.set_allocation([4]*config.data_subcarriers,[1]*config.data_subcarriers) if options.log: log_to_file(self, self.bitcount_src, "data/bitcount_src_rx.int") log_to_file(self, bitloading_src, "data/bitloading_src_rx.char") log_to_file(self, power_src, "data/power_src_rx.cmplx") log_to_file(self, self.id_dec, "data/id_dec_rx.short") ## Power Deallocator pda = self._power_deallocator = multiply_frame_fc(config.frame_data_part, dsubc) self.connect(pda_in,(pda,0)) self.connect(power_src,(pda,1)) ## Demodulator # if 0: # ac_vector = [0.0+0.0j]*208 # ac_vector[0] = (2*10**(-0.452)) # ac_vector[3] = (10**(-0.651)) # ac_vector[7] = (10**(-1.151)) # csi_vector_inv=abs(numpy.fft.fft(numpy.sqrt(ac_vector)))**2 # dm_csi = numpy.fft.fftshift(csi_vector_inv) # TODO dm_csi = [1]*dsubc # TODO dm_csi = blocks.vector_source_f(dm_csi,True) ## Depuncturer dp_trig = [0]*(config.frame_data_blocks/2) dp_trig[0] = 1 dp_trig = blocks.vector_source_b(dp_trig,True) # TODO if(options.coding): fo=ofdm.fsm(1,2,[91,121]) if options.interleave: int_object=trellis.interleaver(2000,666) deinterlv = trellis.permutation(int_object.K(),int_object.DEINTER(),1,gr.sizeof_float) demod = self._data_demodulator = generic_softdemapper_vcf(dsubc, config.frame_data_part, config.coding) #self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2)) if(options.ideal): self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2)) else: dm_csi_filter = self.dm_csi_filter = filter.single_pole_iir_filter_ff(0.01,dsubc) self.connect(self.ctf, self.dm_csi_filter,(demod,2)) #log_to_file(self, dm_csi_filter, "data/softs_csi.float") #self.connect(dm_trig,(demod,3)) else: demod = self._data_demodulator = generic_demapper_vcb(dsubc, config.frame_data_part) if options.benchmarking: # Do receiver benchmarking until the number of frames x symbols are collected self.connect(pda,blocks.head(gr.sizeof_gr_complex*dsubc, options.N*config.frame_data_blocks),demod) else: self.connect(pda,demod) self.connect(bitloading_src,(demod,1)) if(options.coding): ## Depuncturing if not options.nopunct: depuncturing = depuncture_ff(dsubc,0) frametrigger_bitmap_filter = blocks.vector_source_b([1,0],True) self.connect(bitloading_src,(depuncturing,1)) self.connect(dp_trig,(depuncturing,2)) ## Decoding chunkdivisor = int(numpy.ceil(config.frame_data_blocks/5.0)) print "Number of chunks at Viterbi decoder: ", chunkdivisor decoding = self._data_decoder = ofdm.viterbi_combined_fb(fo,dsubc,-1,-1,2,chunkdivisor,[-1,-1,-1,1,1,-1,1,1],ofdm.TRELLIS_EUCLIDEAN) if options.log and options.coding: log_to_file(self, decoding, "data/decoded.char") if not options.nopunct: log_to_file(self, depuncturing, "data/vit_in.float") if not options.nopunct: if options.interleave: self.connect(demod,deinterlv,depuncturing,decoding) else: self.connect(demod,depuncturing,decoding) else: self.connect(demod,decoding) self.connect(self.bitcount_src, multiply_const_ii(1./chunkdivisor), (decoding,1)) if options.scatterplot or options.scatter_plot_before_phase_tracking: if self.ideal2 is False: scatter_vec_elem = self._scatter_vec_elem = ofdm.vector_element(dsubc,40) scatter_s2v = self._scatter_s2v = blocks.stream_to_vector(gr.sizeof_gr_complex,config.frame_data_blocks) scatter_id_filt = skip(gr.sizeof_gr_complex*dsubc,config.frame_data_blocks) scatter_id_filt.skip_call(0) scatter_trig = [0]*config.frame_data_part scatter_trig[0] = 1 scatter_trig = blocks.vector_source_b(scatter_trig,True) self.connect(scatter_trig,(scatter_id_filt,1)) self.connect(scatter_vec_elem,scatter_s2v) if not options.scatter_plot_before_phase_tracking: print "Enabling Scatterplot for data subcarriers" self.connect(pda,scatter_id_filt,scatter_vec_elem) # Work on this #scatter_sink = ofdm.scatterplot_sink(dsubc) #self.connect(pda,scatter_sink) #self.connect(map_src,(scatter_sink,1)) #self.connect(dm_trig,(scatter_sink,2)) #print "Enabled scatterplot gui interface" self.zmq_probe_scatter = zeromq.pub_sink(gr.sizeof_gr_complex,config.frame_data_blocks, "tcp://*:5560") self.connect(scatter_s2v, blocks.keep_one_in_n(gr.sizeof_gr_complex*config.frame_data_blocks,20), self.zmq_probe_scatter) else: print "Enabling Scatterplot for data before phase tracking" inner_rx = inner_receiver.before_phase_tracking #scatter_sink2 = ofdm.scatterplot_sink(dsubc,"phase_tracking") op = copy.copy(options) op.enable_erasure_decision = False new_framesampler = ofdm_frame_sampler(op) self.connect( inner_rx, new_framesampler ) self.connect( orig_frame_start, (new_framesampler,1) ) new_ps_filter = pilot_subcarrier_filter() new_pb_filter = fbmc_pilot_block_filter() self.connect( (new_framesampler,1), (new_pb_filter,1) ) self.connect( new_framesampler, new_pb_filter, new_ps_filter, scatter_id_filt, scatter_vec_elem ) #self.connect( new_ps_filter, scatter_sink2 ) #self.connect( map_src, (scatter_sink2,1)) #self.connect( dm_trig, (scatter_sink2,2)) if options.log: if(options.coding): log_to_file(self, demod, "data/data_stream_out.float") else: data_f = gr.char_to_float() self.connect(demod,data_f) log_to_file(self, data_f, "data/data_stream_out.float") if options.sfo_feedback: used_id_bits = 8 rep_id_bits = config.data_subcarriers/used_id_bits seed(1) whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)] id_enc = ofdm.repetition_encoder_sb(used_id_bits,rep_id_bits,whitener_pn) self.connect( self.id_dec, id_enc ) id_mod = ofdm_bpsk_modulator(dsubc) self.connect( id_enc, id_mod ) id_mod_conj = gr.conjugate_cc(dsubc) self.connect( id_mod, id_mod_conj ) id_mult = blocks.multiply_vcc(dsubc) self.connect( id_bfilt, ( id_mult,0) ) self.connect( id_mod_conj, ( id_mult,1) ) # id_mult_avg = filter.single_pole_iir_filter_cc(0.01,dsubc) # self.connect( id_mult, id_mult_avg ) id_phase = gr.complex_to_arg(dsubc) self.connect( id_mult, id_phase ) log_to_file( self, id_phase, "data/id_phase.float" ) est=ofdm.LS_estimator_straight_slope(dsubc) self.connect(id_phase,est) slope=blocks.multiply_const_ff(1e6/2/3.14159265) self.connect( (est,0), slope ) log_to_file( self, slope, "data/slope.float" ) log_to_file( self, (est,1), "data/offset.float" ) # ------------------------------------------------------------------------ # # Display some information about the setup if config._verbose: self._print_verbage() ## debug logging ## if options.log: # log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.compl") # log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.float",mag=True) fftlen = 256 my_window = window.hamming(fftlen) #.blackmanharris(fftlen) rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen) rxs_sampler_vect = concatenate([[1],[0]*49]) rxs_trigger = blocks.vector_source_b(rxs_sampler_vect.tolist(),True) rxs_window = blocks.multiply_const_vcc(my_window) rxs_spectrum = gr.fft_vcc(fftlen,True,[],True) rxs_mag = gr.complex_to_mag(fftlen) rxs_avg = filter.single_pole_iir_filter_ff(0.01,fftlen) #rxs_logdb = blocks.nlog10_ff(20.0,fftlen,-20*log10(fftlen)) rxs_logdb = gr.kludge_copy( gr.sizeof_float * fftlen ) rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,1) self.connect(rxs_trigger,(rxs_sampler,1)) self.connect(self.input,rxs_sampler,rxs_window, rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate) log_to_file( self, rxs_decimate_rate, "data/psd_input.float" ) #output branches self.publish_rx_performance_measure()
def publish_rx_performance_measure(self): if self._rx_performance_measure_initialized(): return self.rx_performance_measure_initialized = True config = station_configuration() vlen = config.data_subcarriers vlen_sinr_sc = config.subcarriers if self.ideal2 is False: self.setup_ber_measurement() self.setup_snr_measurement() ber_mst = self._ber_measuring_tool if self._options.sinr_est: sinr_mst = self._sinr_measurement else: if self.ideal2 is False: snr_mst = self._snr_measurement if self.ideal is False and self.ideal2 is False: self.ctf = self.filter_ctf() self.zmq_probe_ctf = zeromq.pub_sink(gr.sizeof_float,config.data_subcarriers, "tcp://*:5559") self.connect(self.ctf, blocks.keep_one_in_n(gr.sizeof_float*config.data_subcarriers,20) ,self.zmq_probe_ctf) else: #self.zmq_probe_ctf = zeromq.pub_sink(gr.sizeof_float,config.subcarriers, "tcp://*:5559") self.connect(self.ctf,blocks.null_sink(gr.sizeof_float*config.subcarriers)) #self.rx_per_sink = rpsink = corba_rxinfo_sink("himalaya",config.ns_ip, # config.ns_port,vlen,config.rx_station_id) # print "BER img xfer" # self.connect(ber_mst,(rpsink,3)) # ## no sampling needed # 3. SNR if self.ideal2 is False: print "Normal BER measurement" trig_src = dynamic_trigger_ib(False) self.connect(self.bitcount_src,trig_src) ber_sampler = vector_sampler(gr.sizeof_float,1) self.connect(ber_mst,(ber_sampler,0)) self.connect(trig_src,(ber_sampler,1)) else: if(self._options.coding): demod = self._data_decoder else: demod = self._data_demodulator self.connect(self.bitcount_src,blocks.null_sink(gr.sizeof_int) ) self.connect(demod,blocks.null_sink(gr.sizeof_char)) if self._options.log: trig_src_float = gr.char_to_float() self.connect(trig_src,trig_src_float) log_to_file(self, trig_src_float , 'data/dynamic_trigger_out.float') if self._options.sinr_est is False and self.ideal2 is False: self.zmq_probe_ber = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5556") self.connect(ber_sampler,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_ber) if self.ideal2 is False: self.zmq_probe_snr = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5555") self.connect(snr_mst,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_snr)
def __init__(self, dab_params, rx_params, verbose=False, debug=False): """ Hierarchical block for OFDM demodulation @param dab_params DAB parameter object (dab.parameters.dab_parameters) @param rx_params RX parameter object (dab.parameters.receiver_parameters) @param debug enables debug output to files @param verbose whether to produce verbose messages """ self.dp = dp = dab_params self.rp = rp = rx_params self.verbose = verbose if self.rp.softbits: gr.hier_block2.__init__(self,"ofdm_demod", gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_float*self.dp.num_carriers*2, gr.sizeof_char)) # output signature else: gr.hier_block2.__init__(self,"ofdm_demod", gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_char*self.dp.num_carriers/4, gr.sizeof_char)) # output signature # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) #self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.input = blocks.multiply_const_cc(1.0) # FIXME self.connect(self, self.input) # input filtering if self.rp.input_fft_filter: if verbose: print "--> RX filter enabled" lowpass_taps = filter.firdes_low_pass(1.0, # gain dp.sample_rate, # sampling rate rp.filt_bw, # cutoff frequency rp.filt_tb, # width of transition band filter.firdes.WIN_HAMMING) # Hamming window self.fft_filter = filter.fft_filter_ccc(1, lowpass_taps) # correct sample rate offset, if enabled if self.rp.autocorrect_sample_rate: if verbose: print "--> dynamic sample rate correction enabled" self.rate_detect_ns = dab.detect_null(dp.ns_length, False) self.rate_estimator = dab.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length) self.rate_prober = blocks.probe_signal_f() self.connect(self.input, self.rate_detect_ns, self.rate_estimator, self.rate_prober) # self.resample = gr.fractional_interpolator_cc(0, 1) self.resample = dab.fractional_interpolator_triggered_update_cc(0,1) self.connect(self.rate_detect_ns, (self.resample,1)) self.updater = Timer(0.1,self.update_correction) # self.updater = threading.Thread(target=self.update_correction) self.run_interpolater_update_thread = True self.updater.setDaemon(True) self.updater.start() else: self.run_interpolater_update_thread = False if self.rp.sample_rate_correction_factor != 1: if verbose: print "--> static sample rate correction enabled" self.resample = gr.fractional_interpolator_cc(0, self.rp.sample_rate_correction_factor) # timing and fine frequency synchronisation self.sync = dab.ofdm_sync_dab2(self.dp, self.rp, debug) # ofdm symbol sampler self.sampler = dab.ofdm_sampler(dp.fft_length, dp.cp_length, dp.symbols_per_frame, rp.cp_gap) # fft for symbol vectors self.fft = fft.fft_vcc(dp.fft_length, True, [], True) # coarse frequency synchronisation self.cfs = dab.ofdm_coarse_frequency_correct(dp.fft_length, dp.num_carriers, dp.cp_length) # diff phasor self.phase_diff = dab.diff_phasor_vcc(dp.num_carriers) # remove pilot symbol self.remove_pilot = dab.ofdm_remove_first_symbol_vcc(dp.num_carriers) # magnitude equalisation if self.rp.equalize_magnitude: if verbose: print "--> magnitude equalization enabled" self.equalizer = dab.magnitude_equalizer_vcc(dp.num_carriers, rp.symbols_for_magnitude_equalization) # frequency deinterleaving self.deinterleave = dab.frequency_interleaver_vcc(dp.frequency_deinterleaving_sequence_array) # symbol demapping self.demapper = dab.qpsk_demapper_vcb(dp.num_carriers) # # connect everything # if self.rp.autocorrect_sample_rate or self.rp.sample_rate_correction_factor != 1: self.connect(self.input, self.resample) self.input2 = self.resample else: self.input2 = self.input if self.rp.input_fft_filter: self.connect(self.input2, self.fft_filter, self.sync) else: self.connect(self.input2, self.sync) # data stream self.connect((self.sync, 0), (self.sampler, 0), self.fft, (self.cfs, 0), self.phase_diff, (self.remove_pilot,0)) if self.rp.equalize_magnitude: self.connect((self.remove_pilot,0), (self.equalizer,0), self.deinterleave) else: self.connect((self.remove_pilot,0), self.deinterleave) if self.rp.softbits: if verbose: print "--> using soft bits" self.softbit_interleaver = dab.complex_to_interleaved_float_vcf(self.dp.num_carriers) self.connect(self.deinterleave, self.softbit_interleaver, (self,0)) else: self.connect(self.deinterleave, self.demapper, (self,0)) # control stream self.connect((self.sync, 1), (self.sampler, 1), (self.cfs, 1), (self.remove_pilot,1)) if self.rp.equalize_magnitude: self.connect((self.remove_pilot,1), (self.equalizer,1), (self,1)) else: self.connect((self.remove_pilot,1), (self,1)) # calculate an estimate of the SNR self.phase_var_decim = blocks.keep_one_in_n(gr.sizeof_gr_complex*self.dp.num_carriers, self.rp.phase_var_estimate_downsample) self.phase_var_arg = blocks.complex_to_arg(dp.num_carriers) self.phase_var_v2s = blocks.vector_to_stream(gr.sizeof_float, dp.num_carriers) self.phase_var_mod = dab.modulo_ff(pi/2) self.phase_var_avg_mod = filter.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) self.phase_var_sub_avg = blocks.sub_ff() self.phase_var_sqr = blocks.multiply_ff() self.phase_var_avg = filter.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) self.probe_phase_var = blocks.probe_signal_f() self.connect((self.remove_pilot,0), self.phase_var_decim, self.phase_var_arg, self.phase_var_v2s, self.phase_var_mod, (self.phase_var_sub_avg,0), (self.phase_var_sqr,0)) self.connect(self.phase_var_mod, self.phase_var_avg_mod, (self.phase_var_sub_avg,1)) self.connect(self.phase_var_sub_avg, (self.phase_var_sqr,1)) self.connect(self.phase_var_sqr, self.phase_var_avg, self.probe_phase_var) # measure processing rate self.measure_rate = dab.measure_processing_rate(gr.sizeof_gr_complex, 2000000) self.connect(self.input, self.measure_rate) # debugging if debug: self.connect(self.fft, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/ofdm_after_fft.dat")) self.connect((self.cfs,0), blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_after_cfs.dat")) self.connect(self.phase_diff, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_diff_phasor.dat")) self.connect((self.remove_pilot,0), blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_pilot_removed.dat")) self.connect((self.remove_pilot,1), blocks.file_sink(gr.sizeof_char, "debug/ofdm_after_cfs_trigger.dat")) self.connect(self.deinterleave, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_deinterleaved.dat")) if self.rp.equalize_magnitude: self.connect(self.equalizer, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_equalizer.dat")) if self.rp.softbits: self.connect(self.softbit_interleaver, blocks.file_sink(gr.sizeof_float*dp.num_carriers*2, "debug/softbits.dat"))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Stereo FM receiver and RDS Decoder") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 1000000 self.bb_decim = bb_decim = 4 self.freq_offset = freq_offset = 250000 self.freq = freq = 101.5 self.baseband_rate = baseband_rate = samp_rate/bb_decim self.audio_decim = audio_decim = 5 self.xlate_bandwidth = xlate_bandwidth = 100000 self.gain = gain = 20 self.freq_tune = freq_tune = freq - freq_offset self.audio_rate = audio_rate = 48000 self.audio_decim_rate = audio_decim_rate = baseband_rate/audio_decim ################################################## # Blocks ################################################## self.nb = self.nb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.nb.AddPage(grc_wxgui.Panel(self.nb), "BB") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Demod") self.nb.AddPage(grc_wxgui.Panel(self.nb), "L+R") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Pilot") self.nb.AddPage(grc_wxgui.Panel(self.nb), "DSBSC") self.nb.AddPage(grc_wxgui.Panel(self.nb), "RDS") self.nb.AddPage(grc_wxgui.Panel(self.nb), "L-R") self.nb.AddPage(grc_wxgui.Panel(self.nb), "RDS constellation") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Waterfall") self.GridAdd(self.nb, 2, 0, 1, 2) self.wxgui_scopesink2_1 = scopesink2.scope_sink_c( self.nb.GetPage(7).GetWin(), title="Scope Plot", sample_rate=2375, 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(7).Add(self.wxgui_scopesink2_1.win) self.wxgui_fftsink2_0_0_0_1_0_1 = fftsink2.fft_sink_c( self.nb.GetPage(5).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=audio_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="RDS", peak_hold=False, ) self.nb.GetPage(5).Add(self.wxgui_fftsink2_0_0_0_1_0_1.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.nb.GetPage(0).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=-30, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=True, avg_alpha=0.8, title="Baseband", peak_hold=False, ) self.nb.GetPage(0).Add(self.wxgui_fftsink2_0.win) self.rtl_sdr_source0 = osmosdr.source( args="numchan=" + str(1) + " " + "" ) self.rtl_sdr_source0.set_sample_rate(samp_rate) self.rtl_sdr_source0.set_center_freq(freq_tune, 0) self.rtl_sdr_source0.set_freq_corr(0, 0) self.rtl_sdr_source0.set_dc_offset_mode(0, 0) self.rtl_sdr_source0.set_iq_balance_mode(0, 0) self.rtl_sdr_source0.set_gain_mode(False, 0) self.rtl_sdr_source0.set_gain(gain, 0) self.rtl_sdr_source0.set_if_gain(20, 0) self.rtl_sdr_source0.set_bb_gain(20, 0) self.rtl_sdr_source0.set_antenna("", 0) self.rtl_sdr_source0.set_bandwidth(0, 0) self.root_raised_cosine_filter_0 = filter.fir_filter_ccf(1, firdes.root_raised_cosine( 1, samp_rate/bb_decim/audio_decim, 2375, 1, 100)) self.gr_rds_parser_0 = rds.parser(True, False) self.gr_rds_panel_0 = rds.rdsPanel(freq, self.GetWin()) self.Add(self.gr_rds_panel_0.panel) self.gr_rds_decoder_0 = rds.decoder(False, False) self.freq_xlating_fir_filter_xxx_1 = filter.freq_xlating_fir_filter_fcc(audio_decim, (firdes.low_pass(2500.0,baseband_rate,2.4e3,2e3,firdes.WIN_HAMMING)), 57e3, baseband_rate) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1, samp_rate, xlate_bandwidth, 100000)), freq_offset, samp_rate) self.digital_mpsk_receiver_cc_0 = digital.mpsk_receiver_cc(2, 0, 1*cmath.pi/100.0, -0.06, 0.06, 0.5, 0.05, samp_rate/bb_decim/audio_decim/ 2375.0, 0.001, 0.005) self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(2) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_char*1, 2) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.analog_wfm_rcv_0 = analog.wfm_rcv( quad_rate=samp_rate, audio_decimation=bb_decim, ) ################################################## # Connections ################################################## self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0)) self.connect((self.analog_wfm_rcv_0, 0), (self.freq_xlating_fir_filter_xxx_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_1, 0), (self.wxgui_fftsink2_0_0_0_1_0_1, 0)) self.connect((self.digital_mpsk_receiver_cc_0, 0), (self.wxgui_scopesink2_1, 0)) self.connect((self.freq_xlating_fir_filter_xxx_1, 0), (self.root_raised_cosine_filter_0, 0)) self.connect((self.root_raised_cosine_filter_0, 0), (self.digital_mpsk_receiver_cc_0, 0)) self.connect((self.digital_mpsk_receiver_cc_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.digital_diff_decoder_bb_0, 0)) self.connect((self.rtl_sdr_source0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.digital_diff_decoder_bb_0, 0), (self.gr_rds_decoder_0, 0)) ################################################## # Asynch Message Connections ################################################## self.msg_connect(self.gr_rds_decoder_0, "out", self.gr_rds_parser_0, "in") self.msg_connect(self.gr_rds_parser_0, "out", self.gr_rds_panel_0, "in")
def __init__(self, meta_rate=10): gr.top_block.__init__(self, "Fox1D Playback") Qt.QWidget.__init__(self) self.setWindowTitle("Fox1D Playback") 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", "fox1d_playback") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Parameters ################################################## self.meta_rate = meta_rate ################################################## # Variables ################################################## self.samp_rate = samp_rate = 250e3 self.decim = decim = 5 self.baud = baud = 9600 self.xlate_taps_old = xlate_taps_old = firdes.low_pass( 1.0, samp_rate, samp_rate / 2, 1000, firdes.WIN_HAMMING, 6.76) self.xlate_taps = xlate_taps = firdes.low_pass(1.0, samp_rate, 15e3, 1000, firdes.WIN_HAMMING, 6.76) self.volume = volume = 0.01 self.throttle_factor = throttle_factor = 1 self.samps_per_symb = samps_per_symb = samp_rate / decim / baud self.rf_lpf_cutoff = rf_lpf_cutoff = 8e3 self.fsk_deviation_hz = fsk_deviation_hz = 4000 self.fll_loop_bw_fine = fll_loop_bw_fine = 0.0001 self.fll_loop_bw = fll_loop_bw = math.pi / 200 self.audio_lpf_cutoff = audio_lpf_cutoff = 7e3 ################################################## # Blocks ################################################## self._volume_tool_bar = Qt.QToolBar(self) self._volume_tool_bar.addWidget(Qt.QLabel("volume" + ": ")) self._volume_line_edit = Qt.QLineEdit(str(self.volume)) self._volume_tool_bar.addWidget(self._volume_line_edit) self._volume_line_edit.returnPressed.connect(lambda: self.set_volume( eng_notation.str_to_num( str(self._volume_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._volume_tool_bar, 7, 4, 1, 2) for r in range(7, 8): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 6): self.top_grid_layout.setColumnStretch(c, 1) self._throttle_factor_tool_bar = Qt.QToolBar(self) self._throttle_factor_tool_bar.addWidget( Qt.QLabel("throttle_factor" + ": ")) self._throttle_factor_line_edit = Qt.QLineEdit( str(self.throttle_factor)) self._throttle_factor_tool_bar.addWidget( self._throttle_factor_line_edit) self._throttle_factor_line_edit.returnPressed.connect( lambda: self.set_throttle_factor( eng_notation.str_to_num( str(self._throttle_factor_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._throttle_factor_tool_bar, 6, 4, 1, 2) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 6): self.top_grid_layout.setColumnStretch(c, 1) self._rf_lpf_cutoff_tool_bar = Qt.QToolBar(self) self._rf_lpf_cutoff_tool_bar.addWidget( Qt.QLabel("rf_lpf_cutoff" + ": ")) self._rf_lpf_cutoff_line_edit = Qt.QLineEdit(str(self.rf_lpf_cutoff)) self._rf_lpf_cutoff_tool_bar.addWidget(self._rf_lpf_cutoff_line_edit) self._rf_lpf_cutoff_line_edit.returnPressed.connect( lambda: self.set_rf_lpf_cutoff( eng_notation.str_to_num( str(self._rf_lpf_cutoff_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._rf_lpf_cutoff_tool_bar, 6, 0, 1, 2) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 2): self.top_grid_layout.setColumnStretch(c, 1) self._fll_loop_bw_fine_tool_bar = Qt.QToolBar(self) self._fll_loop_bw_fine_tool_bar.addWidget( Qt.QLabel("fll_loop_bw_fine" + ": ")) self._fll_loop_bw_fine_line_edit = Qt.QLineEdit( str(self.fll_loop_bw_fine)) self._fll_loop_bw_fine_tool_bar.addWidget( self._fll_loop_bw_fine_line_edit) self._fll_loop_bw_fine_line_edit.returnPressed.connect( lambda: self.set_fll_loop_bw_fine( eng_notation.str_to_num( str(self._fll_loop_bw_fine_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._fll_loop_bw_fine_tool_bar, 7, 2, 1, 2) for r in range(7, 8): self.top_grid_layout.setRowStretch(r, 1) for c in range(2, 4): self.top_grid_layout.setColumnStretch(c, 1) self._fll_loop_bw_tool_bar = Qt.QToolBar(self) self._fll_loop_bw_tool_bar.addWidget(Qt.QLabel("fll_loop_bw" + ": ")) self._fll_loop_bw_line_edit = Qt.QLineEdit(str(self.fll_loop_bw)) self._fll_loop_bw_tool_bar.addWidget(self._fll_loop_bw_line_edit) self._fll_loop_bw_line_edit.returnPressed.connect( lambda: self.set_fll_loop_bw( eng_notation.str_to_num( str(self._fll_loop_bw_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._fll_loop_bw_tool_bar, 6, 2, 1, 2) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(2, 4): self.top_grid_layout.setColumnStretch(c, 1) self._audio_lpf_cutoff_tool_bar = Qt.QToolBar(self) self._audio_lpf_cutoff_tool_bar.addWidget( Qt.QLabel("audio_lpf_cutoff" + ": ")) self._audio_lpf_cutoff_line_edit = Qt.QLineEdit( str(self.audio_lpf_cutoff)) self._audio_lpf_cutoff_tool_bar.addWidget( self._audio_lpf_cutoff_line_edit) self._audio_lpf_cutoff_line_edit.returnPressed.connect( lambda: self.set_audio_lpf_cutoff( eng_notation.str_to_num( str(self._audio_lpf_cutoff_line_edit.text().toAscii())))) self.top_grid_layout.addWidget(self._audio_lpf_cutoff_tool_bar, 7, 0, 1, 2) for r in range(7, 8): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 2): self.top_grid_layout.setColumnStretch(c, 1) self.rational_resampler_xxx_1 = filter.rational_resampler_ccc( interpolation=1, decimation=4, taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0_0 = filter.rational_resampler_ccc( interpolation=1, decimation=4, taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0 = filter.rational_resampler_ccc( interpolation=48, decimation=50, taps=None, fractional_bw=None, ) self.qtgui_waterfall_sink_x_0_0 = qtgui.waterfall_sink_c( 2048, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate / decim, #bw "corrected", #name 1 #number of inputs ) self.qtgui_waterfall_sink_x_0_0.set_update_time(0.010) self.qtgui_waterfall_sink_x_0_0.enable_grid(False) self.qtgui_waterfall_sink_x_0_0.enable_axis_labels(True) if not True: self.qtgui_waterfall_sink_x_0_0.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_waterfall_sink_x_0_0.set_plot_pos_half(not 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 xrange(1): if len(labels[i]) == 0: self.qtgui_waterfall_sink_x_0_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_waterfall_sink_x_0_0.set_line_label(i, labels[i]) self.qtgui_waterfall_sink_x_0_0.set_color_map(i, colors[i]) self.qtgui_waterfall_sink_x_0_0.set_line_alpha(i, alphas[i]) self.qtgui_waterfall_sink_x_0_0.set_intensity_range(-80, 0) self._qtgui_waterfall_sink_x_0_0_win = sip.wrapinstance( self.qtgui_waterfall_sink_x_0_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_waterfall_sink_x_0_0_win, 2, 4, 2, 4) for r in range(2, 4): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 8): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_waterfall_sink_x_0 = qtgui.waterfall_sink_c( 2048, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate / decim, #bw "Pre-D", #name 1 #number of inputs ) self.qtgui_waterfall_sink_x_0.set_update_time(0.010) self.qtgui_waterfall_sink_x_0.enable_grid(False) self.qtgui_waterfall_sink_x_0.enable_axis_labels(True) if not True: self.qtgui_waterfall_sink_x_0.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_waterfall_sink_x_0.set_plot_pos_half(not 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 xrange(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(-80, 0) 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, 0, 4, 2, 4) for r in range(0, 2): self.top_grid_layout.setRowStretch(r, 1) for c in range(4, 8): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_time_sink_x_0 = qtgui.time_sink_f( 1024, #size samp_rate / decim / 50 * 48, #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(-1, 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) if not True: self.qtgui_time_sink_x_0.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(1): if len(labels[i]) == 0: self.qtgui_time_sink_x_0.set_line_label( i, "Data {0}".format(i)) 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, 8, 0, 1, 8) for r in range(8, 9): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 8): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_number_sink_0_0_0_0_0 = qtgui.number_sink( gr.sizeof_float, 0, qtgui.NUM_GRAPH_NONE, 1) self.qtgui_number_sink_0_0_0_0_0.set_update_time(0.10) self.qtgui_number_sink_0_0_0_0_0.set_title("") labels = ['SNR', '', '', '', '', '', '', '', '', ''] units = ['dB', '', '', '', '', '', '', '', '', ''] colors = [("blue", "red"), ("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 xrange(1): self.qtgui_number_sink_0_0_0_0_0.set_min(i, 0) self.qtgui_number_sink_0_0_0_0_0.set_max(i, 30) self.qtgui_number_sink_0_0_0_0_0.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_0_0_0_0_0.set_label( i, "Data {0}".format(i)) else: self.qtgui_number_sink_0_0_0_0_0.set_label(i, labels[i]) self.qtgui_number_sink_0_0_0_0_0.set_unit(i, units[i]) self.qtgui_number_sink_0_0_0_0_0.set_factor(i, factor[i]) self.qtgui_number_sink_0_0_0_0_0.enable_autoscale(False) self._qtgui_number_sink_0_0_0_0_0_win = sip.wrapinstance( self.qtgui_number_sink_0_0_0_0_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_number_sink_0_0_0_0_0_win, 6, 6, 1, 1) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(6, 7): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_number_sink_0_0_0_0 = qtgui.number_sink( gr.sizeof_float, 0, qtgui.NUM_GRAPH_NONE, 1) self.qtgui_number_sink_0_0_0_0.set_update_time(0.010) self.qtgui_number_sink_0_0_0_0.set_title("") labels = ['Freq Offset', 'Phase', 'Error', '', '', '', '', '', '', ''] units = ['Hz', '', '', '', '', '', '', '', '', ''] 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 xrange(1): self.qtgui_number_sink_0_0_0_0.set_min(i, -32767) self.qtgui_number_sink_0_0_0_0.set_max(i, 32767) self.qtgui_number_sink_0_0_0_0.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_0_0_0_0.set_label( i, "Data {0}".format(i)) else: self.qtgui_number_sink_0_0_0_0.set_label(i, labels[i]) self.qtgui_number_sink_0_0_0_0.set_unit(i, units[i]) self.qtgui_number_sink_0_0_0_0.set_factor(i, factor[i]) self.qtgui_number_sink_0_0_0_0.enable_autoscale(False) self._qtgui_number_sink_0_0_0_0_win = sip.wrapinstance( self.qtgui_number_sink_0_0_0_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_number_sink_0_0_0_0_win, 6, 7, 1, 1) for r in range(6, 7): self.top_grid_layout.setRowStretch(r, 1) for c in range(7, 8): self.top_grid_layout.setColumnStretch(c, 1) self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( 2048, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc samp_rate / decim, #bw "Pre-D", #name 2 #number of inputs ) self.qtgui_freq_sink_x_0.set_update_time(0.010) self.qtgui_freq_sink_x_0.set_y_axis(-60, 0) self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB') self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "") self.qtgui_freq_sink_x_0.enable_autoscale(False) self.qtgui_freq_sink_x_0.enable_grid(True) self.qtgui_freq_sink_x_0.set_fft_average(0.2) self.qtgui_freq_sink_x_0.enable_axis_labels(True) self.qtgui_freq_sink_x_0.enable_control_panel(False) if not True: self.qtgui_freq_sink_x_0.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_freq_sink_x_0.set_plot_pos_half(not True) labels = ['pre-d', 'corr', '', '', '', '', '', '', '', ''] 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] for i in xrange(2): if len(labels[i]) == 0: self.qtgui_freq_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_freq_sink_x_0.set_line_label(i, labels[i]) self.qtgui_freq_sink_x_0.set_line_width(i, widths[i]) self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_freq_sink_x_0_win = sip.wrapinstance( self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_freq_sink_x_0_win, 0, 0, 4, 4) for r in range(0, 4): self.top_grid_layout.setRowStretch(r, 1) for c in range(0, 4): self.top_grid_layout.setColumnStretch(c, 1) self.low_pass_filter_0_0_0 = filter.fir_filter_fff( 1, firdes.low_pass(1, samp_rate / decim / 50 * 48, audio_lpf_cutoff, 2e3, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0_0 = filter.fir_filter_ccf( 1, firdes.low_pass(1, samp_rate / decim, rf_lpf_cutoff, 2e3, firdes.WIN_HAMMING, 6.76)) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc( decim, (xlate_taps), 0, samp_rate) self.digital_fll_band_edge_cc_0_0 = digital.fll_band_edge_cc( samps_per_symb, .5, 1024, fll_loop_bw_fine) self.digital_fll_band_edge_cc_0 = digital.fll_band_edge_cc( samps_per_symb, .5, 1024, fll_loop_bw) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex * 1, samp_rate * throttle_factor, True) self.blocks_tagged_stream_to_pdu_0_0 = blocks.tagged_stream_to_pdu( blocks.float_t, 'snr') self.blocks_tagged_stream_to_pdu_0 = blocks.tagged_stream_to_pdu( blocks.float_t, 'rfo') self.blocks_stream_to_tagged_stream_0_0 = blocks.stream_to_tagged_stream( gr.sizeof_float, 1, 1, "snr") self.blocks_stream_to_tagged_stream_0 = blocks.stream_to_tagged_stream( gr.sizeof_float, 1, 1, "rfo") self.blocks_socket_pdu_0_0 = blocks.socket_pdu("TCP_SERVER", '0.0.0.0', '52002', 10000, False) self.blocks_socket_pdu_0 = blocks.socket_pdu("TCP_SERVER", '0.0.0.0', '52001', 10000, False) self.blocks_null_sink_0_1 = blocks.null_sink(gr.sizeof_float * 1) self.blocks_null_sink_0_0_0 = blocks.null_sink(gr.sizeof_float * 1) self.blocks_null_sink_0_0 = blocks.null_sink(gr.sizeof_float * 1) self.blocks_null_sink_0 = blocks.null_sink(gr.sizeof_float * 1) self.blocks_nlog10_ff_0_1 = blocks.nlog10_ff(10, 1, 0) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff( (-1 * samp_rate / decim / (2 * math.pi), )) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff( (volume, )) self.blocks_moving_average_xx_0_0_1 = blocks.moving_average_ff( 10000, 0.0001, 4000, 1) self.blocks_moving_average_xx_0 = blocks.moving_average_ff( 100000, 0.00001, 4000, 1) self.blocks_keep_one_in_n_0_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, int(samp_rate * meta_rate)) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * 1, int(samp_rate / 4 * meta_rate)) self.blocks_file_source_0 = blocks.file_source( gr.sizeof_gr_complex * 1, '/home/zleffke/captures/fox1d/20180913/FOX-1D_USRP_20180913_151002.518249_UTC_250k.fc32', False) self.blocks_file_source_0.set_begin_tag(pmt.PMT_NIL) self.blocks_divide_xx_0 = blocks.divide_ff(1) self.blocks_complex_to_mag_squared_0_0 = blocks.complex_to_mag_squared( 1) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.blocks_add_xx_0 = blocks.add_vff(1) self.analog_sig_source_x_0 = analog.sig_source_c( samp_rate, analog.GR_COS_WAVE, samp_rate / 2, 1, 0) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf( samp_rate / (2 * math.pi * fsk_deviation_hz / 8.0)) 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) ################################################## # Connections ################################################## self.msg_connect((self.blocks_tagged_stream_to_pdu_0, 'pdus'), (self.blocks_socket_pdu_0, 'pdus')) self.msg_connect((self.blocks_tagged_stream_to_pdu_0_0, 'pdus'), (self.blocks_socket_pdu_0_0, 'pdus')) self.connect((self.analog_agc2_xx_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.low_pass_filter_0_0_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.blocks_add_xx_0, 0), (self.blocks_multiply_const_vxx_1, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_divide_xx_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0_0, 0), (self.blocks_divide_xx_0, 1)) self.connect((self.blocks_divide_xx_0, 0), (self.blocks_nlog10_ff_0_1, 0)) self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_stream_to_tagged_stream_0_0, 0)) self.connect((self.blocks_keep_one_in_n_0_0, 0), (self.blocks_stream_to_tagged_stream_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_keep_one_in_n_0_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.qtgui_number_sink_0_0_0_0, 0)) self.connect((self.blocks_moving_average_xx_0_0_1, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_moving_average_xx_0_0_1, 0), (self.qtgui_number_sink_0_0_0_0_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.rational_resampler_xxx_1, 0)) self.connect((self.blocks_nlog10_ff_0_1, 0), (self.blocks_moving_average_xx_0_0_1, 0)) self.connect((self.blocks_stream_to_tagged_stream_0, 0), (self.blocks_tagged_stream_to_pdu_0, 0)) self.connect((self.blocks_stream_to_tagged_stream_0_0, 0), (self.blocks_tagged_stream_to_pdu_0_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.analog_agc2_xx_0, 0)) self.connect((self.digital_fll_band_edge_cc_0, 1), (self.blocks_add_xx_0, 1)) self.connect((self.digital_fll_band_edge_cc_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.digital_fll_band_edge_cc_0, 2), (self.blocks_null_sink_0, 0)) self.connect((self.digital_fll_band_edge_cc_0, 3), (self.blocks_null_sink_0_0, 0)) self.connect((self.digital_fll_band_edge_cc_0, 0), (self.low_pass_filter_0_0, 0)) self.connect((self.digital_fll_band_edge_cc_0, 0), (self.rational_resampler_xxx_0_0, 0)) self.connect((self.digital_fll_band_edge_cc_0_0, 1), (self.blocks_add_xx_0, 0)) self.connect((self.digital_fll_band_edge_cc_0_0, 3), (self.blocks_null_sink_0_0_0, 0)) self.connect((self.digital_fll_band_edge_cc_0_0, 2), (self.blocks_null_sink_0_1, 0)) self.connect((self.digital_fll_band_edge_cc_0_0, 0), (self.qtgui_freq_sink_x_0, 1)) self.connect((self.digital_fll_band_edge_cc_0_0, 0), (self.qtgui_waterfall_sink_x_0_0, 0)) self.connect((self.digital_fll_band_edge_cc_0_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.digital_fll_band_edge_cc_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.qtgui_freq_sink_x_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.qtgui_waterfall_sink_x_0, 0)) self.connect((self.low_pass_filter_0_0, 0), (self.digital_fll_band_edge_cc_0_0, 0)) self.connect((self.low_pass_filter_0_0_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.rational_resampler_xxx_0_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.rational_resampler_xxx_1, 0), (self.blocks_complex_to_mag_squared_0_0, 0))
def __init__(self, end_f=2000e6, start_f=50e6): gr.top_block.__init__(self, "Electosense") Qt.QWidget.__init__(self) self.setWindowTitle("Electosense") 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", "electrosense_final") 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 ################################################## # Parameters ################################################## self.end_f = end_f self.start_f = start_f ################################################## # Variables ################################################## self.samp_rate = samp_rate = 5e6 self.prober = prober = 1 self.hop_mode = hop_mode = 0 self.tune_delay = tune_delay = 20e-3 self.sensorid = sensorid = 123456 self.rfgain = rfgain = 40 self.ppm = ppm = 0 self.navg_vectors = navg_vectors = 50 self.fft_size = fft_size = 4096 self.cfreq = cfreq = scanning.step(start_f, end_f, samp_rate / 1.5, prober, hop_mode, 0.8, 0.8) self.alpha = alpha = 0.75 ################################################## # Blocks ################################################## self.vecprobe = blocks.probe_signal_vf(fft_size) self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(('addr=192.168.10.2', "")), uhd.stream_args( cpu_format="fc32", args='', channels=list(range(0, 1)), ), ) self.uhd_usrp_source_0.set_center_freq(cfreq, 0) self.uhd_usrp_source_0.set_gain(35, 0) self.uhd_usrp_source_0.set_antenna('RX2', 0) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec()) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( alpha, fft_size) def _prober_probe(): while True: val = self.vecprobe.level() try: self.set_prober(val) except AttributeError: pass time.sleep(1.0 / (1 / (tune_delay + (1 / samp_rate * fft_size * navg_vectors)))) _prober_thread = threading.Thread(target=_prober_probe) _prober_thread.daemon = True _prober_thread.start() self.fft_vxx_0 = fft.fft_vcc(fft_size, True, window.blackmanharris(fft_size), True, 1) self.electrosense_variable_updater_0 = electrosense.variable_updater self.electrosense_variable_updater_0.register_instance(self) self.electrosense_sensor_sink_0 = electrosense.sensor_sink( 'collector.electrosense.org', 5000, fft_size, "float32", '/home/rsreeraj/gnu_work/gr-electrosense/python/rtl-spec.avsc', '/home/rsreeraj/gnu_work/gr-electrosense/python/sensor_cert/Sensor-SSL-SK.pem', '/home/rsreeraj/gnu_work/gr-electrosense/python/sensor_cert/Sensor-SSL-Cert.pem', sensorid, 0, 2, fft_size, int(3 / alpha), 0.1, int(samp_rate / fft_size), int(cfreq), rfgain) self.electrosense_mqtt_client_0 = electrosense.mqtt_client( '127.0.0.1', 1883, 'electrosense', '', '', '') self.electrosense_discard_samples_0 = electrosense.discard_samples( int(tune_delay * samp_rate), int(cfreq), pmt.intern("burst_len"), False) self.blocks_stream_to_vector_0 = blocks.stream_to_vector( gr.sizeof_gr_complex * 1, fft_size) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_float * fft_size, navg_vectors) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared( fft_size) ################################################## # Connections ################################################## self.msg_connect((self.electrosense_mqtt_client_0, 'out'), (self.electrosense_variable_updater_0, 'in')) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.electrosense_sensor_sink_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.vecprobe, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self.electrosense_discard_samples_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.fft_vxx_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.electrosense_discard_samples_0, 0))
def publish_rx_performance_measure(self): if self._rx_performance_measure_initialized(): return self.rx_performance_measure_initialized = True config = station_configuration() vlen = config.data_subcarriers vlen_sinr_sc = config.subcarriers # self.rx_per_sink = rpsink = rpsink_dummy() self.setup_ber_measurement() self.setup_snr_measurement() self.setup_snr_measurement_2() ber_mst = self._ber_measuring_tool if self._options.sinr_est: sinr_mst = self._sinr_measurement sinr_mst_2 = self._sinr_measurement_2 else: snr_mst = self._snr_measurement snr_mst_2 = self._snr_measurement_2 # 1. frame id # 2. channel transfer function ctf = self.filter_ctf() ctf_2 = self.filter_ctf_2() self.zmq_probe_ctf = zeromq.pub_sink(gr.sizeof_float,config.data_subcarriers, "tcp://*:5559") self.zmq_probe_ctf_2 = zeromq.pub_sink(gr.sizeof_float,config.data_subcarriers, "tcp://*:5558") self.connect(ctf, blocks.keep_one_in_n(gr.sizeof_float*config.data_subcarriers,20) ,self.zmq_probe_ctf) self.connect(ctf_2, blocks.keep_one_in_n(gr.sizeof_float*config.data_subcarriers,20) ,self.zmq_probe_ctf_2) # 3. BER ### FIXME HACK print "Normal BER measurement" trig_src = dynamic_trigger_ib(False) self.connect(self.bitcount_src,trig_src) ber_sampler = vector_sampler(gr.sizeof_float,1) self.connect(ber_mst,(ber_sampler,0)) self.connect(trig_src,(ber_sampler,1)) if self._options.log: trig_src_float = gr.char_to_float() self.connect(trig_src,trig_src_float) log_to_file(self, trig_src_float , 'data/dynamic_trigger_out.float') if self._options.sinr_est is False: self.zmq_probe_ber = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5556") self.connect(ber_sampler,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_ber) self.zmq_probe_snr = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5555") self.connect(snr_mst,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_snr) self.zmq_probe_snr_2 = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5554") self.connect(snr_mst_2,blocks.keep_one_in_n(gr.sizeof_float,20) ,self.zmq_probe_snr_2)
def __init__(self, subdev="A:0", devid="addr=192.168.10.2", frequency=1.4125e9, fftsize=8192): grc_wxgui.top_block_gui.__init__(self, title="Total Power Radiometer - N200") ################################################## # Parameters ################################################## self.subdev = subdev self.devid = devid self.frequency = frequency self.fftsize = fftsize ################################################## # Variables ################################################## self.GUI_samp_rate = GUI_samp_rate = 10e6 self.samp_rate = samp_rate = int(GUI_samp_rate) self.prefix = prefix = "tpr_" self.text_samp_rate = text_samp_rate = GUI_samp_rate self.text_deviceID = text_deviceID = subdev self.text_Device_addr = text_Device_addr = devid self.spec_data_fifo = spec_data_fifo = "spectrum_" + datetime.now().strftime("%Y.%m.%d.%H.%M.%S") + ".dat" self.spavg = spavg = 1 self.scope_rate = scope_rate = 2 self.recfile_tpr = recfile_tpr = prefix + datetime.now().strftime("%Y.%m.%d.%H.%M.%S") + ".dat" self.recfile_kelvin = recfile_kelvin = prefix+"kelvin" + datetime.now().strftime("%Y.%m.%d.%H.%M.%S") + ".dat" self.rec_button_tpr = rec_button_tpr = 1 self.rec_button_iq = rec_button_iq = 1 self.noise_amplitude = noise_amplitude = .5 self.integ = integ = 2 self.gain = gain = 26 self.freq = freq = frequency self.file_rate = file_rate = 2.0 self.fftrate = fftrate = int(samp_rate/fftsize) self.det_rate = det_rate = int(20.0) self.dc_gain = dc_gain = 1 self.calib_2 = calib_2 = -342.774 self.calib_1 = calib_1 = 4.0755e3 self.add_noise = add_noise = 0 ################################################## # Blocks ################################################## self.Main = self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.Main.AddPage(grc_wxgui.Panel(self.Main), "N200 Control Panel") self.Main.AddPage(grc_wxgui.Panel(self.Main), "TPR Measurements") self.Add(self.Main) _spavg_sizer = wx.BoxSizer(wx.VERTICAL) self._spavg_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), sizer=_spavg_sizer, value=self.spavg, callback=self.set_spavg, label="Spectral Averaging (Seconds)", converter=forms.int_converter(), proportion=0, ) self._spavg_slider = forms.slider( parent=self.Main.GetPage(0).GetWin(), sizer=_spavg_sizer, value=self.spavg, callback=self.set_spavg, minimum=1, maximum=20, num_steps=20, style=wx.SL_HORIZONTAL, cast=int, proportion=1, ) self.Main.GetPage(0).GridAdd(_spavg_sizer, 1, 1, 1, 1) self._rec_button_tpr_chooser = forms.button( parent=self.Main.GetPage(0).GetWin(), value=self.rec_button_tpr, callback=self.set_rec_button_tpr, label="Record TPR Data", choices=[0,1], labels=['Stop','Start'], ) self.Main.GetPage(0).GridAdd(self._rec_button_tpr_chooser, 4, 1, 1, 1) self._rec_button_iq_chooser = forms.button( parent=self.Main.GetPage(0).GetWin(), value=self.rec_button_iq, callback=self.set_rec_button_iq, label="Record I/Q Data", choices=[0,1], labels=['Stop','Start'], ) self.Main.GetPage(0).GridAdd(self._rec_button_iq_chooser, 4, 0, 1, 1) _integ_sizer = wx.BoxSizer(wx.VERTICAL) self._integ_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), sizer=_integ_sizer, value=self.integ, callback=self.set_integ, label="Integration Time (Seconds)", converter=forms.float_converter(), proportion=0, ) self._integ_slider = forms.slider( parent=self.Main.GetPage(0).GetWin(), sizer=_integ_sizer, value=self.integ, callback=self.set_integ, minimum=1, maximum=60, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Main.GetPage(0).GridAdd(_integ_sizer, 0, 2, 1, 1) _gain_sizer = wx.BoxSizer(wx.VERTICAL) self._gain_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, label="RF Gain (dB)", converter=forms.float_converter(), proportion=0, ) self._gain_slider = forms.slider( parent=self.Main.GetPage(0).GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, minimum=0, maximum=50, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Main.GetPage(0).GridAdd(_gain_sizer, 0, 1, 1, 1) self._freq_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), value=self.freq, callback=self.set_freq, label="Center Frequency (Hz)", converter=forms.float_converter(), ) self.Main.GetPage(0).GridAdd(self._freq_text_box, 0, 0, 1, 1) self._dc_gain_chooser = forms.radio_buttons( parent=self.Main.GetPage(0).GetWin(), value=self.dc_gain, callback=self.set_dc_gain, label="DC Gain", choices=[1, 10, 100, 1000, 10000], labels=[], style=wx.RA_HORIZONTAL, ) self.Main.GetPage(0).GridAdd(self._dc_gain_chooser, 1, 0, 1, 1) self._calib_2_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), value=self.calib_2, callback=self.set_calib_2, label="Calibration value 2", converter=forms.float_converter(), ) self.Main.GetPage(0).GridAdd(self._calib_2_text_box, 3, 1, 1, 1) self._calib_1_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), value=self.calib_1, callback=self.set_calib_1, label="Calibration value 1", converter=forms.float_converter(), ) self.Main.GetPage(0).GridAdd(self._calib_1_text_box, 3, 0, 1, 1) self._GUI_samp_rate_chooser = forms.radio_buttons( parent=self.Main.GetPage(0).GetWin(), value=self.GUI_samp_rate, callback=self.set_GUI_samp_rate, label="Sample Rate (BW)", choices=[1e6,2e6,5e6,10e6,25e6], labels=['1 MHz','2 MHz','5 MHz','10 MHz','25 MHz'], style=wx.RA_HORIZONTAL, ) self.Main.GetPage(0).GridAdd(self._GUI_samp_rate_chooser, 1, 3, 1, 1) self.wxgui_scopesink2_2 = scopesink2.scope_sink_f( self.Main.GetPage(1).GetWin(), title="Total Power", sample_rate=2, v_scale=.1, v_offset=0, t_scale=100, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=wxgui.TRIG_MODE_STRIPCHART, y_axis_label="power level", ) self.Main.GetPage(1).Add(self.wxgui_scopesink2_2.win) self.wxgui_numbersink2_2 = numbersink2.number_sink_f( self.GetWin(), unit="Units", minval=0, maxval=1, factor=1.0, decimal_places=10, ref_level=0, sample_rate=GUI_samp_rate, number_rate=15, average=False, avg_alpha=None, label="Number Plot", peak_hold=False, show_gauge=True, ) self.Add(self.wxgui_numbersink2_2.win) self.wxgui_numbersink2_0_0 = numbersink2.number_sink_f( self.Main.GetPage(1).GetWin(), unit="", minval=0, maxval=.2, factor=1, decimal_places=6, ref_level=0, sample_rate=scope_rate, number_rate=15, average=True, avg_alpha=.01, label="Raw Power level", peak_hold=False, show_gauge=True, ) self.Main.GetPage(1).Add(self.wxgui_numbersink2_0_0.win) self.wxgui_numbersink2_0 = numbersink2.number_sink_f( self.Main.GetPage(1).GetWin(), unit="Kelvin", minval=0, maxval=400, factor=1, decimal_places=6, ref_level=0, sample_rate=scope_rate, number_rate=15, average=False, avg_alpha=None, label="Calibrated Temperature", peak_hold=False, show_gauge=True, ) self.Main.GetPage(1).Add(self.wxgui_numbersink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.Main.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=10, y_divs=10, ref_level=20, ref_scale=2.0, sample_rate=GUI_samp_rate, fft_size=1024, fft_rate=5, average=True, avg_alpha=0.1, title="Spectrum", peak_hold=False, size=(800,400), ) self.Main.GetPage(0).Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_source_0 = uhd.usrp_source( ",".join((devid, "")), uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(GUI_samp_rate) self.uhd_usrp_source_0.set_center_freq(freq, 0) self.uhd_usrp_source_0.set_gain(gain, 0) (self.uhd_usrp_source_0).set_processor_affinity([0]) self._text_samp_rate_static_text = forms.static_text( parent=self.Main.GetPage(0).GetWin(), value=self.text_samp_rate, callback=self.set_text_samp_rate, label="Samp rate", converter=forms.float_converter(), ) self.Main.GetPage(0).GridAdd(self._text_samp_rate_static_text, 2, 0, 1, 1) self._text_deviceID_static_text = forms.static_text( parent=self.Main.GetPage(0).GetWin(), value=self.text_deviceID, callback=self.set_text_deviceID, label="SubDev", converter=forms.str_converter(), ) self.Main.GetPage(0).GridAdd(self._text_deviceID_static_text, 2, 1, 1, 1) self._text_Device_addr_static_text = forms.static_text( parent=self.Main.GetPage(0).GetWin(), value=self.text_Device_addr, callback=self.set_text_Device_addr, label="Device Address", converter=forms.str_converter(), ) self.Main.GetPage(0).GridAdd(self._text_Device_addr_static_text, 2, 2, 1, 1) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(1.0/((samp_rate*integ)/2.0), 1) (self.single_pole_iir_filter_xx_0).set_processor_affinity([1]) _noise_amplitude_sizer = wx.BoxSizer(wx.VERTICAL) self._noise_amplitude_text_box = forms.text_box( parent=self.Main.GetPage(0).GetWin(), sizer=_noise_amplitude_sizer, value=self.noise_amplitude, callback=self.set_noise_amplitude, label='noise_amplitude', converter=forms.float_converter(), proportion=0, ) self._noise_amplitude_slider = forms.slider( parent=self.Main.GetPage(0).GetWin(), sizer=_noise_amplitude_sizer, value=self.noise_amplitude, callback=self.set_noise_amplitude, minimum=.01, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Main.GetPage(0).GridAdd(_noise_amplitude_sizer, 3, 2, 1, 1) self.logpwrfft_x_0 = logpwrfft.logpwrfft_c( sample_rate=samp_rate, fft_size=fftsize, ref_scale=2, frame_rate=fftrate, avg_alpha=1.0/float(spavg*fftrate), average=True, ) self.blocks_peak_detector_xb_0 = blocks.peak_detector_fb(0.25, 0.40, 10, 0.001) self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff((calib_1, )) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((dc_gain, )) self.blocks_keep_one_in_n_4 = blocks.keep_one_in_n(gr.sizeof_float*1, samp_rate/det_rate) self.blocks_keep_one_in_n_3 = blocks.keep_one_in_n(gr.sizeof_float*fftsize, fftrate) self.blocks_keep_one_in_n_1 = blocks.keep_one_in_n(gr.sizeof_float*1, int(det_rate/file_rate)) self.blocks_file_sink_5 = blocks.file_sink(gr.sizeof_float*fftsize, spec_data_fifo, False) self.blocks_file_sink_5.set_unbuffered(True) self.blocks_file_sink_4 = blocks.file_sink(gr.sizeof_float*1, recfile_tpr, False) self.blocks_file_sink_4.set_unbuffered(True) self.blocks_file_sink_1 = blocks.file_sink(gr.sizeof_gr_complex*1, prefix+"iq_raw" + datetime.now().strftime("%Y.%m.%d.%H.%M.%S") + ".dat", False) self.blocks_file_sink_1.set_unbuffered(False) self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*1, recfile_kelvin, False) self.blocks_file_sink_0.set_unbuffered(True) self.blocks_complex_to_real_0 = blocks.complex_to_real(1) self.blocks_complex_to_mag_squared_1 = blocks.complex_to_mag_squared(1) self.blocks_char_to_float_0 = blocks.char_to_float(1, 1) self.blocks_add_const_vxx_1 = blocks.add_const_vff((calib_2, )) self.blks2_valve_2 = grc_blks2.valve(item_size=gr.sizeof_gr_complex*1, open=bool(rec_button_iq)) self.blks2_valve_1 = grc_blks2.valve(item_size=gr.sizeof_float*1, open=bool(0)) self.blks2_valve_0 = grc_blks2.valve(item_size=gr.sizeof_float*1, open=bool(rec_button_tpr)) self._add_noise_chooser = forms.button( parent=self.Main.GetPage(0).GetWin(), value=self.add_noise, callback=self.set_add_noise, label="Noise Source", choices=[0,1], labels=['Off','On'], ) self.Main.GetPage(0).GridAdd(self._add_noise_chooser, 3, 3, 1, 1) ################################################## # Connections ################################################## self.connect((self.blks2_valve_0, 0), (self.blocks_file_sink_4, 0)) self.connect((self.blks2_valve_1, 0), (self.blocks_file_sink_0, 0)) self.connect((self.blks2_valve_2, 0), (self.blocks_file_sink_1, 0)) self.connect((self.blocks_add_const_vxx_1, 0), (self.blks2_valve_1, 0)) self.connect((self.blocks_add_const_vxx_1, 0), (self.wxgui_numbersink2_0, 0)) self.connect((self.blocks_char_to_float_0, 0), (self.wxgui_numbersink2_2, 0)) self.connect((self.blocks_complex_to_mag_squared_1, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_complex_to_real_0, 0), (self.blocks_peak_detector_xb_0, 0)) self.connect((self.blocks_keep_one_in_n_1, 0), (self.blks2_valve_0, 0)) self.connect((self.blocks_keep_one_in_n_1, 0), (self.blocks_multiply_const_vxx_1, 0)) self.connect((self.blocks_keep_one_in_n_1, 0), (self.wxgui_scopesink2_2, 0)) self.connect((self.blocks_keep_one_in_n_3, 0), (self.blocks_file_sink_5, 0)) self.connect((self.blocks_keep_one_in_n_4, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.blocks_keep_one_in_n_1, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.wxgui_numbersink2_0_0, 0)) self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_add_const_vxx_1, 0)) self.connect((self.blocks_peak_detector_xb_0, 0), (self.blocks_char_to_float_0, 0)) self.connect((self.logpwrfft_x_0, 0), (self.blocks_keep_one_in_n_3, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_4, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.blks2_valve_2, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.blocks_complex_to_mag_squared_1, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.blocks_complex_to_real_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.logpwrfft_x_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.wxgui_fftsink2_0, 0))
def __init__(self, ask_samp_rate=4E6, num_demod=4, type_demod=0, hw_args="uhd", freq_correction=0, record=True): # Call the initialization method from the parent class gr.top_block.__init__(self, "Receiver") # Default values self.center_freq = 144E6 self.gain_db = 10 self.squelch_db = -70 self.volume_db = 0 audio_rate = 8000 # Setup the USRP source, or use the USRP sim self.src = osmosdr.source(args="numchan=" + str(1) + " " + hw_args) self.src.set_sample_rate(ask_samp_rate) self.src.set_gain(self.gain_db) self.src.set_center_freq(self.center_freq) self.src.set_freq_corr(freq_correction) # Get the sample rate and center frequency from the hardware self.samp_rate = self.src.get_sample_rate() self.center_freq = self.src.get_center_freq() # Set the I/Q bandwidth to 80 % of sample rate self.src.set_bandwidth(0.8 * self.samp_rate) # NBFM channel is about 10 KHz wide # Want about 3 FFT bins to span a channel # Use length FFT so 4 Msps / 1024 = 3906.25 Hz/bin # This also means 3906.25 vectors/second # Using below formula keeps FFT size a power of two # Also keeps bin size constant for power of two sampling rates # Use of 256 sets 3906.25 Hz/bin; increase to reduce bin size samp_ratio = self.samp_rate / 1E6 fft_length = 256 * int(pow(2, np.ceil(np.log(samp_ratio)/np.log(2)))) # -----------Flow for FFT-------------- # Convert USRP steam to vector stream_to_vector = blocks.stream_to_vector(gr.sizeof_gr_complex*1, fft_length) # Want about 1000 vector/sec amount = int(round(self.samp_rate/fft_length/1000)) keep_one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex* fft_length, amount) # Take FFT fft_vcc = fft.fft_vcc(fft_length, True, window.blackmanharris(fft_length), True, 1) # Compute the power complex_to_mag_squared = blocks.complex_to_mag_squared(fft_length) # Video average and decimate from 1000 vector/sec to 10 vector/sec integrate_ff = blocks.integrate_ff(100, fft_length) # Probe vector self.probe_signal_vf = blocks.probe_signal_vf(fft_length) # Connect the blocks self.connect(self.src, stream_to_vector, keep_one_in_n, fft_vcc, complex_to_mag_squared, integrate_ff, self.probe_signal_vf) # -----------Flow for Demod-------------- # Create N parallel demodulators as a list of objects # Default to NBFM demod self.demodulators = [] for idx in range(num_demod): if type_demod == 1: self.demodulators.append(TunerDemodAM(self.samp_rate, audio_rate, record)) else: self.demodulators.append(TunerDemodNBFM(self.samp_rate, audio_rate, record)) # Create an adder add_ff = blocks.add_ff(1) # Connect the demodulators between the source and adder for idx, demodulator in enumerate(self.demodulators): self.connect(self.src, demodulator, (add_ff, idx)) # Audio sink audio_sink = audio.sink(audio_rate) # Connect the blocks for the demod self.connect(add_ff, audio_sink)