def __init__(self, alpha=0.0001, threshold_db=-10, gate=False): gr.hier_block2.__init__( self, "standard_squelch", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature #fixed coeffs, Chebyshev type 2 LPF=[0, 0.4, 0.7], HPF=[0.4, 0.7, 1] self.low_iir = iir_filter_ffd([ 0.12260106307699403, -0.22058023529806434, 0.22058023529806436, -0.12260106307699434 ], [ 1.00000000000000000, 0.7589332900264623, 0.5162740252200005, 0.07097813844342238 ], False) self.low_square = blocks.multiply_ff() self.low_smooth = single_pole_iir_filter_ff(alpha) self.hi_iir = iir_filter_ffd([ 0.1913118666668073, 0.4406071020350289, 0.4406071020350288, 0.19131186666680736 ], [ 1.000000000000000000, -0.11503633296078866, 0.3769676347066441, 0.0019066356578167866 ], False) self.hi_square = blocks.multiply_ff() self.hi_smooth = single_pole_iir_filter_ff(alpha) #inverted thresholds because we reversed the division block inputs #to make the threshold output 1 when open and 0 when closed self.gate = blocks.threshold_ff(0, 0, 0) self.set_threshold(threshold_db) self.squelch_lpf = single_pole_iir_filter_ff(alpha) self.squelch_mult = blocks.multiply_ff() self.div = blocks.divide_ff() #This is horrible, but there's no better way to gate samples. #the block is fast, so realistically there's little overhead #TODO: implement a valve block that gates based on an input value self.valve = analog.pwr_squelch_ff(-100, 1, 0, gate) #sample path self.connect(self, (self.squelch_mult, 0)) #filter path (LPF) self.connect(self, self.low_iir) self.connect(self.low_iir, (self.low_square, 0)) self.connect(self.low_iir, (self.low_square, 1)) self.connect(self.low_square, self.low_smooth, (self.div, 0)) #filter path (HPF) self.connect(self, self.hi_iir) self.connect(self.hi_iir, (self.hi_square, 0)) self.connect(self.hi_iir, (self.hi_square, 1)) self.connect(self.hi_square, self.hi_smooth, (self.div, 1)) #control path self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult, 1)) self.connect(self.squelch_mult, self)
def __init__(self, audio_rate): gr.hier_block2.__init__( self, "standard_squelch", # Input signature gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) # Output signature self.input_node = blocks.add_const_ff(0) # FIXME kludge self.low_iir = filter.iir_filter_ffd((0.0193, 0, -0.0193), (1, 1.9524, -0.9615)) self.low_square = blocks.multiply_ff() self.low_smooth = filter.single_pole_iir_filter_ff( 1 / (0.01 * audio_rate)) # 100ms time constant self.hi_iir = filter.iir_filter_ffd((0.0193, 0, -0.0193), (1, 1.3597, -0.9615)) self.hi_square = blocks.multiply_ff() self.hi_smooth = filter.single_pole_iir_filter_ff(1 / (0.01 * audio_rate)) self.sub = blocks.sub_ff() self.add = blocks.add_ff() self.gate = blocks.threshold_ff(0.3, 0.43, 0) self.squelch_lpf = filter.single_pole_iir_filter_ff( 1 / (0.01 * audio_rate)) self.div = blocks.divide_ff() self.squelch_mult = blocks.multiply_ff() self.connect(self, self.input_node) self.connect(self.input_node, (self.squelch_mult, 0)) self.connect(self.input_node, self.low_iir) self.connect(self.low_iir, (self.low_square, 0)) self.connect(self.low_iir, (self.low_square, 1)) self.connect(self.low_square, self.low_smooth, (self.sub, 0)) self.connect(self.low_smooth, (self.add, 0)) self.connect(self.input_node, self.hi_iir) self.connect(self.hi_iir, (self.hi_square, 0)) self.connect(self.hi_iir, (self.hi_square, 1)) self.connect(self.hi_square, self.hi_smooth, (self.sub, 1)) self.connect(self.hi_smooth, (self.add, 1)) self.connect(self.sub, (self.div, 0)) self.connect(self.add, (self.div, 1)) self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult, 1)) self.connect(self.squelch_mult, self)
def __init__(self, alpha=0.0001, threshold_db=-10, gate=False): gr.hier_block2.__init__(self, "standard_squelch", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature #fixed coeffs, Chebyshev type 2 LPF=[0, 0.4, 0.7], HPF=[0.4, 0.7, 1] self.low_iir = iir_filter_ffd([0.12260106307699403, -0.22058023529806434, 0.22058023529806436, -0.12260106307699434], [1.00000000000000000, 0.7589332900264623, 0.5162740252200005, 0.07097813844342238], False) self.low_square = blocks.multiply_ff() self.low_smooth = single_pole_iir_filter_ff(alpha) self.hi_iir = iir_filter_ffd([0.1913118666668073, 0.4406071020350289, 0.4406071020350288, 0.19131186666680736], [1.000000000000000000, -0.11503633296078866, 0.3769676347066441, 0.0019066356578167866], False) self.hi_square = blocks.multiply_ff() self.hi_smooth = single_pole_iir_filter_ff(alpha) #inverted thresholds because we reversed the division block inputs #to make the threshold output 1 when open and 0 when closed self.gate = blocks.threshold_ff(0,0,0) self.set_threshold(threshold_db) self.squelch_lpf = single_pole_iir_filter_ff(alpha) self.squelch_mult = blocks.multiply_ff() self.div = blocks.divide_ff() #This is horrible, but there's no better way to gate samples. #the block is fast, so realistically there's little overhead #TODO: implement a valve block that gates based on an input value self.valve = analog.pwr_squelch_ff(-100, 1, 0, gate) #sample path self.connect(self, (self.squelch_mult, 0)) #filter path (LPF) self.connect(self,self.low_iir) self.connect(self.low_iir,(self.low_square,0)) self.connect(self.low_iir,(self.low_square,1)) self.connect(self.low_square,self.low_smooth,(self.div,0)) #filter path (HPF) self.connect(self,self.hi_iir) self.connect(self.hi_iir,(self.hi_square,0)) self.connect(self.hi_iir,(self.hi_square,1)) self.connect(self.hi_square,self.hi_smooth,(self.div,1)) #control path self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) self.connect(self.squelch_mult, 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, samp_rate=1000, vecsize=500, folding=5, pulse_rate=0.7477): gr.hier_block2.__init__( self, "Synch Folder2", gr.io_signature(1, 1, gr.sizeof_float*1), gr.io_signature(1, 1, gr.sizeof_float*vecsize), ) ################################################## # Parameters ################################################## self.samp_rate = samp_rate self.vecsize = vecsize self.folding = folding self.pulse_rate = pulse_rate ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(1.0/folding, vecsize) self.fractional_resampler_xx_0 = filter.fractional_resampler_ff(0, float(samp_rate)/(float(pulse_rate)*float(vecsize))) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_float*1, vecsize) ################################################## # Connections ################################################## self.connect((self.blocks_stream_to_vector_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.fractional_resampler_xx_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self, 0), (self.fractional_resampler_xx_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self, 0))
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, sample_rate, fft_size, ref_scale, frame_rate): gr.hier_block2.__init__( self, "logpowerfft_win", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float * fft_size)) self._sd = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) fft_window = fft_lib.window_hamming(fft_size) fft = fft_lib.fft_vcc(fft_size, True, fft_window, True) window_power = sum([x * x for x in fft_window]) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) self._log = blocks.nlog10_ff( 10, fft_size, -20 * math.log10(fft_size) # Adjust for number of bins - 10 * math.log10( float(window_power) / fft_size) # Adjust for windowing loss - 20 * math.log10(float(ref_scale) / 2)) # Adjust for reference scale self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)
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, noise_mag=0, alpha=0.1): gr.hier_block2.__init__( self, "Phase Noise Generator", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_gr_complex*1), ) ################################################## # Parameters ################################################## self.noise_mag = noise_mag self.alpha = alpha ################################################## # Blocks ################################################## self.filter_single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(alpha, 1) self.blocks_transcendental_0_0 = blocks.transcendental("sin", "float") self.blocks_transcendental_0 = blocks.transcendental("cos", "float") self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.analog_noise_source_x_0 = analog.noise_source_f(analog.GR_GAUSSIAN, noise_mag, 42) ################################################## # Connections ################################################## self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.analog_noise_source_x_0, 0), (self.filter_single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self, 0)) self.connect((self, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_transcendental_0, 0)) self.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_transcendental_0_0, 0)) self.connect((self.blocks_transcendental_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_transcendental_0_0, 0), (self.blocks_float_to_complex_0, 1))
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 = gr.serial_to_parallel(gr.sizeof_float, self.fft_size) self.one_in_n = gr.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 = gr.complex_to_mag(self.fft_size) self.avg = filter.single_pole_iir_filter_ff(1.0, self.fft_size) self.log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) self.sink = gr.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, 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 filter_ctf(self): if self.__dict__.has_key('filtered_ctf'): return self.filtered_ctf config = self.config vlen = config.data_subcarriers frame_len = config.frame_length # # we want the preamble used for channel estimation # keep_est_preamble = skip(gr.sizeof_float*config.subcarriers, frame_len) # for i in range( frame_len ): # if i != config.training_data.channel_estimation_pilot[0]: # keep_est_preamble.skip_call(i) # # self.connect( self.ctf, (keep_est_preamble,0) ) # self.connect( self.frame_trigger, (keep_est_preamble,1) ) # there is only one CTF estimate (display CTF) per frame ... #self.ctf_soft_dem if config.fbmc: self.rx_01 = self.ctf else: psubc_filt = pilot_subcarrier_filter(complex_value=False) self.connect( self.ctf, psubc_filt ) self.rx_01 = psubc_filt lp_filter = filter.single_pole_iir_filter_ff(0.1,vlen) self.connect( self.rx_01, lp_filter ) #log_to_file(self,lp_filter,"data/filt_ctf.float") self.filtered_ctf = lp_filter return lp_filter
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, auto_carrier, carrier, all_spectrum, freq_central, samp_rate, nintems, signal_bw, noise_bw, avg_alpha, average, win): """ Estimates the SNR. Provide access to the setting the filter and sample rate. Args: sample_rate: Incoming stream sample rate nintems: Number of FFT bins avg_alpha: FFT averaging (over time) constant [0.0-1.0] average: Whether to average [True, False] win: the window taps generation function auto_carrier: To allow self-detection of the carrier, so the highest bin [True, False] carrier: To evalutaion of the CNR or SNR [True, False] all_spectrum: To set the whole spectrum (less the signal's one) to evaluate noise power density [True, False] freq_central: Sets the central frequency (for the bandwidth) of the signal (in the CNR mode, it is the manual set of the carrier's frequency) signal_bw: Sets the bandwidth (for the SNR mode) of the signal to the power evaluation noise_bw: Sets the bandwidth (if all_sepctrum is false) of the noise to the power evaluation """ gr.hier_block2.__init__(self, "snr_estimator_cfv", gr.io_signature(1,1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2,2, gr.sizeof_float, gr.sizeof_float * nintems)) # Output signature self.auto_carrier = auto_carrier self.carrier = carrier self.all_spectrum = all_spectrum self.freq_central = freq_central self.samp_rate = samp_rate self.nintems = nintems self.signal_bw = signal_bw self.noise_bw = noise_bw self.avg_alpha = avg_alpha self.average = average self.win = win fft_window = self.win(self.nintems) self.fft = fft.fft_vcc(self.nintems, True, fft_window, True) self._sd = blocks.stream_to_vector(gr.sizeof_gr_complex, self.nintems) self.c2magsq = blocks.complex_to_mag_squared(self.nintems) self._avg = filter.single_pole_iir_filter_ff(1.0, self.nintems) self.snr = flaress.snr(self.auto_carrier, self.carrier, self.all_spectrum, self.freq_central, self.samp_rate, self.nintems, self.signal_bw, self.noise_bw) window_power = sum(map(lambda x: x*x, fft_window)) self.log = blocks.nlog10_ff(10, self.nintems, -20*math.log10(self.nintems) # Adjust for number of bins -10*math.log10(float(window_power)/self.nintems) # Adjust for windowing loss -20*math.log10(float(2)/2)) # Adjust for reference scale self.connect(self, self._sd, self.fft, self.c2magsq, self._avg, self.snr, (self, 0)) self.connect(self._avg, self.log, (self, 1)) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self, channel=26): gr.top_block.__init__(self, "Top Block") ################################################## # Parameters ################################################## self.channel = channel ################################################## # Variables ################################################## self.samp_rate = samp_rate = 4000000 ################################################## # Blocks ################################################## self.xmlrpc_server_0 = SimpleXMLRPCServer.SimpleXMLRPCServer(('localhost', 8080), allow_none=True) self.xmlrpc_server_0.register_instance(self) self.xmlrpc_server_0_thread = threading.Thread(target=self.xmlrpc_server_0.serve_forever) self.xmlrpc_server_0_thread.daemon = True self.xmlrpc_server_0_thread.start() self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(0.00016, 1) self.rftap_rftap_encap_0 = rftap.rftap_encap(2, 195, '') 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(1000000 * (2400 + 5 * (channel - 10)), 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(10, 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.ieee802_15_4_packet_sink_0 = ieee802_15_4.packet_sink(10) self.epy_block_0 = epy_block_0.blk() self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.000225, 0.5, 0.03, 0.0002) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_socket_pdu_0_0_0 = blocks.socket_pdu("UDP_CLIENT", '127.0.0.1', '52002', 10000, False) self.blocks_message_debug_0 = blocks.message_debug() self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(1) ################################################## # Connections ################################################## self.msg_connect((self.epy_block_0, 'out'), (self.rftap_rftap_encap_0, 'in')) self.msg_connect((self.ieee802_15_4_packet_sink_0, 'out'), (self.epy_block_0, 'in')) self.msg_connect((self.rftap_rftap_encap_0, 'out'), (self.blocks_message_debug_0, 'print_pdu')) self.msg_connect((self.rftap_rftap_encap_0, 'out'), (self.blocks_socket_pdu_0_0_0, 'pdus')) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.ieee802_15_4_packet_sink_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_sub_xx_0, 1))
def __init__(self, sample_rate, pspectrum_len, ref_scale, frame_rate, avg_alpha, average, n, m, nsamples, estimator='esprit'): """ Create an log10(abs(spectrum_estimate)) stream chain. Provide access to the setting the filter and sample rate. @param sample_rate Incoming stream sample rate @param pspectrum_len Number of FFT bins @param ref_scale Sets 0 dB value input amplitude @param frame_rate Output frame rate @param avg_alpha averaging (over time) constant [0.0-1.0] @param average Whether to average [True, False] @param n Parameter n for the estimator @param m Parameter m for the estimator @param nsamples Number of samples to use for estimation @param estimator Estimator to use, can be either 'esprit' or 'music' """ gr.hier_block2.__init__( self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float * pspectrum_len)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=nsamples) if estimator == 'esprit': est = specest.esprit_spectrum_vcf(n, m, nsamples, pspectrum_len) elif estimator == 'music': est = specest.music_spectrum_vcf(n, m, nsamples, pspectrum_len) else: est = specest.esprit_spectrum_vcf(n, m, nsamples, pspectrum_len) self._avg = filter.single_pole_iir_filter_ff(1.0, pspectrum_len) self._log = blocks.nlog10_ff( 20, pspectrum_len, -20 * math.log10(pspectrum_len) # Adjust for number of bins - 20 * math.log10(ref_scale / 2) + 3.0) # Adjust for reference scale self.connect(self, self._sd, est, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self, uhd_address, options): gr.top_block.__init__(self) self.uhd_addr = uhd_address self.freq = options.freq self.samp_rate = options.samp_rate self.gain = options.gain self.threshold = options.threshold self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, stream_args=uhd.stream_args('fc32')) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = filter.fir_filter_ccc(10, taps) self.tagger = blocks.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000*[0,] + 1000*[1,] self.signal = blocks.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = analog.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = blocks.complex_to_mag_squared() ## average to debounce self.avg = filter.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = blocks.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = blocks.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = blocks.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect(self.uhd_src, self.det) self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) self.connect(self.f2s, (self.tagger, 1))
def __init__(self, uhd_address, options): gr.top_block.__init__(self) self.uhd_addr = uhd_address self.freq = options.freq self.samp_rate = options.samp_rate self.gain = options.gain self.threshold = options.threshold self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, stream_args=uhd.stream_args('fc32')) self.uhd_src.set_samp_rate(self.samp_rate) self.uhd_src.set_center_freq(self.freq, 0) self.uhd_src.set_gain(self.gain, 0) taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = filter.fir_filter_ccc(10, taps) self.tagger = blocks.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000 * [0, ] + 1000 * [1, ] self.signal = blocks.vector_source_s(data, True) # Energy detector to get signal burst # use squelch to detect energy self.det = analog.simple_squelch_cc(self.threshold, 0.01) # convert to mag squared (float) self.c2m = blocks.complex_to_mag_squared() # average to debounce self.avg = filter.single_pole_iir_filter_ff(0.01) # rescale signal for conversion to short self.scale = blocks.multiply_const_ff(2**16) # signal input uses shorts self.f2s = blocks.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = blocks.tagged_file_sink( gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections ################################################## self.connect((self.uhd_src, 0), (self.tagger, 0)) self.connect((self.tagger, 0), (self.fsnk, 0)) if self.trigger: # Connect a dummy signaler to the burst tagger self.connect((self.signal, 0), (self.tagger, 1)) else: # Connect an energy detector signaler to the burst tagger self.connect(self.uhd_src, self.det) self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) self.connect(self.f2s, (self.tagger, 1))
def __init__(self): gr.hier_block2.__init__( self, "IEEE802.15.4 OQPSK PHY", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_gr_complex*1), ) self.message_port_register_hier_in("txin") self.message_port_register_hier_out("rxout") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 4000000 ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(0.00016, 1) self.ieee802_15_4_packet_sink_0 = ieee802_15_4.packet_sink(10) self.ieee802_15_4_access_code_prefixer_0 = ieee802_15_4.access_code_prefixer() self.foo_burst_tagger_0 = foo.burst_tagger(pmt.intern("pdu_length"), 128) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(2, 0.000225, 0.5, 0.03, 0.0002) self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bc(([(1+1j), (-1+1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (1-1j), (1+1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1+1j), (1+1j), (1-1j), (1+1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1-1j), (-1+1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (1-1j), (1+1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1-1j), (1+1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (1-1j), (1+1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (1-1j), (1+1j), (1-1j), (-1-1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (1-1j), (-1+1j), (1+1j), (-1-1j), (-1-1j), (1+1j), (-1+1j), (-1+1j), (-1-1j), (1-1j), (-1-1j), (1-1j), (1+1j), (1-1j), (1+1j), (-1+1j), (1+1j), (-1-1j), (1-1j), (-1+1j), (-1+1j), (1-1j), (-1-1j), (-1-1j), (-1+1j), (1+1j), (-1+1j), (1+1j), (1-1j), (1+1j), (1-1j), (-1-1j)]), 16) self.blocks_vector_source_x_0 = blocks.vector_source_c([0, sin(pi/4), 1, sin(3*pi/4)], True, 1, []) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_repeat_0 = blocks.repeat(gr.sizeof_gr_complex*1, 4) self.blocks_pdu_to_tagged_stream_0_0_0 = blocks.pdu_to_tagged_stream(blocks.byte_t, 'pdu_length') self.blocks_packed_to_unpacked_xx_0 = blocks.packed_to_unpacked_bb(4, gr.GR_LSB_FIRST) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, 2) self.blocks_complex_to_float_0 = blocks.complex_to_float(1) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(1) ################################################## # Connections ################################################## self.msg_connect((self.ieee802_15_4_access_code_prefixer_0, 'out'), (self.blocks_pdu_to_tagged_stream_0_0_0, 'pdus')) self.msg_connect((self.ieee802_15_4_packet_sink_0, 'out'), (self, 'rxout')) self.msg_connect((self, 'txin'), (self.ieee802_15_4_access_code_prefixer_0, 'in')) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_complex_to_float_0, 1), (self.blocks_delay_0, 0)) self.connect((self.blocks_complex_to_float_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_float_to_complex_0, 1)) self.connect((self.blocks_float_to_complex_0, 0), (self.foo_burst_tagger_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_float_0, 0)) self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.digital_chunks_to_symbols_xx_0, 0)) self.connect((self.blocks_pdu_to_tagged_stream_0_0_0, 0), (self.blocks_packed_to_unpacked_xx_0, 0)) self.connect((self.blocks_repeat_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.blocks_sub_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.blocks_vector_source_x_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.blocks_repeat_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.ieee802_15_4_packet_sink_0, 0)) self.connect((self.foo_burst_tagger_0, 0), (self, 0)) self.connect((self, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_sub_xx_0, 1))
def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None, shift=False): """ Create an log10(abs(fft)) stream chain. Provide access to the setting the filter and sample rate. Args: sample_rate: Incoming stream sample rate fft_size: Number of FFT bins ref_scale: Sets 0 dB value input amplitude frame_rate: Output frame rate avg_alpha: FFT averaging (over time) constant [0.0-1.0] average: Whether to average [True, False] win: the window taps generation function shift: shift zero-frequency component to center of spectrum """ gr.hier_block2.__init__( self, self._name, # Input signature gr.io_signature(1, 1, self._item_size), gr.io_signature(1, 1, gr.sizeof_float * fft_size)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) if win is None: win = window.blackmanharris fft_window = win(fft_size) fft = self._fft_block[0](fft_size, True, fft_window, shift=shift) window_power = sum([x * x for x in fft_window]) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) self._log = blocks.nlog10_ff( 10, fft_size, # Adjust for number of bins -20 * math.log10(fft_size) - # Adjust for windowing loss 10 * math.log10(float(window_power) / fft_size) - 20 * math.log10(float(ref_scale) / 2)) # Adjust for reference scale self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def test_ff_001(self): src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = src_data src = blocks.vector_source_f(src_data) op = filter.single_pole_iir_filter_ff(1.0) dst = blocks.vector_sink_f() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data)
def test_ff_002(self): src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = (0, 125, 359.375, 689.453125, 1103.271484, 1590.36255) src = blocks.vector_source_f(src_data) op = filter.single_pole_iir_filter_ff(0.125) dst = blocks.vector_sink_f() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data, 3)
def __init__(self, audio_rate): gr.hier_block2.__init__(self, "standard_squelch", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature self.input_node = blocks.add_const_ff(0) # FIXME kludge self.low_iir = filter.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) self.low_square = blocks.multiply_ff() self.low_smooth = filter.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant self.hi_iir = filter.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) self.hi_square = blocks.multiply_ff() self.hi_smooth = filter.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.sub = blocks.sub_ff(); self.add = blocks.add_ff(); self.gate = blocks.threshold_ff(0.3,0.43,0) self.squelch_lpf = filter.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.div = blocks.divide_ff() self.squelch_mult = blocks.multiply_ff() self.connect(self, self.input_node) self.connect(self.input_node, (self.squelch_mult, 0)) self.connect(self.input_node,self.low_iir) self.connect(self.low_iir,(self.low_square,0)) self.connect(self.low_iir,(self.low_square,1)) self.connect(self.low_square,self.low_smooth,(self.sub,0)) self.connect(self.low_smooth, (self.add,0)) self.connect(self.input_node,self.hi_iir) self.connect(self.hi_iir,(self.hi_square,0)) self.connect(self.hi_iir,(self.hi_square,1)) self.connect(self.hi_square,self.hi_smooth,(self.sub,1)) self.connect(self.hi_smooth, (self.add,1)) self.connect(self.sub, (self.div, 0)) self.connect(self.add, (self.div, 1)) self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) self.connect(self.squelch_mult, self)
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 main(): print os.getpid() tb = gr.top_block() u = blocks.file_source(gr.sizeof_float,"/tmp/atsc_pipe_2") input_rate = 19.2e6 IF_freq = 5.75e6 # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE/2. NTAPS = 279 tt = filter.firdes.root_raised_cosine (1.0, input_rate, symbol_rate, .115, NTAPS) # heterodyne the low pass coefficients up to the specified bandpass # center frequency. Note that when we do this, the filter bandwidth # is effectively twice the low pass (2.69 * 2 = 5.38) and hence # matches the diagram in the ATSC spec. arg = 2. * math.pi * IF_freq / input_rate t=[] for i in range(len(tt)): t += [tt[i] * 2. * math.cos(arg * i)] rrc = filter.fir_filter_fff(1, t) fpll = atsc.fpll() pilot_freq = IF_freq - 3e6 + 0.31e6 lower_edge = 6e6 - 0.31e6 upper_edge = IF_freq - 3e6 + pilot_freq transition_width = upper_edge - lower_edge lp_coeffs = filter.firdes.low_pass (1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, filter.firdes.WIN_HAMMING); lp_filter = filter.fir_filter_fff (1,lp_coeffs) alpha = 1e-5 iir = filter.single_pole_iir_filter_ff(alpha) remove_dc = blocks.sub_ff() out = blocks.file_sink(gr.sizeof_float,"/tmp/atsc_pipe_3") # out = blocks.file_sink(gr.sizeof_float,"/mnt/sata/atsc_data_float") tb.connect(u, fpll, lp_filter) tb.connect(lp_filter, iir) tb.connect(lp_filter, (remove_dc,0)) tb.connect(iir, (remove_dc,1)) tb.connect(remove_dc, out) tb.run()
def main(): print os.getpid() tb = gr.top_block() u = blocks.file_source(gr.sizeof_float, "/tmp/atsc_pipe_2") input_rate = 19.2e6 IF_freq = 5.75e6 # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE / 2. NTAPS = 279 tt = filter.firdes.root_raised_cosine(1.0, input_rate, symbol_rate, .115, NTAPS) # heterodyne the low pass coefficients up to the specified bandpass # center frequency. Note that when we do this, the filter bandwidth # is effectively twice the low pass (2.69 * 2 = 5.38) and hence # matches the diagram in the ATSC spec. arg = 2. * math.pi * IF_freq / input_rate t = [] for i in range(len(tt)): t += [tt[i] * 2. * math.cos(arg * i)] rrc = filter.fir_filter_fff(1, t) fpll = atsc.fpll() pilot_freq = IF_freq - 3e6 + 0.31e6 lower_edge = 6e6 - 0.31e6 upper_edge = IF_freq - 3e6 + pilot_freq transition_width = upper_edge - lower_edge lp_coeffs = filter.firdes.low_pass(1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, filter.firdes.WIN_HAMMING) lp_filter = filter.fir_filter_fff(1, lp_coeffs) alpha = 1e-5 iir = filter.single_pole_iir_filter_ff(alpha) remove_dc = blocks.sub_ff() out = blocks.file_sink(gr.sizeof_float, "/tmp/atsc_pipe_3") # out = blocks.file_sink(gr.sizeof_float,"/mnt/sata/atsc_data_float") tb.connect(u, fpll, lp_filter) tb.connect(lp_filter, iir) tb.connect(lp_filter, (remove_dc, 0)) tb.connect(iir, (remove_dc, 1)) tb.connect(remove_dc, out) tb.run()
def test_ff_003(self): block_size = 2 src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = (0, 125, 250, 484.375, 718.75, 1048.828125) src = blocks.vector_source_f(src_data) s2p = blocks.stream_to_vector(gr.sizeof_float, block_size) op = filter.single_pole_iir_filter_ff (0.125, block_size) p2s = blocks.vector_to_stream(gr.sizeof_float, block_size) dst = blocks.vector_sink_f() self.tb.connect(src, s2p, op, p2s, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data, 3)
def test_ff_003(self): block_size = 2 src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = (0, 125, 250, 484.375, 718.75, 1048.828125) src = blocks.vector_source_f(src_data) s2p = blocks.stream_to_vector(gr.sizeof_float, block_size) op = filter.single_pole_iir_filter_ff(0.125, block_size) p2s = blocks.vector_to_stream(gr.sizeof_float, block_size) dst = blocks.vector_sink_f() self.tb.connect(src, s2p, op, p2s, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data, 3)
def __init__(self, fft_size, samp_rate): gr.hier_block2.__init__( self, "spectrum_sense", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float * fft_size)) # Output signature self.fft_size = fft_size self.samp_rate = samp_rate ################################################## # Blocks ################################################## # stream to vector for fft s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) #self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size, # max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) # filter window mywindow = filter.window.blackmanharris(self.fft_size) # fft ffter = fft.fft_vcc(self.fft_size, True, mywindow, True) # complex to magnitude block c2mag = blocks.complex_to_mag_squared( self.fft_size) # use sqrt of this for power # average avg = filter.single_pole_iir_filter_ff(0.4, self.fft_size) multiply_const = blocks.multiply_const_vff( (np.ones(self.fft_size) * (1.0 / self.samp_rate))) nlog10 = blocks.nlog10_ff(10, self.fft_size, 0) # FIXME We need to add 3dB to all bins but the DC bin #self.log = gr.nlog10_ff(20, 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 #v2s = blocks.vector_to_stream(gr.sizeof_float*1, self.fft_size) # connect blocks self.connect(self, s2v, ffter, c2mag, avg, multiply_const, nlog10, self)
def __init__(self, alpha=0): gr.hier_block2.__init__( self, "IQ Phase Balancer", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_gr_complex*1), ) ################################################## # Parameters ################################################## self.alpha = alpha ################################################## # Blocks ################################################## self.filter_single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(alpha, 1) self.blocks_sub_xx_1 = blocks.sub_ff(1) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_multiply_xx_2 = blocks.multiply_vff(1) self.blocks_multiply_xx_1 = blocks.multiply_vff(1) self.blocks_multiply_xx_0 = blocks.multiply_vff(1) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((2, )) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blocks_divide_xx_0 = blocks.divide_ff(1) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.blocks_complex_to_float_0 = blocks.complex_to_float(1) ################################################## # Connections ################################################## self.connect((self.blocks_complex_to_float_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.blocks_complex_to_float_0, 1), (self.blocks_multiply_xx_0, 1)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_divide_xx_0, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.blocks_float_to_complex_0, 1)) self.connect((self.blocks_multiply_xx_1, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_multiply_xx_1, 1)) self.connect((self.blocks_complex_to_float_0, 0), (self.blocks_multiply_xx_1, 0)) self.connect((self.blocks_multiply_xx_2, 0), (self.blocks_sub_xx_1, 1)) self.connect((self.blocks_complex_to_float_0, 1), (self.blocks_sub_xx_0, 0)) self.connect((self.blocks_sub_xx_1, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.blocks_divide_xx_0, 1)) self.connect((self.blocks_complex_to_float_0, 0), (self.blocks_sub_xx_1, 0)) self.connect((self.blocks_divide_xx_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.filter_single_pole_iir_filter_xx_0, 0)) self.connect((self, 0), (self.blocks_complex_to_float_0, 0)) self.connect((self, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self, 0)) self.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_multiply_xx_2, 0)) self.connect((self.blocks_complex_to_float_0, 1), (self.blocks_multiply_xx_2, 1))
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, 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, fftSize=1024, windowType="blackmanharris", iirAlpha=2.0**-3): gr.hier_block2.__init__( self, "LogMagFFT", gr.io_signature(1, 1, gr.sizeof_gr_complex * fftSize), gr.io_signaturev( 2, 2, [gr.sizeof_float * fftSize, gr.sizeof_gr_complex * fftSize]), ) ################################################## # Parameters ################################################## self.fftSize = fftSize self.iirAlpha = iirAlpha self.windowType = windowType ################################################## # Variables ################################################## self.fftWindow = fftWindow = scipy.signal.get_window( windowType, fftSize) ################################################## # Blocks ################################################## self.singlePoleIIR = filter.single_pole_iir_filter_ff( iirAlpha, fftSize) self.nLog10 = CyberRadio.vector_nlog10_ff(10, fftSize, 0) self.fwdFFT = fft.fft_vcc(fftSize, True, (fftWindow / numpy.sum(fftWindow)), True, 1) self.compToMagSq = blocks.complex_to_mag_squared(fftSize) ################################################## # Connections ################################################## self.connect((self, 0), (self.fwdFFT, 0)) self.connect((self.fwdFFT, 0), (self, 1)) self.connect((self.fwdFFT, 0), (self.compToMagSq, 0)) self.connect((self.compToMagSq, 0), (self.singlePoleIIR, 0)) self.connect((self.singlePoleIIR, 0), (self.nLog10, 0)) self.connect((self.nLog10, 0), (self, 0))
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, options): gr.hier_block2.__init__(self, "sensing_path", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(0, 0, 0)) # Output signature options = copy.copy(options) # make a copy so we can destructively modify self._verbose = options.verbose # linklab, fft size for sensing, different from fft length for tx/rx self.fft_size = FFT_SIZE # interpolation rate: sensing fft size / ofdm fft size self.interp_rate = self.fft_size/options.fft_length self._fft_length = options.fft_length self._occupied_tones = options.occupied_tones self.msgq = gr.msg_queue() # linklab , setup the sensing path # FIXME: some components are not necessary self.s2p = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) 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.c2mag = blocks.complex_to_mag(self.fft_size) self.avg = filter.single_pole_iir_filter_ff(1.0, self.fft_size) # linklab, ref scale value from default ref_scale in usrp_fft.py ref_scale = 13490.0 # FIXME We need to add 3dB to all bins but the DC bin self.log = blocks.nlog10_ff(20, self.fft_size, -10*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.fft, self.c2mag, self.avg, self.log, self.sink)
def __init__(self, noise_mag=0, alpha=0.1): gr.hier_block2.__init__( self, "Phase Noise Generator", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) ################################################## # Parameters ################################################## self.noise_mag = noise_mag self.alpha = alpha ################################################## # Blocks ################################################## self.filter_single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( alpha, 1) self.blocks_transcendental_0_0 = blocks.transcendental("sin", "float") self.blocks_transcendental_0 = blocks.transcendental("cos", "float") self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.analog_noise_source_x_0 = analog.noise_source_f( analog.GR_GAUSSIAN, noise_mag, 42) ################################################## # Connections ################################################## self.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.analog_noise_source_x_0, 0), (self.filter_single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self, 0)) self.connect((self, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_transcendental_0, 0)) self.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_transcendental_0_0, 0)) self.connect((self.blocks_transcendental_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_transcendental_0_0, 0), (self.blocks_float_to_complex_0, 1))
def __init__(self, controller, ac_couple_key, sample_rate_key): gr.hier_block2.__init__( self, "ac_couple", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float), ) #blocks lpf = filter.single_pole_iir_filter_ff(0.0) sub = gr.sub_ff() mute = gr.mute_ff() #connect self.connect(self, sub, self) self.connect(self, lpf, mute, (sub, 1)) #subscribe controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x)) controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05)) #initialize controller[ac_couple_key] = controller[ac_couple_key] controller[sample_rate_key] = controller[sample_rate_key]
def __init__(self, controller, ac_couple_key, sample_rate_key): gr.hier_block2.__init__( self, "ac_couple", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float), ) #blocks lpf = filter.single_pole_iir_filter_ff(0.0) sub = blocks.sub_ff() mute = blocks.mute_ff() #connect self.connect(self, sub, self) self.connect(self, lpf, mute, (sub, 1)) #subscribe controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x)) controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05)) #initialize controller[ac_couple_key] = controller[ac_couple_key] controller[sample_rate_key] = controller[sample_rate_key]
def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None): """ Create an log10(abs(fft)) stream chain. Provide access to the setting the filter and sample rate. Args: sample_rate: Incoming stream sample rate fft_size: Number of FFT bins ref_scale: Sets 0 dB value input amplitude frame_rate: Output frame rate avg_alpha: FFT averaging (over time) constant [0.0-1.0] average: Whether to average [True, False] win: the window taps generation function """ gr.hier_block2.__init__(self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) if win is None: win = window.blackmanharris fft_window = win(fft_size) fft = self._fft_block[0](fft_size, True, fft_window) window_power = sum(map(lambda x: x*x, fft_window)) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) self._log = blocks.nlog10_ff(10, fft_size, -20*math.log10(fft_size) # Adjust for number of bins -10*math.log10(window_power/fft_size) # Adjust for windowing loss -20*math.log10(ref_scale/2)) # Adjust for reference scale self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self, samp_rate=1000, vecsize=500, folding=5, pulse_rate=0.7477): gr.hier_block2.__init__( self, "Synch Folder2", gr.io_signature(1, 1, gr.sizeof_float * 1), gr.io_signature(1, 1, gr.sizeof_float * vecsize), ) ################################################## # Parameters ################################################## self.samp_rate = samp_rate self.vecsize = vecsize self.folding = folding self.pulse_rate = pulse_rate ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff( 1.0 / folding, vecsize) self.fractional_resampler_xx_0 = filter.fractional_resampler_ff( 0, float(samp_rate) / (float(pulse_rate) * float(vecsize))) self.blocks_stream_to_vector_0 = blocks.stream_to_vector( gr.sizeof_float * 1, vecsize) ################################################## # Connections ################################################## self.connect((self.blocks_stream_to_vector_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.fractional_resampler_xx_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self, 0), (self.fractional_resampler_xx_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self, 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 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, sample_rate, pspectrum_len, ref_scale, frame_rate, avg_alpha, average, n, m, nsamples, estimator = 'esprit' ): """ Create an log10(abs(spectrum_estimate)) stream chain. Provide access to the setting the filter and sample rate. @param sample_rate Incoming stream sample rate @param pspectrum_len Number of FFT bins @param ref_scale Sets 0 dB value input amplitude @param frame_rate Output frame rate @param avg_alpha averaging (over time) constant [0.0-1.0] @param average Whether to average [True, False] @param n Parameter n for the estimator @param m Parameter m for the estimator @param nsamples Number of samples to use for estimation @param estimator Estimator to use, can be either 'esprit' or 'music' """ gr.hier_block2.__init__(self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float*pspectrum_len)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=nsamples) if estimator == 'music': est = specest.music_spectrum_vcf(n, m, nsamples, pspectrum_len) else: est = specest.esprit_spectrum_vcf(n, m, nsamples, pspectrum_len) self._avg = filter.single_pole_iir_filter_ff(1.0, pspectrum_len) self._log = blocks.nlog10_ff(20, pspectrum_len, -20*math.log10(pspectrum_len) # Adjust for number of bins -20*math.log10(ref_scale/2)+3.0) # Adjust for reference scale self.connect(self, self._sd, est, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self, bw=250, fftsize=512, infile="/dev/null", outfile="/dev/null", reflvl=-53, srate=2500): gr.top_block.__init__(self, "Meteor Bb Analyser") ################################################## # Parameters ################################################## self.bw = bw self.fftsize = fftsize self.infile = infile self.outfile = outfile self.reflvl = reflvl self.srate = srate ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(0.75, fftsize) self.low_pass_filter_0 = filter.fir_filter_ccf(srate/bw, firdes.low_pass( 1, srate, bw/2, bw/4, firdes.WIN_HAMMING, 6.76)) self.fft_vxx_0 = fft.fft_vcc(fftsize, True, (window.blackmanharris(fftsize)), False, 1) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, int(20e3),True) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, fftsize) self.blocks_nlog10_ff_0 = blocks.nlog10_ff(20, fftsize, -10*(math.log10(fftsize))) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, infile, True) self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*fftsize, outfile, False) self.blocks_file_sink_0.set_unbuffered(True) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(fftsize) ################################################## # Connections ################################################## self.connect((self.blocks_complex_to_mag_0, 0), (self.blocks_nlog10_ff_0, 0)) self.connect((self.blocks_file_source_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.blocks_nlog10_ff_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.fft_vxx_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_file_sink_0, 0))
def __init__(self, sample_rate, fac_size, fac_decimation, use_db): gr.hier_block2.__init__( self, "AutoCorrelator", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input sig gr.io_signature(1, 1, gr.sizeof_float * fac_size)) # Output sig 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(1.0, self.fac_size) fac_fac = fft.fft_vfc(self.fac_size, True, ()) fac_c2mag = blocks.complex_to_mag(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(n, self.fac_size, k) if use_db: 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): 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, alpha=0.001): gr.hier_block2.__init__( self, "amp_var_est_hier", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signaturev(2, 2, [gr.sizeof_float*1, gr.sizeof_float*1]), ) ################################################## # Parameters ################################################## self.alpha = alpha ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0_0_1_0 = filter.single_pole_iir_filter_cc(alpha, 1) self.single_pole_iir_filter_xx_0_0_1 = filter.single_pole_iir_filter_ff(alpha, 1) self.blocks_sub_xx_0_0 = blocks.sub_ff(1) self.blocks_multiply_xx_1 = blocks.multiply_vcc(1) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((0.5, )) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) ################################################## # Connections ################################################## self.connect((self, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self, 0), (self.blocks_multiply_xx_1, 0)) self.connect((self, 0), (self.blocks_multiply_xx_1, 1)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.single_pole_iir_filter_xx_0_0_1, 0)) self.connect((self.blocks_multiply_xx_1, 0), (self.single_pole_iir_filter_xx_0_0_1_0, 0)) self.connect((self.single_pole_iir_filter_xx_0_0_1, 0), (self.blocks_sub_xx_0_0, 0)) self.connect((self.blocks_sub_xx_0_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.single_pole_iir_filter_xx_0_0_1_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.blocks_complex_to_mag_0, 0), (self.blocks_sub_xx_0_0, 1)) self.connect((self.blocks_complex_to_mag_0, 0), (self, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self, 1))
def test_001_t (self): # to test we add gaussian phase jitter and additive gaussian noise to the source vector # Each vector has all constellation values number_of_vectors = 50000 dim_constellation = 16 #Our phase jitter probe estimator, estimates the jitter variance and the snr. #gaussian noise added in "volts", the channel add noise with variance noise*noise to each axe I and Q noise = 0.02 # the variance of the phase jitter is math.pow(10.0,phase_noise_mag/20.0) * math.pow(10.0,phase_noise_mag/20.0) # the estimator works fine with an error of around 5-10% with additive noise with standard deviation of 0.01 to 0.03 and phase_noise_mag between -20 (standard deviation = 0.1 radians, approx 6 degrees) and -40 (phase_noise_mag = -40, standard deviation = 0.01 radians approx 0.6 degrees). These values are assuming that pj and snr are filtered. We are averaging the results but we are not filtering the phase jitter noise. If the additive noise is very low the snr estimator has errors and if the additive noise is very high or the phase jitter noise is very high there are many decision errors. phase_noise_mag = -30 #In hardware impairments thre is a single pole iir filter to filter the gaussian noise, we are not filtering the noise using alpha equal one alpha = 1 # creates the probe_pj object withe the symbol table and alpha self.mer_probe_pj_cf_0 = mer.probe_pj_cf((0.9487+0.9487j,0.9487+0.3162j, 0.3162+0.9487j, 0.3162 +0.3162j,0.9487-0.9487j,0.9487- 0.3162j, 0.3162-0.9487j, 0.3162- 0.3162j,-0.9487+0.9487j,-0.9487+ 0.3162j,- 0.3162+0.9487j,- 0.3162+ 0.3162j,-0.9487-0.9487j,-0.9487- 0.3162j,-0.3162-0.9487j,-0.3162- 0.3162j),0.005) #creates a source with all possible symbols repited number_of_vectors src_const = (0.9487+0.9487j,0.9487+0.3162j, 0.3162+0.9487j, 0.3162 +0.3162j,0.9487-0.9487j,0.9487- 0.3162j, 0.3162-0.9487j, 0.3162- 0.3162j,-0.9487+0.9487j,-0.9487+ 0.3162j,- 0.3162+0.9487j,- 0.3162+ 0.3162j,-0.9487-0.9487j,-0.9487- 0.3162j,-0.3162-0.9487j,-0.3162- 0.3162j)*number_of_vectors #creates the blocks and sinks to receive the estimations self.src = blocks.vector_source_c(src_const,False) self.dst0 = blocks.vector_sink_f() self.dst1 = blocks.vector_sink_f() # add a channel model to add additive gaussian noise self.channels_channel_model_0 = channels.channel_model( noise_voltage=noise, frequency_offset=0.0, epsilon=1.0, taps=(1, ), noise_seed=0, block_tags=False ) # A gaussian noise w is generated and filtered w1,a complex signal a= cos(w1) + j sin(w1) is generated # Source data src is added with white noise src1, the output signal with phase jitter and additive noise is a * src1 # the output signal a*src1 is send to the phase jitter probe and the pj and snr are estimated # to filter the gaussian noise added to the phase, we are using alpha equal 1 so we are not filtering self.filter_single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(alpha, 1) self.blocks_transcendental_0_0 = blocks.transcendental("sin", "float") self.blocks_transcendental_0 = blocks.transcendental("cos", "float") self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.analog_noise_source_x_0 = analog.noise_source_f(analog.GR_GAUSSIAN, math.pow(10.0,phase_noise_mag/20.0), 42) ################################################## # Connections ################################################## self.tb.connect((self.blocks_float_to_complex_0, 0), (self.blocks_multiply_xx_0, 1)) self.tb.connect((self.analog_noise_source_x_0, 0), (self.filter_single_pole_iir_filter_xx_0, 0)) self.tb.connect((self.blocks_multiply_xx_0, 0), (self.mer_probe_pj_cf_0, 0)) self.tb.connect((self.src, 0), (self.channels_channel_model_0, 0)) self.tb.connect((self.channels_channel_model_0, 0), (self.blocks_multiply_xx_0, 0)) self.tb.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_transcendental_0, 0)) self.tb.connect((self.filter_single_pole_iir_filter_xx_0, 0), (self.blocks_transcendental_0_0, 0)) self.tb.connect((self.blocks_transcendental_0, 0), (self.blocks_float_to_complex_0, 0)) self.tb.connect((self.blocks_transcendental_0_0, 0), (self.blocks_float_to_complex_0, 1)) self.tb.connect((self.mer_probe_pj_cf_0, 0),(self.dst0, 0)) self.tb.connect((self.mer_probe_pj_cf_0, 1),(self.dst1, 0)) self.tb.run () result_data1 = np.mean(self.dst0.data()[number_of_vectors*dim_constellation-dim_constellation*10000:number_of_vectors*dim_constellation]) result_data2 = np.mean(self.dst1.data()[number_of_vectors*dim_constellation-dim_constellation*10000:number_of_vectors*dim_constellation]) print " result phase jitter variance = ",result_data1 print " result snr = ",result_data2 expected_result1 = math.pow(10.0,phase_noise_mag/20.0) * math.pow(10.0,phase_noise_mag/20.0) print " expected result phase jitter variance = ", expected_result1 expected_result2 = 10*np.log10(1.0/noise/noise/2) print " expected result snr = ",expected_result2 #test an error in the phase jitter variance less than 10 %, self.assertLessEqual(abs((result_data1-expected_result1)/expected_result1), 0.1 ) #test an error in the snr less than 10 %, self.assertLessEqual(abs((result_data2-expected_result2)/expected_result2), 0.1 )
def __init__(self, c_freq, int_time, samp_rate, fftsize, username, config): gr.top_block.__init__(self, "Salsa Receiver") ################################################## # Variables ################################################## self.samp_rate = samp_rate self.outfile = outfile = config.get("USRP", "tmpdir") + "/SALSA_" + username + ".tmp" # Not used self.int_time = int_time self.gain = gain = config.getfloat("USRP", "usrp_gain") self.fftsize = fftsize self.c_freq = c_freq self.probe_var = probe_var = 0 # Integrate 10 FFTS using IIR block and keep 1 in N, increase for higher bandwidths to lower processing times. self.alpha = 0.1 self.N = 10 ################################################## # Blocks ################################################## self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="addr=" + config.get("USRP", "host"), stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), # recv_frame_size=4096, #Problems with overflow at bw>5 MHz, this might be a solution (depends on ethernet connection capabilities) # recv_buff_size=4096, ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(c_freq, 0) self.uhd_usrp_source_0.set_gain(gain, 0) self.fft_vxx_0 = fft.fft_vcc(fftsize, True, (window.blackmanharris(fftsize)), True, 1) self.blocks_vector_to_stream_0 = blocks.vector_to_stream(gr.sizeof_float * 1, fftsize) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_gr_complex * 1, fftsize) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(fftsize) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(self.alpha, fftsize) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float * fftsize, self.N) # Signal and reference file sinks self.signal_file_sink_1 = blocks.file_sink(gr.sizeof_float * 1, self.outfile, False) self.signal_file_sink_1.set_unbuffered(False) self.signal_file_sink_2 = blocks.file_sink(gr.sizeof_float * 1, self.outfile, False) self.signal_file_sink_2.set_unbuffered(False) self.blocks_null_sink = blocks.null_sink(gr.sizeof_float * 1) # Selector for switch self.blks2_selector_0 = grc_blks2.selector( item_size=gr.sizeof_float * 1, num_inputs=1, num_outputs=2 + 1, # +1 for the null sink input_index=0, output_index=0, ) ################################################## # Connections ################################################## self.connect((self.uhd_usrp_source_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self.fft_vxx_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.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_vector_to_stream_0, 0)) self.connect((self.blocks_vector_to_stream_0, 0), (self.blks2_selector_0, 0)) # Selector connections self.connect((self.blks2_selector_0, 1), (self.signal_file_sink_1, 0)) self.connect((self.blks2_selector_0, 2), (self.signal_file_sink_2, 0)) # Null sink connection self.connect((self.blks2_selector_0, 0), (self.blocks_null_sink, 0))
def __init__(self): gr.top_block.__init__(self, "SIMONES_Occupation") ################################################## # Variables ################################################## self.fft_size = fft_size = 1024 self.samp_rate = samp_rate = 20e6 self.fft_window = fft_window = window.blackmanharris(fft_size) self.power = power = sum(x*x for x in fft_window) self.center_freq = center_freq = 98e6 self.bandwidth = bandwidth = samp_rate self.stop_freq = stop_freq = center_freq+(bandwidth/2) self.start_freq = start_freq = center_freq-(bandwidth/2) self.simon_port = simon_port = 65123 self.simon_ip = simon_ip = '127.0.0.1' self.server_port = server_port = 65234 self.server_ip = server_ip = '127.0.0.1' self.n = n = max(1, int(samp_rate/fft_size/15L)) self.k = k = -20*math.log10(fft_size)-10*math.log10(power/fft_size)-20*math.log10(2.0/2) self.device = device = 'bladerf,fpga=/home/i2t/Software/source/bladeRF/pre-built/hostedx115.rbf,xb200=auto' self.canalization = canalization = 1e6 ################################################## # Blocks ################################################## self.xmlrpc_server_0 = SimpleXMLRPCServer.SimpleXMLRPCServer((simon_ip, simon_port), allow_none=True) self.xmlrpc_server_0.register_instance(self) threading.Thread(target=self.xmlrpc_server_0.serve_forever).start() self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(1.0, fft_size) self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + device ) self.osmosdr_source_0.set_sample_rate(samp_rate) self.osmosdr_source_0.set_center_freq(center_freq, 0) self.osmosdr_source_0.set_freq_corr(0, 0) self.osmosdr_source_0.set_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(10, 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(bandwidth, 0) self.fft_vxx_0 = fft.fft_vcc(fft_size, True, (fft_window), True, 1) self.blocks_vector_to_stream_0 = blocks.vector_to_stream(gr.sizeof_float*1, fft_size) self.blocks_udp_sink_0 = blocks.udp_sink(gr.sizeof_float*1, server_ip, server_port, 1472, True) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, fft_size) self.blocks_nlog10_ff_0 = blocks.nlog10_ff(20, fft_size, k) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_gr_complex*fft_size, n) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1024) ################################################## # Connections ################################################## self.connect((self.blocks_keep_one_in_n_0, 0), (self.fft_vxx_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.fft_vxx_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_nlog10_ff_0, 0), (self.blocks_vector_to_stream_0, 0)) self.connect((self.blocks_complex_to_mag_0, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_nlog10_ff_0, 0)) self.connect((self.blocks_vector_to_stream_0, 0), (self.blocks_udp_sink_0, 0))
def setup_snr_measurement(self): """ Perform SNR measurement. It uses the data reference from the BER measurement. I.e. if that is not setup, it will be setup. Only data subcarriers that are assigned to the station are considered in the measurement. Note that there is no sink prepared. You need to setup a sink, e.g. with one or more invocation of a "publish.."-function. SNR output is in dB. """ if not self.measuring_ber(): self.setup_ber_measurement() print "Warning: Setup BER Measurement forced" if self.measuring_snr(): return config = station_configuration() vlen = config.subcarriers frame_length = config.frame_length L = config.periodic_parts snr_est_filt = skip(gr.sizeof_gr_complex*vlen,frame_length/2) skipping_symbols = [0] + range(config.training_data.fbmc_no_preambles/2,frame_length/2) for x in skipping_symbols: snr_est_filt.skip_call(x) #snr_est_filt = skip(gr.sizeof_gr_complex*vlen,frame_length) #for x in range(1,frame_length): #snr_est_filt.skip_call(x) ## NOTE HACK!! first preamble is not equalized self.connect(self.symbol_output,snr_est_filt) self.connect(self.frame_trigger,(snr_est_filt,1)) # snrm = self._snr_measurement = milans_snr_estimator( vlen, vlen, L ) # # self.connect(snr_est_filt,snrm) # # if self._options.log: # log_to_file(self, self._snr_measurement, "data/milan_snr.float") #Addition for SINR estimation if self._options.sinr_est: snr_est_filt_2 = skip(gr.sizeof_gr_complex*vlen,frame_length) for x in range(frame_length): if x != config.training_data.channel_estimation_pilot[0]: snr_est_filt_2.skip_call(x) self.connect(self.symbol_output,snr_est_filt_2) self.connect(self.frame_trigger,(snr_est_filt_2,1)) sinrm = self._sinr_measurement = milans_sinr_sc_estimator2( vlen, vlen, L ) self.connect(snr_est_filt,sinrm) self.connect(snr_est_filt_2,(sinrm,1)) if self._options.log: log_to_file(self, (self._sinr_measurement,0), "data/milan_sinr_sc.float") log_to_file(self, (self._sinr_measurement,1), "data/milan_snr.float") else: #snrm = self._snr_measurement = milans_snr_estimator( vlen, vlen, L ) snr_estim = fbmc_snr_estimator( vlen, config.training_data.fbmc_no_preambles/2 -1 ) scsnrdb = filter.single_pole_iir_filter_ff(0.1) snrm = self._snr_measurement = blocks.nlog10_ff(10,1,0) #self.connect(self.snr_est_preamble,scsnrdb,snrm) #terminate_stream(self,self.snr_est_preamble) #self.connect(self.snr_est_preamble,snr_estim,scsnrdb,snrm) #self.connect((snr_estim,1),blocks.null_sink(gr.sizeof_float)) #log_to_file(self, snrm, "data/snrm.float") #log_to_file(self, snrm, "data/snrm.float") collect_preambles = blocks.stream_to_vector(gr.sizeof_gr_complex*vlen, config.training_data.fbmc_no_preambles/2 -1) self.connect(snr_est_filt, collect_preambles) self.connect(collect_preambles,snr_estim,scsnrdb,snrm) self.connect((snr_estim,1),blocks.null_sink(gr.sizeof_float))
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 __init__(self, large_sig_len=0.0015, signal_mult=2, freq=433866000): gr.top_block.__init__(self, "Top Block") Qt.QWidget.__init__(self) self.setWindowTitle("Top Block") 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", "top_block") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Parameters ################################################## self.large_sig_len = large_sig_len self.signal_mult = signal_mult self.freq = freq ################################################## # Variables ################################################## self.samp_rate = samp_rate = 240000 ################################################## # Blocks ################################################## self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(0.2, 1) self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "" ) self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_center_freq(freq, 0) self.rtlsdr_source_0.set_freq_corr(-24, 0) self.rtlsdr_source_0.set_dc_offset_mode(0, 0) self.rtlsdr_source_0.set_iq_balance_mode(1, 0) self.rtlsdr_source_0.set_gain_mode(False, 0) self.rtlsdr_source_0.set_gain(50, 0) self.rtlsdr_source_0.set_if_gain(20, 0) self.rtlsdr_source_0.set_bb_gain(20, 0) self.rtlsdr_source_0.set_antenna("", 0) self.rtlsdr_source_0.set_bandwidth(0, 0) self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass( 1, samp_rate, 10000, 10000, firdes.WIN_HAMMING, 6.76)) self.blocks_threshold_ff_2 = blocks.threshold_ff(0, 0, 0) self.blocks_threshold_ff_1 = blocks.threshold_ff(0, 0, 0) self.blocks_sub_xx_2 = blocks.sub_ff(1) self.blocks_sub_xx_1 = blocks.sub_ff(1) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "localhost", "52001", 10000, False) self.blocks_multiply_const_vxx_1 = blocks.multiply_const_vff((signal_mult, )) self.blocks_moving_average_xx_1 = blocks.moving_average_ff(int(samp_rate*large_sig_len), 0.8/samp_rate/large_sig_len, 4000) self.blocks_float_to_char_1 = blocks.float_to_char(1, 1) self.blocks_float_to_char_0_0 = blocks.float_to_char(1, 1) self.blocks_delay_1 = blocks.delay(gr.sizeof_float*1, int(samp_rate*0.00005)) self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, 1) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.bitgate_triggered_bits_0 = bitgate.triggered_bits(int(samp_rate*large_sig_len*5), False) self.analog_rail_ff_1 = analog.rail_ff(0.001, 1) self.analog_rail_ff_0 = analog.rail_ff(0, 1) ################################################## # Connections ################################################## self.msg_connect((self.bitgate_triggered_bits_0, 'pdus'), (self.blocks_socket_pdu_0, 'pdus')) self.connect((self.analog_rail_ff_0, 0), (self.blocks_float_to_char_0_0, 0)) self.connect((self.analog_rail_ff_1, 0), (self.blocks_multiply_const_vxx_1, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.analog_rail_ff_1, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.blocks_delay_1, 0), (self.blocks_float_to_char_1, 0)) self.connect((self.blocks_float_to_char_0_0, 0), (self.bitgate_triggered_bits_0, 1)) self.connect((self.blocks_float_to_char_1, 0), (self.bitgate_triggered_bits_0, 0)) self.connect((self.blocks_moving_average_xx_1, 0), (self.blocks_sub_xx_1, 1)) self.connect((self.blocks_moving_average_xx_1, 0), (self.blocks_sub_xx_2, 1)) self.connect((self.blocks_multiply_const_vxx_1, 0), (self.blocks_moving_average_xx_1, 0)) self.connect((self.blocks_multiply_const_vxx_1, 0), (self.single_pole_iir_filter_xx_0, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.analog_rail_ff_0, 0)) self.connect((self.blocks_sub_xx_1, 0), (self.blocks_sub_xx_2, 0)) self.connect((self.blocks_sub_xx_1, 0), (self.blocks_threshold_ff_1, 0)) self.connect((self.blocks_sub_xx_2, 0), (self.blocks_threshold_ff_2, 0)) self.connect((self.blocks_threshold_ff_1, 0), (self.blocks_delay_0, 0)) self.connect((self.blocks_threshold_ff_1, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.blocks_threshold_ff_2, 0), (self.blocks_delay_1, 0)) self.connect((self.low_pass_filter_0, 0), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.rtlsdr_source_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.single_pole_iir_filter_xx_0, 0), (self.blocks_sub_xx_1, 0))
def graph (args): print os.getpid() nargs = len(args) if nargs == 2: infile = args[0] outfile = args[1] else: raise ValueError('usage: interp.py input_file output_file.ts\n') input_rate = 19.2e6 IF_freq = 5.75e6 tb = gr.top_block() # Read from input file srcf = blocks.file_source(gr.sizeof_short, infile) # Convert interleaved shorts (I,Q,I,Q) to complex is2c = blocks.interleaved_short_to_complex() # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE/2. NTAPS = 279 tt = filter.firdes.root_raised_cosine (1.0, input_rate / 3, symbol_rate, .1152, NTAPS) rrc = filter.fir_filter_ccf(1, tt) # Interpolate Filter our 6MHz wide signal centered at 0 ilp_coeffs = filter.firdes.low_pass(1, input_rate, 3.2e6, .5e6, filter.firdes.WIN_HAMMING) ilp = filter.interp_fir_filter_ccf(3, ilp_coeffs) # Move the center frequency to 5.75MHz ( this wont be needed soon ) duc_coeffs = filter.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, filter.firdes.WIN_HAMMING ) duc = filter.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, -5.75e6, 19.2e6 ) # fpll input is float c2f = blocks.complex_to_float() # Phase locked loop fpll = atsc.fpll() # Clean fpll output lp_coeffs2 = filter.firdes.low_pass (1.0, input_rate, 5.75e6, 120e3, filter.firdes.WIN_HAMMING); lp_filter = filter.fir_filter_fff (1, lp_coeffs2) # Remove pilot ( at DC now ) iir = filter.single_pole_iir_filter_ff(1e-5) remove_dc = blocks.sub_ff() # Bit Timing Loop, Field Sync Checker and Equalizer btl = atsc.bit_timing_loop() fsc = atsc.fs_checker() eq = atsc.equalizer() fsd = atsc.field_sync_demux() # Viterbi viterbi = atsc.viterbi_decoder() deinter = atsc.deinterleaver() rs_dec = atsc.rs_decoder() derand = atsc.derandomizer() depad = atsc.depad() # Write to output file outf = blocks.file_sink(gr.sizeof_char,outfile) # Connect it all together tb.connect( srcf, is2c, rrc, ilp, duc, c2f, fpll, lp_filter) tb.connect( lp_filter, iir ) tb.connect( lp_filter, (remove_dc, 0) ) tb.connect( iir, (remove_dc, 1) ) tb.connect( remove_dc, btl ) tb.connect( (btl, 0), (fsc, 0), (eq, 0), (fsd,0) ) tb.connect( (btl, 1), (fsc, 1), (eq, 1), (fsd,1) ) tb.connect( fsd, viterbi, deinter, rs_dec, derand, depad, outf ) tb.run()
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, fftsize, samp_rate, gain, c_freq, windows): gr.top_block.__init__(self, "CalculateFFT") #Class variables self.samp_rate = samp_rate self.gain = gain self.fftsize = fftsize self.c_freq = c_freq self.dump1 = "/tmp/ramdisk/dump1" #View as null sinks self.dump2 = "/tmp/ramdisk/dump2" self.alpha = 0.01 #Integrate 100 FFTS 0.01 self.N = 100 #100 self.probe_var = probe_var = 0 blackman_harris = window.blackmanharris(self.fftsize) hanning = window.hanning(self.fftsize) rectangular = window.rectangular(self.fftsize) self.window = blackman_harris #Default window self.select_window = windows ###Selectable FFT Windows### if self.select_window == "blackman-harris": self.window = blackman_harris elif self.select_window == "hanning": self.window = hanning elif self.select_window == "rectangular": self.window = rectangular ########## GNURADIO BLOCKS ######### #################################### self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(("", "master_clock_rate=120e6")), #Set the master_clock_rate, default = 200 MHz, alt 184.32 MHz and 120 MHz (Set) uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) #Configure USRP channel 0 self.uhd_usrp_source_0.set_samp_rate(self.samp_rate) self.uhd_usrp_source_0.set_center_freq(self.c_freq, 0) self.uhd_usrp_source_0.set_gain(self.gain, 0) self.uhd_usrp_source_0.set_bandwidth(self.samp_rate, 0) self.uhd_usrp_source_0.set_clock_source('internal', 0) #Signal and reference file sinks self.signal_file_sink_1 = blocks.file_sink(gr.sizeof_float*1, self.dump1, False) self.signal_file_sink_1.set_unbuffered(False) self.signal_file_sink_2 = blocks.file_sink(gr.sizeof_float*1, self.dump2, False) self.signal_file_sink_2.set_unbuffered(False) #Selector for GPIO switch self.blks2_selector_0 = grc_blks2.selector( item_size=gr.sizeof_float*1, num_inputs=1, num_outputs=2+1, #+1 for the null sink input_index=0, output_index=0, ) self.blocks_null_sink = blocks.null_sink(gr.sizeof_float*1) self.single_pole_iir_filter_xx_0 = filter.single_pole_iir_filter_ff(self.alpha, self.fftsize) self.fft_vxx_0 = fft.fft_vcc(self.fftsize, True, (self.window), True, 1) self.blocks_vector_to_stream_0 = blocks.vector_to_stream(gr.sizeof_float*1, self.fftsize) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, self.fftsize) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float*self.fftsize, self.N) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(self.fftsize) #Block connections self.connect((self.uhd_usrp_source_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self.fft_vxx_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.single_pole_iir_filter_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.blocks_vector_to_stream_0, 0)) self.connect((self.blocks_vector_to_stream_0, 0), (self.blks2_selector_0, 0)) #Selector connections self.connect((self.blks2_selector_0, 1), (self.signal_file_sink_1, 0)) self.connect((self.blks2_selector_0, 2), (self.signal_file_sink_2, 0)) #Null sink connection self.connect((self.blks2_selector_0, 0), (self.blocks_null_sink, 0)) #PROBE SAMPLES self.probe_signal = blocks.probe_signal_f() self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.connect((self.blocks_complex_to_mag_0, 0), (self.probe_signal, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.blocks_complex_to_mag_0, 0)) #Probe update rate def _probe_var_probe(): while True: val = self.probe_signal.level() try: self.set_probe_var(val) except AttributeError: pass time.sleep(10 / (self.samp_rate)) #Update probe variabel every 10/samp_rate seconds _probe_var_thread = threading.Thread(target=_probe_var_probe) _probe_var_thread.daemon = True _probe_var_thread.start()