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 qamtest(self, nbits): data = tuple(range(2**nbits)) src = gr.vector_source_b(data) unpack = gr.unpack_k_bits_bb(nbits) enc = raw.qam_enc(nbits) dec = raw.qam_dec(nbits) tofloat = gr.uchar_to_float() slicer = gr.binary_slicer_fb() unpacked = gr.vector_sink_b() encoded = gr.vector_sink_c() decoded = gr.vector_sink_b() dst = gr.vector_sink_b() self.tb.connect(src, unpack, enc, dec, tofloat, gr.add_const_ff(-128.0), slicer, dst) self.tb.connect(unpack, unpacked) self.tb.connect(enc, encoded) self.tb.connect(dec, decoded) self.tb.run() #print "data = ", data #print "unpacked = ", unpacked.data() #print "encoded = ", encoded.data() #print "decoded = ", decoded.data() #print "dst = ", dst.data() self.assertEqual(unpacked.data(), dst.data()) pwr = sum([abs(x)**2 for x in encoded.data()]) / len(encoded.data()) #print pwr self.assertAlmostEqual(1.0, pwr, 6)
def __init__(self, fs, svn, alpha, fd_range, dump_bins=False): gr.hier_block2.__init__(self, "acquisition", gr.io_signature(1,1, gr.sizeof_gr_complex), gr.io_signature(3,3, gr.sizeof_float)) fft_size = int( 1e-3*fs) doppler_range = self.get_doppler_range(fd_range) agc = gr.agc_cc( 1.0/fs, 1.0, 1.0, 1.0) s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size) fft = gr.fft_vcc(fft_size, True, []) argmax = gr.argmax_fs(fft_size) max = gr.max_ff(fft_size) self.connect( self, s2v, fft) self.connect( (argmax, 0), gr.short_to_float(), (self, 0)) self.connect( (argmax,1), gr.short_to_float(), gr.add_const_ff(-fd_range), gr.multiply_const_ff(1e3), (self,1)) self.connect( max, (self, 2)) # Connect the individual channels to the input and the output. self.correlators = [ single_channel_correlator( fs, fd, svn, alpha, dump_bins) for fd in doppler_range ] for (correlator, i) in zip( self.correlators, range(len(self.correlators))): self.connect( fft, correlator ) self.connect( correlator, (argmax, i) ) self.connect( correlator, (max, i) )
def qamtest (self, nbits): data = tuple(range(2**nbits)) src = gr.vector_source_b(data) unpack = gr.unpack_k_bits_bb(nbits) enc = raw.qam_enc(nbits) dec = raw.qam_dec(nbits) tofloat = gr.uchar_to_float() slicer = gr.binary_slicer_fb() unpacked = gr.vector_sink_b() encoded = gr.vector_sink_c() decoded = gr.vector_sink_b() dst = gr.vector_sink_b() self.tb.connect(src, unpack, enc, dec, tofloat, gr.add_const_ff(-128.0), slicer, dst) self.tb.connect(unpack, unpacked) self.tb.connect(enc, encoded) self.tb.connect(dec, decoded) self.tb.run() #print "data = ", data #print "unpacked = ", unpacked.data() #print "encoded = ", encoded.data() #print "decoded = ", decoded.data() #print "dst = ", dst.data() self.assertEqual(unpacked.data(), dst.data()) pwr = sum([abs(x)**2 for x in encoded.data()]) / len(encoded.data()) #print pwr self.assertAlmostEqual(1.0, pwr, 6)
def test_00(self): expected_result = ( 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) # Filter taps to expand the data to oversample by 8 # Just using a RRC for some basic filter shape taps = gr.firdes.root_raised_cosine(8, 8, 1.0, 0.5, 21) src = gr.vector_source_b(expected_result) frame = digital.simple_framer(4) unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) expand = gr.interp_fir_filter_fff(8, taps) b2f = gr.char_to_float() mult2 = gr.multiply_const_ff(2) sub1 = gr.add_const_ff(-1) op = digital.simple_correlator(4) dst = gr.vector_sink_b() self.tb.connect(src, frame, unpack, b2f, mult2, sub1, expand) self.tb.connect(expand, op, dst) self.tb.run() result_data = dst.data() self.assertEqual(expected_result, result_data)
def __init__(self, fs, svn, alpha, fd_range, dump_bins=False): gr.hier_block2.__init__(self, "acquisition", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(3, 3, gr.sizeof_float)) fft_size = int(1e-3 * fs) doppler_range = self.get_doppler_range(fd_range) agc = gr.agc_cc(1.0 / fs, 1.0, 1.0, 1.0) s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size) fft = gr.fft_vcc(fft_size, True, []) argmax = gr.argmax_fs(fft_size) max = gr.max_ff(fft_size) self.connect(self, s2v, fft) self.connect((argmax, 0), gr.short_to_float(), (self, 0)) self.connect((argmax, 1), gr.short_to_float(), gr.add_const_ff(-fd_range), gr.multiply_const_ff(1e3), (self, 1)) self.connect(max, (self, 2)) # Connect the individual channels to the input and the output. self.correlators = [ single_channel_correlator(fs, fd, svn, alpha, dump_bins) for fd in doppler_range ] for (correlator, i) in zip(self.correlators, range(len(self.correlators))): self.connect(fft, correlator) self.connect(correlator, (argmax, i)) self.connect(correlator, (max, i))
def __init__( self, parent, unit='%', minval=0, maxval=100, decimal_places=5, sample_rate=1, number_rate=DEFAULT_NUMBER_RATE, label='Bit Error Rate', size=DEFAULT_WIN_SIZE, show_gauge=True, **kwargs #catchall for backwards compatibility ): gr.hier_block2.__init__( self, "number_sink", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0), ) #blocks sd = blks2.stream_to_vector_decimator( item_size=self._item_size, sample_rate=sample_rate, vec_rate=number_rate, vec_len=1, ) mult = gr.multiply_const_ff(100) add = gr.add_const_ff(1e-10) msgq = gr.msg_queue(2) sink = gr.message_sink(self._item_size, msgq, True) #connect self.connect(self, sd, mult, add, sink) #controller self.controller = pubsub() #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = number_window( parent=parent, controller=self.controller, size=size, title=label, units=unit, real=self._real, minval=minval, maxval=maxval, decimal_places=decimal_places, show_gauge=show_gauge, msg_key=MSG_KEY, sample_rate_key=SAMPLE_RATE_KEY)
def xtest_ccsds_27(self): src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) expected = (0, 0, 0, 0, 1, 2, 3, 4, 5, 6) src = gr.vector_source_b(src_data) enc = gr.encode_ccsds_27_bb() b2f = gr.char_to_float() add = gr.add_const_ff(-0.5) mul = gr.multiply_const_ff(2.0) dec = gr.decode_ccsds_27_fb() dst = gr.vector_sink_b() self.tb.connect(src, enc, b2f, add, mul, dec, dst) self.tb.run() dst_data = dst.data() self.assertEqual(expected, dst_data)
def __init__(self, fg, channel_rate, audio_decim, audio_pass, audio_stop): MAG = gr.complex_to_mag() DCR = gr.add_const_ff(-1.0) audio_taps = optfir.low_pass(0.5, # Filter gain channel_rate, # Sample rate audio_pass, # Audio passband audio_stop, # Audio stopband 0.1, # Passband ripple 60) # Stopband attenuation LPF = gr.fir_filter_fff(audio_decim, audio_taps) fg.connect(MAG, DCR, LPF) gr.hier_block.__init__(self, fg, MAG, LPF)
def __init__( self, parent, unit='%', minval=0, maxval=100, decimal_places=5, sample_rate=1, number_rate=DEFAULT_NUMBER_RATE, label='Bit Error Rate', size=DEFAULT_WIN_SIZE, show_gauge=True, **kwargs #catchall for backwards compatibility ): gr.hier_block2.__init__( self, "number_sink", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0), ) #blocks sd = blks2.stream_to_vector_decimator( item_size=self._item_size, sample_rate=sample_rate, vec_rate=number_rate, vec_len=1, ) mult = gr.multiply_const_ff(100) add = gr.add_const_ff(1e-10) msgq = gr.msg_queue(2) sink = gr.message_sink(self._item_size, msgq, True) #connect self.connect(self, sd, mult, add, sink) #controller self.controller = pubsub() #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = number_window(parent=parent, controller=self.controller, size=size, title=label, units=unit, real=self._real, minval=minval, maxval=maxval, decimal_places=decimal_places, show_gauge=show_gauge, msg_key=MSG_KEY, sample_rate_key=SAMPLE_RATE_KEY)
def xtest_ccsds_27 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) expected = (0, 0, 0, 0, 1, 2, 3, 4, 5, 6) src = gr.vector_source_b(src_data) enc = gr.encode_ccsds_27_bb() b2f = gr.char_to_float() add = gr.add_const_ff(-0.5) mul = gr.multiply_const_ff(2.0) dec = gr.decode_ccsds_27_fb() dst = gr.vector_sink_b() self.tb.connect(src, enc, b2f, add, mul, dec, dst) self.tb.run() dst_data = dst.data() self.assertEqual(expected, dst_data)
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, startup, window ): gr.hier_block2.__init__( self, "vector_acc_se2", gr.io_signature( 1, 1, gr.sizeof_float), gr.io_signature( 1, 1, gr.sizeof_float ) ) #mse = ofdm.mean_squared_error( vlen, window, False, float(window) ) if startup > 0: startup_skip = gr.skiphead( gr.sizeof_float, startup ) self.connect( self, startup_skip,self ) else: self.odd= gr.add_const_ff(0.0) self.connect( self, self.odd,self ) #self.mse = mse self.startup = startup
def __init__(self, channel_rate, audio_decim, audio_pass, audio_stop): gr.hier_block2.__init__(self, "am_demod_cf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Input signature MAG = gr.complex_to_mag() DCR = gr.add_const_ff(-1.0) audio_taps = optfir.low_pass(0.5, # Filter gain channel_rate, # Sample rate audio_pass, # Audio passband audio_stop, # Audio stopband 0.1, # Passband ripple 60) # Stopband attenuation LPF = gr.fir_filter_fff(audio_decim, audio_taps) self.connect(self, MAG, DCR, LPF, self)
def __init__(self, fg): self.split = gr.multiply_const_ff(1) self.sqr = gr.multiply_ff() self.int0 = gr.iir_filter_ffd([0.004, 0], [0, 0.999]) self.offs = gr.add_const_ff(-30) self.gain = gr.multiply_const_ff(70) self.log = gr.nlog10_ff(10, 1) self.agc = gr.divide_ff() fg.connect(self.split, (self.agc, 0)) fg.connect(self.split, (self.sqr, 0)) fg.connect(self.split, (self.sqr, 1)) fg.connect(self.sqr, self.int0) fg.connect(self.int0, self.log) fg.connect(self.log, self.offs) fg.connect(self.offs, self.gain) fg.connect(self.gain, (self.agc, 1)) gr.hier_block.__init__(self, fg, self.split, self.agc)
def __init__(self): gr.top_block.__init__(self) self.src = gr.message_source(gr.sizeof_char, msgq_limit) src = self.src b_to_syms = gr.bytes_to_syms() self.mult = gr.multiply_const_ff(MULTIPLIER) add = gr.add_const_ff(CENTER_FREQ) repeater = gr.repeat(gr.sizeof_float,REPEAT_TIME) fsk_f = gr.vco_f(AUDIO_RATE, 2*pi,0.5) speaker = audio.sink(AUDIO_RATE, "plughw:0,0"); self.connect(src,b_to_syms,self.mult,add,repeater,fsk_f,speaker)
def __init__(self, fg): self.split = gr.multiply_const_ff(1) self.sqr = gr.multiply_ff() self.int0 = gr.iir_filter_ffd([.004, 0], [0, .999]) self.offs = gr.add_const_ff(-30) self.gain = gr.multiply_const_ff(70) self.log = gr.nlog10_ff(10, 1) self.agc = gr.divide_ff() fg.connect(self.split, (self.agc, 0)) fg.connect(self.split, (self.sqr, 0)) fg.connect(self.split, (self.sqr, 1)) fg.connect(self.sqr, self.int0) fg.connect(self.int0, self.log) fg.connect(self.log, self.offs) fg.connect(self.offs, self.gain) fg.connect(self.gain, (self.agc, 1)) gr.hier_block.__init__(self, fg, self.split, self.agc)
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 build_blocks( self, vlen, cp_len, snr_db, sigpow, startup, N, LOS_power, no_taps, have_LOS ): self.fading_channel = \ static_fading_channel( LOS_power, no_taps, vlen, have_LOS ) self.freq_resp = self.fading_channel.freq_resp assert( len(self.freq_resp) == vlen ) ############################################################################ # select channel estimator to be tested herls #self.uut = channel_estimator_001( vlen ) self.uut = channel_estimator_003( vlen, cp_len) #self.uut = snr_estimator_001( vlen) ############################################################################ block = self.uut.preamble_td #print abs(sigpow) #print sum(numpy.abs(block)**2.0)/len(block) assert( abs( sigpow - sum(numpy.abs(block)**2.0)/len(block) ) < 1e-4 ) # power self.snr_lin = 10**(snr_db/10) if cp_len > 0: block = concatenate([ block[ len(block) - cp_len : len(block) ], block ]) self.block = block #self.compare = gr.add_const_vcc( -1.0 * numpy.array(self.freq_resp) ) #self.mean_squared_error = vector_acc_se2( vlen, startup, N ) self.compare = gr.add_const_ff(-1.0 *self.snr_lin) self.mean_squared_error = vector_acc_se3( startup, N ) #self.normal = gr.multiply_const_ff(1./(snr_lin**2)) self.dst = gr.vector_sink_f() self.awgn_channel = awgn_channel( snr_db, sigpow ) self.block_src = gr.vector_source_c( self.block, True ) self.sampler = ofdm.vector_sampler( gr.sizeof_gr_complex, vlen ) self.perfect_trigger = perfect_block_trigger( len(self.block) ) self.fft = scaled_fft( vlen )
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): gr.top_block.__init__(self) self.rcvd_pktq = gr.msg_queue() audio_rate = 48000 src = audio.source (audio_rate,"plughw:0,0") mult = gr.multiply_const_ff(10) # multiply raw_wave = gr.wavfile_sink(filename, 1, audio_rate,16) raw_wave1 = gr.wavfile_sink(filename2, 1, audio_rate,16) fsk_c = gr.hilbert_fc((audio_rate/300)+1) bp_coeff = gr.firdes.band_pass(1,audio_rate,BandPass,BandStop,100) bpf = gr.fir_filter_fff(1,bp_coeff) quad_demod = gr.quadrature_demod_cf(1)#originally 1 hpf_coeff = gr.firdes.high_pass(10, audio_rate, 10, 5) dc_block = gr.add_const_ff(-2.225) mm = gr.clock_recovery_mm_ff(RepeatTime,0.000625,0.5,0.01,0.1) slicer = gr.binary_slicer_fb() sync_corr = gr.correlate_access_code_bb("0100011101111000",0) file_sink = gr.file_sink(1, "decoded-bits.dat") sink = goodney.sink2(self.rcvd_pktq) self.connect(bpf,raw_wave1) self.connect(src,raw_wave) self.connect(src,bpf,fsk_c,quad_demod,dc_block,mm,slicer,sync_corr,sink) self.watcher = _queue_watcher_thread(self.rcvd_pktq, message_callback)
def __init__( self ): gr.hier_block2.__init__(self, "agc", gr.io_signature(1,1,gr.sizeof_float), gr.io_signature(1,1,gr.sizeof_float)) self.split = gr.multiply_const_ff( 1 ) self.sqr = gr.multiply_ff( ) self.int0 = gr.iir_filter_ffd( [.004, 0], [0, .999] ) self.offs = gr.add_const_ff( -30 ) self.gain = gr.multiply_const_ff( 70 ) self.log = gr.nlog10_ff( 10, 1 ) self.agc = gr.divide_ff( ) self.connect(self, self.split) self.connect(self.split, (self.agc, 0)) self.connect(self.split, (self.sqr, 0)) self.connect(self.split, (self.sqr, 1)) self.connect(self.sqr, self.int0) self.connect(self.int0, self.log) self.connect(self.log, self.offs) self.connect(self.offs, self.gain) self.connect(self.gain, (self.agc, 1)) self.connect(self.agc, self)
def __init__(self): gr.hier_block2.__init__(self, "agc", gr.io_signature(1, 1, gr.sizeof_float), gr.io_signature(1, 1, gr.sizeof_float)) self.split = gr.multiply_const_ff(1) self.sqr = gr.multiply_ff() self.int0 = gr.iir_filter_ffd([.004, 0], [0, .999]) self.offs = gr.add_const_ff(-30) self.gain = gr.multiply_const_ff(70) self.log = gr.nlog10_ff(10, 1) self.agc = gr.divide_ff() self.connect(self, self.split) self.connect(self.split, (self.agc, 0)) self.connect(self.split, (self.sqr, 0)) self.connect(self.split, (self.sqr, 1)) self.connect(self.sqr, self.int0) self.connect(self.int0, self.log) self.connect(self.log, self.offs) self.connect(self.offs, self.gain) self.connect(self.gain, (self.agc, 1)) self.connect(self.agc, self)
def __init__(self): gr.top_block.__init__(self) audio_rate =48000 # audio rate changed self.src = gr.message_source(gr.sizeof_char, msgq_limit) src = self.src b_to_syms = gr.bytes_to_syms() mult = gr.multiply_const_ff(1000) add = gr.add_const_ff(CentreFreq) repeater = gr.repeat(gr.sizeof_float,RepeatTime) fsk_f = gr.vco_f(audio_rate, 2*pi,0.5) # Sensitivity is rad/sec/volt ( e.g 2*pi*f/sec = 1Khz) and here f = volts (input amplitude of VCO) attenuator = gr.multiply_const_ff(0.05) # multiply speaker = audio.sink(audio_rate, "plughw:0,0"); dst = gr.wavfile_sink("tx-signal.wav",1, audio_rate, 16) self.connect(src,b_to_syms,mult,add,repeater,fsk_f,attenuator,speaker) self.connect(fsk_f,dst)
def __init__(self, fft_length, block_length, block_header, range, options): gr.hier_block2.__init__(self, "integer_fo_estimator", gr.io_signature3(3,3,gr.sizeof_gr_complex,gr.sizeof_float,gr.sizeof_char), gr.io_signature2(3,3,gr.sizeof_float,gr.sizeof_char)) raise NotImplementedError,"Obsolete class" self._range = range # threshold after integer part frequency offset estimation # if peak value below threshold, assume false triggering self._thr_lo = 0.4 #0.19 # empirically found threshold. see ioe_metric.float self._thr_hi = 0.4 #0.2 # stuff to be removed after bugfix for hierblock2s self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.time_sync = gr.kludge_copy(gr.sizeof_char) self.epsilon = (self,1) self.connect((self,0),self.input) self.connect((self,2),self.time_sync) delay(gr.sizeof_char, block_header.schmidl_fine_sync[0]*block_length) # sample ofdm symbol (preamble 1 and 2) sampler_symbol1 = vector_sampler(gr.sizeof_gr_complex,fft_length) sampler_symbol2 = vector_sampler(gr.sizeof_gr_complex,fft_length) time_delay1 = delay(gr.sizeof_char,block_length*block_header.schmidl_fine_sync[1]) self.connect(self.input, (sampler_symbol1,0)) self.connect(self.input, (sampler_symbol2,0)) if block_header.schmidl_fine_sync[0] > 0: time_delay0 = delay(gr.sizeof_char,block_length*block_header.schmidl_fine_sync[0]) self.connect(self.time_sync, time_delay0, (sampler_symbol1,1)) else: self.connect(self.time_sync, (sampler_symbol1,1)) self.connect(self.time_sync, time_delay1, (sampler_symbol2,1)) # negative fractional frequency offset estimate epsilon = gr.multiply_const_ff(-1.0) self.connect(self.epsilon, epsilon) # compensate for fractional frequency offset on per symbol base # freq_shift: vector length, modulator sensitivity # freq_shift third input: reset phase accumulator # symbol/preamble 1 freq_shift_sym1 = frequency_shift_vcc(fft_length, 1.0/fft_length) self.connect(sampler_symbol1, (freq_shift_sym1,0)) self.connect(epsilon, (freq_shift_sym1,1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym1,2)) # symbol/preamble 2 freq_shift_sym2 = frequency_shift_vcc(fft_length, 1.0/fft_length) self.connect(sampler_symbol2, (freq_shift_sym2,0)) self.connect(epsilon, (freq_shift_sym2,1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym2,2)) # fourier transfrom on both preambles fft_sym1 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift fft_sym2 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift # calculate schmidl's metric for estimation of freq. offset's integer part assert(hasattr(block_header, "schmidl_fine_sync")) pre1 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[0]] pre2 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[1]] diff_pn = concatenate([[conjugate(math.sqrt(2)*pre2[2*i]/pre1[2*i]),0.0j] for i in arange(len(pre1)/2)]) cfo_estimator = schmidl_cfo_estimator(fft_length, len(pre1), self._range, diff_pn) self.connect(freq_shift_sym1, fft_sym1, (cfo_estimator,0)) # preamble 1 self.connect(freq_shift_sym2, fft_sym2, (cfo_estimator,1)) # preamble 2 # search for maximum and its argument in interval [-range .. +range] #arg_max = arg_max_vff(2*self._range + 1) arg_max_s = gr.argmax_fs(2*self._range+1) arg_max = gr.short_to_float() ifo_max = gr.max_ff(2*self._range + 1) # vlen ifo_estimate = gr.add_const_ff(-self._range) self.connect(cfo_estimator, arg_max_s, arg_max, ifo_estimate) self.connect(cfo_estimator, ifo_max) self.connect((arg_max_s,1),gr.null_sink(gr.sizeof_short)) # threshold maximal value ifo_threshold = gr.threshold_ff(self._thr_lo, self._thr_hi, 0.0) ifo_thr_f2b = gr.float_to_char() self.connect(ifo_max, ifo_threshold, ifo_thr_f2b) # gating the streams ifo_estimate (integer part) and epsilon (frac. part) # if the metric's peak value was above the chosen threshold, assume to have # found a new burst. peak value below threshold results in blocking the # streams self.gate = gate_ff() self.connect(ifo_thr_f2b, (self.gate,0)) # threshold stream self.connect(ifo_estimate, (self.gate,1)) self.connect(epsilon, (self.gate,2)) # peak filtering # resynchronize and suppress peaks that didn't match a preamble filtered_time_sync = peak_resync_bb(True) # replace self.connect(self.time_sync, (filtered_time_sync,0)) self.connect(ifo_thr_f2b, (filtered_time_sync,1)) # find complete estimation for frequency offset # add together fractional and integer part freq_offset = gr.add_ff() self.connect((self.gate,1), gr.multiply_const_ff(-1.0), (freq_offset,0)) # integer offset self.connect((self.gate,2), (freq_offset,1)) # frac offset # output connections self.connect(freq_offset, (self,0)) self.connect(filtered_time_sync, (self,1)) self.connect((self.gate,0), (self,2)) # used for frame trigger ######################################### # debugging if options.log: self.epsilon2_sink = gr.vector_sink_f() self.connect(epsilon, self.epsilon2_sink) self.connect(cfo_estimator, gr.file_sink(gr.sizeof_float*(self._range*2+1), "data/ioe_metric.float")) # output joint stream preamble_stream = gr.streams_to_vector(fft_length * gr.sizeof_gr_complex, 2) self.connect(fft_sym1, (preamble_stream,0)) self.connect(fft_sym2, (preamble_stream,1)) self.connect(preamble_stream, gr.file_sink(gr.sizeof_gr_complex * 2 * fft_length, "data/preambles.compl")) # output, preambles before and after correction, magnitude and complex spectrum self.connect(sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre1_bef.compl")) self.connect(sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre1_bef.float")) self.connect(sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre2_bef.compl")) self.connect(sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre2_bef.float")) self.connect(freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length,"data/pre1.compl")) self.connect(freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length,"data/pre1.float")) self.connect(freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length,"data/pre2.compl")) self.connect(freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length,"data/pre2.float")) # calculate epsilon from corrected source to check function test_cp = cyclic_prefixer(fft_length, block_length) test_eps = foe(fft_length) self.connect(freq_shift_sym1, test_cp, test_eps, gr.file_sink(gr.sizeof_float, "data/eps_after.float")) try: gr.hier_block.update_var_names(self, "ifo_estimator", vars()) gr.hier_block.update_var_names(self, "ifo_estimator", vars(self)) except: pass
def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \ "Make sure your input capture file containes interleaved shorts not complex floats" parser=OptionParser(option_class=eng_option, usage=usage) parser.add_option("-a", "--args", type="string", default="", help="UHD device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate") parser.add_option("-f", "--freq", type="eng_float", default=519.25e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-c", "--contrast", type="eng_float", default=1.0, help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") parser.add_option("-p", "--pal", action="store_true", default=False, help="PAL video format (this is the default)") parser.add_option("-n", "--ntsc", action="store_true", default=False, help="NTSC video format") parser.add_option("-o", "--out-filename", type="string", default="sdl", help="For example out_raw_uchar.gray. If you don't specify an output filename you will get a video_sink_sdl realtime output window. You then need to have gr-video-sdl installed)") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat file in a loop") parser.add_option("", "--freq-min", type="eng_float", default=50.25e6, help="Set a minimum frequency [default=%default]") parser.add_option("", "--freq-max", type="eng_float", default=900.25e6, help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if not ((len(args) == 1) or (len(args) == 0)): parser.print_help() sys.exit(1) if len(args) == 1: filename = args[0] else: filename = None self.frame = frame self.panel = panel self.contrast = options.contrast self.brightness = options.brightness self.state = "FREQ" self.freq = 0 self.tv_freq_min = options.freq_min self.tv_freq_max = options.freq_max # build graph self.u=None if not (options.out_filename=="sdl"): options.repeat=False usrp_rate = options.samp_rate if not ((filename is None) or (filename=="usrp")): # file is data source self.filesource = gr.file_source(gr.sizeof_short,filename,options.repeat) self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource,self.istoc) self.src=self.istoc options.gain=0.0 self.gain=0.0 else: # use a UHD device self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if(options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if(options.antenna): self.u.set_antenna(options.antenna, 0) self.u.set_samp_rate(usrp_rate) dev_rate = self.u.get_samp_rate() if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.u.get_gain_range() options.gain = float(g.start()+g.stop())/2.0 self.src=self.u self.gain = options.gain f2uc=gr.float_to_uchar() # sdl window as final sink if not (options.pal or options.ntsc): options.pal=True #set default to PAL if options.pal: lines_per_frame=625.0 frames_per_sec=25.0 show_width=768 elif options.ntsc: lines_per_frame=525.0 frames_per_sec=29.97002997 show_width=640 width=int(usrp_rate/(lines_per_frame*frames_per_sec)) height=int(lines_per_frame) if (options.out_filename=="sdl"): #Here comes the tv screen, you have to build and install #gr-video-sdl for this (subproject of gnuradio, only in cvs #for now) try: video_sink = video_sdl.sink_uc ( frames_per_sec, width, height, 0, show_width, height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" raise SystemExit, 1 self.dst=video_sink else: print "You can use the imagemagick display tool to show the resulting imagesequence" print "use the following line to show the demodulated TV-signal:" print "display -depth 8 -size " +str(width)+ "x" + str(height) \ + " gray:" + options.out_filename print "(Use the spacebar to advance to next frames)" options.repeat=False file_sink=gr.file_sink(gr.sizeof_char, options.out_filename) self.dst =file_sink self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7 self.am_demod = gr.complex_to_mag () self.set_blacklevel=gr.add_const_ff(0.0) self.invert_and_scale = gr.multiply_const_ff (0.0) #-self.contrast *128.0*255.0/(200.0) # now wire it all together #sample_rate=options.width*options.height*options.framerate process_type='do_no_sync' if process_type=='do_no_sync': self.connect (self.src, self.agc,self.am_demod, self.invert_and_scale, self.set_blacklevel, f2uc,self.dst) elif process_type=='do_tv_sync_adv': #defaults: gr.tv_sync_adv (double sampling_freq, unsigned #int tv_format,bool output_active_video_only=false, bool #do_invert=false, double wanted_black_level=0.0, double #wanted_white_level=255.0, double avg_alpha=0.1, double #initial_gain=1.0, double initial_offset=0.0,bool #debug=false) #note, this block is not yet in cvs self.tv_sync_adv=gr.tv_sync_adv(usrp_rate, 0, False, False, 0.0, 255.0, 0.01, 1.0, 0.0, False) self.connect (self.src, self.am_demod, self.invert_and_scale, self.tv_sync_adv, s2f, f2uc, self.dst) elif process_type=='do_nullsink': #self.connect (self.src, self.am_demod,self.invert_and_scale,f2uc,video_sink) c2r=gr.complex_to_real() nullsink=gr.null_sink(gr.sizeof_float) self.connect (self.src, c2r,nullsink) #video_sink) elif process_type=='do_tv_sync_corr': frame_size=width*height #int(usrp_rate/25.0) nframes=10# 32 search_window=20*nframes debug=False video_alpha=0.3 #0.1 corr_alpha=0.3 #Note: this block is not yet in cvs tv_corr=gr.tv_correlator_ff(frame_size,nframes, search_window, video_alpha, corr_alpha,debug) shift=gr.add_const_ff(-0.7) self.connect (self.src, self.agc, self.am_demod, tv_corr, self.invert_and_scale, self.set_blacklevel, f2uc, self.dst) else: # process_type=='do_test_image': src_vertical_bars = gr.sig_source_f (usrp_rate, gr.GR_SIN_WAVE, 10.0 *usrp_rate/320, 255,128) self.connect(src_vertical_bars, f2uc, self.dst) self._build_gui(vbox, usrp_rate, usrp_rate, usrp_rate) frange = self.u.get_freq_range() if(frange.start() > self.tv_freq_max or frange.stop() < self.tv_freq_min): sys.stderr.write("Radio does not support required frequency range.\n") sys.exit(1) if(options.freq < self.tv_freq_min or options.freq > self.tv_freq_max): sys.stderr.write("Requested frequency is outside of required frequency range.\n") sys.exit(1) # set initial values self.set_gain(options.gain) self.set_contrast(self.contrast) self.set_brightness(options.brightness) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency")
#!/usr/bin/env python from gnuradio import gr, audio, ais import sys fg = gr.flow_graph() samplerate = 48000 src = audio.source(samplerate, "hw:1") pluss = gr.add_const_ff(0.0) lpcoeffs = gr.firdes.low_pass(1, samplerate, 8000, 3000) lpfilter = gr.fir_filter_fff(1, lpcoeffs) forsterk = gr.multiply_const_ff(5) clockrec = gr.clock_recovery_mm_ff( float(samplerate) / 9600, 0.25 * 0.175 * 0.175, 0.5, 0.175, 0.005) slicer = gr.binary_slicer_fb() # Parameters: ([mysql-server],[database name],[database user],[database password]) datadec = ais.ais_decoder_mysql("localhost", "diverse", "ruben", "elg") # You should use the create_mysql.sql to create the necessary tables # in the database. # See create_mysql.txt for help. Those files can be found in the root folder of # the source tree. diff = gr.diff_decoder_bb(2) invert = ais.invert10_bb() fg.connect(src, pluss, lpfilter, forsterk, clockrec, slicer, diff, invert, datadec)
def __init__( self, parent, unit="units", minval=0, maxval=1, factor=1, decimal_places=3, ref_level=0, sample_rate=1, number_rate=number_window.DEFAULT_NUMBER_RATE, average=False, avg_alpha=None, label="Number Plot", size=number_window.DEFAULT_WIN_SIZE, peak_hold=False, show_gauge=True, **kwargs # catchall for backwards compatibility ): # ensure avg alpha if avg_alpha is None: avg_alpha = 2.0 / number_rate # init gr.hier_block2.__init__(self, "number_sink", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0)) # blocks sd = blks2.stream_to_vector_decimator( item_size=self._item_size, sample_rate=sample_rate, vec_rate=number_rate, vec_len=1 ) if self._real: mult = gr.multiply_const_ff(factor) add = gr.add_const_ff(ref_level) avg = gr.single_pole_iir_filter_ff(1.0) else: mult = gr.multiply_const_cc(factor) add = gr.add_const_cc(ref_level) avg = gr.single_pole_iir_filter_cc(1.0) msgq = gr.msg_queue(2) sink = gr.message_sink(self._item_size, msgq, True) # controller self.controller = pubsub() self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate) self.controller[AVERAGE_KEY] = average self.controller[AVG_ALPHA_KEY] = avg_alpha def update_avg(*args): if self.controller[AVERAGE_KEY]: avg.set_taps(self.controller[AVG_ALPHA_KEY]) else: avg.set_taps(1.0) update_avg() self.controller.subscribe(AVERAGE_KEY, update_avg) self.controller.subscribe(AVG_ALPHA_KEY, update_avg) # start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) # create window self.win = number_window.number_window( parent=parent, controller=self.controller, size=size, title=label, units=unit, real=self._real, minval=minval, maxval=maxval, decimal_places=decimal_places, show_gauge=show_gauge, average_key=AVERAGE_KEY, avg_alpha_key=AVG_ALPHA_KEY, peak_hold=peak_hold, msg_key=MSG_KEY, sample_rate_key=SAMPLE_RATE_KEY, ) common.register_access_methods(self, self.controller) # backwards compadibility self.set_show_gauge = self.win.show_gauges # connect self.wxgui_connect(self, sd, mult, add, avg, sink)
def __init__(self, fft_length, block_length, block_header, range, options): gr.hier_block2.__init__( self, "integer_fo_estimator", gr.io_signature3(3, 3, gr.sizeof_gr_complex, gr.sizeof_float, gr.sizeof_char), gr.io_signature2(3, 3, gr.sizeof_float, gr.sizeof_char)) raise NotImplementedError, "Obsolete class" self._range = range # threshold after integer part frequency offset estimation # if peak value below threshold, assume false triggering self._thr_lo = 0.4 #0.19 # empirically found threshold. see ioe_metric.float self._thr_hi = 0.4 #0.2 # stuff to be removed after bugfix for hierblock2s self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.time_sync = gr.kludge_copy(gr.sizeof_char) self.epsilon = (self, 1) self.connect((self, 0), self.input) self.connect((self, 2), self.time_sync) delay(gr.sizeof_char, block_header.schmidl_fine_sync[0] * block_length) # sample ofdm symbol (preamble 1 and 2) sampler_symbol1 = vector_sampler(gr.sizeof_gr_complex, fft_length) sampler_symbol2 = vector_sampler(gr.sizeof_gr_complex, fft_length) time_delay1 = delay(gr.sizeof_char, block_length * block_header.schmidl_fine_sync[1]) self.connect(self.input, (sampler_symbol1, 0)) self.connect(self.input, (sampler_symbol2, 0)) if block_header.schmidl_fine_sync[0] > 0: time_delay0 = delay( gr.sizeof_char, block_length * block_header.schmidl_fine_sync[0]) self.connect(self.time_sync, time_delay0, (sampler_symbol1, 1)) else: self.connect(self.time_sync, (sampler_symbol1, 1)) self.connect(self.time_sync, time_delay1, (sampler_symbol2, 1)) # negative fractional frequency offset estimate epsilon = gr.multiply_const_ff(-1.0) self.connect(self.epsilon, epsilon) # compensate for fractional frequency offset on per symbol base # freq_shift: vector length, modulator sensitivity # freq_shift third input: reset phase accumulator # symbol/preamble 1 freq_shift_sym1 = frequency_shift_vcc(fft_length, 1.0 / fft_length) self.connect(sampler_symbol1, (freq_shift_sym1, 0)) self.connect(epsilon, (freq_shift_sym1, 1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym1, 2)) # symbol/preamble 2 freq_shift_sym2 = frequency_shift_vcc(fft_length, 1.0 / fft_length) self.connect(sampler_symbol2, (freq_shift_sym2, 0)) self.connect(epsilon, (freq_shift_sym2, 1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym2, 2)) # fourier transfrom on both preambles fft_sym1 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift fft_sym2 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift # calculate schmidl's metric for estimation of freq. offset's integer part assert (hasattr(block_header, "schmidl_fine_sync")) pre1 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[0]] pre2 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[1]] diff_pn = concatenate( [[conjugate(math.sqrt(2) * pre2[2 * i] / pre1[2 * i]), 0.0j] for i in arange(len(pre1) / 2)]) cfo_estimator = schmidl_cfo_estimator(fft_length, len(pre1), self._range, diff_pn) self.connect(freq_shift_sym1, fft_sym1, (cfo_estimator, 0)) # preamble 1 self.connect(freq_shift_sym2, fft_sym2, (cfo_estimator, 1)) # preamble 2 # search for maximum and its argument in interval [-range .. +range] #arg_max = arg_max_vff(2*self._range + 1) arg_max_s = gr.argmax_fs(2 * self._range + 1) arg_max = gr.short_to_float() ifo_max = gr.max_ff(2 * self._range + 1) # vlen ifo_estimate = gr.add_const_ff(-self._range) self.connect(cfo_estimator, arg_max_s, arg_max, ifo_estimate) self.connect(cfo_estimator, ifo_max) self.connect((arg_max_s, 1), gr.null_sink(gr.sizeof_short)) # threshold maximal value ifo_threshold = gr.threshold_ff(self._thr_lo, self._thr_hi, 0.0) ifo_thr_f2b = gr.float_to_char() self.connect(ifo_max, ifo_threshold, ifo_thr_f2b) # gating the streams ifo_estimate (integer part) and epsilon (frac. part) # if the metric's peak value was above the chosen threshold, assume to have # found a new burst. peak value below threshold results in blocking the # streams self.gate = gate_ff() self.connect(ifo_thr_f2b, (self.gate, 0)) # threshold stream self.connect(ifo_estimate, (self.gate, 1)) self.connect(epsilon, (self.gate, 2)) # peak filtering # resynchronize and suppress peaks that didn't match a preamble filtered_time_sync = peak_resync_bb(True) # replace self.connect(self.time_sync, (filtered_time_sync, 0)) self.connect(ifo_thr_f2b, (filtered_time_sync, 1)) # find complete estimation for frequency offset # add together fractional and integer part freq_offset = gr.add_ff() self.connect((self.gate, 1), gr.multiply_const_ff(-1.0), (freq_offset, 0)) # integer offset self.connect((self.gate, 2), (freq_offset, 1)) # frac offset # output connections self.connect(freq_offset, (self, 0)) self.connect(filtered_time_sync, (self, 1)) self.connect((self.gate, 0), (self, 2)) # used for frame trigger ######################################### # debugging if options.log: self.epsilon2_sink = gr.vector_sink_f() self.connect(epsilon, self.epsilon2_sink) self.connect( cfo_estimator, gr.file_sink(gr.sizeof_float * (self._range * 2 + 1), "data/ioe_metric.float")) # output joint stream preamble_stream = gr.streams_to_vector( fft_length * gr.sizeof_gr_complex, 2) self.connect(fft_sym1, (preamble_stream, 0)) self.connect(fft_sym2, (preamble_stream, 1)) self.connect( preamble_stream, gr.file_sink(gr.sizeof_gr_complex * 2 * fft_length, "data/preambles.compl")) # output, preambles before and after correction, magnitude and complex spectrum self.connect( sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre1_bef.compl")) self.connect( sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre1_bef.float")) self.connect( sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre2_bef.compl")) self.connect( sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre2_bef.float")) self.connect( freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre1.compl")) self.connect( freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre1.float")) self.connect( freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre2.compl")) self.connect( freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre2.float")) # calculate epsilon from corrected source to check function test_cp = cyclic_prefixer(fft_length, block_length) test_eps = foe(fft_length) self.connect(freq_shift_sym1, test_cp, test_eps, gr.file_sink(gr.sizeof_float, "data/eps_after.float")) try: gr.hier_block.update_var_names(self, "ifo_estimator", vars()) gr.hier_block.update_var_names(self, "ifo_estimator", vars(self)) except: pass
def __init__(self, fft_length, cp_length, half_sync, logging=False): gr.hier_block2.__init__(self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature3(3, 3, # Output signature gr.sizeof_gr_complex, # delayed input gr.sizeof_float, # fine frequency offset gr.sizeof_char # timing indicator )) if half_sync: period = fft_length/2 window = fft_length/2 else: # full symbol period = fft_length + cp_length window = fft_length # makes the plateau cp_length long # Calculate the frequency offset from the correlation of the preamble x_corr = gr.multiply_cc() self.connect(self, gr.conjugate_cc(), (x_corr, 0)) self.connect(self, gr.delay(gr.sizeof_gr_complex, period), (x_corr, 1)) P_d = gr.moving_average_cc(window, 1.0) self.connect(x_corr, P_d) P_d_angle = gr.complex_to_arg() self.connect(P_d, P_d_angle) # Get the power of the input signal to normalize the output of the correlation R_d = gr.moving_average_ff(window, 1.0) self.connect(self, gr.complex_to_mag_squared(), R_d) R_d_squared = gr.multiply_ff() # this is retarded self.connect(R_d, (R_d_squared, 0)) self.connect(R_d, (R_d_squared, 1)) M_d = gr.divide_ff() self.connect(P_d, gr.complex_to_mag_squared(), (M_d, 0)) self.connect(R_d_squared, (M_d, 1)) # Now we need to detect peak of M_d # NOTE: replaced fir_filter with moving_average for clarity # the peak is up to cp_length long, but noisy, so average it out #matched_filter_taps = [1.0/cp_length for i in range(cp_length)] #matched_filter = gr.fir_filter_fff(1, matched_filter_taps) matched_filter = gr.moving_average_ff(cp_length, 1.0/cp_length) # NOTE: the look_ahead parameter doesn't do anything # these parameters are kind of magic, increase 1 and 2 (==) to be more tolerant #peak_detect = raw.peak_detector_fb(0.55, 0.55, 30, 0.001) peak_detect = raw.peak_detector_fb(0.25, 0.25, 30, 0.001) # NOTE: gr.peak_detector_fb is broken! #peak_detect = gr.peak_detector_fb(0.55, 0.55, 30, 0.001) #peak_detect = gr.peak_detector_fb(0.45, 0.45, 30, 0.001) #peak_detect = gr.peak_detector_fb(0.30, 0.30, 30, 0.001) # offset by -1 self.connect(M_d, matched_filter, gr.add_const_ff(-1), peak_detect) # peak_detect indicates the time M_d is highest, which is the end of the symbol. # We should try to sample in the middle of the plateau!! # FIXME until we figure out how to do this, just offset by cp_length/2 offset = 6 #cp_length/2 # nco(t) = P_d_angle(t-offset) sampled at peak_detect(t) # modulate input(t - fft_length) by nco(t) # signal to sample input(t) at t-offset # # We can't delay by < 0 so instead: # input is delayed by fft_length # P_d_angle is delayed by offset # signal to sample is delayed by fft_length - offset # phi = gr.sample_and_hold_ff() self.connect(peak_detect, (phi,1)) self.connect(P_d_angle, gr.delay(gr.sizeof_float, offset), (phi,0)) #self.connect(P_d_angle, matched_filter2, (phi,0)) # why isn't this better?!? # FIXME: we add fft_length delay so that the preamble is nco corrected too # BUT is this buffering worth it? consider implementing sync as a proper block # delay the input signal to follow the frequency offset signal self.connect(self, gr.delay(gr.sizeof_gr_complex, (fft_length+offset)), (self,0)) self.connect(phi, (self,1)) self.connect(peak_detect, (self,2)) if logging: self.connect(matched_filter, gr.file_sink(gr.sizeof_float, "sync-mf.dat")) self.connect(M_d, gr.file_sink(gr.sizeof_float, "sync-M.dat")) self.connect(P_d_angle, gr.file_sink(gr.sizeof_float, "sync-angle.dat")) self.connect(peak_detect, gr.file_sink(gr.sizeof_char, "sync-peaks.datb")) self.connect(phi, gr.file_sink(gr.sizeof_float, "sync-phi.dat"))
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)
def __init__(self, fft_length, cp_length, logging=False): """ OFDM synchronization using PN Correlation: T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchonization for OFDM," IEEE Trans. Communications, vol. 45, no. 12, 1997. """ gr.hier_block2.__init__(self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) # PN Sync # Create a delay line self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) # Correlation from ML Sync self.conjg = gr.conjugate_cc(); self.corr = gr.multiply_cc(); # Create a moving sum filter for the corr output if 1: moving_sum_taps = [1.0 for i in range(fft_length//2)] self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps) else: moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)] self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps) # Create a moving sum filter for the input self.inputmag2 = gr.complex_to_mag_squared() movingsum2_taps = [1.0 for i in range(fft_length//2)] if 1: self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps) else: self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps) self.square = gr.multiply_ff() self.normalize = gr.divide_ff() # Get magnitude (peaks) and angle (phase/freq error) self.c2mag = gr.complex_to_mag_squared() self.angle = gr.complex_to_arg() self.sample_and_hold = gr.sample_and_hold_ff() #ML measurements input to sampler block and detect #self.sub1 = gr.add_const_ff(-1) self.sub1 = gr.add_const_ff(0) self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001) #self.pk_detect = gr.peak_detector2_fb(9) self.connect(self, self.input) # Calculate the frequency offset from the correlation of the preamble self.connect(self.input, self.delay) self.connect(self.input, (self.corr,0)) self.connect(self.delay, self.conjg) self.connect(self.conjg, (self.corr,1)) self.connect(self.corr, self.moving_sum_filter) self.connect(self.moving_sum_filter, self.c2mag) self.connect(self.moving_sum_filter, self.angle) self.connect(self.angle, (self.sample_and_hold,0)) # Get the power of the input signal to normalize the output of the correlation self.connect(self.input, self.inputmag2, self.inputmovingsum) self.connect(self.inputmovingsum, (self.square,0)) self.connect(self.inputmovingsum, (self.square,1)) self.connect(self.square, (self.normalize,1)) self.connect(self.c2mag, (self.normalize,0)) # Create a moving sum filter for the corr output matched_filter_taps = [1.0/cp_length for i in range(cp_length)] self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps) self.connect(self.normalize, self.matched_filter) self.connect(self.matched_filter, self.sub1, self.pk_detect) #self.connect(self.matched_filter, self.pk_detect) self.connect(self.pk_detect, (self.sample_and_hold,1)) # Set output signals # Output 0: fine frequency correction value # Output 1: timing signal self.connect(self.sample_and_hold, (self,0)) self.connect(self.pk_detect, (self,1)) if logging: self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
def __init__(self,frame,panel,vbox,argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \ "Make sure your input capture file containes interleaved shorts not complex floats" parser=OptionParser(option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, help="select USRP Rx side A or B (default=A)") parser.add_option("-d", "--decim", type="int", default=64, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option("-f", "--freq", type="eng_float", default=519.25e6, help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-c", "--contrast", type="eng_float", default=1.0, help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option("-p", "--pal", action="store_true", default=False, help="PAL video format (this is the default)") parser.add_option("-n", "--ntsc", action="store_true", default=False, help="NTSC video format") parser.add_option("-o", "--out-filename", type="string", default="sdl", help="For example out_raw_uchar.gray. If you don't specify an output filename you will get a video_sink_sdl realtime output window. You then need to have gr-video-sdl installed)") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat file in a loop") parser.add_option("-N", "--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") (options, args) = parser.parse_args() if not ((len(args) == 1) or (len(args) == 0)): parser.print_help() sys.exit(1) if len(args) == 1: filename = args[0] else: filename = None self.frame = frame self.panel = panel self.contrast = options.contrast self.brightness = options.brightness self.state = "FREQ" self.freq = 0 # build graph self.u=None usrp_decim = options.decim # 32 if not (options.out_filename=="sdl"): options.repeat=False if not ((filename is None) or (filename=="usrp")): self.filesource = gr.file_source(gr.sizeof_short,filename,options.repeat) # file is data source self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource,self.istoc) adc_rate=64e6 self.src=self.istoc options.gain=0.0 self.gain=0.0 else: if options.no_hb or (options.decim<8): self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths else: self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default) self.u = usrp.source_c(0,fpga_filename=self.fpga_filename) # usrp is data source if options.width_8: sample_width = 8 sample_shift = 8 format = self.u.make_format(sample_width, sample_shift) r = self.u.set_format(format) adc_rate = self.u.adc_rate() # 64 MS/s self.u.set_decim_rate(usrp_decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.u) self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) print "Using RX d'board %s" % (self.subdev.side_and_name(),) 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 self.src=self.u usrp_rate = adc_rate / usrp_decim # 320 kS/s f2uc=gr.float_to_uchar() # sdl window as final sink if not (options.pal or options.ntsc): options.pal=True #set default to PAL if options.pal: lines_per_frame=625.0 frames_per_sec=25.0 show_width=768 elif options.ntsc: lines_per_frame=525.0 frames_per_sec=29.97002997 show_width=640 width=int(usrp_rate/(lines_per_frame*frames_per_sec)) height=int(lines_per_frame) if (options.out_filename=="sdl"): #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now) try: video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" raise SystemExit, 1 self.dst=video_sink else: print "You can use the imagemagick display tool to show the resulting imagesequence" print "use the following line to show the demodulated TV-signal:" print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" + options.out_filename print "(Use the spacebar to advance to next frames)" options.repeat=False file_sink=gr.file_sink(gr.sizeof_char, options.out_filename) self.dst =file_sink self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7 self.am_demod = gr.complex_to_mag () self.set_blacklevel=gr.add_const_ff(0.0) self.invert_and_scale = gr.multiply_const_ff (0.0) #-self.contrast *128.0*255.0/(200.0) # now wire it all together #sample_rate=options.width*options.height*options.framerate process_type='do_no_sync' if process_type=='do_no_sync': self.connect (self.src, self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst) elif process_type=='do_tv_sync_adv': #defaults: gr.tv_sync_adv (double sampling_freq, unsigned int tv_format,bool output_active_video_only=false, bool do_invert=false, double wanted_black_level=0.0, double wanted_white_level=255.0, double avg_alpha=0.1, double initial_gain=1.0, double initial_offset=0.0,bool debug=false) self.tv_sync_adv=gr.tv_sync_adv(usrp_rate,0,False,False,0.0,255.0,0.01,1.0,0.0,False) #note, this block is not yet in cvs self.connect (self.src, self.am_demod,self.invert_and_scale,self.tv_sync_adv,s2f,f2uc,self.dst) elif process_type=='do_nullsink': #self.connect (self.src, self.am_demod,self.invert_and_scale,f2uc,video_sink) c2r=gr.complex_to_real() nullsink=gr.null_sink(gr.sizeof_float) self.connect (self.src, c2r,nullsink) #video_sink) elif process_type=='do_tv_sync_corr': frame_size=width*height #int(usrp_rate/25.0) nframes=10# 32 search_window=20*nframes debug=False video_alpha=0.3 #0.1 corr_alpha=0.3 tv_corr=gr.tv_correlator_ff(frame_size,nframes, search_window, video_alpha, corr_alpha,debug) #Note: this block is not yet in cvs shift=gr.add_const_ff(-0.7) self.connect (self.src, self.agc,self.am_demod,tv_corr,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst) #self.agc, else: # process_type=='do_test_image': src_vertical_bars = gr.sig_source_f (usrp_rate, gr.GR_SIN_WAVE, 10.0 *usrp_rate/320, 255,128) self.connect(src_vertical_bars,f2uc,self.dst) self._build_gui(vbox, usrp_rate, usrp_rate, usrp_rate) if abs(options.freq) < 1e6: options.freq *= 1e6 # set initial values self.set_gain(options.gain) self.set_contrast(self.contrast) self.set_brightness(options.brightness) if not(self.set_freq(options.freq)): self._set_status_msg("Failed to set initial frequency")
def __init__(self, fft_length, cp_length, half_sync, logging=False): gr.hier_block2.__init__( self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature3( 3, 3, # Output signature gr.sizeof_gr_complex, # delayed input gr.sizeof_float, # fine frequency offset gr.sizeof_char # timing indicator )) if half_sync: period = fft_length / 2 window = fft_length / 2 else: # full symbol period = fft_length + cp_length window = fft_length # makes the plateau cp_length long # Calculate the frequency offset from the correlation of the preamble x_corr = gr.multiply_cc() self.connect(self, gr.conjugate_cc(), (x_corr, 0)) self.connect(self, gr.delay(gr.sizeof_gr_complex, period), (x_corr, 1)) P_d = gr.moving_average_cc(window, 1.0) self.connect(x_corr, P_d) P_d_angle = gr.complex_to_arg() self.connect(P_d, P_d_angle) # Get the power of the input signal to normalize the output of the correlation R_d = gr.moving_average_ff(window, 1.0) self.connect(self, gr.complex_to_mag_squared(), R_d) R_d_squared = gr.multiply_ff() # this is retarded self.connect(R_d, (R_d_squared, 0)) self.connect(R_d, (R_d_squared, 1)) M_d = gr.divide_ff() self.connect(P_d, gr.complex_to_mag_squared(), (M_d, 0)) self.connect(R_d_squared, (M_d, 1)) # Now we need to detect peak of M_d # NOTE: replaced fir_filter with moving_average for clarity # the peak is up to cp_length long, but noisy, so average it out #matched_filter_taps = [1.0/cp_length for i in range(cp_length)] #matched_filter = gr.fir_filter_fff(1, matched_filter_taps) matched_filter = gr.moving_average_ff(cp_length, 1.0 / cp_length) # NOTE: the look_ahead parameter doesn't do anything # these parameters are kind of magic, increase 1 and 2 (==) to be more tolerant #peak_detect = raw.peak_detector_fb(0.55, 0.55, 30, 0.001) peak_detect = raw.peak_detector_fb(0.25, 0.25, 30, 0.001) # NOTE: gr.peak_detector_fb is broken! #peak_detect = gr.peak_detector_fb(0.55, 0.55, 30, 0.001) #peak_detect = gr.peak_detector_fb(0.45, 0.45, 30, 0.001) #peak_detect = gr.peak_detector_fb(0.30, 0.30, 30, 0.001) # offset by -1 self.connect(M_d, matched_filter, gr.add_const_ff(-1), peak_detect) # peak_detect indicates the time M_d is highest, which is the end of the symbol. # We should try to sample in the middle of the plateau!! # FIXME until we figure out how to do this, just offset by cp_length/2 offset = 6 #cp_length/2 # nco(t) = P_d_angle(t-offset) sampled at peak_detect(t) # modulate input(t - fft_length) by nco(t) # signal to sample input(t) at t-offset # # We can't delay by < 0 so instead: # input is delayed by fft_length # P_d_angle is delayed by offset # signal to sample is delayed by fft_length - offset # phi = gr.sample_and_hold_ff() self.connect(peak_detect, (phi, 1)) self.connect(P_d_angle, gr.delay(gr.sizeof_float, offset), (phi, 0)) #self.connect(P_d_angle, matched_filter2, (phi,0)) # why isn't this better?!? # FIXME: we add fft_length delay so that the preamble is nco corrected too # BUT is this buffering worth it? consider implementing sync as a proper block # delay the input signal to follow the frequency offset signal self.connect(self, gr.delay(gr.sizeof_gr_complex, (fft_length + offset)), (self, 0)) self.connect(phi, (self, 1)) self.connect(peak_detect, (self, 2)) if logging: self.connect(matched_filter, gr.file_sink(gr.sizeof_float, "sync-mf.dat")) self.connect(M_d, gr.file_sink(gr.sizeof_float, "sync-M.dat")) self.connect(P_d_angle, gr.file_sink(gr.sizeof_float, "sync-angle.dat")) self.connect(peak_detect, gr.file_sink(gr.sizeof_char, "sync-peaks.datb")) self.connect(phi, gr.file_sink(gr.sizeof_float, "sync-phi.dat"))
def __init__(self, fft_length, cp_length, half_sync, kstime, ks1time, threshold, logging=False): gr.hier_block2.__init__( self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature3( 3, 3, # Output signature gr.sizeof_gr_complex, # delayed input gr.sizeof_float, # fine frequency offset gr.sizeof_char, # timing indicator ), ) if half_sync: period = fft_length / 2 window = fft_length / 2 else: # full symbol period = fft_length + cp_length window = fft_length # makes the plateau cp_length long # Calculate the frequency offset from the correlation of the preamble x_corr = gr.multiply_cc() self.connect(self, gr.conjugate_cc(), (x_corr, 0)) self.connect(self, gr.delay(gr.sizeof_gr_complex, period), (x_corr, 1)) P_d = gr.moving_average_cc(window, 1.0) self.connect(x_corr, P_d) # offset by -1 phi = gr.sample_and_hold_ff() self.corrmag = gr.complex_to_mag_squared() P_d_angle = gr.complex_to_arg() self.connect(P_d, P_d_angle, (phi, 0)) cross_correlate = 1 if cross_correlate == 1: # cross-correlate with the known symbol kstime = [k.conjugate() for k in kstime] kstime.reverse() self.crosscorr_filter = gr.fir_filter_ccc(1, kstime) """ self.f2b = gr.float_to_char() self.slice = gr.threshold_ff(threshold, threshold, 0, fft_length) #self.connect(self, self.crosscorr_filter, self.corrmag, self.slice, self.f2b) self.connect(self.f2b, (phi,1)) self.connect(self.f2b, (self,2)) self.connect(self.f2b, gr.file_sink(gr.sizeof_char, "ofdm_f2b.dat")) """ # new method starts here - only crosscorrelate and use peak_detect block # peak_detect = gr.peak_detector_fb(100, 100, 30, 0.001) self.corrmag1 = gr.complex_to_mag_squared() self.connect(self, self.crosscorr_filter, self.corrmag, peak_detect) self.connect(peak_detect, (phi, 1)) self.connect(peak_detect, (self, 2)) self.connect(peak_detect, gr.file_sink(gr.sizeof_char, "sync-peaks_b.dat")) self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "ofdm_corrmag.dat")) self.connect(self, gr.delay(gr.sizeof_gr_complex, (fft_length)), (self, 0)) else: # Get the power of the input signal to normalize the output of the correlation R_d = gr.moving_average_ff(window, 1.0) self.connect(self, gr.complex_to_mag_squared(), R_d) R_d_squared = gr.multiply_ff() # this is retarded self.connect(R_d, (R_d_squared, 0)) self.connect(R_d, (R_d_squared, 1)) M_d = gr.divide_ff() self.connect(P_d, gr.complex_to_mag_squared(), (M_d, 0)) self.connect(R_d_squared, (M_d, 1)) # Now we need to detect peak of M_d matched_filter = gr.moving_average_ff(cp_length, 1.0 / cp_length) peak_detect = gr.peak_detector_fb(0.25, 0.25, 30, 0.001) self.connect(M_d, matched_filter, gr.add_const_ff(-1), peak_detect) offset = cp_length / 2 # cp_length/2 self.connect(peak_detect, (phi, 1)) self.connect(peak_detect, (self, 2)) self.connect(P_d_angle, gr.delay(gr.sizeof_float, offset), (phi, 0)) self.connect( self, gr.delay(gr.sizeof_gr_complex, (fft_length + offset)), (self, 0) ) # delay the input to follow the freq offset self.connect(peak_detect, gr.delay(gr.sizeof_char, (fft_length + offset)), (self, 2)) self.connect(peak_detect, gr.file_sink(gr.sizeof_char, "sync-peaks_b.dat")) self.connect(matched_filter, gr.file_sink(gr.sizeof_float, "sync-mf.dat")) self.connect(phi, (self, 1)) if logging: self.connect(matched_filter, gr.file_sink(gr.sizeof_float, "sync-mf.dat")) self.connect(M_d, gr.file_sink(gr.sizeof_float, "sync-M.dat")) self.connect(P_d_angle, gr.file_sink(gr.sizeof_float, "sync-angle.dat")) self.connect(peak_detect, gr.file_sink(gr.sizeof_char, "sync-peaks.datb")) self.connect(phi, gr.file_sink(gr.sizeof_float, "sync-phi.dat"))
def __init__(self, fft_length, cp_length, logging=False): """ OFDM synchronization using PN Correlation: T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchonization for OFDM," IEEE Trans. Communications, vol. 45, no. 12, 1997. Improved with averaging over the whole FFT and peak averaging over cp_length. """ gr.hier_block2.__init__(self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) self.conjg = gr.conjugate_cc(); self.corr = gr.multiply_cc(); moving_sum_taps = [1.0 for i in range(fft_length//2)] self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps) self.inputmag2 = gr.complex_to_mag_squared() #movingsum2_taps = [0.125 for i in range(fft_length*4)] movingsum2_taps = [0.5 for i in range(fft_length*4)] self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps) self.square = gr.multiply_ff() self.normalize = gr.divide_ff() self.c2mag = gr.complex_to_mag_squared() self.angle = gr.complex_to_arg() self.sample_and_hold = flex.sample_and_hold_ff() self.sub1 = gr.add_const_ff(-1) # linklab, change peak detector parameters: use higher threshold to detect rise/fall of peak #self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001) self.pk_detect = flex.peak_detector_fb(0.7, 0.7, 30, 0.001) # linklab #self.pk_detect = gr.peak_detector2_fb(9) self.connect(self, self.input) # Lower branch: self.connect(self.input, self.delay) self.connect(self.input, (self.corr,0)) self.connect(self.delay, self.conjg) self.connect(self.conjg, (self.corr,1)) self.connect(self.corr, self.moving_sum_filter) self.connect(self.moving_sum_filter, self.c2mag) self.connect(self.moving_sum_filter, self.angle) self.connect(self.angle, (self.sample_and_hold,0)) self.connect(self.c2mag, (self.normalize,0)) # Upper branch self.connect(self.input, self.inputmag2, self.inputmovingsum) self.connect(self.inputmovingsum, (self.square,0)) self.connect(self.inputmovingsum, (self.square,1)) self.connect(self.square, (self.normalize,1)) matched_filter_taps = [1.0/cp_length for i in range(cp_length)] self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps) self.connect(self.normalize, self.matched_filter) # linklab, provide the signal power into peak detector, linklab self.connect(self.square, (self.pk_detect,1)) self.connect(self.matched_filter, self.sub1, (self.pk_detect, 0)) self.connect(self.pk_detect, (self.sample_and_hold,1)) # Set output signals # Output 0: fine frequency correction value # Output 1: timing signal self.connect(self.sample_and_hold, (self,0)) self.connect(self.pk_detect, (self,1)) if logging: self.connect(self.square, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-square.dat")) self.connect(self.c2mag, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-c2mag.dat")) self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) self.connect(self.sub1, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sub1.dat")) self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
def __init__(self): gr.top_block.__init__(self) usage=("%prog: [options] output_filename.\nSpecial output_filename" + \ "\"sdl\" will use video_sink_sdl as realtime output window. " + \ "You then need to have gr-video-sdl installed.\n" +\ "Make sure your input capture file containes interleaved " + \ "shorts not complex floats") parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-a", "--args", type="string", default="", help="UHD device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate") parser.add_option("-c", "--contrast", type="eng_float", default=1.0, help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") parser.add_option("-i", "--in-filename", type="string", default=None, help="Use input file as source. samples must be " + \ "interleaved shorts \n Use usrp_rx_file.py or " + \ "usrp_rx_cfile.py --output-shorts.\n Special " + \ "name \"usrp\" results in realtime capturing " + \ "and processing using usrp.\n" + \ "You then probably need a decimation factor of 64 or higher.") parser.add_option( "-f", "--freq", type="eng_float", default=519.25e6, help= "set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-p", "--pal", action="store_true", default=False, help="PAL video format (this is the default)") parser.add_option("-n", "--ntsc", action="store_true", default=False, help="NTSC video format") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat in_file in a loop") parser.add_option("-N", "--nframes", type="eng_float", default=None, help="number of frames to collect [default=+inf]") parser.add_option("", "--freq-min", type="eng_float", default=50.25e6, help="Set a minimum frequency [default=%default]") parser.add_option("", "--freq-max", type="eng_float", default=900.25e6, help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args() if not (len(args) == 1): parser.print_help() sys.stderr.write('You must specify the output. FILENAME or sdl \n') sys.exit(1) filename = args[0] self.tv_freq_min = options.freq_min self.tv_freq_max = options.freq_max if options.in_filename is None: parser.print_help() sys.stderr.write( 'You must specify the input -i FILENAME or -i usrp\n') raise SystemExit, 1 if not (filename == "sdl"): options.repeat = False input_rate = options.samp_rate print "video sample rate %s" % (eng_notation.num_to_str(input_rate)) if not (options.in_filename == "usrp"): # file is data source, capture with usr_rx_csfile.py self.filesource = gr.file_source(gr.sizeof_short, options.in_filename, options.repeat) self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource, self.istoc) self.src = self.istoc else: if options.freq is None: parser.print_help() sys.stderr.write( 'You must specify the frequency with -f FREQ\n') raise SystemExit, 1 # build the graph self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if (options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if (options.antenna): self.u.set_antenna(options.antenna, 0) self.u.set_samp_rate(input_rate) dev_rate = self.u.get_samp_rate() self.src = self.u if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.u.get_gain_range() options.gain = float(g.start() + g.stop()) / 2.0 self.u.set_gain(options.gain) r = self.u.set_center_freq(options.freq) if not r: sys.stderr.write('Failed to set frequency\n') raise SystemExit, 1 self.agc = gr.agc_cc(1e-7, 1.0, 1.0) #1e-7 self.am_demod = gr.complex_to_mag() self.set_blacklevel = gr.add_const_ff(options.brightness + 255.0) self.invert_and_scale = gr.multiply_const_ff(-options.contrast * 128.0 * 255.0 / (200.0)) self.f2uc = gr.float_to_uchar() # sdl window as final sink if not (options.pal or options.ntsc): options.pal = True #set default to PAL if options.pal: lines_per_frame = 625.0 frames_per_sec = 25.0 show_width = 768 elif options.ntsc: lines_per_frame = 525.0 frames_per_sec = 29.97002997 show_width = 640 width = int(input_rate / (lines_per_frame * frames_per_sec)) height = int(lines_per_frame) if filename == "sdl": #Here comes the tv screen, you have to build and install #gr-video-sdl for this (subproject of gnuradio, only in cvs #for now) try: video_sink = video_sdl.sink_uc(frames_per_sec, width, height, 0, show_width, height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" raise SystemExit, 1 self.dst = video_sink else: print "You can use the imagemagick display tool to show the resulting imagesequence" print "use the following line to show the demodulated TV-signal:" print "display -depth 8 -size " + str(width) + "x" + str( height) + " gray:" + filename print "(Use the spacebar to advance to next frames)" file_sink = gr.file_sink(gr.sizeof_char, filename) self.dst = file_sink if options.nframes is None: self.connect(self.src, self.agc) else: self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes * width * height)) self.connect(self.src, self.head, self.agc) self.connect(self.agc, self.am_demod, self.invert_and_scale, self.set_blacklevel, self.f2uc, self.dst)
def __init__(self): gr.top_block.__init__(self) usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \ "You then need to have gr-video-sdl installed. \n" \ "Make sure your input capture file containes interleaved shorts not complex floats" parser = OptionParser(option_class=eng_option, usage=usage) 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("-c", "--contrast", type="eng_float", default=1.0, help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") parser.add_option( "-d", "--decim", type="int", default=8, help="set fgpa decimation rate to DECIM [default=%default]") parser.add_option( "-i", "--in-filename", type="string", default=None, help= "Use input file as source. samples must be interleaved shorts \n " + "Use usrp_rx_file.py or usrp_rx_cfile.py --output-shorts. \n" "Special name \"usrp\" results in realtime capturing and processing using usrp. \n" + "You then probably need a decimation factor of 64 or higher.") parser.add_option( "-f", "--freq", type="eng_float", default=None, help= "set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-p", "--pal", action="store_true", default=False, help="PAL video format (this is the default)") parser.add_option("-n", "--ntsc", action="store_true", default=False, help="NTSC video format") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat in_file in a loop") parser.add_option("-8", "--width-8", action="store_true", default=False, help="Enable 8-bit samples across USB") parser.add_option("-N", "--nframes", type="eng_float", default=None, help="number of frames to collect [default=+inf]") parser.add_option("--no-hb", action="store_true", default=False, help="don't use halfband filter in usrp") (options, args) = parser.parse_args() if not (len(args) == 1): parser.print_help() sys.stderr.write('You must specify the output. FILENAME or sdl \n') sys.exit(1) filename = args[0] if options.in_filename is None: parser.print_help() sys.stderr.write( 'You must specify the input -i FILENAME or -i usrp\n') raise SystemExit, 1 if not (filename == "sdl"): options.repeat = False if not (options.in_filename == "usrp"): self.filesource = gr.file_source( gr.sizeof_short, options.in_filename, options.repeat ) # file is data source, capture with usr_rx_csfile.py self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource, self.istoc) self.adc_rate = 64e6 self.src = self.istoc else: if options.freq is None: parser.print_help() sys.stderr.write( 'You must specify the frequency with -f FREQ\n') raise SystemExit, 1 if abs(options.freq) < 1e6: options.freq *= 1e6 if options.no_hb or (options.decim < 8): self.fpga_filename = "std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths else: self.fpga_filename = "std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default) # build the graph self.u = usrp.source_c(decim_rate=options.decim, fpga_filename=self.fpga_filename) self.src = self.u if options.width_8: sample_width = 8 sample_shift = 8 format = self.u.make_format(sample_width, sample_shift) r = self.u.set_format(format) self.adc_rate = self.u.adc_freq() if options.rx_subdev_spec is None: options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u) self.u.set_mux( usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) # determine the daughterboard subdevice we're using self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) print "Using RX d'board %s" % (self.subdev.side_and_name(), ) 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 self.subdev.set_gain(options.gain) r = self.u.tune(0, self.subdev, options.freq) if not r: sys.stderr.write('Failed to set frequency\n') raise SystemExit, 1 input_rate = self.adc_rate / options.decim print "video sample rate %s" % (eng_notation.num_to_str(input_rate)) self.agc = gr.agc_cc(1e-7, 1.0, 1.0) #1e-7 self.am_demod = gr.complex_to_mag() self.set_blacklevel = gr.add_const_ff(options.brightness + 255.0) self.invert_and_scale = gr.multiply_const_ff(-options.contrast * 128.0 * 255.0 / (200.0)) self.f2uc = gr.float_to_uchar() # sdl window as final sink if not (options.pal or options.ntsc): options.pal = True #set default to PAL if options.pal: lines_per_frame = 625.0 frames_per_sec = 25.0 show_width = 768 elif options.ntsc: lines_per_frame = 525.0 frames_per_sec = 29.97002997 show_width = 640 width = int(input_rate / (lines_per_frame * frames_per_sec)) height = int(lines_per_frame) if filename == "sdl": #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now) try: video_sink = video_sdl.sink_uc(frames_per_sec, width, height, 0, show_width, height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" raise SystemExit, 1 self.dst = video_sink else: print "You can use the imagemagick display tool to show the resulting imagesequence" print "use the following line to show the demodulated TV-signal:" print "display -depth 8 -size " + str(width) + "x" + str( height) + " gray:" + filename print "(Use the spacebar to advance to next frames)" file_sink = gr.file_sink(gr.sizeof_char, filename) self.dst = file_sink if options.nframes is None: self.connect(self.src, self.agc) else: self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes * width * height)) self.connect(self.src, self.head, self.agc) self.connect(self.agc, self.am_demod, self.invert_and_scale, self.set_blacklevel, self.f2uc, self.dst)
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option( "-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ" ) parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option("-d", "--decim", type="int", default=250, help="USRP decimation") parser.add_option( "-R", "--rx-subdev-spec", type="subdev", default=None, help="select USRP Rx side A or B (default=first one with a daughterboard)", ) (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq usb_rate = 64e6 / options.decim self.slider_range = usb_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(usb_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 / options.decim self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue((self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = usrp.source_s(decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.src) self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) self.src.tune(0, self.subdev, self.usrp_center) self.tune_offset = 0 # -self.usrp_center - self.src.rx_freq(0) else: self.src = gr.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # save radio data to a file if SAVE_RADIO_TO_FILE: file = gr.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, file) # 2nd DDC xlate_taps = gr.firdes.low_pass(1.0, usb_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING) self.xlate = gr.freq_xlating_fir_filter_ccf(fir_decim, xlate_taps, self.tune_offset, usb_rate) # convert rf data in interleaved short int form to complex s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING, ) # window self.slider_1.SetValue(0) self.slider_2.SetValue(-3000) self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c( self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240) ) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c( self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240), ) c2f = gr.complex_to_float() # AM branch self.sel_am = gr.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = gr.pll_refout_cc( 0.5, 0.0625, (2.0 * math.pi * 7.5e3 / self.af_sample_rate), (2.0 * math.pi * 6.5e3 / self.af_sample_rate) ) self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason gr.conjugate_cc() adds noise ?? c2f2 = gr.complex_to_float() c2f3 = gr.complex_to_float() f2c = gr.float_to_complex() phaser1 = gr.multiply_const_ff(1) phaser2 = gr.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = gr.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition gr.firdes.WIN_HAMMING, ) # window self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() # AGC sqr1 = gr.multiply_ff() intr = gr.iir_filter_ffd([0.004, 0], [0, 0.999]) offset = gr.add_const_ff(1) agc = gr.divide_ff() self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate)) self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short, options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win) # and left click to re-tune em.eventManager.Register(self.Click, wx.EVT_LEFT_DOWN, self.fft.win) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def __init__(self, fft_length, cp_length, kstime, threshold, threshold_type, threshold_gap, logging=False): """ OFDM synchronization using PN Correlation: T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchonization for OFDM," IEEE Trans. Communications, vol. 45, no. 12, 1997. """ gr.hier_block2.__init__(self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) # PN Sync # Create a delay line self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) # Correlation from ML Sync self.conjg = gr.conjugate_cc(); self.corr = gr.multiply_cc(); # Create a moving sum filter for the corr output if 1: moving_sum_taps = [1.0 for i in range(fft_length//2)] self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps) else: moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)] self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps) # Create a moving sum filter for the input self.inputmag2 = gr.complex_to_mag_squared() movingsum2_taps = [1.0 for i in range(fft_length//2)] #movingsum2_taps = [0.5 for i in range(fft_length*4)] #apurv - implementing Veljo's suggestion, when pause b/w packets if 1: self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps) else: self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps) self.square = gr.multiply_ff() self.normalize = gr.divide_ff() # Get magnitude (peaks) and angle (phase/freq error) self.c2mag = gr.complex_to_mag_squared() self.angle = gr.complex_to_arg() self.sample_and_hold = gr.sample_and_hold_ff() #ML measurements input to sampler block and detect self.sub1 = gr.add_const_ff(-1) self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001) #apurv - implementing Veljo's suggestion, when pause b/w packets self.connect(self, self.input) # Calculate the frequency offset from the correlation of the preamble self.connect(self.input, self.delay) self.connect(self.input, (self.corr,0)) self.connect(self.delay, self.conjg) self.connect(self.conjg, (self.corr,1)) self.connect(self.corr, self.moving_sum_filter) #self.connect(self.moving_sum_filter, self.c2mag) self.connect(self.moving_sum_filter, self.angle) self.connect(self.angle, (self.sample_and_hold,0)) # apurv-- #self.connect(self.angle, gr.delay(gr.sizeof_float, offset), (self.sample_and_hold, 0)) #apurv++ cross_correlate = 1 if cross_correlate==1: # cross-correlate with the known symbol kstime = [k.conjugate() for k in kstime] kstime.reverse() self.crosscorr_filter = gr.fir_filter_ccc(1, kstime) # get the magnitude # self.corrmag = gr.complex_to_mag_squared() self.f2b = gr.float_to_char() self.threshold_factor = threshold #0.0012 #0.012 #0.0015 if 0: self.slice = gr.threshold_ff(self.threshold_factor, self.threshold_factor, 0, fft_length) else: #thresholds = [self.threshold_factor, 9e-5] self.slice = gr.threshold_ff(threshold, threshold, 0, fft_length, threshold_type, threshold_gap) self.connect(self.input, self.crosscorr_filter, self.corrmag, self.slice, self.f2b) # some debug dump # self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "ofdm_corrmag.dat")) #self.connect(self.f2b, gr.file_sink(gr.sizeof_char, "ofdm_f2b.dat")) self.connect(self.f2b, (self.sample_and_hold,1)) # Set output signals # Output 0: fine frequency correction value # Output 1: timing signal self.connect(self.sample_and_hold, (self,0)) #self.connect(self.pk_detect, (self,1)) #removed #self.connect(self.f2b, gr.delay(gr.sizeof_char, 1), (self, 1)) self.connect(self.f2b, (self, 1)) if logging: self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_fcutoff_hi = wx.Slider(self, ID_SLIDER_1, 0, -15798, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_fcutoff_lo = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15798, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option("", "--address", type="string", default="addr=192.168.10.2", help="Address of UHD device, [default=%default]") parser.add_option("-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ") parser.add_option( "-s", "--samp-rate", type="eng_float", default=256e3, help="set sample rate (bandwidth) [default=%default]") parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option( "-O", "--audio-output", type="string", default="", help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse") (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq input_rate = options.samp_rate self.slider_range = input_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(input_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue( (self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = uhd.usrp_source(device_addr=options.address, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) self.src.set_samp_rate(input_rate) input_rate = self.src.get_samp_rate() self.src.set_center_freq(self.usrp_center, 0) self.tune_offset = 0 else: self.src = gr.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # convert rf data in interleaved short int form to complex s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # save radio data to a file if SAVE_RADIO_TO_FILE: radio_file = gr.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, radio_file) # 2nd DDC xlate_taps = gr.firdes.low_pass ( \ 1.0, input_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING ) self.xlate = gr.freq_xlating_fir_filter_ccf ( \ fir_decim, xlate_taps, self.tune_offset, input_rate ) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.slider_fcutoff_hi.SetValue(0) self.slider_fcutoff_lo.SetValue(-3000) self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c(self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c(self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)) c2f = gr.complex_to_float() # AM branch self.sel_am = gr.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = gr.pll_refout_cc(.5, .0625, (2. * math.pi * 7.5e3 / self.af_sample_rate), (2. * math.pi * 6.5e3 / self.af_sample_rate)) self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason gr.conjugate_cc() adds noise ?? c2f2 = gr.complex_to_float() c2f3 = gr.complex_to_float() f2c = gr.float_to_complex() phaser1 = gr.multiply_const_ff(1) phaser2 = gr.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = gr.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() #AGC sqr1 = gr.multiply_ff() intr = gr.iir_filter_ffd([.004, 0], [0, .999]) offset = gr.add_const_ff(1) agc = gr.divide_ff() self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate), options.audio_output) if self.PLAY_FROM_USRP: self.tb.connect(self.src, self.xlate, self.fft) else: self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short, options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display self.fft.win.Bind(wx.EVT_LEFT_UP, self.Mouse) # and left click to re-tune self.fft.win.Bind(wx.EVT_LEFT_DOWN, self.Click) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def __init__(self): gr.top_block.__init__(self) usage=("%prog: [options] output_filename.\nSpecial output_filename" + \ "\"sdl\" will use video_sink_sdl as realtime output window. " + \ "You then need to have gr-video-sdl installed.\n" +\ "Make sure your input capture file containes interleaved " + \ "shorts not complex floats") parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-a", "--args", type="string", default="", help="UHD device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate") parser.add_option("-c", "--contrast", type="eng_float", default=1.0, help="set contrast (default is 1.0)") parser.add_option("-b", "--brightness", type="eng_float", default=0.0, help="set brightness (default is 0)") parser.add_option("-i", "--in-filename", type="string", default=None, help="Use input file as source. samples must be " + \ "interleaved shorts \n Use usrp_rx_file.py or " + \ "usrp_rx_cfile.py --output-shorts.\n Special " + \ "name \"usrp\" results in realtime capturing " + \ "and processing using usrp.\n" + \ "You then probably need a decimation factor of 64 or higher.") parser.add_option("-f", "--freq", type="eng_float", default=519.25e6, help="set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("-p", "--pal", action="store_true", default=False, help="PAL video format (this is the default)") parser.add_option("-n", "--ntsc", action="store_true", default=False, help="NTSC video format") parser.add_option("-r", "--repeat", action="store_false", default=True, help="repeat in_file in a loop") parser.add_option("-N", "--nframes", type="eng_float", default=None, help="number of frames to collect [default=+inf]") parser.add_option("", "--freq-min", type="eng_float", default=50.25e6, help="Set a minimum frequency [default=%default]") parser.add_option("", "--freq-max", type="eng_float", default=900.25e6, help="Set a maximum frequency [default=%default]") (options, args) = parser.parse_args () if not (len(args) == 1): parser.print_help() sys.stderr.write('You must specify the output. FILENAME or sdl \n'); sys.exit(1) filename = args[0] self.tv_freq_min = options.freq_min self.tv_freq_max = options.freq_max if options.in_filename is None: parser.print_help() sys.stderr.write('You must specify the input -i FILENAME or -i usrp\n'); raise SystemExit, 1 if not (filename=="sdl"): options.repeat=False input_rate = options.samp_rate print "video sample rate %s" % (eng_notation.num_to_str(input_rate)) if not (options.in_filename=="usrp"): # file is data source, capture with usr_rx_csfile.py self.filesource = gr.file_source(gr.sizeof_short, options.in_filename, options.repeat) self.istoc = gr.interleaved_short_to_complex() self.connect(self.filesource,self.istoc) self.src=self.istoc else: if options.freq is None: parser.print_help() sys.stderr.write('You must specify the frequency with -f FREQ\n'); raise SystemExit, 1 # build the graph self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if(options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if(options.antenna): self.u.set_antenna(options.antenna, 0) self.u.set_samp_rate(input_rate) dev_rate = self.u.get_samp_rate() self.src=self.u if options.gain is None: # if no gain was specified, use the mid-point in dB g = self.u.get_gain_range() options.gain = float(g.start()+g.stop())/2.0 self.u.set_gain(options.gain) r = self.u.set_center_freq(options.freq) if not r: sys.stderr.write('Failed to set frequency\n') raise SystemExit, 1 self.agc = gr.agc_cc(1e-7,1.0,1.0) #1e-7 self.am_demod = gr.complex_to_mag () self.set_blacklevel = gr.add_const_ff(options.brightness +255.0) self.invert_and_scale = gr.multiply_const_ff (-options.contrast *128.0*255.0/(200.0)) self.f2uc = gr.float_to_uchar() # sdl window as final sink if not (options.pal or options.ntsc): options.pal=True #set default to PAL if options.pal: lines_per_frame=625.0 frames_per_sec=25.0 show_width=768 elif options.ntsc: lines_per_frame=525.0 frames_per_sec=29.97002997 show_width=640 width=int(input_rate/(lines_per_frame*frames_per_sec)) height=int(lines_per_frame) if filename=="sdl": #Here comes the tv screen, you have to build and install #gr-video-sdl for this (subproject of gnuradio, only in cvs #for now) try: video_sink = video_sdl.sink_uc(frames_per_sec, width, height, 0, show_width,height) except: print "gr-video-sdl is not installed" print "realtime \"sdl\" video output window is not available" raise SystemExit, 1 self.dst=video_sink else: print "You can use the imagemagick display tool to show the resulting imagesequence" print "use the following line to show the demodulated TV-signal:" print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" +filename print "(Use the spacebar to advance to next frames)" file_sink=gr.file_sink(gr.sizeof_char, filename) self.dst =file_sink if options.nframes is None: self.connect(self.src, self.agc) else: self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes*width*height)) self.connect(self.src, self.head, self.agc) self.connect (self.agc, self.am_demod, self.invert_and_scale, self.set_blacklevel, self.f2uc, self.dst)
def __init__(self, fft_length, cp_length, logging=False): """ OFDM synchronization using PN Correlation: T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchonization for OFDM," IEEE Trans. Communications, vol. 45, no. 12, 1997. """ gr.hier_block2.__init__(self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) # PN Sync # Create a delay line self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) # Correlation from ML Sync self.conjg = gr.conjugate_cc(); self.corr = gr.multiply_cc(); # Create a moving sum filter for the corr output if 1: moving_sum_taps = [1.0 for i in range(fft_length//2)] self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps) else: moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)] self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps) # Create a moving sum filter for the input self.inputmag2 = gr.complex_to_mag_squared() # Modified by Yong (12.06.27) #movingsum2_taps = [1.0 for i in range(fft_length//2)] movingsum2_taps = [0.5 for i in range(fft_length)] if 1: self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps) else: self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps) self.square = gr.multiply_ff() self.normalize = gr.divide_ff() # Get magnitude (peaks) and angle (phase/freq error) self.c2mag = gr.complex_to_mag_squared() self.angle = gr.complex_to_arg() self.sample_and_hold = gr.sample_and_hold_ff() #ML measurements input to sampler block and detect self.sub1 = gr.add_const_ff(-1) self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001) #self.pk_detect = gr.peak_detector2_fb(9) self.connect(self, self.input) # Calculate the frequency offset from the correlation of the preamble self.connect(self.input, self.delay) self.connect(self.input, (self.corr,0)) self.connect(self.delay, self.conjg) self.connect(self.conjg, (self.corr,1)) self.connect(self.corr, self.moving_sum_filter) self.connect(self.moving_sum_filter, self.c2mag) self.connect(self.moving_sum_filter, self.angle) self.connect(self.angle, (self.sample_and_hold,0)) # Get the power of the input signal to normalize the output of the correlation self.connect(self.input, self.inputmag2, self.inputmovingsum) self.connect(self.inputmovingsum, (self.square,0)) self.connect(self.inputmovingsum, (self.square,1)) self.connect(self.square, (self.normalize,1)) self.connect(self.c2mag, (self.normalize,0)) # Create a moving sum filter for the corr output matched_filter_taps = [1.0/cp_length for i in range(cp_length)] self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps) self.connect(self.normalize, self.matched_filter) self.connect(self.matched_filter, self.sub1, self.pk_detect) #self.connect(self.matched_filter, self.pk_detect) self.connect(self.pk_detect, (self.sample_and_hold,1)) # Set output signals # Output 0: fine frequency correction value # Output 1: timing signal self.connect(self.sample_and_hold, (self,0)) self.connect(self.pk_detect, (self,1)) if logging: self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) self.connect(self.c2mag, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-nominator_f.dat")) self.connect(self.square, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-denominator_f.dat")) self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
def __init__(self, fft_length, cp_length, kstime, threshold, threshold_type, threshold_gap, logging=False): """ OFDM synchronization using PN Correlation: T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchonization for OFDM," IEEE Trans. Communications, vol. 45, no. 12, 1997. """ gr.hier_block2.__init__( self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) # PN Sync # Create a delay line self.delay = gr.delay(gr.sizeof_gr_complex, fft_length / 2) # Correlation from ML Sync self.conjg = gr.conjugate_cc() self.corr = gr.multiply_cc() # Create a moving sum filter for the corr output if 1: moving_sum_taps = [1.0 for i in range(fft_length // 2)] self.moving_sum_filter = gr.fir_filter_ccf(1, moving_sum_taps) else: moving_sum_taps = [ complex(1.0, 0.0) for i in range(fft_length // 2) ] self.moving_sum_filter = gr.fft_filter_ccc(1, moving_sum_taps) # Create a moving sum filter for the input self.inputmag2 = gr.complex_to_mag_squared() movingsum2_taps = [1.0 for i in range(fft_length // 2)] #movingsum2_taps = [0.5 for i in range(fft_length*4)] #apurv - implementing Veljo's suggestion, when pause b/w packets if 1: self.inputmovingsum = gr.fir_filter_fff(1, movingsum2_taps) else: self.inputmovingsum = gr.fft_filter_fff(1, movingsum2_taps) self.square = gr.multiply_ff() self.normalize = gr.divide_ff() # Get magnitude (peaks) and angle (phase/freq error) self.c2mag = gr.complex_to_mag_squared() self.angle = gr.complex_to_arg() self.sample_and_hold = gr.sample_and_hold_ff() #ML measurements input to sampler block and detect self.sub1 = gr.add_const_ff(-1) self.pk_detect = gr.peak_detector_fb( 0.20, 0.20, 30, 0.001 ) #apurv - implementing Veljo's suggestion, when pause b/w packets self.connect(self, self.input) # Calculate the frequency offset from the correlation of the preamble self.connect(self.input, self.delay) self.connect(self.input, (self.corr, 0)) self.connect(self.delay, self.conjg) self.connect(self.conjg, (self.corr, 1)) self.connect(self.corr, self.moving_sum_filter) #self.connect(self.moving_sum_filter, self.c2mag) self.connect(self.moving_sum_filter, self.angle) self.connect(self.angle, (self.sample_and_hold, 0)) # apurv-- #self.connect(self.angle, gr.delay(gr.sizeof_float, offset), (self.sample_and_hold, 0)) #apurv++ cross_correlate = 1 if cross_correlate == 1: # cross-correlate with the known symbol kstime = [k.conjugate() for k in kstime] kstime.reverse() self.crosscorr_filter = gr.fir_filter_ccc(1, kstime) # get the magnitude # self.corrmag = gr.complex_to_mag_squared() self.f2b = gr.float_to_char() self.threshold_factor = threshold #0.0012 #0.012 #0.0015 if 0: self.slice = gr.threshold_ff(self.threshold_factor, self.threshold_factor, 0, fft_length) else: #thresholds = [self.threshold_factor, 9e-5] self.slice = gr.threshold_ff(threshold, threshold, 0, fft_length, threshold_type, threshold_gap) self.connect(self.input, self.crosscorr_filter, self.corrmag, self.slice, self.f2b) # some debug dump # self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "ofdm_corrmag.dat")) #self.connect(self.f2b, gr.file_sink(gr.sizeof_char, "ofdm_f2b.dat")) self.connect(self.f2b, (self.sample_and_hold, 1)) # Set output signals # Output 0: fine frequency correction value # Output 1: timing signal self.connect(self.sample_and_hold, (self, 0)) #self.connect(self.pk_detect, (self,1)) #removed #self.connect(self.f2b, gr.delay(gr.sizeof_char, 1), (self, 1)) self.connect(self.f2b, (self, 1)) if logging: self.connect( self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) self.connect( self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) self.connect( self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) self.connect( self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) self.connect( self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) self.connect( self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
def __init__(self, vlen): gr.hier_block2.__init__( self, "snr_estimator", gr.io_signature2(2, 2, gr.sizeof_gr_complex, gr.sizeof_char), gr.io_signature(1, 1, gr.sizeof_float)) data_in = (self, 0) trig_in = (self, 1) snr_out = (self, 0) ## Preamble Extraction sampler = vector_sampler(gr.sizeof_gr_complex, vlen) self.connect(data_in, sampler) self.connect(trig_in, (sampler, 1)) ## Algorithm implementation estim = sc_snr_estimator(vlen) self.connect(sampler, estim) self.connect(estim, snr_out) return ## Split block into two parts splitter = gr.vector_to_streams(gr.sizeof_gr_complex * vlen / 2, 2) self.connect(sampler, splitter) ## Conjugate first half block conj = gr.conjugate_cc(vlen / 2) self.connect(splitter, conj) ## Vector multiplication of both half blocks vmult = gr.multiply_vcc(vlen / 2) self.connect(conj, vmult) self.connect((splitter, 1), (vmult, 1)) ## Sum of Products psum = vector_sum_vcc(vlen / 2) self.connect(vmult, psum) ## Magnitude of P(d) p_mag = gr.complex_to_mag() self.connect(psum, p_mag) ## Squared Magnitude of block r_magsqrd = gr.complex_to_mag_squared(vlen) self.connect(sampler, r_magsqrd) ## Sum of squared second half block r_sum = vector_sum_vff(vlen) self.connect(r_magsqrd, r_sum) ## Square Root of Metric m_sqrt = gr.divide_ff() self.connect(p_mag, (m_sqrt, 0)) self.connect(r_sum, gr.multiply_const_ff(0.5), (m_sqrt, 1)) ## Denominator of SNR estimate denom = gr.add_const_ff(1) neg_m_sqrt = gr.multiply_const_ff(-1.0) self.connect(m_sqrt, limit_vff(1, 1 - 2e-5, -1000), neg_m_sqrt, denom) ## SNR estimate snr_est = gr.divide_ff() self.connect(m_sqrt, (snr_est, 0)) self.connect(denom, (snr_est, 1)) ## Setup Output Connections self.connect(snr_est, self)
def __init__(self, vlen): gr.hier_block2.__init__(self, "snr_estimator", gr.io_signature2(2,2,gr.sizeof_gr_complex,gr.sizeof_char), gr.io_signature (1,1,gr.sizeof_float)) data_in = (self,0) trig_in = (self,1) snr_out = (self,0) ## Preamble Extraction sampler = vector_sampler(gr.sizeof_gr_complex,vlen) self.connect(data_in,sampler) self.connect(trig_in,(sampler,1)) ## Algorithm implementation estim = sc_snr_estimator(vlen) self.connect(sampler,estim) self.connect(estim,snr_out) return ## Split block into two parts splitter = gr.vector_to_streams(gr.sizeof_gr_complex*vlen/2,2) self.connect(sampler,splitter) ## Conjugate first half block conj = gr.conjugate_cc(vlen/2) self.connect(splitter,conj) ## Vector multiplication of both half blocks vmult = gr.multiply_vcc(vlen/2) self.connect(conj,vmult) self.connect((splitter,1),(vmult,1)) ## Sum of Products psum = vector_sum_vcc(vlen/2) self.connect(vmult,psum) ## Magnitude of P(d) p_mag = gr.complex_to_mag() self.connect(psum,p_mag) ## Squared Magnitude of block r_magsqrd = gr.complex_to_mag_squared(vlen) self.connect(sampler,r_magsqrd) ## Sum of squared second half block r_sum = vector_sum_vff(vlen) self.connect(r_magsqrd,r_sum) ## Square Root of Metric m_sqrt = gr.divide_ff() self.connect(p_mag,(m_sqrt,0)) self.connect(r_sum,gr.multiply_const_ff(0.5),(m_sqrt,1)) ## Denominator of SNR estimate denom = gr.add_const_ff(1) neg_m_sqrt = gr.multiply_const_ff(-1.0) self.connect(m_sqrt,limit_vff(1,1-2e-5,-1000),neg_m_sqrt,denom) ## SNR estimate snr_est = gr.divide_ff() self.connect(m_sqrt,(snr_est,0)) self.connect(denom,(snr_est,1)) ## Setup Output Connections self.connect(snr_est,self)
def __init__( self, parent, unit='units', minval=0, maxval=1, factor=1, decimal_places=3, ref_level=0, sample_rate=1, number_rate=number_window.DEFAULT_NUMBER_RATE, average=False, avg_alpha=None, label='Number Plot', size=number_window.DEFAULT_WIN_SIZE, peak_hold=False, show_gauge=True, **kwargs #catchall for backwards compatibility ): #ensure avg alpha if avg_alpha is None: avg_alpha = 2.0 / number_rate #init gr.hier_block2.__init__( self, "number_sink", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0), ) #blocks sd = blks2.stream_to_vector_decimator( item_size=self._item_size, sample_rate=sample_rate, vec_rate=number_rate, vec_len=1, ) if self._real: mult = gr.multiply_const_ff(factor) add = gr.add_const_ff(ref_level) avg = gr.single_pole_iir_filter_ff(1.0) else: mult = gr.multiply_const_cc(factor) add = gr.add_const_cc(ref_level) avg = gr.single_pole_iir_filter_cc(1.0) msgq = gr.msg_queue(2) sink = gr.message_sink(self._item_size, msgq, True) #controller self.controller = pubsub() self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate) self.controller[AVERAGE_KEY] = average self.controller[AVG_ALPHA_KEY] = avg_alpha def update_avg(*args): if self.controller[AVERAGE_KEY]: avg.set_taps(self.controller[AVG_ALPHA_KEY]) else: avg.set_taps(1.0) update_avg() self.controller.subscribe(AVERAGE_KEY, update_avg) self.controller.subscribe(AVG_ALPHA_KEY, update_avg) #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = number_window.number_window( parent=parent, controller=self.controller, size=size, title=label, units=unit, real=self._real, minval=minval, maxval=maxval, decimal_places=decimal_places, show_gauge=show_gauge, average_key=AVERAGE_KEY, avg_alpha_key=AVG_ALPHA_KEY, peak_hold=peak_hold, msg_key=MSG_KEY, sample_rate_key=SAMPLE_RATE_KEY, ) common.register_access_methods(self, self.controller) #backwards compadibility self.set_show_gauge = self.win.show_gauges #connect self.wxgui_connect(self, sd, mult, add, avg, sink)
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)