def setup_radiometer_common(self,n): # The IIR integration filter for post-detection self.integrator = gr.single_pole_iir_filter_ff(1.0) self.integrator.set_taps (1.0/self.bw) if (self.use_notches == True): self.compute_notch_taps(self.notches) if (n == 2): self.notch_filt1 = gr.fft_filter_ccc(1, self.notch_taps) self.notch_filt2 = gr.fft_filter_ccc(1, self.notch_taps) else: self.notch_filt = gr.fft_filter_ccc(1, self.notch_taps) # Signal probe self.probe = gr.probe_signal_f() # # Continuum calibration stuff # x = self.calib_coeff/100.0 self.cal_mult = gr.multiply_const_ff(self.calib_coeff/100.0) self.cal_offs = gr.add_const_ff(self.calib_offset*(x*8000)) # # Mega decimator after IIR filter # if (self.switch_mode == False): self.keepn = gr.keep_one_in_n(gr.sizeof_float, self.bw) else: self.keepn = gr.keep_one_in_n(gr.sizeof_float, int(self.bw/2)) # # For the Dicke-switching scheme # #self.switch = gr.multiply_const_ff(1.0) # if (self.switch_mode == True): self.vector = gr.vector_sink_f() self.swkeep = gr.keep_one_in_n(gr.sizeof_float, int(self.bw/3)) self.mute = gr.keep_one_in_n(gr.sizeof_float, 1) self.cmute = gr.keep_one_in_n(gr.sizeof_float, int(1.0e9)) self.cintegrator = gr.single_pole_iir_filter_ff(1.0/(self.bw/2)) self.cprobe = gr.probe_signal_f() else: self.mute = gr.multiply_const_ff(1.0) self.avg_reference_value = 0.0 self.reference_level = gr.add_const_ff(0.0)
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 = gr.add_const_ff(0) # FIXME kludge self.low_iir = gr.iir_filter_ffd((0.0193, 0, -0.0193), (1, 1.9524, -0.9615)) self.low_square = gr.multiply_ff() self.low_smooth = gr.single_pole_iir_filter_ff( 1 / (0.01 * audio_rate)) # 100ms time constant self.hi_iir = gr.iir_filter_ffd((0.0193, 0, -0.0193), (1, 1.3597, -0.9615)) self.hi_square = gr.multiply_ff() self.hi_smooth = gr.single_pole_iir_filter_ff(1 / (0.01 * audio_rate)) self.sub = gr.sub_ff() self.add = gr.add_ff() self.gate = gr.threshold_ff(0.3, 0.43, 0) self.squelch_lpf = gr.single_pole_iir_filter_ff(1 / (0.01 * audio_rate)) self.div = gr.divide_ff() self.squelch_mult = gr.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 supply_rx_baseband(self): ## RX Spectrum if self.__dict__.has_key('rx_baseband'): return self.rx_baseband config = self.config fftlen = config.fft_length my_window = window.hamming(fftlen) #.blackmanharris(fftlen) rxs_sampler = vector_sampler(gr.sizeof_gr_complex, fftlen) rxs_trigger = blocks.vector_source_b(concatenate([[1], [0] * 199]), 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 = gr.single_pole_iir_filter_ff(0.01, fftlen) rxs_logdb = gr.nlog10_ff(20.0, fftlen, -20 * log10(fftlen)) rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float * fftlen, 50) t = self.u if self.filter is None else self.filter self.connect(rxs_trigger, (rxs_sampler, 1)) self.connect(t, rxs_sampler, rxs_window, rxs_spectrum, rxs_mag, rxs_avg, rxs_logdb, rxs_decimate_rate) if self._options.log: log_to_file(self, rxs_decimate_rate, "data/supply_rx.float") self.rx_baseband = rxs_decimate_rate return rxs_decimate_rate
def __init__(self, fg, parent, baseband_freq=0, y_per_div=10, ref_level=100, sample_rate=1, fft_size=512, fft_rate=20, average=False, avg_alpha=None, title='', size=default_fftsink_size): fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title) s2p = gr.serial_to_parallel(gr.sizeof_float, fft_size) one_in_n = gr.keep_one_in_n(gr.sizeof_float * fft_size, int(sample_rate/fft_size/fft_rate)) mywindow = window.blackmanharris(fft_size) fft = gr.fft_vfc(self.fft_size, True, mywindow) #fft = gr.fft_vfc(fft_size, True, True) c2mag = gr.complex_to_mag(fft_size) self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size) log = gr.nlog10_ff(20, fft_size) sink = gr.file_descriptor_sink(gr.sizeof_float * fft_size, self.w_fd) fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink) gr.hier_block.__init__(self, fg, s2p, sink) self.fg = fg self.gl_fft_window(self)
def __init__(self, fg, 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, peak_hold=False): fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold) s2p = gr.stream_to_vector(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) fft = gr.fft_vfc(self.fft_size, True, mywindow) power = 0 for tap in mywindow: power += tap*tap c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) # FIXME We need to add 3dB to all bins but the DC bin log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size)) sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) fg.connect (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) gr.hier_block.__init__(self, fg, s2p, sink) self.win = fft_window(self, parent, size=size) self.set_average(self.average)
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 = gr.fft_vfc(self.fft_size, True, mywindow) self.c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.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 main(): parser = OptionParser(conflict_handler="resolve") expert_grp = parser.add_option_group("Expert") add_options(parser, expert_grp) (options, args) = parser.parse_args () fft_length = options.fft_length or 512 file = options.file or "input.compl" out = options.out or "output.compl" src = gr.file_source(gr.sizeof_gr_complex,file) sampler = ofdm.vector_sampler( gr.sizeof_gr_complex, fft_length ) trig = gr.vector_source_b([1],True) fft = gr.fft_vcc( fft_length, True, [], True ) mag = gr.complex_to_mag( fft_length ) avg = gr.single_pole_iir_filter_ff(0.01, fft_length) nlog = gr.nlog10_ff( 20, fft_length, -10*math.log10(fft_length) ) dst = gr.file_sink( gr.sizeof_float * fft_length, out ) fg = gr.top_block() fg.connect( src, sampler, fft, mag, avg, nlog, dst ) fg.connect( trig, (sampler,1)) # fg.connect(src,limit, # gr.stream_to_vector(gr.sizeof_gr_complex,fft_length), # fft, # gr.multiply_const_vcc([1./fft_length]*fft_length), # gr.complex_to_mag(fft_length), # gr.nlog10_ff(10.0,fft_length), # dst) # fg.connect( src, fft, dst ) fg.run() print "done"
def __init__( self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fac_size=512, fac_rate=default_fac_rate, average=False, avg_alpha=None, title="", size=default_facsink_size, peak_hold=False, ): fac_sink_base.__init__( self, input_is_real=False, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fac_size=fac_size, fac_rate=fac_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold, ) s2p = gr.stream_to_vector(gr.sizeof_gr_complex, self.fac_size) self.one_in_n = gr.keep_one_in_n( gr.sizeof_gr_complex * self.fac_size, max(1, int(self.sample_rate / self.fac_size / self.fac_rate)) ) # windowing removed ... fac = gr.fft_vcc(self.fac_size, True, ()) c2mag = gr.complex_to_mag(fac_size) # Things go off into the weeds if we try for an inverse FFT so a forward FFT will have to do... fac_fac = gr.fft_vfc(self.fac_size, True, ()) fac_c2mag = gr.complex_to_mag(fac_size) self.avg = gr.single_pole_iir_filter_ff(1.0, fac_size) log = gr.nlog10_ff( 20, self.fac_size, -20 * math.log10(self.fac_size) ) # - 20*math.log10(norm) ) # - self.avg[0] ) sink = gr.message_sink(gr.sizeof_float * fac_size, self.msgq, True) self.connect(s2p, self.one_in_n, fac, c2mag, fac_fac, fac_c2mag, self.avg, log, sink) # gr.hier_block2.__init__(self, fg, s2p, sink) self.win = fac_window(self, parent, size=size) self.set_average(self.average) self.wxgui_connect(self, s2p)
def __init__(self, fg, parent, baseband_freq=0, ref_level=0, sample_rate=1, fft_size=512, fft_rate=default_fft_rate, average=False, avg_alpha=None, title='', size=default_fftsink_size, report=None, span=40, ofunc=None, xydfunc=None): waterfall_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title) s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, self.fft_size) self.one_in_n = gr.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) fft = gr.fft_vcc(self.fft_size, True, mywindow) c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) self.block_list = (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) self.reconnect( fg ) gr.hier_block.__init__(self, fg, s2p, sink) self.win = waterfall_window(self, parent, size=size, report=report, ref_level=ref_level, span=span, ofunc=ofunc, xydfunc=xydfunc) self.set_average(self.average)
def publish_rx_spectrum(self,fftlen): ## RX Spectrum fftlen = 256 my_window = window.hamming(fftlen) #.blackmanharris(fftlen) rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen) rxs_trigger = gr.vector_source_b(concatenate([[1],[0]*199]),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 = gr.single_pole_iir_filter_ff(0.01,fftlen) rxs_logdb = gr.nlog10_ff(20.0,fftlen,-20*log10(fftlen)) rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,1) msgq = gr.msg_queue(5) rxs_msg_sink = gr.message_sink(gr.sizeof_float*fftlen,msgq,True) self.connect(rxs_trigger,(rxs_sampler,1)) t = self.u if self.filter is None else self.filter self.connect(t,rxs_sampler,rxs_window, rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate, rxs_msg_sink) self.servants.append(corba_data_buffer_servant("spectrum",fftlen,msgq)) print "RXS trigger unique id", rxs_trigger.unique_id() print "Publishing RX baseband under id: spectrum"
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): 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 = gr.fft_vfc(self.fft_size, True, mywindow) self.c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.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, parent, baseband_freq=0, y_per_div=10, sc_y_per_div=0.5, sc_ref_level=40, ref_level=50, sample_rate=1, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title='', size=default_ra_fftsink_size, peak_hold=False, ofunc=None, xydfunc=None): gr.hier_block2.__init__(self, "ra_fft_sink_f", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(0, 0, 0)) ra_fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, y_per_div=y_per_div, sc_y_per_div=sc_y_per_div, sc_ref_level=sc_ref_level, 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, ofunc=ofunc, xydfunc=xydfunc) self.binwidth = float(sample_rate/2.0)/float(fft_size) s2p = gr.serial_to_parallel(gr.sizeof_float, fft_size) one_in_n = gr.keep_one_in_n(gr.sizeof_float * fft_size, max(1, int(sample_rate/fft_size/fft_rate))) mywindow = window.blackmanharris(fft_size) fft = gr.fft_vfc(fft_size, True, mywindow) c2mag = gr.complex_to_mag(fft_size) self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size) log = gr.nlog10_ff(20, fft_size, -20*math.log10(fft_size)) sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True) self.connect (self, s2p, one_in_n, fft, c2mag, self.avg, log, sink) self.win = fft_window(self, parent, size=size) self.set_average(self.average)
def supply_rx_baseband(self): ## RX Spectrum if self.__dict__.has_key('rx_baseband'): return self.rx_baseband config = self.config fftlen = config.fft_length my_window = window.hamming(fftlen) #.blackmanharris(fftlen) rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen) rxs_trigger = gr.vector_source_b(concatenate([[1],[0]*199]),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 = gr.single_pole_iir_filter_ff(0.01,fftlen) rxs_logdb = gr.nlog10_ff(20.0,fftlen,-20*log10(fftlen)) rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,50) t = self.u if self.filter is None else self.filter self.connect(rxs_trigger,(rxs_sampler,1)) self.connect(t,rxs_sampler,rxs_window, rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate) if self._options.log: log_to_file(self, rxs_decimate_rate, "data/supply_rx.float") self.rx_baseband = rxs_decimate_rate return rxs_decimate_rate
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 = gr.fir_filter_ccc(10, taps) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000 * [ 0, ] + 1000 * [ 1, ] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = gr.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() ## average to debounce self.avg = gr.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = gr.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = gr.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = gr.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, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average): """! Create an log10(abs(fft)) stream chain. Provide access to the setting the filter and sample rate. @param sample_rate Incoming stream sample rate @param fft_size Number of FFT bins @param ref_scale Sets 0 dB value input amplitude @param frame_rate Output frame rate @param avg_alpha FFT averaging (over time) constant [0.0-1.0] @param average Whether to average [True, False] """ 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 = stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) fft_window = window.blackmanharris(fft_size) fft = self._fft_block[0](fft_size, True, fft_window) window_power = sum(map(lambda x: x*x, fft_window)) c2mag = gr.complex_to_mag(fft_size) self._avg = gr.single_pole_iir_filter_ff(1.0, fft_size) self._log = gr.nlog10_ff(20, fft_size, -10*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, c2mag, self._avg, self._log, self) self.set_average(average) self.set_avg_alpha(avg_alpha)
def __init__(self, fg, parent, unit='',base_value=0,minval=-100.0,maxval=100.0,factor=1.0, decimal_places=10, ref_level=50, sample_rate=1, #number_size=512, number_rate=default_number_rate, average=False, avg_alpha=None, label='', size=default_numbersink_size, peak_hold=False): number_sink_base.__init__(self, unit=unit, input_is_real=True, base_value=base_value, minval=minval,maxval=maxval,factor=factor, decimal_places=decimal_places, ref_level=ref_level, sample_rate=sample_rate, #number_size=number_size, number_rate=number_rate, average=average, avg_alpha=avg_alpha, label=label, peak_hold=peak_hold) number_size=1 #s2p = gr.stream_to_vector(gr.sizeof_float, number_size) one_in_n = gr.keep_one_in_n(gr.sizeof_float, max(1, int(sample_rate/number_rate))) #c2mag = gr.complex_to_mag(number_size) self.avg = gr.single_pole_iir_filter_ff(1.0, number_size) # FIXME We need to add 3dB to all bins but the DC bin #log = gr.nlog10_ff(20, number_size, # -20*math.log10(number_size)-10*math.log10(power/number_size)) sink = gr.message_sink(gr.sizeof_float , self.msgq, True) #fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink) fg.connect(self.avg,one_in_n,sink) gr.hier_block.__init__(self, fg, self.avg, sink) self.win = number_window(self, parent, size=size,label=label) self.set_average(self.average)
def __init__(self, parent, unit='',base_value=0,minval=-100.0,maxval=100.0,factor=1.0, decimal_places=10, ref_level=50, sample_rate=1, number_rate=default_number_rate, average=False, avg_alpha=None, label='', size=default_numbersink_size, peak_hold=False): gr.hier_block2.__init__(self, "number_sink_f", gr.io_signature(1, 1, gr.sizeof_float), # Input signature gr.io_signature(0, 0, 0)) # Output signature number_sink_base.__init__(self, unit=unit, input_is_real=True, base_value=base_value, minval=minval,maxval=maxval,factor=factor, decimal_places=decimal_places, ref_level=ref_level, sample_rate=sample_rate, number_rate=number_rate, average=average, avg_alpha=avg_alpha, label=label, peak_hold=peak_hold) number_size=1 one_in_n = gr.keep_one_in_n(gr.sizeof_float, max(1, int(sample_rate/number_rate))) self.avg = gr.single_pole_iir_filter_ff(1.0, number_size) sink = gr.message_sink(gr.sizeof_float , self.msgq, True) self.connect(self, self.avg, one_in_n, sink) self.win = number_window(self, parent, size=size,label=label) self.set_average(self.average) self.set_peak_hold(self.peak_hold)
def main(): parser = OptionParser(conflict_handler="resolve") expert_grp = parser.add_option_group("Expert") add_options(parser, expert_grp) (options, args) = parser.parse_args() fft_length = options.fft_length or 512 file = options.file or "input.compl" out = options.out or "output.compl" src = gr.file_source(gr.sizeof_gr_complex, file) sampler = ofdm.vector_sampler(gr.sizeof_gr_complex, fft_length) trig = gr.vector_source_b([1], True) fft = gr.fft_vcc(fft_length, True, [], True) mag = gr.complex_to_mag(fft_length) avg = gr.single_pole_iir_filter_ff(0.01, fft_length) nlog = gr.nlog10_ff(20, fft_length, -10 * math.log10(fft_length)) dst = gr.file_sink(gr.sizeof_float * fft_length, out) fg = gr.top_block() fg.connect(src, sampler, fft, mag, avg, nlog, dst) fg.connect(trig, (sampler, 1)) # fg.connect(src,limit, # gr.stream_to_vector(gr.sizeof_gr_complex,fft_length), # fft, # gr.multiply_const_vcc([1./fft_length]*fft_length), # gr.complex_to_mag(fft_length), # gr.nlog10_ff(10.0,fft_length), # dst) # fg.connect( src, fft, dst ) fg.run() print "done"
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, io_type=uhd.io_type_t.COMPLEX_FLOAT32, num_channels=1, ) 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 = gr.fir_filter_ccc(10, taps) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods data = 1000*[0,] + 1000*[1,] self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst ## use squelch to detect energy self.det = gr.simple_squelch_cc(self.threshold, 0.01) ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() ## average to debounce self.avg = gr.single_pole_iir_filter_ff(0.01) ## rescale signal for conversion to short self.scale = gr.multiply_const_ff(2**16) ## signal input uses shorts self.f2s = gr.float_to_short() # Use file sink burst tagger to capture bursts self.fsnk = gr.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, 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 = blks2.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 = gr.single_pole_iir_filter_ff(1.0, pspectrum_len) self._log = gr.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, *args, **kwargs): """ Hierarchical block for O-QPSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param sps: samples per symbol @type sps: integer """ try: self.sps = kwargs.pop('sps') self.log = kwargs.pop('log') except KeyError: pass gr.hier_block2.__init__( self, "ieee802_15_4_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input gr.io_signature(1, 1, gr.sizeof_float)) # Output # Demodulate FM sensitivity = (pi / 2) / self.sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0008 / self.sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.connect(self, self.fmdemod) self.connect(self.fmdemod, (self.sub, 0)) self.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = self.sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff( omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect self.connect(self.sub, self.clock_recovery, self) if self.log: self.connect(self.fmdemod, gr.file_sink(gr.sizeof_float, 'rx-fmdemod.dat')) self.connect(self.freq_offset, gr.file_sink(gr.sizeof_float, 'rx-fo.dat')) self.connect(self.sub, gr.file_sink(gr.sizeof_float, 'rx-sub.dat')) self.connect(self.clock_recovery, gr.file_sink(gr.sizeof_float, 'rx-recovery.dat'))
def __init__( self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fac_size=512, fac_rate=default_fac_rate, average=False, avg_alpha=None, title="", size=default_facsink_size, peak_hold=False, ): fac_sink_base.__init__( self, input_is_real=True, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fac_size=fac_size, fac_rate=fac_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold, ) s2p = gr.stream_to_vector(gr.sizeof_float, self.fac_size) self.one_in_n = gr.keep_one_in_n( gr.sizeof_float * self.fac_size, max(1, int(self.sample_rate / self.fac_size / self.fac_rate)) ) # windowing removed... fac = gr.fft_vfc(self.fac_size, True, ()) c2mag = gr.complex_to_mag(self.fac_size) self.avg = gr.single_pole_iir_filter_ff(1.0, self.fac_size) fac_fac = gr.fft_vfc(self.fac_size, True, ()) fac_c2mag = gr.complex_to_mag(fac_size) # FIXME We need to add 3dB to all bins but the DC bin log = gr.nlog10_ff(20, self.fac_size, -20 * math.log10(self.fac_size)) sink = gr.message_sink(gr.sizeof_float * self.fac_size, self.msgq, True) self.connect(s2p, self.one_in_n, fac, c2mag, fac_fac, fac_c2mag, self.avg, log, sink) # gr.hier_block.__init__(self, fg, s2p, sink) self.win = fac_window(self, parent, size=size) self.set_average(self.average) self.wxgui_connect(self, s2p)
def __init__(self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fac_size=512, fac_rate=default_fac_rate, average=False, avg_alpha=None, title='', size=default_facsink_size, peak_hold=False): fac_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fac_size=fac_size, fac_rate=fac_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold) s2p = gr.stream_to_vector(gr.sizeof_float, self.fac_size) self.one_in_n = gr.keep_one_in_n( gr.sizeof_float * self.fac_size, max(1, int(self.sample_rate / self.fac_size / self.fac_rate))) # windowing removed... fac = gr.fft_vfc(self.fac_size, True, ()) c2mag = gr.complex_to_mag(self.fac_size) self.avg = gr.single_pole_iir_filter_ff(1.0, self.fac_size) fac_fac = gr.fft_vfc(self.fac_size, True, ()) fac_c2mag = gr.complex_to_mag(fac_size) # FIXME We need to add 3dB to all bins but the DC bin log = gr.nlog10_ff(20, self.fac_size, -20 * math.log10(self.fac_size)) sink = gr.message_sink(gr.sizeof_float * self.fac_size, self.msgq, True) self.connect(s2p, self.one_in_n, fac, c2mag, fac_fac, fac_c2mag, self.avg, log, sink) # gr.hier_block.__init__(self, fg, s2p, sink) self.win = fac_window(self, parent, size=size) self.set_average(self.average) self.wxgui_connect(self, s2p)
def __init__(self, parent, baseband_freq=0, y_per_div=10, ref_level=50, sample_rate=1, fac_size=512, fac_rate=default_fac_rate, average=False, avg_alpha=None, title='', size=default_facsink_size, peak_hold=False): fac_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, y_per_div=y_per_div, ref_level=ref_level, sample_rate=sample_rate, fac_size=fac_size, fac_rate=fac_rate, average=average, avg_alpha=avg_alpha, title=title, peak_hold=peak_hold) s2p = gr.stream_to_vector(gr.sizeof_gr_complex, self.fac_size) self.one_in_n = gr.keep_one_in_n( gr.sizeof_gr_complex * self.fac_size, max(1, int(self.sample_rate / self.fac_size / self.fac_rate))) # windowing removed ... fac = gr.fft_vcc(self.fac_size, True, ()) c2mag = gr.complex_to_mag(fac_size) # Things go off into the weeds if we try for an inverse FFT so a forward FFT will have to do... fac_fac = gr.fft_vfc(self.fac_size, True, ()) fac_c2mag = gr.complex_to_mag(fac_size) self.avg = gr.single_pole_iir_filter_ff(1.0, fac_size) log = gr.nlog10_ff(20, self.fac_size, -20 * math.log10( self.fac_size)) # - 20*math.log10(norm) ) # - self.avg[0] ) sink = gr.message_sink(gr.sizeof_float * fac_size, self.msgq, True) self.connect(s2p, self.one_in_n, fac, c2mag, fac_fac, fac_c2mag, self.avg, log, sink) # gr.hier_block2.__init__(self, fg, s2p, sink) self.win = fac_window(self, parent, size=size) self.set_average(self.average) self.wxgui_connect(self, s2p)
def test_002(self): src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = (0, 125, 359.375, 689.453125, 1103.271484, 1590.36255) src = gr.vector_source_f(src_data) op = gr.single_pole_iir_filter_ff (0.125) dst = gr.vector_sink_f() self.tb.connect (src, op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual (expected_result, result_data, 3)
def test_001(self): src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = src_data src = gr.vector_source_f(src_data) op = gr.single_pole_iir_filter_ff(1.0) dst = gr.vector_sink_f() self.tb.connect(src, op, dst) self.tb.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual(expected_result, result_data)
def test_001(self): src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = src_data src = gr.vector_source_f(src_data) op = gr.single_pole_iir_filter_ff (1.0) dst = gr.vector_sink_f() self.fg.connect (src, op, dst) self.fg.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual (expected_result, result_data)
def test_002(self): src_data = (0, 1000, 2000, 3000, 4000, 5000) expected_result = (0, 125, 359.375, 689.453125, 1103.271484, 1590.36255) src = gr.vector_source_f(src_data) op = gr.single_pole_iir_filter_ff (0.125) dst = gr.vector_sink_f() self.fg.connect (src, op, dst) self.fg.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual (expected_result, result_data, 3)
def __init__(self, *args, **kwargs): """ Hierarchical block for O-QPSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param sps: samples per symbol @type sps: integer """ try: self.sps = kwargs.pop('sps') self.log = kwargs.pop('log') except KeyError: pass gr.hier_block2.__init__(self, "ieee802_15_4_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input gr.io_signature(1, 1, gr.sizeof_float)) # Output # Demodulate FM sensitivity = (pi / 2) / self.sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0008/self.sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.connect(self, self.fmdemod) self.connect(self.fmdemod, (self.sub, 0)) self.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = self.sps gain_mu=0.03 mu=0.5 omega_relative_limit=0.0002 freq_error=0.0 gain_omega = .25*gain_mu*gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect self.connect(self.sub, self.clock_recovery, self) if self.log: self.connect(self.fmdemod, gr.file_sink(gr.sizeof_float, 'rx-fmdemod.dat')) self.connect(self.freq_offset, gr.file_sink(gr.sizeof_float, 'rx-fo.dat')) self.connect(self.sub, gr.file_sink(gr.sizeof_float, 'rx-sub.dat')) self.connect(self.clock_recovery, gr.file_sink(gr.sizeof_float, 'rx-recovery.dat'))
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 = gr.add_const_ff(0) # FIXME kludge self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) self.low_square = gr.multiply_ff() self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) self.hi_square = gr.multiply_ff() self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.sub = gr.sub_ff(); self.add = gr.add_ff(); self.gate = gr.threshold_ff(0.3,0.43,0) self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.div = gr.divide_ff() self.squelch_mult = gr.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): gr.top_block.__init__(self, "FSK Demod Demo") # Variables self.symbol_rate = symbol_rate = 125e3 self.samp_rate = samp_rate = symbol_rate self.f_center = f_center = 868e6 self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512 / sps self.bandwidth = bandwidth = 100e3 # Blocks self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(f_center, 0) self.uhd_usrp_source_0.set_gain(0, 0) self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0) self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1, )) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff( omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() self.sink = gr.vector_sink_b(1) self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log') # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self.uhd_usrp_source_0, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self.slice, self.file_sink) self.connect(self.slice, self.sink)
def main(): print os.getpid() tb = gr.top_block() u = gr.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 = gr.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 = gr.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 = gr.firdes.low_pass (1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, gr.firdes.WIN_HAMMING); lp_filter = gr.fir_filter_fff (1,lp_coeffs) alpha = 1e-5 iir = gr.single_pole_iir_filter_ff(alpha) remove_dc = gr.sub_ff() out = gr.file_sink(gr.sizeof_float,"/tmp/atsc_pipe_3") # out = gr.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 __init__(self, parent, baseband_freq=0, ref_level=0, sample_rate=1, fft_size=512, fft_rate=default_fft_rate, average=False, avg_alpha=None, title='', size=default_fftsink_size, report=None, span=40, ofunc=None, xydfunc=None): gr.hier_block2.__init__(self, "waterfall_sink_c", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) waterfall_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, sample_rate=sample_rate, fft_size=fft_size, fft_rate=fft_rate, average=average, avg_alpha=avg_alpha, title=title) s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, self.fft_size) self.one_in_n = gr.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) fft = gr.fft_vcc(self.fft_size, True, mywindow) c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) log = gr.nlog10_ff(20, self.fft_size, -20 * math.log10(self.fft_size)) sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) self.connect(self, s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) self.win = waterfall_window(self, parent, size=size, report=report, ref_level=ref_level, span=span, ofunc=ofunc, xydfunc=xydfunc) self.set_average(self.average)
def __init__(self, fg, sps=8, symbol_rate=38400, p_size=13): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param fg: flow graph @type fg: flow graph @param sps: samples per symbol @type sps: integer @param symbol_rate: symbols per second @type symbol_rate: float @param p_size: packet size @type p_size: integer """ # Demodulate FM sensitivity = (pi / 2) / sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1 / sensitivity) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0512 / sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() fg.connect(self.fmdemod, (self.sub, 0)) fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect fg.connect(self.sub, self.clock_recovery) #filesink = gr.file_sink(gr.sizeof_float, 'rx_fsk_test.dat') #fg.connect(self.clock_recovery, filesink) # Initialize base class gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery)
def __init__(self): gr.top_block.__init__(self, "FSK Demod Demo") # Variables self.symbol_rate = symbol_rate = 125e3 self.samp_rate = samp_rate = symbol_rate self.f_center = f_center = 868e6 self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512/sps self.bandwidth = bandwidth = 100e3 # Blocks self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(f_center, 0) self.uhd_usrp_source_0.set_gain(0, 0) self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0) self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1, )) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() self.sink = gr.vector_sink_b(1) self.file_sink = gr.file_sink(gr.sizeof_char, 'fsk_dump.log') # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self.uhd_usrp_source_0, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self.slice, self.file_sink) self.connect(self.slice, self.sink)
def main(): print os.getpid() tb = gr.top_block() u = gr.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 = gr.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 = gr.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 = gr.firdes.low_pass(1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, gr.firdes.WIN_HAMMING) lp_filter = gr.fir_filter_fff(1, lp_coeffs) alpha = 1e-5 iir = gr.single_pole_iir_filter_ff(alpha) remove_dc = gr.sub_ff() out = gr.file_sink(gr.sizeof_float, "/tmp/atsc_pipe_3") # out = gr.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 __init__(self, fg, sps = 8, symbol_rate = 38400, p_size = 13): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of bytes. @param fg: flow graph @type fg: flow graph @param sps: samples per symbol @type sps: integer @param symbol_rate: symbols per second @type symbol_rate: float @param p_size: packet size @type p_size: integer """ # Demodulate FM sensitivity = (pi / 2) / sps #self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) self.fmdemod = gr.quadrature_demod_cf(1 / sensitivity) # Low pass the output of fmdemod to allow us to remove # the DC offset resulting from frequency offset alpha = 0.0512/sps self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() fg.connect(self.fmdemod, (self.sub, 0)) fg.connect(self.fmdemod, self.freq_offset, (self.sub, 1)) # recover the clock omega = sps gain_mu=0.03 mu=0.5 omega_relative_limit=0.0002 freq_error=0.0 gain_omega = .25*gain_mu*gain_mu # critically damped self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_relative_limit) # Connect fg.connect(self.sub, self.clock_recovery) #filesink = gr.file_sink(gr.sizeof_float, 'rx_fsk_test.dat') #fg.connect(self.clock_recovery, filesink) # Initialize base class gr.hier_block.__init__(self, fg, self.fmdemod, self.clock_recovery)
def test_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 = gr.vector_source_f(src_data) s2p = gr.serial_to_parallel(gr.sizeof_float, block_size) op = gr.single_pole_iir_filter_ff (0.125, block_size) p2s = gr.parallel_to_serial(gr.sizeof_float, block_size) dst = gr.vector_sink_f() self.fg.connect (src, s2p, op, p2s, dst) self.fg.run() result_data = dst.data() self.assertFloatTuplesAlmostEqual (expected_result, result_data, 3)
def test_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 = gr.vector_source_f(src_data) s2p = gr.serial_to_parallel(gr.sizeof_float, block_size) op = gr.single_pole_iir_filter_ff(0.125, block_size) p2s = gr.parallel_to_serial(gr.sizeof_float, block_size) dst = gr.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, fg, audio_rate): self.input_node = gr.add_const_ff(0) # FIXME kludge self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) self.low_square = gr.multiply_ff() self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) self.hi_square = gr.multiply_ff() self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.sub = gr.sub_ff(); self.add = gr.add_ff(); self.gate = gr.threshold_ff(0.3,0.43,0) self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) self.div = gr.divide_ff() self.squelch_mult = gr.multiply_ff() fg.connect (self.input_node, (self.squelch_mult, 0)) fg.connect (self.input_node,self.low_iir) fg.connect (self.low_iir,(self.low_square,0)) fg.connect (self.low_iir,(self.low_square,1)) fg.connect (self.low_square,self.low_smooth,(self.sub,0)) fg.connect (self.low_smooth, (self.add,0)) fg.connect (self.input_node,self.hi_iir) fg.connect (self.hi_iir,(self.hi_square,0)) fg.connect (self.hi_iir,(self.hi_square,1)) fg.connect (self.hi_square,self.hi_smooth,(self.sub,1)) fg.connect (self.hi_smooth, (self.add,1)) fg.connect (self.sub, (self.div, 0)) fg.connect (self.add, (self.div, 1)) fg.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) gr.hier_block.__init__(self, fg, self.input_node, self.squelch_mult)
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. @param sample_rate Incoming stream sample rate @param fft_size Number of FFT bins @param ref_scale Sets 0 dB value input amplitude @param frame_rate Output frame rate @param avg_alpha FFT averaging (over time) constant [0.0-1.0] @param average Whether to average [True, False] @param 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 = 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 = gr.complex_to_mag_squared(fft_size) self._avg = gr.single_pole_iir_filter_ff(1.0, fft_size) self._log = gr.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, 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 = blks2.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 = gr.single_pole_iir_filter_ff(1.0, pspectrum_len) self._log = gr.nlog10_ff( 20, pspectrum_len, -20 * math.log10(pspectrum_len) - 20 * math.log10(ref_scale / 2) + 3.0, # Adjust for number of bins ) # 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, alpha=0.1, noise_mag=0): """ Parameters: alpha: float noise_mag: float """ gr.hier_block2.__init__( self, "Phase Noise Generator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_gr_complex), ) ################################################## # Parameters ################################################## self.alpha = alpha self.noise_mag = noise_mag ################################################## # Blocks ################################################## self.gr_transcendental_0_0 = gr.transcendental("sin", "float") self.gr_transcendental_0 = gr.transcendental("cos", "float") self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff( alpha, 1) self.gr_noise_source_x_0 = gr.noise_source_f(gr.GR_GAUSSIAN, noise_mag, 42) self.gr_multiply_xx_0 = gr.multiply_vcc(1) self.gr_float_to_complex_0 = gr.float_to_complex(1) ################################################## # Connections ################################################## self.connect((self.gr_float_to_complex_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_noise_source_x_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self, 0)) self.connect((self, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_transcendental_0, 0)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_transcendental_0_0, 0)) self.connect((self.gr_transcendental_0, 0), (self.gr_float_to_complex_0, 0)) self.connect((self.gr_transcendental_0_0, 0), (self.gr_float_to_complex_0, 1))
def __init__(self): gr.hier_block2.__init__(self, "rx_path", gr.io_signature(0, 0, 0), gr.io_signature(0, 0, 0)) self.frequency = 13.56e6 self.gain = 10 # USRP settings self.u_rx = usrp.source_c() #create the USRP source for RX #try and set the LF_RX for this rx_subdev_spec = usrp.pick_subdev(self.u_rx, (usrp_dbid.LF_RX, usrp_dbid.LF_TX)) #Configure the MUX for the daughterboard self.u_rx.set_mux( usrp.determine_rx_mux_value(self.u_rx, rx_subdev_spec)) #Tell it to use the LF_RX self.subdev_rx = usrp.selected_subdev(self.u_rx, rx_subdev_spec) #Make sure it worked print "Using RX dboard %s" % (self.subdev_rx.side_and_name(), ) #Set gain.. duh self.subdev_rx.set_gain(self.gain) #Tune the center frequency self.u_rx.tune(0, self.subdev_rx, self.frequency) adc_rate = self.u_rx.adc_rate() #64 MS/s usrp_decim = 256 self.u_rx.set_decim_rate(usrp_decim) #BW = 64 MS/s / decim = 64,000,000 / 256 = 250 kHz #Not sure if this decim rate exceeds USRP capabilities, #if it does then some software decim may have to be done as well usrp_rx_rate = adc_rate / usrp_decim self.iir = gr.single_pole_iir_filter_ff(.001) self.mag = gr.complex_to_mag() self.snk = gr.probe_signal_f() # dst = audio.sink (sample_rate, "") # stv = gr.stream_to_vector (gr.sizeof_float, fft_size) # c2m = gr.complex_to_mag_squared (fft_size) self.connect(self.u_rx, self.mag, self.iir, self.snk)
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/FFT_SIZE #options.fft_length self._fft_length = FFT_SIZE #options.fft_length self._occupied_tones = FFT_SIZE #options.occupied_tones self.msgq = gr.msg_queue() # linklab , setup the sensing path # FIXME: some components are not necessary self.s2p = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) mywindow = window.blackmanharris(self.fft_size) self.fft = gr.fft_vcc(self.fft_size, True, mywindow) power = 0 for tap in mywindow: power += tap*tap self.c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.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 = gr.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 = gr.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): gr.hier_block2.__init__(self, "rx_path", gr.io_signature(0, 0, 0), gr.io_signature(0, 0, 0)) self.frequency = 13.56e6 self.gain = 10 # USRP settings self.u_rx = usrp.source_c() #create the USRP source for RX #try and set the LF_RX for this rx_subdev_spec = usrp.pick_subdev(self.u_rx, (usrp_dbid.LF_RX, usrp_dbid.LF_TX)) #Configure the MUX for the daughterboard self.u_rx.set_mux(usrp.determine_rx_mux_value(self.u_rx, rx_subdev_spec)) #Tell it to use the LF_RX self.subdev_rx = usrp.selected_subdev(self.u_rx, rx_subdev_spec) #Make sure it worked print "Using RX dboard %s" % (self.subdev_rx.side_and_name(),) #Set gain.. duh self.subdev_rx.set_gain(self.gain) #Tune the center frequency self.u_rx.tune(0, self.subdev_rx, self.frequency) adc_rate = self.u_rx.adc_rate() #64 MS/s usrp_decim = 256 self.u_rx.set_decim_rate(usrp_decim) #BW = 64 MS/s / decim = 64,000,000 / 256 = 250 kHz #Not sure if this decim rate exceeds USRP capabilities, #if it does then some software decim may have to be done as well usrp_rx_rate = adc_rate / usrp_decim self.iir = gr.single_pole_iir_filter_ff(.001) self.mag = gr.complex_to_mag() self.snk = gr.probe_signal_f() # dst = audio.sink (sample_rate, "") # stv = gr.stream_to_vector (gr.sizeof_float, fft_size) # c2m = gr.complex_to_mag_squared (fft_size) self.connect(self.u_rx, self.mag, self.iir, self.snk)
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 = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) self.one_in_n = gr.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 = gr.fft_vcc(self.fft_size, True, mywindow) power = 0 for tap in mywindow: power += tap*tap self.c2mag = gr.complex_to_mag(self.fft_size) self.avg = gr.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 = gr.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 = 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 = 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): """ Hierarchical block for FSK demodulation. The input is the complex modulated signal at baseband and the output is a stream of floats. """ # Initialize base class gr.hier_block2.__init__(self, "fsk_demod", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) # Variables self.sps = sps = 2 self.sensitivity = sensitivity = (pi / 2) / sps self.alpha = alpha = 0.0512 / sps self.fm_demod = gr.quadrature_demod_cf(1 / sensitivity) self.freq_offset = gr.single_pole_iir_filter_ff(alpha) self.sub = gr.sub_ff() self.add = gr.add_ff() self.multiply = gr.multiply_ff() self.invert = gr.multiply_const_vff((-1, )) # recover the clock omega = sps gain_mu = 0.03 mu = 0.5 omega_relative_limit = 0.0002 freq_error = 0.0 gain_omega = .25 * gain_mu * gain_mu # critically damped self.clock_recovery = digital.clock_recovery_mm_ff( omega, gain_omega, mu, gain_mu, omega_relative_limit) self.slice = digital.binary_slicer_fb() # Connections self.connect(self.fm_demod, (self.add, 0)) self.connect(self.fm_demod, self.freq_offset, (self.add, 1)) self.connect(self, self.fm_demod) self.connect(self.add, self.clock_recovery, self.invert, self)
def __init__(self, samp_rate=1600000, samp_per_sym=16, freq_error=-0.0025000): gr.hier_block2.__init__( self, "Wireless M-Bus Demod", gr.io_signature(1, 1, gr.sizeof_gr_complex*1), gr.io_signature(1, 1, gr.sizeof_char*1), ) ################################################## # Parameters ################################################## self.samp_rate = samp_rate self.samp_per_sym = samp_per_sym self.freq_error = freq_error ################################################## # Variables ################################################## self.cutoff = cutoff = 120e3 self.chip_rate = chip_rate = samp_rate/samp_per_sym ################################################## # Blocks ################################################## self.low_pass_filter_0 = gr.fir_filter_ccf(1, firdes.low_pass( 1, samp_rate, cutoff, cutoff/2, firdes.WIN_HAMMING, 6.76)) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(0.0512/samp_per_sym, 1) self.gr_quadrature_demod_cf_0 = gr.quadrature_demod_cf(1) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff(samp_per_sym*(1+freq_error), .25 *0.06*0.06*4, 0.5, 0.06*2, 0.002*2) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() ################################################## # Connections ################################################## self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.gr_quadrature_demod_cf_0, 0), (self.gr_sub_xx_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.gr_quadrature_demod_cf_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self, 0)) self.connect((self, 0), (self.low_pass_filter_0, 0))
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 = gr.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, fs, fd, svn, alpha, dump_bins=False): fft_size = int(1e-3 * fs) gr.hier_block2.__init__( self, "single_channel_correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex * fft_size), gr.io_signature(1, 1, gr.sizeof_float * fft_size)) lc = local_code(svn=svn, fs=fs, fd=fd) mult = gr.multiply_vcc(fft_size) ifft = gr.fft_vcc(fft_size, False, []) mag = gr.complex_to_mag_squared(fft_size) self.iir = gr.single_pole_iir_filter_ff(alpha, fft_size) self.connect(self, (mult, 0)) self.connect(lc, (mult, 1)) self.connect(mult, ifft, mag, self.iir, self) if dump_bins == True: self.connect_debug_sink(self.iir, fft_size, '/home/trondd/opengnss_output', fd)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="APRS Receiver") ################################################## # Variables ################################################## self.space = space = 1200 self.mark = mark = 2200 self.xlate_decim = xlate_decim = 8 self.xlate_bandwidth = xlate_bandwidth = 1200 * 6 self.sym_dev = sym_dev = (mark - space) / 2 self.samp_rate = samp_rate = 1e6 self.quad_rate = quad_rate = 96000 self.gain = gain = 10 self.freq_offset = freq_offset = 390e3 self.freq = freq = 144e6 self.baud = baud = 1200 self.audio_rate = audio_rate = 48000 self.audio_mul = audio_mul = 1 self.aprs_rate = aprs_rate = 12000 self.ant = ant = 'TX/RX' ################################################## # Message Queues ################################################## ax25_hdlc_framer_b_0_msgq_out = ax25_print_frame_0_msgq_in = gr.msg_queue( 2) ################################################## # Blocks ################################################## self.nb = self.nb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.nb.AddPage(grc_wxgui.Panel(self.nb), "Baseband") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Waterfall") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Signal") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Slicer") self.nb.AddPage(grc_wxgui.Panel(self.nb), "Eye") self.Add(self.nb) _gain_sizer = wx.BoxSizer(wx.VERTICAL) self._gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._gain_slider = forms.slider( parent=self.GetWin(), sizer=_gain_sizer, value=self.gain, callback=self.set_gain, minimum=0, maximum=50, num_steps=50, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_gain_sizer) _freq_offset_sizer = wx.BoxSizer(wx.VERTICAL) self._freq_offset_text_box = forms.text_box( parent=self.GetWin(), sizer=_freq_offset_sizer, value=self.freq_offset, callback=self.set_freq_offset, label="Freq Offset", converter=forms.float_converter(), proportion=0, ) self._freq_offset_slider = forms.slider( parent=self.GetWin(), sizer=_freq_offset_sizer, value=self.freq_offset, callback=self.set_freq_offset, minimum=-500e3, maximum=500e3, num_steps=1000, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_freq_offset_sizer) self._freq_text_box = forms.text_box( parent=self.GetWin(), value=self.freq, callback=self.set_freq, label="Freq", converter=forms.float_converter(), ) self.Add(self._freq_text_box) _audio_mul_sizer = wx.BoxSizer(wx.VERTICAL) self._audio_mul_text_box = forms.text_box( parent=self.GetWin(), sizer=_audio_mul_sizer, value=self.audio_mul, callback=self.set_audio_mul, label="Audio", converter=forms.float_converter(), proportion=0, ) self._audio_mul_slider = forms.slider( parent=self.GetWin(), sizer=_audio_mul_sizer, value=self.audio_mul, callback=self.set_audio_mul, minimum=0, maximum=10, num_steps=1000, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_audio_mul_sizer) self._ant_chooser = forms.drop_down( parent=self.GetWin(), value=self.ant, callback=self.set_ant, label="Antenna", choices=['TX/RX', 'RX2'], labels=[], ) self.Add(self._ant_chooser) self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c( self.nb.GetPage(1).GetWin(), baseband_freq=0, dynamic_range=50, ref_level=-65, ref_scale=2.0, sample_rate=aprs_rate, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", ) self.nb.GetPage(1).Add(self.wxgui_waterfallsink2_0.win) self.wxgui_scopesink2_0_0_0 = scopesink2.scope_sink_f( self.nb.GetPage(4).GetWin(), title="Scope Plot", sample_rate=aprs_rate / 10, v_scale=0.5, v_offset=0, t_scale=0.002, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(4).Add(self.wxgui_scopesink2_0_0_0.win) self.wxgui_scopesink2_0_0 = scopesink2.scope_sink_f( self.nb.GetPage(3).GetWin(), title="Scope Plot", sample_rate=aprs_rate, v_scale=0.5, v_offset=0, t_scale=0.002, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(3).Add(self.wxgui_scopesink2_0_0.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.nb.GetPage(2).GetWin(), title="Scope Plot", sample_rate=aprs_rate, v_scale=0.05, v_offset=0, t_scale=0.002, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.nb.GetPage(2).Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.nb.GetPage(0).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=-20, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=True, avg_alpha=0.5, title="FFT Plot", peak_hold=False, ) self.nb.GetPage(0).Add(self.wxgui_fftsink2_0.win) def wxgui_fftsink2_0_callback(x, y): self.set_freq_offset(x) self.wxgui_fftsink2_0.set_callback(wxgui_fftsink2_0_callback) self.uhd_usrp_source_0 = uhd.usrp_source( device_addr="", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_source_0.set_samp_rate(samp_rate) self.uhd_usrp_source_0.set_center_freq(freq, 0) self.uhd_usrp_source_0.set_gain(gain, 0) self.uhd_usrp_source_0.set_antenna(ant, 0) self.low_pass_filter_0 = gr.fir_filter_ccf( 1, firdes.low_pass(1, aprs_rate, 2e3, 600, firdes.WIN_HAMMING, 6.76)) self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff( 0.0001, 1) self.gr_null_sink_0 = gr.null_sink(gr.sizeof_float * 1) self.gr_multiply_xx_0 = gr.multiply_vcc(1) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((audio_mul, )) self.gr_agc_xx_1 = gr.agc_ff(1e-3, 0.8, 0.1, 10.0) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc( xlate_decim, (firdes.low_pass(1, samp_rate, xlate_bandwidth / 2, 1000)), freq_offset, samp_rate) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_ff( 10, .25 * (0.05)**2, 0.5, 0.005, 0.005) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blks2_rational_resampler_xxx_0_0 = blks2.rational_resampler_ccc( interpolation=quad_rate, decimation=int(samp_rate / xlate_decim), taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_ccc( interpolation=aprs_rate, decimation=quad_rate, taps=None, fractional_bw=None, ) self.blks2_nbfm_rx_0_0 = blks2.nbfm_rx( audio_rate=audio_rate, quad_rate=quad_rate, tau=75e-6, max_dev=25000, ) self.blks2_nbfm_rx_0 = blks2.nbfm_rx( audio_rate=aprs_rate, quad_rate=quad_rate, tau=75e-6, max_dev=3e3, ) self.ax25_print_frame_0 = packetradio.queue_watcher_thread( ax25_print_frame_0_msgq_in) self.ax25_hdlc_framer_b_0 = packetradio.hdlc_framer( ax25_hdlc_framer_b_0_msgq_out, False) self.analog_sig_source_x_0 = analog.sig_source_c( aprs_rate, analog.GR_SIN_WAVE, -(min(mark, space) + sym_dev), 1, 0) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf( aprs_rate / (2 * math.pi * sym_dev)) self.analog_pwr_squelch_xx_0_0_0 = analog.pwr_squelch_cc( -70, 1e-1, 0, False) self.analog_pwr_squelch_xx_0_0 = analog.pwr_squelch_cc( -70, 1e-1, 0, False) ################################################## # Connections ################################################## self.connect((self.uhd_usrp_source_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.blks2_rational_resampler_xxx_0_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.wxgui_waterfallsink2_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.blocks_float_to_complex_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.blks2_nbfm_rx_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blks2_nbfm_rx_0, 0), (self.blocks_float_to_complex_0, 1)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.wxgui_scopesink2_0_0_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.ax25_hdlc_framer_b_0, 0)) self.connect((self.blks2_nbfm_rx_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0_0, 0), (self.analog_pwr_squelch_xx_0_0, 0)) self.connect((self.analog_pwr_squelch_xx_0_0_0, 0), (self.blks2_nbfm_rx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0_0, 0), (self.analog_pwr_squelch_xx_0_0_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.wxgui_scopesink2_0_0, 0)) self.connect((self.blks2_nbfm_rx_0_0, 0), (self.gr_agc_xx_1, 0)) self.connect((self.analog_pwr_squelch_xx_0_0, 0), (self.blks2_nbfm_rx_0_0, 0)) self.connect((self.gr_agc_xx_1, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.gr_null_sink_0, 0))
def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel parser = OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0), help="select USRP Rx side A or B (default=A)") parser.add_option( "-d", "--decim", type="int", default=16, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=None, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-Q", "--observing", type="eng_float", default=0.0, help="set observing frequency to FREQ") parser.add_option("-a", "--avg", type="eng_float", default=1.0, help="set spectral averaging alpha") parser.add_option("-V", "--favg", type="eng_float", default=2.0, help="set folder averaging alpha") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-l", "--reflevel", type="eng_float", default=30.0, help="Set pulse display reference level") parser.add_option("-L", "--lowest", type="eng_float", default=1.5, help="Lowest valid frequency bin") parser.add_option("-e", "--longitude", type="eng_float", default=-76.02, help="Set Observer Longitude") parser.add_option("-c", "--latitude", type="eng_float", default=44.85, help="Set Observer Latitude") parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT") parser.add_option("-t", "--threshold", type="eng_float", default=2.5, help="pulsar threshold") parser.add_option("-p", "--lowpass", type="eng_float", default=100, help="Pulse spectra cutoff freq") parser.add_option("-P", "--prefix", default="./", help="File prefix") parser.add_option("-u", "--pulsefreq", type="eng_float", default=0.748, help="Observation pulse rate") parser.add_option("-D", "--dm", type="eng_float", default=1.0e-5, help="Dispersion Measure") parser.add_option("-O", "--doppler", type="eng_float", default=1.0, help="Doppler ratio") parser.add_option("-B", "--divbase", type="eng_float", default=20, help="Y/Div menu base") parser.add_option("-I", "--division", type="eng_float", default=100, help="Y/Div") parser.add_option("-A", "--audio_source", default="plughw:0,0", help="Audio input device spec") parser.add_option("-N", "--num_pulses", default=1, type="eng_float", help="Number of display pulses") (options, args) = parser.parse_args() if len(args) != 0: parser.print_help() sys.exit(1) self.show_debug_info = True self.reflevel = options.reflevel self.divbase = options.divbase self.division = options.division self.audiodev = options.audio_source self.mult = int(options.num_pulses) # Low-pass cutoff for post-detector filter # Set to 100Hz usually, since lots of pulsars fit in this # range self.lowpass = options.lowpass # What is lowest valid frequency bin in post-detector FFT? # There's some pollution very close to DC self.lowest_freq = options.lowest # What (dB) threshold to use in determining spectral candidates self.threshold = options.threshold # Filename prefix for recording file self.prefix = options.prefix # Dispersion Measure (DM) self.dm = options.dm # Doppler shift, as a ratio # 1.0 == no doppler shift # 1.005 == a little negative shift # 0.995 == a little positive shift self.doppler = options.doppler # # Input frequency and observing frequency--not necessarily the # same thing, if we're looking at the IF of some downconverter # that's ahead of the USRP and daughtercard. This distinction # is important in computing the correct de-dispersion filter. # self.frequency = options.freq if options.observing <= 0: self.observing_freq = options.freq else: self.observing_freq = options.observing # build the graph self.u = usrp.source_c(decim_rate=options.decim) self.u.set_mux( usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) # # Recording file, in case we ever need to record baseband data # self.recording = gr.file_sink(gr.sizeof_char, "/dev/null") self.recording_state = False self.pulse_recording = gr.file_sink(gr.sizeof_short, "/dev/null") self.pulse_recording_state = False # # We come up with recording turned off, but the user may # request recording later on self.recording.close() self.pulse_recording.close() # # Need these two for converting 12-bit baseband signals to 8-bit # self.tofloat = gr.complex_to_float() self.tochar = gr.float_to_char() # Need this for recording pulses (post-detector) self.toshort = gr.float_to_short() # # The spectral measurer sets this when it has a valid # average spectral peak-to-peak distance # We can then use this to program the parameters for the epoch folder # # We set a sentimental value here self.pulse_freq = options.pulsefreq # Folder runs at this raw sample rate self.folder_input_rate = 20000 # Each pulse in the epoch folder is sampled at 128 times the nominal # pulse rate self.folding = 128 # # Try to find candidate parameters for rational resampler # save_i = 0 candidates = [] for i in range(20, 300): input_rate = self.folder_input_rate output_rate = int(self.pulse_freq * i) interp = gru.lcm(input_rate, output_rate) / input_rate decim = gru.lcm(input_rate, output_rate) / output_rate if (interp < 500 and decim < 250000): candidates.append(i) # We didn't find anything, bail! if (len(candidates) < 1): print "Couldn't converge on resampler parameters" sys.exit(1) # # Now try to find candidate with the least sampling error # mindiff = 999.999 for i in candidates: diff = self.pulse_freq * i diff = diff - int(diff) if (diff < mindiff): mindiff = diff save_i = i # Recompute rates input_rate = self.folder_input_rate output_rate = int(self.pulse_freq * save_i) # Compute new interp and decim, based on best candidate interp = gru.lcm(input_rate, output_rate) / input_rate decim = gru.lcm(input_rate, output_rate) / output_rate # Save optimized folding parameters, used later self.folding = save_i self.interp = int(interp) self.decim = int(decim) # So that we can view N pulses in the pulse viewer window FOLD_MULT = self.mult # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) self.cardtype = self.u.daughterboard_id(0) # Compute raw input rate input_rate = self.u.adc_freq() / self.u.decim_rate() # BW==input_rate for complex data self.bw = input_rate # # Set baseband filter bandwidth if DBS_RX: # if self.cardtype == usrp_dbid.DBS_RX: lbw = input_rate / 2 if lbw < 1.0e6: lbw = 1.0e6 self.subdev.set_bw(lbw) # # We use this as a crude volume control for the audio output # #self.volume = gr.multiply_const_ff(10**(-1)) # # Create location data for ephem package # self.locality = ephem.Observer() self.locality.long = str(options.longitude) self.locality.lat = str(options.latitude) # # What is the post-detector LPF cutoff for the FFT? # PULSAR_MAX_FREQ = int(options.lowpass) # First low-pass filters down to input_rate/FIRST_FACTOR # and decimates appropriately FIRST_FACTOR = int(input_rate / (self.folder_input_rate / 2)) first_filter = gr.firdes.low_pass(1.0, input_rate, input_rate / FIRST_FACTOR, input_rate / (FIRST_FACTOR * 20), gr.firdes.WIN_HAMMING) # Second filter runs at the output rate of the first filter, # And low-pass filters down to PULSAR_MAX_FREQ*10 # second_input_rate = int(input_rate / (FIRST_FACTOR / 2)) second_filter = gr.firdes.band_pass(1.0, second_input_rate, 0.10, PULSAR_MAX_FREQ * 10, PULSAR_MAX_FREQ * 1.5, gr.firdes.WIN_HAMMING) # Third filter runs at PULSAR_MAX_FREQ*20 # and filters down to PULSAR_MAX_FREQ # third_input_rate = PULSAR_MAX_FREQ * 20 third_filter = gr.firdes_band_pass(1.0, third_input_rate, 0.10, PULSAR_MAX_FREQ, PULSAR_MAX_FREQ / 10.0, gr.firdes.WIN_HAMMING) # # Create the appropriate FFT scope # self.scope = ra_fftsink.ra_fft_sink_f(panel, fft_size=int(options.fft_size), sample_rate=PULSAR_MAX_FREQ * 2, title="Post-detector spectrum", ofunc=self.pulsarfunc, xydfunc=self.xydfunc, fft_rate=200) # # Tell scope we're looking from DC to PULSAR_MAX_FREQ # self.scope.set_baseband_freq(0.0) # # Setup stripchart for showing pulse profiles # hz = "%5.3fHz " % self.pulse_freq per = "(%5.3f sec)" % (1.0 / self.pulse_freq) sr = "%d sps" % (int(self.pulse_freq * self.folding)) times = " %d Pulse Intervals" % self.mult self.chart = ra_stripchartsink.stripchart_sink_f( panel, sample_rate=1, stripsize=self.folding * FOLD_MULT, parallel=True, title="Pulse Profiles: " + hz + per + times, xlabel="Seconds @ " + sr, ylabel="Level", autoscale=True, divbase=self.divbase, scaling=1.0 / (self.folding * self.pulse_freq)) self.chart.set_ref_level(self.reflevel) self.chart.set_y_per_div(self.division) # De-dispersion filter setup # # Do this here, just before creating the filter # that will use the taps. # ntaps = self.compute_disp_ntaps(self.dm, self.bw, self.observing_freq) # Taps for the de-dispersion filter self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64) # Compute the de-dispersion filter now self.compute_dispfilter(self.dm, self.doppler, self.bw, self.observing_freq) # # Call constructors for receive chains # # # Now create the FFT filter using the computed taps self.dispfilt = gr.fft_filter_ccc(1, self.disp_taps) # # Audio sink # #print "input_rate ", second_input_rate, "audiodev ", self.audiodev #self.audio = audio.sink(second_input_rate, self.audiodev) # # The three post-detector filters # Done this way to allow an audio path (up to 10Khz) # ...and also because going from xMhz down to ~100Hz # In a single filter doesn't seem to work. # self.first = gr.fir_filter_fff(FIRST_FACTOR / 2, first_filter) p = second_input_rate / (PULSAR_MAX_FREQ * 20) self.second = gr.fir_filter_fff(int(p), second_filter) self.third = gr.fir_filter_fff(10, third_filter) # Detector self.detector = gr.complex_to_mag_squared() self.enable_comb_filter = False # Epoch folder comb filter if self.enable_comb_filter == True: bogtaps = Numeric.zeros(512, Numeric.Float64) self.folder_comb = gr.fft_filter_ccc(1, bogtaps) # Rational resampler self.folder_rr = blks2.rational_resampler_fff(self.interp, self.decim) # Epoch folder bandpass bogtaps = Numeric.zeros(1, Numeric.Float64) self.folder_bandpass = gr.fir_filter_fff(1, bogtaps) # Epoch folder F2C/C2F self.folder_f2c = gr.float_to_complex() self.folder_c2f = gr.complex_to_float() # Epoch folder S2P self.folder_s2p = gr.serial_to_parallel(gr.sizeof_float, self.folding * FOLD_MULT) # Epoch folder IIR Filter (produces average pulse profiles) self.folder_iir = gr.single_pole_iir_filter_ff( 1.0 / options.favg, self.folding * FOLD_MULT) # # Set all the epoch-folder goop up # self.set_folding_params() # # Start connecting configured modules in the receive chain # # Connect raw USRP to de-dispersion filter, detector self.connect(self.u, self.dispfilt, self.detector) # Connect detector output to FIR LPF # in two stages, followed by the FFT scope self.connect(self.detector, self.first, self.second, self.third, self.scope) # Connect audio output #self.connect(self.first, self.volume) #self.connect(self.volume, (self.audio, 0)) #self.connect(self.volume, (self.audio, 1)) # Connect epoch folder if self.enable_comb_filter == True: self.connect(self.first, self.folder_bandpass, self.folder_rr, self.folder_f2c, self.folder_comb, self.folder_c2f, self.folder_s2p, self.folder_iir, self.chart) else: self.connect(self.first, self.folder_bandpass, self.folder_rr, self.folder_s2p, self.folder_iir, self.chart) # Connect baseband recording file (initially /dev/null) self.connect(self.u, self.tofloat, self.tochar, self.recording) # Connect pulse recording file (initially /dev/null) self.connect(self.first, self.toshort, self.pulse_recording) # # Build the GUI elements # self._build_gui(vbox) # Make GUI agree with command-line self.myform['average'].set_value(int(options.avg)) self.myform['foldavg'].set_value(int(options.favg)) # Make spectral averager agree with command line if options.avg != 1.0: self.scope.set_avg_alpha(float(1.0 / options.avg)) self.scope.set_average(True) # set initial values if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.subdev.gain_range() options.gain = float(g[0] + g[1]) / 2 if options.freq is None: # if no freq was specified, use the mid-point r = self.subdev.freq_range() options.freq = float(r[0] + r[1]) / 2 self.set_gain(options.gain) #self.set_volume(-10.0) if not (self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency") self.myform['decim'].set_value(self.u.decim_rate()) self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) self.myform['dbname'].set_value(self.subdev.name()) self.myform['DM'].set_value(self.dm) self.myform['Doppler'].set_value(self.doppler) # # Start the timer that shows current LMST on the GUI # self.lmst_timer.Start(1000)
def __init__(self, subc, vlen, ss): gr.hier_block2.__init__( self, "new_snr_estimator", gr.io_signature(2, 2, gr.sizeof_gr_complex * vlen), #gr.io_signature2(2,2,gr.sizeof_float*vlen,gr.sizeof_float*vlen/ss*(ss-1))) gr.io_signature2(2, 2, gr.sizeof_float * vlen, gr.sizeof_float)) print "Created Milan's SINR estimator 3" # trigger = [0]*vlen # trigger[0] = 1 # # v = range (vlen/ss) # ones_ind= map(lambda z: z*ss,v) # # skip2_pr0 = skip(gr.sizeof_gr_complex,vlen) # skip2_pr1 = skip(gr.sizeof_gr_complex,vlen) # for x in ones_ind: # skip2_pr0.skip(x) # skip2_pr1.skip(x) # # #print "skipped ones",ones_ind # # v2s_pr0 = gr.vector_to_stream(gr.sizeof_gr_complex,vlen) # v2s_pr1 = gr.vector_to_stream(gr.sizeof_gr_complex,vlen) # # s2v2_pr0 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1)) # trigger_src_2_pr0 = gr.vector_source_b(trigger,True) # s2v2_pr1 = gr.stream_to_vector(gr.sizeof_gr_complex,vlen/ss*(ss-1)) # trigger_src_2_pr1 = gr.vector_source_b(trigger,True) # # mag_sq_zeros_pr0 = gr.complex_to_mag_squared(vlen/ss*(ss-1)) # mag_sq_zeros_pr1 = gr.complex_to_mag_squared(vlen/ss*(ss-1)) # # # filt_zeros_pr0 = gr.single_pole_iir_filter_ff(0.01,vlen/ss*(ss-1)) # filt_zeros_pr1 = gr.single_pole_iir_filter_ff(0.01,vlen/ss*(ss-1)) # v1 = vlen/ss*(ss-1) # vevc1 =[-1]*v1 # neg_nomin_z = gr.multiply_const_vff(vevc1) # div_z=gr.divide_ff(vlen/ss*(ss-1)) # on_zeros = gr.add_const_vff(vevc1) # sum_zeros = add_vff(vlen/ss*(ss-1)) # # For average #sum_all = vector_sum_vff(vlen) #mult = gr.multiply_const_ff(1./vlen) scsnr_db_av = gr.nlog10_ff(10, 1, 0) filt_end_av = gr.single_pole_iir_filter_ff(0.1) # # # self.connect((self,0),v2s_pr0,skip2_pr0,s2v2_pr0,mag_sq_zeros_pr0,filt_zeros_pr0) # self.connect(trigger_src_2_pr0,(skip2_pr0,1)) # # # # self.connect((self,1),v2s_pr1,skip2_pr1,s2v2_pr1,mag_sq_zeros_pr1,filt_zeros_pr1) # self.connect(trigger_src_2_pr1,(skip2_pr1,1)) # # # # On zeros # self.connect(filt_zeros_pr1,(sum_zeros,0)) # self.connect(filt_zeros_pr0,neg_nomin_z,(sum_zeros,1)) # self.connect(sum_zeros,div_z) # self.connect(filt_zeros_pr0,(div_z,1)) estimator = sinr_estimator2(vlen, ss) scsnr_db = gr.nlog10_ff(10, vlen, 0) filt_end = gr.single_pole_iir_filter_ff(0.1, vlen) dd = [] for i in range(vlen / ss): dd.extend([i * ss]) #print dd #interpolator = sinr_interpolator(vlen, ss,dd) self.connect((self, 0), (estimator, 0)) self.connect((self, 1), (estimator, 1)) self.connect(estimator, filt_end, scsnr_db, self) self.connect((estimator, 1), scsnr_db_av, filt_end_av, (self, 1))
def __init__(self, devid="type=b100", rdsfile="rds_fifo", gain=35.0, freq=101.1e6, xmlport=13777, arate=int(48e3), mute=-15.0, ftune=0, ant="J1", subdev="A:0", ahw="pulse", deemph=75.0e-6, prenames='["UWRF","89.3","950","WEVR"]', prefreqs="[88.715e6,89.3e6,950.735e6,106.317e6]", volume=1.0): grc_wxgui.top_block_gui.__init__(self, title="Simple FM (Stereo) Receiver") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.devid = devid self.rdsfile = rdsfile self.gain = gain self.freq = freq self.xmlport = xmlport self.arate = arate self.mute = mute self.ftune = ftune self.ant = ant self.subdev = subdev self.ahw = ahw self.deemph = deemph self.prenames = prenames self.prefreqs = prefreqs self.volume = volume ################################################## # Variables ################################################## self.pthresh = pthresh = 350 self.preselect = preselect = eval(prefreqs)[0] self.pilot_level = pilot_level = 0 self.ifreq = ifreq = freq self.stpilotdet = stpilotdet = True if (pilot_level > pthresh) else False self.stereo = stereo = True self.rf_pwr_lvl = rf_pwr_lvl = 0 self.cur_freq = cur_freq = simple_fm_helper.freq_select(ifreq,preselect) self.vol = vol = volume self.variable_static_text_0 = variable_static_text_0 = 10.0*math.log(rf_pwr_lvl+1.0e-11)/math.log(10) self.tone_med = tone_med = 5 self.tone_low = tone_low = 5 self.tone_high = tone_high = 5 self.stereo_0 = stereo_0 = stpilotdet self.st_enabled = st_enabled = 1 if (stereo == True and pilot_level > pthresh) else 0 self.squelch_probe = squelch_probe = 0 self.sq_thresh = sq_thresh = mute self.samp_rate = samp_rate = 250e3 self.rtext_0 = rtext_0 = cur_freq self.record = record = False self.rdsrate = rdsrate = 25e3 self.osmo_taps = osmo_taps = firdes.low_pass(1.0,1.00e6,95e3,20e3,firdes.WIN_HAMMING,6.76) self.mod_reset = mod_reset = 0 self.igain = igain = gain self.fine = fine = ftune self.farate = farate = arate self.dm = dm = deemph self.discrim_dc = discrim_dc = 0 self.capture_file = capture_file = "capture.wav" self.asrate = asrate = 125e3 ################################################## # Blocks ################################################## _sq_thresh_sizer = wx.BoxSizer(wx.VERTICAL) self._sq_thresh_text_box = forms.text_box( parent=self.GetWin(), sizer=_sq_thresh_sizer, value=self.sq_thresh, callback=self.set_sq_thresh, label="Mute Level", converter=forms.float_converter(), proportion=0, ) self._sq_thresh_slider = forms.slider( parent=self.GetWin(), sizer=_sq_thresh_sizer, value=self.sq_thresh, callback=self.set_sq_thresh, minimum=-30.0, maximum=-5.0, num_steps=40, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_sq_thresh_sizer, 1, 5, 1, 1) self.input_power = gr.probe_avg_mag_sqrd_c(sq_thresh, 1.0/(samp_rate/10)) self.dc_level = gr.probe_signal_f() _vol_sizer = wx.BoxSizer(wx.VERTICAL) self._vol_text_box = forms.text_box( parent=self.GetWin(), sizer=_vol_sizer, value=self.vol, callback=self.set_vol, label="Volume", converter=forms.float_converter(), proportion=0, ) self._vol_slider = forms.slider( parent=self.GetWin(), sizer=_vol_sizer, value=self.vol, callback=self.set_vol, minimum=0, maximum=11, num_steps=110, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_vol_sizer, 0, 3, 1, 1) _tone_med_sizer = wx.BoxSizer(wx.VERTICAL) self._tone_med_text_box = forms.text_box( parent=self.GetWin(), sizer=_tone_med_sizer, value=self.tone_med, callback=self.set_tone_med, label="1Khz-4Khz", converter=forms.float_converter(), proportion=0, ) self._tone_med_slider = forms.slider( parent=self.GetWin(), sizer=_tone_med_sizer, value=self.tone_med, callback=self.set_tone_med, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_tone_med_sizer, 1, 3, 1, 1) _tone_low_sizer = wx.BoxSizer(wx.VERTICAL) self._tone_low_text_box = forms.text_box( parent=self.GetWin(), sizer=_tone_low_sizer, value=self.tone_low, callback=self.set_tone_low, label="0-1Khz", converter=forms.float_converter(), proportion=0, ) self._tone_low_slider = forms.slider( parent=self.GetWin(), sizer=_tone_low_sizer, value=self.tone_low, callback=self.set_tone_low, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_tone_low_sizer, 1, 2, 1, 1) _tone_high_sizer = wx.BoxSizer(wx.VERTICAL) self._tone_high_text_box = forms.text_box( parent=self.GetWin(), sizer=_tone_high_sizer, value=self.tone_high, callback=self.set_tone_high, label="4Khz-15Khz", converter=forms.float_converter(), proportion=0, ) self._tone_high_slider = forms.slider( parent=self.GetWin(), sizer=_tone_high_sizer, value=self.tone_high, callback=self.set_tone_high, minimum=0, maximum=10, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_tone_high_sizer, 1, 4, 1, 1) def _squelch_probe_probe(): while True: val = self.input_power.unmuted() try: self.set_squelch_probe(val) except AttributeError, e: pass time.sleep(1.0/(10)) _squelch_probe_thread = threading.Thread(target=_squelch_probe_probe) _squelch_probe_thread.daemon = True _squelch_probe_thread.start() self._record_check_box = forms.check_box( parent=self.GetWin(), value=self.record, callback=self.set_record, label="Record Audio", true=True, false=False, ) self.GridAdd(self._record_check_box, 2, 2, 1, 1) self.pilot_probe = gr.probe_signal_f() _fine_sizer = wx.BoxSizer(wx.VERTICAL) self._fine_text_box = forms.text_box( parent=self.GetWin(), sizer=_fine_sizer, value=self.fine, callback=self.set_fine, label="Fine Tuning", converter=forms.float_converter(), proportion=0, ) self._fine_slider = forms.slider( parent=self.GetWin(), sizer=_fine_sizer, value=self.fine, callback=self.set_fine, minimum=-50.0e3, maximum=50.e03, num_steps=400, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_fine_sizer, 1, 0, 1, 1) def _discrim_dc_probe(): while True: val = self.dc_level.level() try: self.set_discrim_dc(val) except AttributeError, e: pass time.sleep(1.0/(2.5)) _discrim_dc_thread = threading.Thread(target=_discrim_dc_probe) _discrim_dc_thread.daemon = True _discrim_dc_thread.start() self._capture_file_text_box = forms.text_box( parent=self.GetWin(), value=self.capture_file, callback=self.set_capture_file, label="Record Filename", converter=forms.str_converter(), ) self.GridAdd(self._capture_file_text_box, 2, 0, 1, 2) self.Main = self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.Main.AddPage(grc_wxgui.Panel(self.Main), "L/R") self.Main.AddPage(grc_wxgui.Panel(self.Main), "FM Demod Spectrum") self.Add(self.Main) self.wxgui_waterfallsink2_0 = waterfallsink2.waterfall_sink_c( self.GetWin(), baseband_freq=0, dynamic_range=100, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=512, fft_rate=15, average=False, avg_alpha=None, title="Waterfall Plot", ) self.Add(self.wxgui_waterfallsink2_0.win) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.Main.GetPage(0).GetWin(), title="Audio Channels (L and R)", sample_rate=farate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=2, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Rel. Audio Level", ) self.Main.GetPage(0).Add(self.wxgui_scopesink2_0.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_f( self.Main.GetPage(1).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=asrate, fft_size=1024, fft_rate=6, average=True, avg_alpha=0.1, title="FM Demod Spectrum", peak_hold=False, ) self.Main.GetPage(1).Add(self.wxgui_fftsink2_0.win) self._variable_static_text_0_static_text = forms.static_text( parent=self.GetWin(), value=self.variable_static_text_0, callback=self.set_variable_static_text_0, label="RF Power ", converter=forms.float_converter(formatter=lambda x: "%4.1f" % x), ) self.GridAdd(self._variable_static_text_0_static_text, 0, 2, 1, 1) self._stereo_0_check_box = forms.check_box( parent=self.GetWin(), value=self.stereo_0, callback=self.set_stereo_0, label="Stereo Detect", true=True, false=False, ) self.GridAdd(self._stereo_0_check_box, 2, 5, 1, 1) self._stereo_check_box = forms.check_box( parent=self.GetWin(), value=self.stereo, callback=self.set_stereo, label="Stereo", true=True, false=False, ) self.GridAdd(self._stereo_check_box, 2, 4, 1, 1) self.rtl2832_source_0 = baz.rtl_source_c(defer_creation=True) self.rtl2832_source_0.set_verbose(True) self.rtl2832_source_0.set_vid(0x0) self.rtl2832_source_0.set_pid(0x0) self.rtl2832_source_0.set_tuner_name("") self.rtl2832_source_0.set_default_timeout(0) self.rtl2832_source_0.set_use_buffer(True) self.rtl2832_source_0.set_fir_coefficients(([])) if self.rtl2832_source_0.create() == False: raise Exception("Failed to create RTL2832 Source: rtl2832_source_0") self.rtl2832_source_0.set_sample_rate(1.0e6) self.rtl2832_source_0.set_frequency(cur_freq+200e3) self.rtl2832_source_0.set_auto_gain_mode(False) self.rtl2832_source_0.set_relative_gain(True) self.rtl2832_source_0.set_gain(gain) self._rtext_0_static_text = forms.static_text( parent=self.GetWin(), value=self.rtext_0, callback=self.set_rtext_0, label="CURRENT FREQUENCY>>", converter=forms.float_converter(), ) self.GridAdd(self._rtext_0_static_text, 0, 1, 1, 1) def _rf_pwr_lvl_probe(): while True: val = self.input_power.level() try: self.set_rf_pwr_lvl(val) except AttributeError, e: pass time.sleep(1.0/(2)) _rf_pwr_lvl_thread = threading.Thread(target=_rf_pwr_lvl_probe) _rf_pwr_lvl_thread.daemon = True _rf_pwr_lvl_thread.start() self._preselect_chooser = forms.radio_buttons( parent=self.GetWin(), value=self.preselect, callback=self.set_preselect, label='preselect', choices=eval(prefreqs), labels=eval(prenames), style=wx.RA_HORIZONTAL, ) self.GridAdd(self._preselect_chooser, 0, 4, 1, 1) def _pilot_level_probe(): while True: val = self.pilot_probe.level() try: self.set_pilot_level(val) except AttributeError, e: pass time.sleep(1.0/(5)) _pilot_level_thread = threading.Thread(target=_pilot_level_probe) _pilot_level_thread.daemon = True _pilot_level_thread.start() self.low_pass_filter_3 = gr.fir_filter_fff(1, firdes.low_pass( 3, asrate/500, 10, 3, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_2 = gr.fir_filter_fff(10, firdes.low_pass( 3, asrate/50, 100, 30, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_1 = gr.fir_filter_fff(10, firdes.low_pass( 3, asrate/5, 1e3, 200, firdes.WIN_HAMMING, 6.76)) self.low_pass_filter_0 = gr.fir_filter_fff(5, firdes.low_pass( 3, asrate, 10e3, 2e3, firdes.WIN_HAMMING, 6.76)) _igain_sizer = wx.BoxSizer(wx.VERTICAL) self._igain_text_box = forms.text_box( parent=self.GetWin(), sizer=_igain_sizer, value=self.igain, callback=self.set_igain, label="RF Gain", converter=forms.float_converter(), proportion=0, ) self._igain_slider = forms.slider( parent=self.GetWin(), sizer=_igain_sizer, value=self.igain, callback=self.set_igain, minimum=0, maximum=50, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_igain_sizer, 1, 1, 1, 1) _ifreq_sizer = wx.BoxSizer(wx.VERTICAL) self._ifreq_text_box = forms.text_box( parent=self.GetWin(), sizer=_ifreq_sizer, value=self.ifreq, callback=self.set_ifreq, label="Center Frequency", converter=forms.float_converter(), proportion=0, ) self._ifreq_slider = forms.slider( parent=self.GetWin(), sizer=_ifreq_sizer, value=self.ifreq, callback=self.set_ifreq, minimum=88.1e6, maximum=108.1e6, num_steps=200, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.GridAdd(_ifreq_sizer, 0, 0, 1, 1) self.gr_wavfile_sink_0 = gr.wavfile_sink("/dev/null" if record == False else capture_file, 2, int(farate), 16) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_single_pole_iir_filter_xx_1 = gr.single_pole_iir_filter_ff(2.5/(asrate/500), 1) self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff(1.0/(asrate/3), 1) self.gr_multiply_xx_1 = gr.multiply_vff(1) self.gr_multiply_xx_0_0 = gr.multiply_vff(1) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_multiply_const_vxx_3 = gr.multiply_const_vff((3.16e3 if st_enabled else 0, )) self.gr_multiply_const_vxx_2 = gr.multiply_const_vff((1.0 if st_enabled else 1.414, )) self.gr_multiply_const_vxx_1_0 = gr.multiply_const_vff((0 if st_enabled else 1, )) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((0 if squelch_probe == 0 else 1.0, )) self.gr_multiply_const_vxx_0_0 = gr.multiply_const_vff((vol*1.5*10.0, )) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((vol*1.5*10.0 if st_enabled else 0, )) self.gr_keep_one_in_n_0 = gr.keep_one_in_n(gr.sizeof_float*1, int(asrate/3)) self.gr_freq_xlating_fir_filter_xxx_0 = gr.freq_xlating_fir_filter_ccc(4, (osmo_taps), 200e3+fine+(-12e3*discrim_dc), 1.0e6) self.gr_fractional_interpolator_xx_0_0 = gr.fractional_interpolator_ff(0, asrate/farate) self.gr_fractional_interpolator_xx_0 = gr.fractional_interpolator_ff(0, asrate/farate) self.gr_fft_filter_xxx_1_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_high/10.0,asrate,3.5e3,15.0e3,5.0e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_1_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_med/10.0,asrate,1.0e3,4.0e3,2.0e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_1 = gr.fft_filter_fff(1, (firdes.low_pass(tone_low/10.0,asrate,1.2e3,500,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_0_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_high/10.0,asrate,3.5e3,13.5e3,3.5e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_0_0 = gr.fft_filter_fff(1, (firdes.band_pass(tone_med/10.0,asrate,1.0e3,4.0e3,2.0e3,firdes.WIN_HAMMING)), 1) self.gr_fft_filter_xxx_0 = gr.fft_filter_fff(1, (firdes.low_pass(tone_low/10.0,asrate,1.2e3,500,firdes.WIN_HAMMING)), 1) self.gr_divide_xx_0 = gr.divide_ff(1) self.gr_agc_xx_1 = gr.agc_cc(1e-2, 0.35, 1.0, 5000) self.gr_add_xx_2_0 = gr.add_vff(1) self.gr_add_xx_2 = gr.add_vff(1) self.gr_add_xx_1 = gr.add_vff(1) self.gr_add_xx_0 = gr.add_vff(1) self.gr_add_const_vxx_0 = gr.add_const_vff((1.0e-7, )) self._dm_chooser = forms.radio_buttons( parent=self.GetWin(), value=self.dm, callback=self.set_dm, label="FM Deemphasis", choices=[75.0e-6, 50.0e-6], labels=["NA", "EU"], style=wx.RA_HORIZONTAL, ) self.GridAdd(self._dm_chooser, 0, 5, 1, 1) self.blks2_wfm_rcv_0 = blks2.wfm_rcv( quad_rate=samp_rate, audio_decimation=2, ) self.blks2_fm_deemph_0_0 = blks2.fm_deemph(fs=farate, tau=deemph) self.blks2_fm_deemph_0 = blks2.fm_deemph(fs=farate, tau=deemph) self.band_pass_filter_2_0 = gr.fir_filter_fff(1, firdes.band_pass( 20, asrate, 17.5e3, 17.9e3, 250, firdes.WIN_HAMMING, 6.76)) self.band_pass_filter_2 = gr.fir_filter_fff(1, firdes.band_pass( 10, asrate, 18.8e3, 19.2e3, 350, firdes.WIN_HAMMING, 6.76)) self.band_pass_filter_0_0 = gr.fir_filter_fff(1, firdes.band_pass( 1, asrate, 38e3-(15e3), 38e3+(15e3), 4.0e3, firdes.WIN_HAMMING, 6.76)) self.audio_sink_0 = audio.sink(int(farate), "" if ahw == "Default" else ahw, True) ################################################## # Connections ################################################## self.connect((self.gr_add_xx_1, 0), (self.gr_fractional_interpolator_xx_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.gr_fractional_interpolator_xx_0_0, 0)) self.connect((self.band_pass_filter_0_0, 0), (self.gr_multiply_xx_1, 0)) self.connect((self.gr_multiply_const_vxx_1_0, 0), (self.gr_add_xx_0, 0)) self.connect((self.band_pass_filter_2_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.band_pass_filter_2_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_multiply_xx_0_0, 0), (self.gr_divide_xx_0, 0)) self.connect((self.gr_divide_xx_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.connect((self.gr_multiply_xx_0, 0), (self.gr_add_const_vxx_0, 0)) self.connect((self.gr_add_const_vxx_0, 0), (self.gr_divide_xx_0, 1)) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0)) self.connect((self.gr_keep_one_in_n_0, 0), (self.pilot_probe, 0)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_1, 2)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_0_0, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_add_xx_1, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_sub_xx_0, 0)) self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_sub_xx_0, 1)) self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_add_xx_1, 1)) self.connect((self.gr_fractional_interpolator_xx_0, 0), (self.gr_multiply_const_vxx_0_0, 0)) self.connect((self.gr_fractional_interpolator_xx_0_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_1, 1)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0, 0)) self.connect((self.gr_fft_filter_xxx_1, 0), (self.gr_add_xx_2, 0)) self.connect((self.gr_fft_filter_xxx_1_0, 0), (self.gr_add_xx_2, 1)) self.connect((self.gr_fft_filter_xxx_1_0_0, 0), (self.gr_add_xx_2, 2)) self.connect((self.gr_add_xx_2, 0), (self.gr_multiply_const_vxx_2, 0)) self.connect((self.gr_add_xx_2_0, 0), (self.gr_multiply_const_vxx_3, 0)) self.connect((self.gr_fft_filter_xxx_0, 0), (self.gr_add_xx_2_0, 0)) self.connect((self.gr_fft_filter_xxx_0_0, 0), (self.gr_add_xx_2_0, 1)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0_0, 0)) self.connect((self.gr_fft_filter_xxx_0_0_0, 0), (self.gr_add_xx_2_0, 2)) self.connect((self.gr_multiply_xx_1, 0), (self.gr_fft_filter_xxx_0_0_0, 0)) self.connect((self.blks2_fm_deemph_0, 0), (self.gr_multiply_const_vxx_1_0, 0)) self.connect((self.blks2_fm_deemph_0, 0), (self.gr_wavfile_sink_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_fft_filter_xxx_1_0_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_multiply_const_vxx_0_0, 0), (self.blks2_fm_deemph_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.audio_sink_0, 1)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_fm_deemph_0_0, 0)) self.connect((self.blks2_fm_deemph_0_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.band_pass_filter_2, 0), (self.gr_multiply_xx_0_0, 1)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_2, 0)) self.connect((self.blks2_fm_deemph_0, 0), (self.audio_sink_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_2_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.band_pass_filter_0_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.gr_wavfile_sink_0, 1)) self.connect((self.blks2_fm_deemph_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.wxgui_scopesink2_0, 1)) self.connect((self.blks2_wfm_rcv_0, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_agc_xx_1, 0), (self.blks2_wfm_rcv_0, 0)) self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.gr_agc_xx_1, 0)) self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.input_power, 0)) self.connect((self.blks2_wfm_rcv_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.low_pass_filter_0, 0), (self.low_pass_filter_1, 0)) self.connect((self.low_pass_filter_1, 0), (self.low_pass_filter_2, 0)) self.connect((self.low_pass_filter_2, 0), (self.low_pass_filter_3, 0)) self.connect((self.gr_single_pole_iir_filter_xx_1, 0), (self.dc_level, 0)) self.connect((self.low_pass_filter_3, 0), (self.gr_single_pole_iir_filter_xx_1, 0)) self.connect((self.rtl2832_source_0, 0), (self.gr_freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.gr_freq_xlating_fir_filter_xxx_0, 0), (self.wxgui_waterfallsink2_0, 0))
def __init__( self, sample_rate, ber_threshold=0, # Above which to do search ber_smoothing=0, # Alpha of BER smoother (0.01) ber_duration=0, # Length before trying next combo ber_sample_decimation=1, settling_period=0, pre_lock_duration=0, #ber_sample_skip=0 **kwargs): use_throttle = False base_duration = 1024 if sample_rate > 0: use_throttle = True base_duration *= 4 # Has to be high enough for block-delay if ber_threshold == 0: ber_threshold = 512 * 4 if ber_smoothing == 0: ber_smoothing = 0.01 if ber_duration == 0: ber_duration = base_duration * 2 # 1000ms if settling_period == 0: settling_period = base_duration * 1 # 500ms if pre_lock_duration == 0: pre_lock_duration = base_duration * 2 #1000ms print "Creating Auto-FEC:" print "\tsample_rate:\t\t", sample_rate print "\tber_threshold:\t\t", ber_threshold print "\tber_smoothing:\t\t", ber_smoothing print "\tber_duration:\t\t", ber_duration print "\tber_sample_decimation:\t", ber_sample_decimation print "\tsettling_period:\t", settling_period print "\tpre_lock_duration:\t", pre_lock_duration print "" self.sample_rate = sample_rate self.ber_threshold = ber_threshold #self.ber_smoothing = ber_smoothing self.ber_duration = ber_duration self.settling_period = settling_period self.pre_lock_duration = pre_lock_duration #self.ber_sample_skip = ber_sample_skip self.data_lock = threading.Lock() gr.hier_block2.__init__( self, "auto_fec", gr.io_signature( 1, 1, gr.sizeof_gr_complex), # Post MPSK-receiver complex input gr.io_signature3( 3, 3, gr.sizeof_char, gr.sizeof_float, gr.sizeof_float)) # Decoded packed bytes, BER metric, lock self.input_watcher = auto_fec_input_watcher(self) default_xform = self.input_watcher.xform_lock self.gr_conjugate_cc_0 = gr.conjugate_cc() self.connect((self, 0), (self.gr_conjugate_cc_0, 0)) # Input self.blks2_selector_0 = grc_blks2.selector( item_size=gr.sizeof_gr_complex * 1, num_inputs=2, num_outputs=1, input_index=default_xform.get_conjugation_index(), output_index=0, ) self.connect((self.gr_conjugate_cc_0, 0), (self.blks2_selector_0, 0)) self.connect((self, 0), (self.blks2_selector_0, 1)) # Input self.gr_multiply_const_vxx_3 = gr.multiply_const_vcc( (0.707 * (1 + 1j), )) self.connect((self.blks2_selector_0, 0), (self.gr_multiply_const_vxx_3, 0)) self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc( (default_xform.get_rotation(), )) # phase_mult self.connect((self.gr_multiply_const_vxx_3, 0), (self.gr_multiply_const_vxx_2, 0)) self.gr_complex_to_float_0_0 = gr.complex_to_float(1) self.connect((self.gr_multiply_const_vxx_2, 0), (self.gr_complex_to_float_0_0, 0)) self.gr_interleave_1 = gr.interleave(gr.sizeof_float * 1) self.connect((self.gr_complex_to_float_0_0, 1), (self.gr_interleave_1, 1)) self.connect((self.gr_complex_to_float_0_0, 0), (self.gr_interleave_1, 0)) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((1, )) # invert self.connect((self.gr_interleave_1, 0), (self.gr_multiply_const_vxx_0, 0)) self.baz_delay_2 = baz.delay( gr.sizeof_float * 1, default_xform.get_puncture_delay()) # delay_puncture self.connect((self.gr_multiply_const_vxx_0, 0), (self.baz_delay_2, 0)) self.depuncture_ff_0 = baz.depuncture_ff( (_puncture_matrices[self.input_watcher.puncture_matrix][1] )) # puncture_matrix self.connect((self.baz_delay_2, 0), (self.depuncture_ff_0, 0)) self.baz_delay_1 = baz.delay( gr.sizeof_float * 1, default_xform.get_viterbi_delay()) # delay_viterbi self.connect((self.depuncture_ff_0, 0), (self.baz_delay_1, 0)) self.swap_ff_0 = baz.swap_ff( default_xform.get_viterbi_swap()) # swap_viterbi self.connect((self.baz_delay_1, 0), (self.swap_ff_0, 0)) self.gr_decode_ccsds_27_fb_0 = gr.decode_ccsds_27_fb() if use_throttle: print "==> Using throttle at sample rate:", self.sample_rate self.gr_throttle_0 = gr.throttle(gr.sizeof_float, self.sample_rate) self.connect((self.swap_ff_0, 0), (self.gr_throttle_0, 0)) self.connect((self.gr_throttle_0, 0), (self.gr_decode_ccsds_27_fb_0, 0)) else: self.connect((self.swap_ff_0, 0), (self.gr_decode_ccsds_27_fb_0, 0)) self.connect((self.gr_decode_ccsds_27_fb_0, 0), (self, 0)) # Output bytes self.gr_add_const_vxx_1 = gr.add_const_vff((-4096, )) self.connect((self.gr_decode_ccsds_27_fb_0, 1), (self.gr_add_const_vxx_1, 0)) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((-1, )) self.connect((self.gr_add_const_vxx_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self, 1)) # Output BER self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff( ber_smoothing, 1) self.connect((self.gr_multiply_const_vxx_1, 0), (self.gr_single_pole_iir_filter_xx_0, 0)) self.gr_keep_one_in_n_0 = blocks.keep_one_in_n(gr.sizeof_float, ber_sample_decimation) self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0)) self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0) # Last param is const value if use_throttle: lock_throttle_rate = self.sample_rate // 16 print "==> Using lock throttle rate:", lock_throttle_rate self.gr_throttle_1 = gr.throttle(gr.sizeof_float, lock_throttle_rate) self.connect((self.const_source_x_0, 0), (self.gr_throttle_1, 0)) self.connect((self.gr_throttle_1, 0), (self, 2)) else: self.connect((self.const_source_x_0, 0), (self, 2)) self.msg_q = gr.msg_queue( 2 * 256 ) # message queue that holds at most 2 messages, increase to speed up process self.msg_sink = gr.message_sink( gr.sizeof_float, self.msg_q, dont_block=0) # Block to speed up process self.connect((self.gr_keep_one_in_n_0, 0), self.msg_sink) self.input_watcher.start()
def __init__(self, subc, vlen, ss): gr.hier_block2.__init__( self, "new_snr_estimator", gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen), gr.io_signature(1, 1, gr.sizeof_float)) print "Created Milan's SNR estimator" trigger = [0] * vlen trigger[0] = 1 u = range(vlen / ss * (ss - 1)) zeros_ind = map(lambda z: z + 1 + z / (ss - 1), u) skip1 = skip(gr.sizeof_gr_complex, vlen) for x in zeros_ind: skip1.skip(x) #print "skipped zeros",zeros_ind v = range(vlen / ss) ones_ind = map(lambda z: z * ss, v) skip2 = skip(gr.sizeof_gr_complex, vlen) for x in ones_ind: skip2.skip(x) #print "skipped ones",ones_ind v2s = gr.vector_to_stream(gr.sizeof_gr_complex, vlen) s2v1 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss) trigger_src_1 = gr.vector_source_b(trigger, True) s2v2 = gr.stream_to_vector(gr.sizeof_gr_complex, vlen / ss * (ss - 1)) trigger_src_2 = gr.vector_source_b(trigger, True) mag_sq_ones = gr.complex_to_mag_squared(vlen / ss) mag_sq_zeros = gr.complex_to_mag_squared(vlen / ss * (ss - 1)) filt_ones = gr.single_pole_iir_filter_ff(0.1, vlen / ss) filt_zeros = gr.single_pole_iir_filter_ff(0.1, vlen / ss * (ss - 1)) sum_ones = vector_sum_vff(vlen / ss) sum_zeros = vector_sum_vff(vlen / ss * (ss - 1)) D = gr.divide_ff() P = gr.multiply_ff() mult1 = gr.multiply_const_ff(ss - 1.0) add1 = gr.add_const_ff(-1.0) mult2 = gr.multiply_const_ff(1. / ss) scsnrdb = gr.nlog10_ff(10, 1, 0) filt_end = gr.single_pole_iir_filter_ff(0.1) self.connect(self, v2s, skip1, s2v1, mag_sq_ones, filt_ones, sum_ones) self.connect(trigger_src_1, (skip1, 1)) self.connect(v2s, skip2, s2v2, mag_sq_zeros, filt_zeros, sum_zeros) self.connect(trigger_src_2, (skip2, 1)) self.connect(sum_ones, D) self.connect(sum_zeros, (D, 1)) self.connect(D, mult1, add1, mult2) self.connect(mult2, scsnrdb, filt_end, self)