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): gr.top_block.__init__(self) length = 101 data_r = range(length) data_i = range(length,2*length) src_r = gr.vector_source_s(data_r, False) src_i = gr.vector_source_s(data_i, False) s2f_r = gr.short_to_float() s2f_i = gr.short_to_float() f2c = gr.float_to_complex() s2v = gr.stream_to_vector(gr.sizeof_gr_complex, length) shift = True ifft = gr.fft_vcc(length, False, [], shift) fft = gr.fft_vcc(length, True, [], shift) v2s = gr.vector_to_stream(gr.sizeof_gr_complex, length) snk_in = gr.file_sink(gr.sizeof_gr_complex, "fftshift.in") snk_out = gr.file_sink(gr.sizeof_gr_complex, "fftshift.out") self.connect(src_r, s2f_r, (f2c,0)) self.connect(src_i, s2f_i, (f2c,1)) self.connect(f2c, snk_in) self.connect(f2c, s2v, ifft, fft, v2s, snk_out)
def graph(args): print os.getpid() nargs = len(args) if nargs == 1: infile = args[0] else: sys.stderr.write('usage: interp.py input_file\n') sys.exit(1) tb = gr.top_block() srcf = gr.file_source(gr.sizeof_short, infile) s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src0 = gr.float_to_complex() lp_coeffs = gr.firdes.low_pass(3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING) lp = gr.interp_fir_filter_ccf(3, lp_coeffs) file = gr.file_sink(gr.sizeof_gr_complex, "/tmp/atsc_pipe_1") tb.connect(srcf, s2ss) tb.connect((s2ss, 0), s2f1, (src0, 0)) tb.connect((s2ss, 1), s2f2, (src0, 1)) tb.connect(src0, lp, file) tb.start() raw_input('Head End: Press Enter to stop') tb.stop()
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 graph (args): print os.getpid() nargs = len (args) if nargs == 1: infile = args[0] else: sys.stderr.write('usage: interp.py input_file\n') sys.exit (1) tb = gr.top_block () srcf = gr.file_source (gr.sizeof_short,infile) s2ss = gr.stream_to_streams(gr.sizeof_short,2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src0 = gr.float_to_complex() lp_coeffs = gr.firdes.low_pass ( 3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING ) lp = gr.interp_fir_filter_ccf ( 3, lp_coeffs ) file = gr.file_sink(gr.sizeof_gr_complex,"/tmp/atsc_pipe_1") tb.connect( srcf, s2ss ) tb.connect( (s2ss, 0), s2f1, (src0,0) ) tb.connect( (s2ss, 1), s2f2, (src0,1) ) tb.connect( src0, lp, file) tb.start() raw_input ('Head End: Press Enter to stop') tb.stop()
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 32000 self.remove_head = remove_head = 0 ################################################## # Blocks ################################################## self._remove_head_chooser = forms.radio_buttons( parent=self.GetWin(), value=self.remove_head, callback=self.set_remove_head, label="Remove Head", choices=[0,1], labels=[], style=wx.RA_HORIZONTAL, ) self.Add(self._remove_head_chooser) self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=samp_rate, v_scale=0, v_offset=0, t_scale=0, ac_couple=False, xy_mode=False, num_inputs=2, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.gr_udp_source_0 = gr.udp_source(gr.sizeof_short*1, "192.168.2.200", 9997, 590, False, True) self.gr_short_to_float_0_0 = gr.short_to_float(1, 1) self.gr_short_to_float_0 = gr.short_to_float(1, 1) self.gr_file_sink_0_1_0 = gr.file_sink(gr.sizeof_short*1, "/home/cgardner/sandbox/gr-csg/gr-fp/grc_testfp/test_fp_odd.bin") self.gr_file_sink_0_1_0.set_unbuffered(True) self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_short*1, "/home/cgardner/sandbox/gr-csg/gr-fp/grc_testfp/test_raw_even.bin") self.gr_file_sink_0_1.set_unbuffered(True) self.gr_deinterleave_0 = gr.deinterleave(gr.sizeof_short*1) self.fpgnu_fpdata_sink_0 = fpgnu_swig.fpdata_sink(remove_head) ################################################## # Connections ################################################## self.connect((self.gr_udp_source_0, 0), (self.fpgnu_fpdata_sink_0, 0)) self.connect((self.gr_short_to_float_0, 0), (self.wxgui_scopesink2_0, 0)) self.connect((self.gr_deinterleave_0, 1), (self.gr_file_sink_0_1_0, 0)) self.connect((self.fpgnu_fpdata_sink_0, 0), (self.gr_deinterleave_0, 0)) self.connect((self.gr_deinterleave_0, 0), (self.gr_file_sink_0_1, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.wxgui_scopesink2_0, 1)) self.connect((self.gr_deinterleave_0, 1), (self.gr_short_to_float_0_0, 0)) self.connect((self.gr_deinterleave_0, 0), (self.gr_short_to_float_0, 0))
def __init__(self, Source): gr.top_block.__init__(self, "Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 750e3 self.transition = transition = 100e3 self.cutoff = cutoff = 100000 ################################################## # Blocks ################################################## self.frame_source = FrameS.FrameSource(Source) self.gr_short_to_float_0 = gr.short_to_float(1, 32768) self.gr_short_to_float_1 = gr.short_to_float(1, 32768) self.high_pass_filter_0 = gr.fir_filter_fff(1, firdes.high_pass( 1, samp_rate, cutoff, transition, firdes.WIN_RECTANGULAR, 6.76)) self.high_pass_filter_1 = gr.fir_filter_fff(1, firdes.high_pass( 1, samp_rate, cutoff, transition, firdes.WIN_RECTANGULAR, 6.76)) self.gr_float_to_short_0 = gr.float_to_short(1, 32768) self.gr_float_to_short_1 = gr.float_to_short(1, 32768) self.threshold = Threshold.CustomTwoChannelThreshold() self.gr_interleave = gr.interleave(gr.sizeof_short*1) self.frame_sink = FrameTFS.FrameToFileSink() ################################################## # Connections ################################################## self.connect((self.frame_source, 0), (self.gr_short_to_float_0, 0)) self.connect((self.frame_source, 1), (self.gr_short_to_float_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.high_pass_filter_0, 0)) self.connect((self.gr_short_to_float_1, 0), (self.high_pass_filter_1, 0)) self.connect((self.high_pass_filter_0, 0), (self.gr_float_to_short_0, 0)) self.connect((self.high_pass_filter_1, 0), (self.gr_float_to_short_1, 0)) self.connect((self.gr_float_to_short_0, 0), (self.threshold, 0)) self.connect((self.gr_float_to_short_1, 0), (self.threshold, 1)) self.connect((self.threshold, 0), (self.gr_interleave, 0)) self.connect((self.threshold, 1), (self.gr_interleave, 1)) self.connect((self.gr_interleave, 0), (self.frame_sink, 0))
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-a", "--audio-input", type="string", default="") parser.add_option("-A", "--audio-output", type="string", default="") parser.add_option("-f", "--factor", type="eng_float", default=1) parser.add_option("-i", "--do-interp", action="store_true", default=False, help="enable output interpolator") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-S", "--stretch", type="int", default=0, help="flex amt") parser.add_option("-y", "--symbol-rate", type="int", default=4800, help="input symbol rate") parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = options.symbol_rate IN = audio.source(sample_rate, options.audio_input) audio_output_rate = 8000 if options.do_interp: audio_output_rate = 48000 OUT = audio.sink(audio_output_rate, options.audio_output) symbol_decim = 1 symbol_coeffs = gr.firdes.root_raised_cosine(1.0, # gain sample_rate , # sampling rate symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff (symbol_decim, symbol_coeffs) AMP = gr.multiply_const_ff(options.factor) msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(msgq, sample_rate, symbol_rate) levels = levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) framer_msgq = gr.msg_queue(2) DECODE = repeater.p25_frame_assembler('', # udp hostname 0, # udp port no. options.verbose, #debug True, # do_imbe True, # do_output False, # do_msgq framer_msgq) IMBE = repeater.vocoder(False, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors CVT = gr.short_to_float() if options.do_interp: interp_taps = gr.firdes.low_pass(1.0, 48000, 4000, 4000 * 0.1, gr.firdes.WIN_HANN) INTERP = gr.interp_fir_filter_fff(48000 // 8000, interp_taps) AMP2 = gr.multiply_const_ff(1.0 / 32767.0) self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CVT, AMP2) if options.do_interp: self.connect(AMP2, INTERP, OUT) else: self.connect(AMP2, OUT)
def build_graph(): sample_rate = 8000 scale_factor = 32000 tb = gr.top_block() src = audio.source(sample_rate, "plughw:0,0") src_scale = gr.multiply_const_ff(scale_factor) interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short() enc = cvsd_vocoder.encode_sb() dec = cvsd_vocoder.decode_bs() s2f = gr.short_to_float() decim = blks2.rational_resampler_fff(1, 8) sink_scale = gr.multiply_const_ff(1.0 / scale_factor) sink = audio.sink(sample_rate, "plughw:0,0") tb.connect(src, src_scale, interp, f2s, enc) tb.connect(enc, dec, s2f, decim, sink_scale, sink) if 0: # debug tb.conect(src, gr.file_sink(gr.sizeof_float, "source.dat")) tb.conect(src_scale, gr.file_sink(gr.sizeof_float, "src_scale.dat")) tb.conect(interp, gr.file_sink(gr.sizeof_float, "interp.dat")) tb.conect(f2s, gr.file_sink(gr.sizeof_short, "f2s.dat")) tb.conect(enc, gr.file_sink(gr.sizeof_char, "enc.dat")) tb.conect(dec, gr.file_sink(gr.sizeof_short, "dec.dat")) tb.conect(s2f, gr.file_sink(gr.sizeof_float, "s2f.dat")) tb.conect(decim, gr.file_sink(gr.sizeof_float, "decim.dat")) tb.conect(sink_scale, gr.file_sink(gr.sizeof_float, "sink_scale.dat")) return tb
def build_graph(): sample_rate = 8000 scale_factor = 32000 tb = gr.top_block() src = audio.source(sample_rate, "plughw:0,0") src_scale = gr.multiply_const_ff(scale_factor) interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short () enc = vocoder.cvsd_encode_sb() dec = vocoder.cvsd_decode_bs() s2f = gr.short_to_float () decim = blks2.rational_resampler_fff(1, 8) sink_scale = gr.multiply_const_ff(1.0/scale_factor) sink = audio.sink(sample_rate, "plughw:0,0") tb.connect(src, src_scale, interp, f2s, enc) tb.connect(enc, dec, s2f, decim, sink_scale, sink) if 0: # debug tb.conect(src, gr.file_sink(gr.sizeof_float, "source.dat")) tb.conect(src_scale, gr.file_sink(gr.sizeof_float, "src_scale.dat")) tb.conect(interp, gr.file_sink(gr.sizeof_float, "interp.dat")) tb.conect(f2s, gr.file_sink(gr.sizeof_short, "f2s.dat")) tb.conect(enc, gr.file_sink(gr.sizeof_char, "enc.dat")) tb.conect(dec, gr.file_sink(gr.sizeof_short, "dec.dat")) tb.conect(s2f, gr.file_sink(gr.sizeof_float, "s2f.dat")) tb.conect(decim, gr.file_sink(gr.sizeof_float, "decim.dat")) tb.conect(sink_scale, gr.file_sink(gr.sizeof_float, "sink_scale.dat")) return tb
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 32000 ################################################## # Blocks ################################################## self.wxgui_scopesink2_0 = scopesink2.scope_sink_f( self.GetWin(), title="Scope Plot", sample_rate=125, v_scale=0, v_offset=0, t_scale=1000, ac_couple=False, xy_mode=False, num_inputs=1, trig_mode=gr.gr_TRIG_MODE_AUTO, y_axis_label="Counts", ) self.Add(self.wxgui_scopesink2_0.win) self.gr_udp_source_1 = gr.udp_source(gr.sizeof_short*1, "127.0.0.1", 1235, 2, True, True) self.gr_short_to_float_0_0 = gr.short_to_float() ################################################## # Connections ################################################## self.connect((self.gr_udp_source_1, 0), (self.gr_short_to_float_0_0, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.wxgui_scopesink2_0, 0))
def __init__(self, N_id_2, decim=16, avg_halfframes=2 * 8, freq_corr=0, dump=None): gr.hier_block2.__init__( self, "PSS correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float), ) vec_half_frame = 30720 * 5 / decim self.taps = [] for i in range(0, 3): self.taps.append( gen_pss_td(i, N_re=2048 / decim, freq_corr=freq_corr).get_data_conj_rev()) self.corr = filter.fir_filter_ccc(1, self.taps[N_id_2]) self.mag = gr.complex_to_mag_squared() self.vec = gr.stream_to_vector(gr.sizeof_float * 1, vec_half_frame) self.deint = gr.deinterleave(gr.sizeof_float * vec_half_frame) self.add = gr.add_vff(vec_half_frame) self.argmax = gr.argmax_fs(vec_half_frame) self.null = gr.null_sink(gr.sizeof_short * 1) self.max = gr.max_ff(vec_half_frame) self.to_float = gr.short_to_float(1, 1. / decim) self.interleave = gr.interleave(gr.sizeof_float) #self.framestart = gr.add_const_ii(-160-144*5-2048*6+30720*5) self.connect(self, self.corr, self.mag, self.vec) self.connect((self.argmax, 1), self.null) #self.connect(self.argmax, self.to_float, self.to_int, self.framestart, self) self.connect(self.argmax, self.to_float, self.interleave, self) self.connect(self.max, (self.interleave, 1)) if avg_halfframes == 1: self.connect(self.vec, self.argmax) self.connect(self.vec, self.max) else: self.connect(self.vec, self.deint) self.connect(self.add, self.argmax) self.connect(self.add, self.max) for i in range(0, avg_halfframes): self.connect((self.deint, i), (self.add, i)) if dump != None: self.connect( self.mag, gr.file_sink(gr.sizeof_float, dump + "_pss_corr_f.cfile")) self.connect( self.add, gr.file_sink(gr.sizeof_float * vec_half_frame, dump + "_pss_corr_add_f.cfile"))
def __init__(self, audio_output_dev): gr.hier_block2.__init__(self, "audio_tx", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature self.packet_src = gr.message_source(33) voice_decoder = gsm_full_rate.decode_ps() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) audio_sink = audio.sink(8000, audio_output_dev) self.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink)
def build_graph(): fg = gr.flow_graph() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () enc = gsm_full_rate.encode_sp() dec = gsm_full_rate.decode_ps() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) fg.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) return fg
def build_graph(): tb = gr.top_block() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () enc = vocoder.ulaw_encode_sb() dec = vocoder.ulaw_decode_bs() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) return tb
def build_graph(): tb = gr.top_block() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () enc = vocoder.g723_40_encode_sb() dec = vocoder.g723_40_decode_bs() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) return tb
def __init__(self): gr.flow_graph.__init__(self) parser = OptionParser (option_class=eng_option) parser.add_option("-R", "--rx-subdev-spec", type="subdev", default='B', help="select USRP Rx side A or B (default=first one with a daughterboard)") parser.add_option ("-c", "--cordic-freq", type="eng_float", default=434845200, help="set rx cordic frequency to FREQ", metavar="FREQ") parser.add_option ("-g", "--gain", type="eng_float", default=0, help="set Rx PGA gain in dB [0,20]") (options, args) = parser.parse_args () print "cordic_freq = %s" % (eng_notation.num_to_str (options.cordic_freq)) # ---------------------------------------------------------------- self.freq = 1000 self.samples_per_symbol = 256 self.usrp_decim = int (64e6 / self.samples_per_symbol / self.freq) self.fs = self.freq * self.samples_per_symbol print "freq = ", eng_notation.num_to_str(self.freq) print "samples_per_symbol = ", self.samples_per_symbol print "usrp_decim = ", self.usrp_decim print "fs = ", eng_notation.num_to_str(self.fs) u = usrp.source_s (0, self.usrp_decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(u) u.set_mux(usrp.determine_rx_mux_value(u, options.rx_subdev_spec)) subdev = usrp.selected_subdev(u, options.rx_subdev_spec) print "Using RX d'board %s" % (subdev.side_and_name(),) u.tune(0, subdev, options.cordic_freq) u.set_pga(0, options.gain) u.set_pga(1, options.gain) self.u = u self.filesink = gr.file_sink(gr.sizeof_float, 'rx_sin.dat') self.stof = gr.short_to_float() filter_coeffs = gr.firdes.low_pass (1.0, # gain self.fs, # sampling rate self.freq, # low pass cutoff freq 0.1*self.freq, # width of trans. band gr.firdes.WIN_HANN) # filter type self.lowpass = gr.fir_filter_fff(1, filter_coeffs) self.connect(self.u, self.stof, self.lowpass, self.filesink)
def __init__(self, audio_output_dev): gr.hier_block2.__init__( self, "audio_tx", gr.io_signature(0, 0, 0), # Input signature gr.io_signature(0, 0, 0)) # Output signature self.packet_src = gr.message_source(33) voice_decoder = gsm_full_rate.decode_ps() s2f = gr.short_to_float() sink_scale = gr.multiply_const_ff(1.0 / 32767.) audio_sink = audio.sink(8000, audio_output_dev) self.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink)
def __init__(self, filename="usrp.dat", output="frames.dat", decim=16, pll_alpha=0.05, sync_alpha=0.05): gr.top_block.__init__(self, "USRP HRPT Receiver") ################################################## # Parameters ################################################## self.filename = filename self.output = output self.decim = decim self.pll_alpha = pll_alpha self.sync_alpha = sync_alpha ################################################## # Variables ################################################## self.sym_rate = sym_rate = 600*1109 self.sample_rate = sample_rate = 64e6/decim self.sps = sps = sample_rate/sym_rate self.hs = hs = int(sps/2.0) self.mf_taps = mf_taps = [-0.5/hs,]*hs+[0.5/hs,]*hs self.max_sync_offset = max_sync_offset = 0.01 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate ################################################## # Blocks ################################################## self.decoder = noaa.hrpt_decoder() self.deframer = noaa.hrpt_deframer() self.deinterleave = gr.deinterleave(gr.sizeof_float*1) self.f2c = gr.float_to_complex(1) self.file_sink = gr.file_sink(gr.sizeof_short*1, output) self.file_source = gr.file_source(gr.sizeof_short*1, filename, False) self.gr_fir_filter_xxx_0 = gr.fir_filter_ccc(1, (mf_taps)) self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) self.s2f = gr.short_to_float() self.sync = noaa.hrpt_sync_fb(sync_alpha, sync_alpha**2/4.0, sps, max_sync_offset) ################################################## # Connections ################################################## self.connect((self.deframer, 0), (self.file_sink, 0)) self.connect((self.sync, 0), (self.deframer, 0)) self.connect((self.pll, 0), (self.sync, 0)) self.connect((self.deinterleave, 1), (self.f2c, 1)) self.connect((self.deinterleave, 0), (self.f2c, 0)) self.connect((self.deframer, 0), (self.decoder, 0)) self.connect((self.gr_fir_filter_xxx_0, 0), (self.pll, 0)) self.connect((self.f2c, 0), (self.gr_fir_filter_xxx_0, 0)) self.connect((self.s2f, 0), (self.deinterleave, 0)) self.connect((self.file_source, 0), (self.s2f, 0))
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file") parser.add_option("-g", "--gain", type="eng_float", default=1.0) parser.add_option("-L", "--low-pass", type="eng_float", default=15e3, help="low pass cut-off", metavar="Hz") parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") (options, args) = parser.parse_args() sample_rate = options.sample_rate sps = 10 symbol_rate = 4800 # output rate will be 48,000 ntaps = 11 * sps channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN) IN = gr.file_source(gr.sizeof_short, options.input_file) OUT = gr.file_sink(gr.sizeof_char, options.output_file) CVT = gr.short_to_float() AMP = gr.multiply_const_ff(options.gain / 32767.0) symbol_decim = 1 symbol_coeffs = gr.firdes.root_raised_cosine (1.0, # gain sample_rate , # sampling rate symbol_rate, # symbol rate 0.20, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff (symbol_decim, symbol_coeffs) self.msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(self.msgq, sample_rate, symbol_rate) levels = [ -2.0, 0.0, 2.0, 4.0 ] SLICER = repeater.fsk4_slicer_fb(levels) hostname = "127.0.0.1" port = 23456 debug = 255 do_imbe = False do_output = True do_msgq = False msgqd = gr.msg_queue(2) DECODER = repeater.p25_frame_assembler(hostname, port, debug, do_imbe, do_output, do_msgq, msgqd) self.connect(IN, CVT, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODER, OUT)
def test_001(self): src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5) expected_result = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0, -3.0, -4.0, -5.0] src = gr.vector_source_s(src_data) op = gr.short_to_float() dst = gr.vector_sink_f() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_001(self): src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5) expected_result = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0, -3.0, -4.0, -5.0] src = gr.vector_source_s(src_data) op = gr.short_to_float() dst = gr.vector_sink_f() self.tb.connect(src, op, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_002(self): vlen = 3 src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3) expected_result = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0, -3.0] src = gr.vector_source_s(src_data) s2v = gr.stream_to_vector(gr.sizeof_short, vlen) op = gr.short_to_float(vlen) v2s = gr.vector_to_stream(gr.sizeof_float, vlen) dst = gr.vector_sink_f() self.tb.connect(src, s2v, op, v2s, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def test_002(self): vlen = 3 src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3) expected_result = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0, -3.0] src = gr.vector_source_s(src_data) s2v = gr.stream_to_vector(gr.sizeof_short, vlen) op = gr.short_to_float(vlen) v2s = gr.vector_to_stream(gr.sizeof_float, vlen) dst = gr.vector_sink_f() self.tb.connect(src, s2v, op, v2s, dst) self.tb.run() result_data = list(dst.data()) self.assertEqual(expected_result, result_data)
def __init__(self,Freq): gr.top_block.__init__(self) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 195.312e3 self.FM_freq = FM_freq = Freq.value self.uhd_usrp_sink_0 = uhd.usrp_sink( device_addr="addr=192.168.10.2", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0) self.uhd_usrp_sink_0.set_gain(0, 0) self.uhd_usrp_sink_0.set_antenna("TX/RX", 0) self.gr_short_to_float_0 = gr.short_to_float(1, 1) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((30e-6, )) self.gr_file_source_0 = gr.file_source(gr.sizeof_short*1, "/home/kranthi/documents/sound_cognition/test.raw", True) self.blks2_wfm_tx_0 = blks2.wfm_tx( audio_rate=32000, quad_rate=800000, tau=75e-6, max_dev=75e3, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_ccc( interpolation=1, decimation=2, taps=None, fractional_bw=None, ) # print "#####Start of transmitter########" ################################################## # Connections ################################################## self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.uhd_usrp_sink_0, 0)) self.connect((self.blks2_wfm_tx_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.gr_file_source_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_wfm_tx_0, 0))
def __init__(self, resample=8, bw=0.5): ''' When using the CVSD vocoder, appropriate sampling rates are from 8k to 64k with resampling rates from 1 to 8. A rate of 8k with a resampling rate of 8 provides a good quality signal. ''' gr.hier_block2.__init__(self, "cvsd_decode", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_float)) # Output signature scale_factor = 32000.0 self.decim = resample dec = vocoder_swig.cvsd_decode_bs() s2f = gr.short_to_float() taps = gr.firdes.low_pass(1, 1, bw, 2*bw) decim = gr.fir_filter_fff(self.decim, taps) sink_scale = gr.multiply_const_ff(1.0/scale_factor) self.connect(self, dec, s2f, decim, sink_scale, self)
def __init__(self, N_id_2, decim=16, avg_halfframes=2*8, freq_corr=0, dump=None): gr.hier_block2.__init__( self, "PSS correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float), ) vec_half_frame = 30720*5/decim self.taps = [] for i in range(0,3): self.taps.append(gen_pss_td(i, N_re=2048/decim, freq_corr=freq_corr).get_data_conj_rev()) self.corr = filter.fir_filter_ccc(1, self.taps[N_id_2]) self.mag = gr.complex_to_mag_squared() self.vec = gr.stream_to_vector(gr.sizeof_float*1, vec_half_frame) self.deint = gr.deinterleave(gr.sizeof_float*vec_half_frame) self.add = gr.add_vff(vec_half_frame) self.argmax = gr.argmax_fs(vec_half_frame) self.null = gr.null_sink(gr.sizeof_short*1) self.max = gr.max_ff(vec_half_frame) self.to_float = gr.short_to_float(1, 1./decim) self.interleave = gr.interleave(gr.sizeof_float) #self.framestart = gr.add_const_ii(-160-144*5-2048*6+30720*5) self.connect(self, self.corr, self.mag, self.vec) self.connect((self.argmax,1), self.null) #self.connect(self.argmax, self.to_float, self.to_int, self.framestart, self) self.connect(self.argmax, self.to_float, self.interleave, self) self.connect(self.max, (self.interleave,1)) if avg_halfframes == 1: self.connect(self.vec, self.argmax) self.connect(self.vec, self.max) else: self.connect(self.vec, self.deint) self.connect(self.add, self.argmax) self.connect(self.add, self.max) for i in range(0, avg_halfframes): self.connect((self.deint, i), (self.add, i)) if dump != None: self.connect(self.mag, gr.file_sink(gr.sizeof_float, dump + "_pss_corr_f.cfile")) self.connect(self.add, gr.file_sink(gr.sizeof_float*vec_half_frame, dump + "_pss_corr_add_f.cfile"))
def __init__(self): gr.top_block.__init__(self) self.frequency = 13.56e6 self.gain = 10 # USRP settings self.u_rx = usrp.source_s() #create the USRP source for RX #try and set the LF_RX for this rx_subdev_spec = usrp.pick_subdev(self.u_rx, (usrp_dbid.LF_RX, usrp_dbid.LF_TX)) #Configure the MUX for the daughterboard self.u_rx.set_mux(usrp.determine_rx_mux_value(self.u_rx, rx_subdev_spec)) #Tell it to use the LF_RX self.subdev_rx = usrp.selected_subdev(self.u_rx, rx_subdev_spec) #Make sure it worked print "Using RX dboard %s" % (self.subdev_rx.side_and_name(),) #Set gain.. duh self.subdev_rx.set_gain(self.gain) #Tune the center frequency self.u_rx.tune(0, self.subdev_rx, self.frequency) adc_rate = self.u_rx.adc_rate() #64 MS/s usrp_decim = 8 self.u_rx.set_decim_rate(usrp_decim) #BW = 64 MS/s / decim = 64,000,000 / 256 = 250 kHz #Not sure if this decim rate exceeds USRP capabilities, #if it does then some software decim may have to be done as well usrp_rx_rate = adc_rate / usrp_decim self.convert = gr.short_to_float() self.snk = gr.probe_avg_mag_sqrd_f(1,0.01) # dst = audio.sink (sample_rate, "") # stv = gr.stream_to_vector (gr.sizeof_float, fft_size) # c2m = gr.complex_to_mag_squared (fft_size) self.connect(self.u_rx, self.convert, self.snk)
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file") parser.add_option("-g", "--gain", type="eng_float", default=1.0) parser.add_option("-L", "--low-pass", type="eng_float", default=15e3, help="low pass cut-off", metavar="Hz") parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") (options, args) = parser.parse_args() sample_rate = options.sample_rate sps = 10 symbol_rate = 4800 # output rate will be 48,000 ntaps = 11 * sps channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN) IN = gr.file_source(gr.sizeof_short, options.input_file) OUT = gr.file_sink(gr.sizeof_char, options.output_file) CVT = gr.short_to_float() AMP = gr.multiply_const_ff(options.gain / 32767.0) symbol_decim = 1 symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain sample_rate, # sampling rate symbol_rate, # symbol rate 0.20, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff(symbol_decim, symbol_coeffs) self.msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(self.msgq, sample_rate, symbol_rate) levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) hostname = "127.0.0.1" port = 23456 debug = 255 do_imbe = False do_output = True do_msgq = False msgqd = gr.msg_queue(2) DECODER = repeater.p25_frame_assembler(hostname, port, debug, do_imbe, do_output, do_msgq, msgqd) self.connect(IN, CVT, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODER, OUT)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Fm Stereo Tx") ################################################## # Variables ################################################## self.st_gain = st_gain = 10 self.samp_rate = samp_rate = 195.312e3 self.pilot_gain = pilot_gain = 80e-3 self.mpx_rate = mpx_rate = 160e3 self.Mono_gain = Mono_gain = 300e-3 self.FM_freq = FM_freq = 96.5e6 ################################################## # Blocks ################################################## _st_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._st_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_st_gain_sizer, value=self.st_gain, callback=self.set_st_gain, label='st_gain', converter=forms.float_converter(), proportion=0, ) self._st_gain_slider = forms.slider( parent=self.GetWin(), sizer=_st_gain_sizer, value=self.st_gain, callback=self.set_st_gain, minimum=0, maximum=100, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_st_gain_sizer) _pilot_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._pilot_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_pilot_gain_sizer, value=self.pilot_gain, callback=self.set_pilot_gain, label='pilot_gain', converter=forms.float_converter(), proportion=0, ) self._pilot_gain_slider = forms.slider( parent=self.GetWin(), sizer=_pilot_gain_sizer, value=self.pilot_gain, callback=self.set_pilot_gain, minimum=0, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_pilot_gain_sizer) self.notebook_0 = self.notebook_0 = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "FM") self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "audio") self.Add(self.notebook_0) _Mono_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._Mono_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_Mono_gain_sizer, value=self.Mono_gain, callback=self.set_Mono_gain, label='Mono_gain', converter=forms.float_converter(), proportion=0, ) self._Mono_gain_slider = forms.slider( parent=self.GetWin(), sizer=_Mono_gain_sizer, value=self.Mono_gain, callback=self.set_Mono_gain, minimum=0, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_Mono_gain_sizer) _FM_freq_sizer = wx.BoxSizer(wx.VERTICAL) self._FM_freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, label='FM_freq', converter=forms.float_converter(), proportion=0, ) self._FM_freq_slider = forms.slider( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, minimum=88e6, maximum=108e6, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_FM_freq_sizer) self.wxgui_fftsink2_1 = fftsink2.fft_sink_f( self.notebook_0.GetPage(1).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.notebook_0.GetPage(1).Add(self.wxgui_fftsink2_1.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.notebook_0.GetPage(0).GetWin(), baseband_freq=FM_freq, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.notebook_0.GetPage(0).Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_sink_0 = uhd.usrp_sink( device_addr="addr=192.168.10.2", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0) self.uhd_usrp_sink_0.set_gain(0, 0) self.uhd_usrp_sink_0.set_antenna("TX/RX", 0) self.low_pass_filter_0 = gr.fir_filter_fff(1, firdes.low_pass( Mono_gain, mpx_rate, 15000, 2000, firdes.WIN_HAMMING, 6.76)) self.gr_vector_to_streams_0 = gr.vector_to_streams(gr.sizeof_short*1, 2) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_sig_source_x_1 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 19000, pilot_gain, 0) self.gr_sig_source_x_0 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 38000, 30e-3, 0) self.gr_short_to_float_1 = gr.short_to_float(1, 1) self.gr_short_to_float_0 = gr.short_to_float(1, 1) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc((32.768e3, )) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((30e-6, )) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((30e-6, )) self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(980e-3) self.gr_file_source_0 = gr.file_source(gr.sizeof_short*2, "/home/kranthi/Documents/project/FM Transceiver/FM Transmitter/test.raw", True) self.gr_add_xx_1 = gr.add_vff(1) self.gr_add_xx_0 = gr.add_vff(1) self.blks2_rational_resampler_xxx_2 = blks2.rational_resampler_fff( interpolation=4, decimation=1, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff( interpolation=5, decimation=1, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff( interpolation=5, decimation=1, taps=None, fractional_bw=None, ) self.blks2_fm_preemph_0 = blks2.fm_preemph(fs=mpx_rate, tau=50e-6) self.band_pass_filter_0 = gr.fir_filter_fff(1, firdes.band_pass( st_gain, mpx_rate, 23000, 53000, 2000, firdes.WIN_HAMMING, 6.76)) ################################################## # Connections ################################################## self.connect((self.gr_file_source_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_short_to_float_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_sub_xx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_add_xx_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.gr_sig_source_x_1, 0), (self.gr_add_xx_1, 0)) self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 1)) self.connect((self.low_pass_filter_0, 0), (self.gr_add_xx_1, 2)) self.connect((self.gr_add_xx_1, 0), (self.blks2_fm_preemph_0, 0)) self.connect((self.blks2_fm_preemph_0, 0), (self.blks2_rational_resampler_xxx_2, 0)) self.connect((self.blks2_rational_resampler_xxx_2, 0), (self.gr_frequency_modulator_fc_0, 0)) self.connect((self.gr_frequency_modulator_fc_0, 0), (self.gr_multiply_const_vxx_2, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.uhd_usrp_sink_0, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_fftsink2_1, 0))
def graph(args): nargs = len(args) if nargs == 2: infile = args[0] outfile = args[1] else: raise ValueError('usage: interp.py input_file output_file\n') tb = gr.top_block() # Convert to a from shorts to a stream of complex numbers. srcf = gr.file_source(gr.sizeof_short, infile) s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src0 = gr.float_to_complex() tb.connect(srcf, s2ss) tb.connect((s2ss, 0), s2f1, (src0, 0)) tb.connect((s2ss, 1), s2f2, (src0, 1)) # Low pass filter it and increase sample rate by a factor of 3. lp_coeffs = gr.firdes.low_pass(3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING) lp = gr.interp_fir_filter_ccf(3, lp_coeffs) tb.connect(src0, lp) # Upconvert it. duc_coeffs = gr.firdes.low_pass(1, 19.2e6, 9e6, 1e6, gr.firdes.WIN_HAMMING) duc = gr.freq_xlating_fir_filter_ccf(1, duc_coeffs, 5.75e6, 19.2e6) # Discard the imaginary component. c2f = gr.complex_to_float() tb.connect(lp, duc, c2f) # Frequency Phase Lock Loop input_rate = 19.2e6 IF_freq = 5.75e6 # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE / 2. NTAPS = 279 tt = gr.firdes.root_raised_cosine(1.0, input_rate, symbol_rate, .115, NTAPS) # heterodyne the low pass coefficients up to the specified bandpass # center frequency. Note that when we do this, the filter bandwidth # is effectively twice the low pass (2.69 * 2 = 5.38) and hence # matches the diagram in the ATSC spec. arg = 2. * math.pi * IF_freq / input_rate t = [] for i in range(len(tt)): t += [tt[i] * 2. * math.cos(arg * i)] rrc = gr.fir_filter_fff(1, t) fpll = atsc.fpll() pilot_freq = IF_freq - 3e6 + 0.31e6 lower_edge = 6e6 - 0.31e6 upper_edge = IF_freq - 3e6 + pilot_freq transition_width = upper_edge - lower_edge lp_coeffs = gr.firdes.low_pass(1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, gr.firdes.WIN_HAMMING) lp_filter = gr.fir_filter_fff(1, lp_coeffs) alpha = 1e-5 iir = gr.single_pole_iir_filter_ff(alpha) remove_dc = gr.sub_ff() tb.connect(c2f, fpll, lp_filter) tb.connect(lp_filter, iir) tb.connect(lp_filter, (remove_dc, 0)) tb.connect(iir, (remove_dc, 1)) # Bit Timing Loop, Field Sync Checker and Equalizer btl = atsc.bit_timing_loop() fsc = atsc.fs_checker() eq = atsc.equalizer() fsd = atsc.field_sync_demux() tb.connect(remove_dc, btl) tb.connect((btl, 0), (fsc, 0), (eq, 0), (fsd, 0)) tb.connect((btl, 1), (fsc, 1), (eq, 1), (fsd, 1)) # Viterbi viterbi = atsc.viterbi_decoder() deinter = atsc.deinterleaver() rs_dec = atsc.rs_decoder() derand = atsc.derandomizer() depad = atsc.depad() dst = gr.file_sink(gr.sizeof_char, outfile) tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst) dst2 = gr.file_sink(gr.sizeof_gr_complex, "atsc_complex.data") tb.connect(src0, dst2) tb.run()
def __init__(self, FileOrDir): gr.top_block.__init__(self, "Top Block") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 750e3 self.transition = transition = 100e3 self.cutoff = cutoff = 100000 ################################################## # Blocks ################################################## self.frame_source = fs.frame_source_ss(FileOrDir) self.gr_short_to_float_0 = gr.short_to_float(1, 32768) self.gr_short_to_float_1 = gr.short_to_float(1, 32768) self.high_pass_filter_0 = gr.fir_filter_fff(1, firdes.high_pass(1, # gain samp_rate, # sampling rate cutoff, # cutoff frequency transition, # transition width firdes.WIN_RECTANGULAR, # filter type 6.76)) # beta = 6.76 by default self.high_pass_filter_1 = gr.fir_filter_fff(1, firdes.high_pass(1, # gain samp_rate, # sampling rate cutoff, # cutoff frequency transition, # transition width firdes.WIN_RECTANGULAR, # filter type 6.76)) # beta = 6.76 by default self.gr_float_to_short_0 = gr.float_to_short(1, 32768) self.gr_float_to_short_1 = gr.float_to_short(1, 32768) self.gr_threshold = tct.two_channel_threshold_ssss(983, 600, 500) self.gr_interleave = gr.interleave(gr.sizeof_short*1) self.frame_sink = FrameTFS.FrameToFileSink() ################################################## # Connections ################################################## self.connect((self.frame_source, 0), (self.gr_short_to_float_0, 0)) self.connect((self.frame_source, 1), (self.gr_short_to_float_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.high_pass_filter_0, 0)) self.connect((self.gr_short_to_float_1, 0), (self.high_pass_filter_1, 0)) self.connect((self.high_pass_filter_0, 0), (self.gr_float_to_short_0, 0)) self.connect((self.high_pass_filter_1, 0), (self.gr_float_to_short_1, 0)) self.connect((self.gr_float_to_short_0, 0), (self.gr_threshold, 0)) self.connect((self.gr_float_to_short_1, 0), (self.gr_threshold, 1)) self.connect((self.gr_threshold, 0), (self.gr_interleave, 0)) self.connect((self.gr_threshold, 1), (self.gr_interleave, 1)) self.connect((self.gr_interleave, 0), (self.frame_sink, 0))
def __init__(self): gr.flow_graph.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option( "-R", "--rx-subdev-spec", type="subdev", default='B', help= "select USRP Rx side A or B (default=first one with a daughterboard)" ) parser.add_option("-c", "--cordic-freq", type="eng_float", default=434845200, help="set rx cordic frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=0, help="set Rx PGA gain in dB [0,20]") (options, args) = parser.parse_args() print "cordic_freq = %s" % (eng_notation.num_to_str( options.cordic_freq)) # ---------------------------------------------------------------- self.freq = 1000 self.samples_per_symbol = 256 self.usrp_decim = int(64e6 / self.samples_per_symbol / self.freq) self.fs = self.freq * self.samples_per_symbol print "freq = ", eng_notation.num_to_str(self.freq) print "samples_per_symbol = ", self.samples_per_symbol print "usrp_decim = ", self.usrp_decim print "fs = ", eng_notation.num_to_str(self.fs) u = usrp.source_s(0, self.usrp_decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(u) u.set_mux(usrp.determine_rx_mux_value(u, options.rx_subdev_spec)) subdev = usrp.selected_subdev(u, options.rx_subdev_spec) print "Using RX d'board %s" % (subdev.side_and_name(), ) u.tune(0, subdev, options.cordic_freq) u.set_pga(0, options.gain) u.set_pga(1, options.gain) self.u = u self.filesink = gr.file_sink(gr.sizeof_float, 'rx_sin.dat') self.stof = gr.short_to_float() filter_coeffs = gr.firdes.low_pass( 1.0, # gain self.fs, # sampling rate self.freq, # low pass cutoff freq 0.1 * self.freq, # width of trans. band gr.firdes.WIN_HANN) # filter type self.lowpass = gr.fir_filter_fff(1, filter_coeffs) self.connect(self.u, self.stof, self.lowpass, self.filesink)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Fm Tx Fifo") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 195.312e3 self.FM_freq = FM_freq = 96.5e6 ################################################## # Blocks ################################################## self.notebook_0 = self.notebook_0 = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "Audio") self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "FM") self.Add(self.notebook_0) _FM_freq_sizer = wx.BoxSizer(wx.VERTICAL) self._FM_freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, label="FM Frequency", converter=forms.float_converter(), proportion=0, ) self._FM_freq_slider = forms.slider( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, minimum=87.5e6, maximum=108e6, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_FM_freq_sizer) self.wxgui_fftsink2_1 = fftsink2.fft_sink_f( self.notebook_0.GetPage(0).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, win=window.hamming, ) self.notebook_0.GetPage(0).Add(self.wxgui_fftsink2_1.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.notebook_0.GetPage(1).GetWin(), baseband_freq=FM_freq, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.notebook_0.GetPage(1).Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_sink_0 = uhd.usrp_sink( device_addr="addr=192.168.10.2", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0) self.uhd_usrp_sink_0.set_gain(60, 0) self.uhd_usrp_sink_0.set_antenna("TX/RX", 0) self.gr_short_to_float_0 = gr.short_to_float(1, 1) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((400e-6, )) self.gr_file_source_0 = gr.file_source(gr.sizeof_short*1, "/home/kranthi/documents/project/FM Transceiver Original/test.raw", True) self.blks2_wfm_tx_0 = blks2.wfm_tx( audio_rate=32000, quad_rate=800000, tau=75e-6, max_dev=75e3, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_ccc( interpolation=1, decimation=2, taps=None, fractional_bw=None, ) ################################################## # Connections ################################################## self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.uhd_usrp_sink_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.blks2_wfm_tx_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.gr_file_source_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_wfm_tx_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.wxgui_fftsink2_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_multiply_const_vxx_0, 0))
def __init__(self, gain=23, baseband_file=os.environ['HOME'] + '/GOES-LRIT_baseband.dat', decim=25, freq=137.50e6, satellite='SATxx'): grc_wxgui.top_block_gui.__init__(self, title="USRP2 baseband sampler") _icon_path = "/home/martin/.local/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.gain = gain self.baseband_file = baseband_file self.decim = decim self.freq = freq self.satellite = satellite ################################################## # Variables ################################################## self.decim_tb = decim_tb = decim self.samp_rate = samp_rate = 100e6 / decim_tb self.satellite_text = satellite_text = satellite self.samp_rate_st = samp_rate_st = samp_rate self.gain_tb = gain_tb = gain self.freq_tb = freq_tb = freq self.decimtext = decimtext = '_d' + str(decim) self.datetime_text = datetime_text = strftime("%A, %B %d %Y %H:%M:%S", localtime()) self.baseband_file_text_inf = baseband_file_text_inf = baseband_file ################################################## # Blocks ################################################## self.rx_ntb = self.rx_ntb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "USRP Receiver") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Output") self.Add(self.rx_ntb) self._gain_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.gain_tb, callback=self.set_gain_tb, label="RX gain [dB]", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._gain_tb_text_box, 1, 2, 1, 1) self._freq_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.freq_tb, callback=self.set_freq_tb, label="Frequency", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._freq_tb_text_box, 1, 1, 1, 1) self._decim_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.decim_tb, callback=self.set_decim_tb, label="Decimation", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._decim_tb_text_box, 1, 3, 1, 1) self.wxgui_fftsink1 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=5, y_divs=10, ref_level=60, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="USRP signal spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink1.win) self.usrp2_source_xxxx2_0 = usrp2.source_16sc() self.usrp2_source_xxxx2_0.set_decim(decim_tb) self.usrp2_source_xxxx2_0.set_center_freq(freq_tb) self.usrp2_source_xxxx2_0.set_gain(gain_tb) self._satellite_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.satellite_text, callback=self.set_satellite_text, label="Sat ", converter=forms.str_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._satellite_text_static_text, 1, 0, 1, 1) self._samp_rate_st_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.samp_rate_st, callback=self.set_samp_rate_st, label="Sample rate", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._samp_rate_st_static_text, 1, 4, 1, 1) self.gr_vector_to_streams_0 = gr.vector_to_streams( gr.sizeof_short * 1, 2) self.gr_short_to_float_0_0 = gr.short_to_float() self.gr_short_to_float_0 = gr.short_to_float() self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_file_sink_0 = gr.file_sink(gr.sizeof_short * 2, baseband_file) self.gr_file_sink_0.set_unbuffered(False) self._datetime_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(1).GetWin(), value=self.datetime_text, callback=self.set_datetime_text, label="Local time of aquisition start", converter=forms.str_converter(), ) self.rx_ntb.GetPage(1).GridAdd(self._datetime_text_static_text, 1, 0, 1, 1) self._baseband_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(1).GetWin(), value=self.baseband_file_text_inf, callback=self.set_baseband_file_text_inf, label="Baseband filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(1).GridAdd( self._baseband_file_text_inf_static_text, 4, 0, 1, 1) ################################################## # Connections ################################################## self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_0_0, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_float_to_complex_0, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink1, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_file_sink_0, 0))
def __init__(self, gain=25, clock_alpha=0.005, freq=1707e6, decim=25, satellite='MetOp', symb_rate=(3500e3/3+3500e3)/2, pll_alpha=0.005, deframer_sync_check=True, deframer_insync_frames=2, deframer_outsync_frames=5, frames_file=os.environ['HOME'] + '/metop_ahrpt_frames.cadu', baseband_file=os.environ['HOME'] + '/metop_ahrpt_baseband.dat', viterbi_sync_threshold=0.1, viterbi_sync_check=True, viterbi_insync_frames=5, viterbi_outsync_frames=20): grc_wxgui.top_block_gui.__init__(self, title="USRP2 MetOp AHRPT Receiver") ################################################## # Parameters ################################################## self.gain = gain self.clock_alpha = clock_alpha self.freq = freq self.decim = decim self.satellite = satellite self.symb_rate = symb_rate self.pll_alpha = pll_alpha self.deframer_sync_check = deframer_sync_check self.deframer_insync_frames = deframer_insync_frames self.deframer_outsync_frames = deframer_outsync_frames self.frames_file = frames_file self.baseband_file = baseband_file self.viterbi_sync_threshold = viterbi_sync_threshold self.viterbi_sync_check = viterbi_sync_check self.viterbi_insync_frames = viterbi_insync_frames self.viterbi_outsync_frames = viterbi_outsync_frames ################################################## # Variables ################################################## self.decim_tb = decim_tb = decim self.symb_rate_tb = symb_rate_tb = symb_rate self.samp_rate = samp_rate = 100e6/decim_tb self.viterbi_sync_threshold_text = viterbi_sync_threshold_text = viterbi_sync_threshold self.viterbi_sync_after_text = viterbi_sync_after_text = viterbi_insync_frames self.viterbi_outofsync_after_text = viterbi_outofsync_after_text = viterbi_outsync_frames self.viterbi_node_sync_text = viterbi_node_sync_text = viterbi_sync_check self.sps = sps = samp_rate/symb_rate_tb self.satellite_text = satellite_text = satellite self.samp_rate_st = samp_rate_st = samp_rate self.pll_alpha_sl = pll_alpha_sl = pll_alpha self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/samp_rate self.gain_tb = gain_tb = gain self.freq_tb = freq_tb = freq self.frames_file_text_inf = frames_file_text_inf = frames_file self.deframer_sync_after_text = deframer_sync_after_text = deframer_insync_frames self.deframer_nosync_after_text = deframer_nosync_after_text = deframer_outsync_frames self.deframer_check_sync_text = deframer_check_sync_text = deframer_sync_check self.datetime_text = datetime_text = strftime("%A, %B %d %Y %H:%M:%S", localtime()) self.clock_alpha_sl = clock_alpha_sl = clock_alpha self.baseband_file_text_inf = baseband_file_text_inf = baseband_file ################################################## # Notebooks ################################################## self.rx_ntb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "USRP Receiver") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "PLL demodulator and Clock sync") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Viterbi decoder") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Deframer") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Output") self.Add(self.rx_ntb) ################################################## # Controls ################################################## self._decim_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.decim_tb, callback=self.set_decim_tb, label="Decimation", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._decim_tb_text_box, 1, 3, 1, 1) self._symb_rate_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), value=self.symb_rate_tb, callback=self.set_symb_rate_tb, label="Symbol rate", converter=forms.int_converter(), ) self.rx_ntb.GetPage(1).GridAdd(self._symb_rate_tb_text_box, 2, 1, 1, 1) self._viterbi_sync_threshold_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_sync_threshold_text, callback=self.set_viterbi_sync_threshold_text, label="Viterbi node sync threshold [BER]", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._viterbi_sync_threshold_text_static_text, 3, 0, 1, 1) self._viterbi_sync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_sync_after_text, callback=self.set_viterbi_sync_after_text, label="Valid frames for Viterbi decoder sync", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._viterbi_sync_after_text_static_text, 4, 0, 1, 1) self._viterbi_outofsync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_outofsync_after_text, callback=self.set_viterbi_outofsync_after_text, label="Invalid frames for Viterbi decoder out of sync", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._viterbi_outofsync_after_text_static_text, 5, 0, 1, 1) self._viterbi_node_sync_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_node_sync_text, callback=self.set_viterbi_node_sync_text, label="Viterbi node sync enable", converter=forms.str_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._viterbi_node_sync_text_static_text, 2, 0, 1, 1) self._satellite_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.satellite_text, callback=self.set_satellite_text, label="Sat ", converter=forms.str_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._satellite_text_static_text, 1, 0, 1, 1) self._samp_rate_st_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.samp_rate_st, callback=self.set_samp_rate_st, label="Sample rate", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._samp_rate_st_static_text, 1, 4, 1, 1) _pll_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._pll_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, label="PLL Alpha", converter=forms.float_converter(), proportion=0, ) self._pll_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_pll_alpha_sl_sizer, 1, 0, 1, 1) self._gain_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.gain_tb, callback=self.set_gain_tb, label="RX gain [dB]", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._gain_tb_text_box, 1, 2, 1, 1) self._freq_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.freq_tb, callback=self.set_freq_tb, label="Frequency", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._freq_tb_text_box, 1, 1, 1, 1) self._frames_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(4).GetWin(), value=self.frames_file_text_inf, callback=self.set_frames_file_text_inf, label="Frames filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(4).GridAdd(self._frames_file_text_inf_static_text, 3, 0, 1, 1) self._deframer_sync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.deframer_sync_after_text, callback=self.set_deframer_sync_after_text, label="Deframe sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._deframer_sync_after_text_static_text, 3, 0, 1, 1) self._deframer_nosync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.deframer_nosync_after_text, callback=self.set_deframer_nosync_after_text, label="Deframer out of sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._deframer_nosync_after_text_static_text, 4, 0, 1, 1) self._deframer_check_sync_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.deframer_check_sync_text, callback=self.set_deframer_check_sync_text, label="Deframer check sync enable", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._deframer_check_sync_text_static_text, 2, 0, 1, 1) self._datetime_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(4).GetWin(), value=self.datetime_text, callback=self.set_datetime_text, label="Local time of aquisition start", converter=forms.str_converter(), ) self.rx_ntb.GetPage(4).GridAdd(self._datetime_text_static_text, 1, 0, 1, 1) _clock_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._clock_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, label="Clock alpha", converter=forms.float_converter(), proportion=0, ) self._clock_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_clock_alpha_sl_sizer, 1, 1, 1, 1) self._baseband_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(4).GetWin(), value=self.baseband_file_text_inf, callback=self.set_baseband_file_text_inf, label="Baseband filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(4).Add(self._baseband_file_text_inf_static_text) ################################################## # Blocks ################################################## self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_cc(sps, clock_alpha_sl*clock_alpha_sl/4.0, 0.5, clock_alpha_sl, 0.05) self.gr_costas_loop_cc_0 = gr.costas_loop_cc(pll_alpha_sl, pll_alpha_sl*pll_alpha_sl/4.0, 0.07, -0.07, 4) self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_short*2, baseband_file) self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc((1, )) self.gr_short_to_float_0 = gr.short_to_float() self.gr_short_to_float_0_0 = gr.short_to_float() self.gr_vector_to_streams_0 = gr.vector_to_streams(gr.sizeof_short*1, 2) self.usrp2_source_xxxx2_0 = usrp2.source_16sc() self.usrp2_source_xxxx2_0.set_decim(decim_tb) self.usrp2_source_xxxx2_0.set_center_freq(freq_tb) self.usrp2_source_xxxx2_0.set_gain(gain_tb) self.wxgui_fftsink1 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=5, y_divs=10, ref_level=50, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="Not filtered spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink1.win) self.wxgui_fftsink2 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=0, y_per_div=5, y_divs=10, ref_level=50, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="RRC filtered spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink2.win) self.wxgui_scopesink2_1 = scopesink2.scope_sink_c( self.rx_ntb.GetPage(1).GetWin(), title="QPSK constellation diagram", sample_rate=symb_rate, v_scale=0.4, v_offset=0, t_scale=1/samp_rate, ac_couple=False, xy_mode=True, num_inputs=1, ) self.rx_ntb.GetPage(1).Add(self.wxgui_scopesink2_1.win) ################################################## # Connections ################################################## self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink1, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink2, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_float_to_complex_0, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_file_sink_0_1, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_0_0, 0)) self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_costas_loop_cc_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.gr_costas_loop_cc_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.wxgui_scopesink2_1, 0))
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, *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, 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 graph (args): nargs = len(args) if nargs == 2: infile = args[0] outfile = args[1] else: raise ValueError('usage: interp.py input_file output_file\n') tb = gr.top_block () # Convert to a from shorts to a stream of complex numbers. srcf = gr.file_source (gr.sizeof_short,infile) s2ss = gr.stream_to_streams(gr.sizeof_short,2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src0 = gr.float_to_complex() tb.connect(srcf, s2ss) tb.connect((s2ss, 0), s2f1, (src0, 0)) tb.connect((s2ss, 1), s2f2, (src0, 1)) # Low pass filter it and increase sample rate by a factor of 3. lp_coeffs = gr.firdes.low_pass ( 3, 19.2e6, 3.2e6, .5e6, gr.firdes.WIN_HAMMING ) lp = gr.interp_fir_filter_ccf ( 3, lp_coeffs ) tb.connect(src0, lp) # Upconvert it. duc_coeffs = gr.firdes.low_pass ( 1, 19.2e6, 9e6, 1e6, gr.firdes.WIN_HAMMING ) duc = gr.freq_xlating_fir_filter_ccf ( 1, duc_coeffs, 5.75e6, 19.2e6 ) # Discard the imaginary component. c2f = gr.complex_to_float() tb.connect(lp, duc, c2f) # Frequency Phase Lock Loop input_rate = 19.2e6 IF_freq = 5.75e6 # 1/2 as wide because we're designing lp filter symbol_rate = atsc.ATSC_SYMBOL_RATE/2. NTAPS = 279 tt = gr.firdes.root_raised_cosine (1.0, input_rate, symbol_rate, .115, NTAPS) # heterodyne the low pass coefficients up to the specified bandpass # center frequency. Note that when we do this, the filter bandwidth # is effectively twice the low pass (2.69 * 2 = 5.38) and hence # matches the diagram in the ATSC spec. arg = 2. * math.pi * IF_freq / input_rate t=[] for i in range(len(tt)): t += [tt[i] * 2. * math.cos(arg * i)] rrc = gr.fir_filter_fff(1, t) fpll = atsc.fpll() pilot_freq = IF_freq - 3e6 + 0.31e6 lower_edge = 6e6 - 0.31e6 upper_edge = IF_freq - 3e6 + pilot_freq transition_width = upper_edge - lower_edge lp_coeffs = gr.firdes.low_pass (1.0, input_rate, (lower_edge + upper_edge) * 0.5, transition_width, gr.firdes.WIN_HAMMING); lp_filter = gr.fir_filter_fff (1,lp_coeffs) alpha = 1e-5 iir = gr.single_pole_iir_filter_ff(alpha) remove_dc = gr.sub_ff() tb.connect(c2f, fpll, lp_filter) tb.connect(lp_filter, iir) tb.connect(lp_filter, (remove_dc,0)) tb.connect(iir, (remove_dc,1)) # Bit Timing Loop, Field Sync Checker and Equalizer btl = atsc.bit_timing_loop() fsc = atsc.fs_checker() eq = atsc.equalizer() fsd = atsc.field_sync_demux() tb.connect(remove_dc, btl) tb.connect((btl, 0),(fsc, 0),(eq, 0),(fsd, 0)) tb.connect((btl, 1),(fsc, 1),(eq, 1),(fsd, 1)) # Viterbi viterbi = atsc.viterbi_decoder() deinter = atsc.deinterleaver() rs_dec = atsc.rs_decoder() derand = atsc.derandomizer() depad = atsc.depad() dst = gr.file_sink(gr.sizeof_char, outfile) tb.connect(fsd, viterbi, deinter, rs_dec, derand, depad, dst) dst2 = gr.file_sink(gr.sizeof_gr_complex, "atsc_complex.data") tb.connect(src0, dst2) tb.run ()
def __init__(self, gain=25, clock_alpha=0.005, freq=1707e6, decim=25, satellite='MetOp', symb_rate=(3500e3 / 3 + 3500e3) / 2, pll_alpha=0.005, deframer_sync_check=True, deframer_insync_frames=2, deframer_outsync_frames=5, frames_file=os.environ['HOME'] + '/metop_ahrpt_frames.cadu', baseband_file=os.environ['HOME'] + '/metop_ahrpt_baseband.dat', viterbi_sync_threshold=0.1, viterbi_sync_check=True, viterbi_insync_frames=5, viterbi_outsync_frames=20): grc_wxgui.top_block_gui.__init__(self, title="USRP2 MetOp AHRPT Receiver") ################################################## # Parameters ################################################## self.gain = gain self.clock_alpha = clock_alpha self.freq = freq self.decim = decim self.satellite = satellite self.symb_rate = symb_rate self.pll_alpha = pll_alpha self.deframer_sync_check = deframer_sync_check self.deframer_insync_frames = deframer_insync_frames self.deframer_outsync_frames = deframer_outsync_frames self.frames_file = frames_file self.baseband_file = baseband_file self.viterbi_sync_threshold = viterbi_sync_threshold self.viterbi_sync_check = viterbi_sync_check self.viterbi_insync_frames = viterbi_insync_frames self.viterbi_outsync_frames = viterbi_outsync_frames ################################################## # Variables ################################################## self.decim_tb = decim_tb = decim self.symb_rate_tb = symb_rate_tb = symb_rate self.samp_rate = samp_rate = 100e6 / decim_tb self.viterbi_sync_threshold_text = viterbi_sync_threshold_text = viterbi_sync_threshold self.viterbi_sync_after_text = viterbi_sync_after_text = viterbi_insync_frames self.viterbi_outofsync_after_text = viterbi_outofsync_after_text = viterbi_outsync_frames self.viterbi_node_sync_text = viterbi_node_sync_text = viterbi_sync_check self.sps = sps = samp_rate / symb_rate_tb self.satellite_text = satellite_text = satellite self.samp_rate_st = samp_rate_st = samp_rate self.pll_alpha_sl = pll_alpha_sl = pll_alpha self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2 * math.pi * 100e3 / samp_rate self.gain_tb = gain_tb = gain self.freq_tb = freq_tb = freq self.frames_file_text_inf = frames_file_text_inf = frames_file self.deframer_sync_after_text = deframer_sync_after_text = deframer_insync_frames self.deframer_nosync_after_text = deframer_nosync_after_text = deframer_outsync_frames self.deframer_check_sync_text = deframer_check_sync_text = deframer_sync_check self.datetime_text = datetime_text = strftime("%A, %B %d %Y %H:%M:%S", localtime()) self.clock_alpha_sl = clock_alpha_sl = clock_alpha self.baseband_file_text_inf = baseband_file_text_inf = baseband_file ################################################## # Notebooks ################################################## self.rx_ntb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "USRP Receiver") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "PLL demodulator and Clock sync") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Viterbi decoder") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Deframer") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Output") self.Add(self.rx_ntb) ################################################## # Controls ################################################## self._decim_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.decim_tb, callback=self.set_decim_tb, label="Decimation", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._decim_tb_text_box, 1, 3, 1, 1) self._symb_rate_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), value=self.symb_rate_tb, callback=self.set_symb_rate_tb, label="Symbol rate", converter=forms.int_converter(), ) self.rx_ntb.GetPage(1).GridAdd(self._symb_rate_tb_text_box, 2, 1, 1, 1) self._viterbi_sync_threshold_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_sync_threshold_text, callback=self.set_viterbi_sync_threshold_text, label="Viterbi node sync threshold [BER]", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._viterbi_sync_threshold_text_static_text, 3, 0, 1, 1) self._viterbi_sync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_sync_after_text, callback=self.set_viterbi_sync_after_text, label="Valid frames for Viterbi decoder sync", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._viterbi_sync_after_text_static_text, 4, 0, 1, 1) self._viterbi_outofsync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_outofsync_after_text, callback=self.set_viterbi_outofsync_after_text, label="Invalid frames for Viterbi decoder out of sync", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._viterbi_outofsync_after_text_static_text, 5, 0, 1, 1) self._viterbi_node_sync_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.viterbi_node_sync_text, callback=self.set_viterbi_node_sync_text, label="Viterbi node sync enable", converter=forms.str_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._viterbi_node_sync_text_static_text, 2, 0, 1, 1) self._satellite_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.satellite_text, callback=self.set_satellite_text, label="Sat ", converter=forms.str_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._satellite_text_static_text, 1, 0, 1, 1) self._samp_rate_st_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.samp_rate_st, callback=self.set_samp_rate_st, label="Sample rate", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._samp_rate_st_static_text, 1, 4, 1, 1) _pll_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._pll_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, label="PLL Alpha", converter=forms.float_converter(), proportion=0, ) self._pll_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_pll_alpha_sl_sizer, 1, 0, 1, 1) self._gain_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.gain_tb, callback=self.set_gain_tb, label="RX gain [dB]", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._gain_tb_text_box, 1, 2, 1, 1) self._freq_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.freq_tb, callback=self.set_freq_tb, label="Frequency", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._freq_tb_text_box, 1, 1, 1, 1) self._frames_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(4).GetWin(), value=self.frames_file_text_inf, callback=self.set_frames_file_text_inf, label="Frames filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(4).GridAdd(self._frames_file_text_inf_static_text, 3, 0, 1, 1) self._deframer_sync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.deframer_sync_after_text, callback=self.set_deframer_sync_after_text, label="Deframe sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(3).GridAdd( self._deframer_sync_after_text_static_text, 3, 0, 1, 1) self._deframer_nosync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.deframer_nosync_after_text, callback=self.set_deframer_nosync_after_text, label="Deframer out of sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(3).GridAdd( self._deframer_nosync_after_text_static_text, 4, 0, 1, 1) self._deframer_check_sync_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.deframer_check_sync_text, callback=self.set_deframer_check_sync_text, label="Deframer check sync enable", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd( self._deframer_check_sync_text_static_text, 2, 0, 1, 1) self._datetime_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(4).GetWin(), value=self.datetime_text, callback=self.set_datetime_text, label="Local time of aquisition start", converter=forms.str_converter(), ) self.rx_ntb.GetPage(4).GridAdd(self._datetime_text_static_text, 1, 0, 1, 1) _clock_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._clock_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, label="Clock alpha", converter=forms.float_converter(), proportion=0, ) self._clock_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_clock_alpha_sl_sizer, 1, 1, 1, 1) self._baseband_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(4).GetWin(), value=self.baseband_file_text_inf, callback=self.set_baseband_file_text_inf, label="Baseband filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(4).Add(self._baseband_file_text_inf_static_text) ################################################## # Blocks ################################################## self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_cc( sps, clock_alpha_sl * clock_alpha_sl / 4.0, 0.5, clock_alpha_sl, 0.05) self.gr_costas_loop_cc_0 = gr.costas_loop_cc( pll_alpha_sl, pll_alpha_sl * pll_alpha_sl / 4.0, 0.07, -0.07, 4) self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_short * 2, baseband_file) self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_multiply_const_vxx_0 = gr.multiply_const_vcc((1, )) self.gr_short_to_float_0 = gr.short_to_float() self.gr_short_to_float_0_0 = gr.short_to_float() self.gr_vector_to_streams_0 = gr.vector_to_streams( gr.sizeof_short * 1, 2) self.usrp2_source_xxxx2_0 = usrp2.source_16sc() self.usrp2_source_xxxx2_0.set_decim(decim_tb) self.usrp2_source_xxxx2_0.set_center_freq(freq_tb) self.usrp2_source_xxxx2_0.set_gain(gain_tb) self.wxgui_fftsink1 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=5, y_divs=10, ref_level=50, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="Not filtered spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink1.win) self.wxgui_fftsink2 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=0, y_per_div=5, y_divs=10, ref_level=50, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="RRC filtered spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink2.win) self.wxgui_scopesink2_1 = scopesink2.scope_sink_c( self.rx_ntb.GetPage(1).GetWin(), title="QPSK constellation diagram", sample_rate=symb_rate, v_scale=0.4, v_offset=0, t_scale=1 / samp_rate, ac_couple=False, xy_mode=True, num_inputs=1, ) self.rx_ntb.GetPage(1).Add(self.wxgui_scopesink2_1.win) ################################################## # Connections ################################################## self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink1, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink2, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_float_to_complex_0, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_file_sink_0_1, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_0_0, 0)) self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_costas_loop_cc_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.gr_costas_loop_cc_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.wxgui_scopesink2_1, 0))
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, pll_alpha=0.005, satellite='NOAA18', decim=50, gain=25, clock_alpha=0.005, freq=1707e6, deframer_sync_check=True, deframer_insync_frames=2, deframer_outsync_frames=5, symb_rate=600*1109, baseband_file=os.environ['HOME'] + '/noaa_hrpt_baseband.dat', frames_file=os.environ['HOME'] + '/noaa_hrpt_frames.hmf'): grc_wxgui.top_block_gui.__init__(self, title="USRP2 NOAA HRPT Receiver") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.pll_alpha = pll_alpha self.satellite = satellite self.decim = decim self.gain = gain self.clock_alpha = clock_alpha self.freq = freq self.deframer_sync_check = deframer_sync_check self.deframer_insync_frames = deframer_insync_frames self.deframer_outsync_frames = deframer_outsync_frames self.symb_rate = symb_rate self.baseband_file = baseband_file self.frames_file = frames_file ################################################## # Variables ################################################## self.decim_tb = decim_tb = decim self.symb_rate_tb = symb_rate_tb = symb_rate self.samp_rate = samp_rate = 100e6/decim_tb self.sps = sps = samp_rate/symb_rate_tb self.satellite_text = satellite_text = satellite self.samp_rate_st = samp_rate_st = samp_rate self.pll_alpha_sl = pll_alpha_sl = pll_alpha self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/samp_rate self.hs = hs = int(sps/2.0) self.gain_tb = gain_tb = gain self.freq_tb = freq_tb = freq self.frames_file_text_inf = frames_file_text_inf = frames_file self.deframer_sync_after_text = deframer_sync_after_text = deframer_insync_frames self.deframer_nosync_after_text = deframer_nosync_after_text = deframer_outsync_frames self.deframer_check_sync_text = deframer_check_sync_text = deframer_sync_check self.datetime_text = datetime_text = strftime("%A, %B %d %Y %H:%M:%S", localtime()) self.clock_alpha_sl = clock_alpha_sl = clock_alpha self.baseband_file_text_inf = baseband_file_text_inf = baseband_file ################################################## # Notebooks ################################################## self.rx_ntb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "USRP Receiver") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "PLL demodulator and Clock sync") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Deframer") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Output") self.Add(self.rx_ntb) ################################################## # Controls ################################################## self._decim_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.decim_tb, callback=self.set_decim_tb, label="Decimation", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._decim_tb_text_box, 1, 3, 1, 1) self._symb_rate_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), value=self.symb_rate_tb, callback=self.set_symb_rate_tb, label="Symbol rate", converter=forms.int_converter(), ) self.rx_ntb.GetPage(1).GridAdd(self._symb_rate_tb_text_box, 2, 1, 1, 1) self._satellite_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.satellite_text, callback=self.set_satellite_text, label="Sat ", converter=forms.str_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._satellite_text_static_text, 1, 0, 1, 1) self._samp_rate_st_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.samp_rate_st, callback=self.set_samp_rate_st, label="Sample rate", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._samp_rate_st_static_text, 1, 4, 1, 1) _pll_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._pll_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, label="PLL Alpha", converter=forms.float_converter(), proportion=0, ) self._pll_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_pll_alpha_sl_sizer, 1, 0, 1, 1) self._gain_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.gain_tb, callback=self.set_gain_tb, label="RX gain [dB]", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._gain_tb_text_box, 1, 2, 1, 1) self._freq_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.freq_tb, callback=self.set_freq_tb, label="Frequency", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._freq_tb_text_box, 1, 1, 1, 1) self._frames_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.frames_file_text_inf, callback=self.set_frames_file_text_inf, label="Frames filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._frames_file_text_inf_static_text, 3, 0, 1, 1) self._deframer_sync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.deframer_sync_after_text, callback=self.set_deframer_sync_after_text, label="Deframe sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._deframer_sync_after_text_static_text, 3, 0, 1, 1) self._deframer_nosync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.deframer_nosync_after_text, callback=self.set_deframer_nosync_after_text, label="Deframer out of sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._deframer_nosync_after_text_static_text, 4, 0, 1, 1) self._deframer_check_sync_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.deframer_check_sync_text, callback=self.set_deframer_check_sync_text, label="Deframer check sync enable", converter=forms.str_converter(), ) self.rx_ntb.GetPage(2).GridAdd(self._deframer_check_sync_text_static_text, 2, 0, 1, 1) self._datetime_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.datetime_text, callback=self.set_datetime_text, label="Local time of aquisition start", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._datetime_text_static_text, 1, 0, 1, 1) _clock_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._clock_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, label="Clock alpha", converter=forms.float_converter(), proportion=0, ) self._clock_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_clock_alpha_sl_sizer, 1, 1, 1, 1) self._baseband_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.baseband_file_text_inf, callback=self.set_baseband_file_text_inf, label="Baseband filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._baseband_file_text_inf_static_text, 4, 0, 1, 1) ################################################## # Blocks ################################################## self.gr_agc_xx_0 = gr.agc_cc(10e-6, 1, 1.0/32767.0, 1.0) self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset) self.gr_file_sink_0_0 = gr.file_sink(gr.sizeof_short*1, frames_file) self.gr_file_sink_0_0.set_unbuffered(False) self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_short*2, baseband_file) self.gr_file_sink_0_1.set_unbuffered(False) self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000) self.gr_short_to_float_0 = gr.short_to_float() self.gr_short_to_float_0_0 = gr.short_to_float() self.gr_vector_to_streams_0 = gr.vector_to_streams(gr.sizeof_short*1, 2) self.noaa_hrpt_decoder_0 = noaa.hrpt_decoder(True,False) self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset) self.poesweather_univ_hrpt_deframer_0 = poesweather.univ_hrpt_deframer(deframer_sync_check, 11090, deframer_insync_frames, deframer_outsync_frames) self.usrp2_source_xxxx2_0 = usrp2.source_16sc() self.usrp2_source_xxxx2_0.set_decim(decim_tb) self.usrp2_source_xxxx2_0.set_center_freq(freq_tb) self.usrp2_source_xxxx2_0.set_gain(gain_tb) self.wxgui_fftsink1 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=5, y_divs=10, ref_level=65, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="Not filtered spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink1.win) ################################################## # Connections ################################################## self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink1, 0)) self.connect((self.poesweather_univ_hrpt_deframer_0, 0), (self.noaa_hrpt_decoder_0, 0)) self.connect((self.gr_binary_slicer_fb_0, 0), (self.poesweather_univ_hrpt_deframer_0, 0)) self.connect((self.poesweather_univ_hrpt_deframer_0, 0), (self.gr_file_sink_0_0, 0)) self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0)) self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0)) self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_agc_xx_0, 0), (self.pll, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.gr_agc_xx_0, 0)) self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_0_0, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_file_sink_0_1, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.gr_short_to_float_0, 0), (self.gr_float_to_complex_0, 0))
def __init__(self, options): gr.hier_block2.__init__(self, "fbmc_receive_path", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(0,0,0)) print "This is FBMC receive path 1x1" common_options.defaults(options) config = self.config = station_configuration() config.data_subcarriers = dsubc = options.subcarriers config.cp_length = 0 config.frame_data_blocks = options.data_blocks config._verbose = options.verbose #TODO: update config.fft_length = options.fft_length config.dc_null = options.dc_null config.training_data = default_block_header(dsubc, config.fft_length,config.dc_null,options) config.coding = options.coding config.ber_window = options.ber_window config.periodic_parts = 8 config.frame_id_blocks = 1 # FIXME self._options = copy.copy(options) #FIXME: do we need this? config.fbmc = options.fbmc config.block_length = config.fft_length + config.cp_length config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks config.frame_length = config.training_data.fbmc_no_preambles + 2*config.frame_data_part config.postpro_frame_length = config.frame_data_part + \ config.training_data.no_pilotsyms config.subcarriers = dsubc + \ config.training_data.pilot_subcarriers config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null total_subc = config.subcarriers # check some bounds if config.fft_length < config.subcarriers: raise SystemError, "Subcarrier number must be less than FFT length" if config.fft_length < config.cp_length: raise SystemError, "Cyclic prefix length must be less than FFT length" #self.input = gr.kludge_copy(gr.sizeof_gr_complex) #self.connect( self, self.input ) self.input = self self.ideal = options.ideal self.ideal2 = options.ideal2 ## Inner receiver ## Timing & Frequency Synchronization ## Channel estimation + Equalization ## Phase Tracking for sampling clock frequency offset correction inner_receiver = self.inner_receiver = fbmc_inner_receiver( options, options.log ) self.connect( self.input, inner_receiver ) ofdm_blocks = ( inner_receiver, 2 ) frame_start = ( inner_receiver, 1 ) disp_ctf = ( inner_receiver, 0 ) #self.snr_est_preamble = ( inner_receiver, 3 ) #terminate_stream(self,snr_est_preamble) disp_cfo = ( inner_receiver, 3 ) if self.ideal is False and self.ideal2 is False: self.zmq_probe_freqoff = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5557") self.connect(disp_cfo, self.zmq_probe_freqoff) else: self.connect(disp_cfo, blocks.null_sink(gr.sizeof_float)) # for ID decoder used_id_bits = config.used_id_bits = 8 #TODO: constant in source code! rep_id_bits = config.rep_id_bits = dsubc/used_id_bits #BPSK if options.log: print "rep_id_bits %d" % (rep_id_bits) if dsubc % used_id_bits <> 0: raise SystemError,"Data subcarriers need to be multiple of 10" ## Workaround to avoid periodic structure seed(1) whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)] ## NOTE!!! BIG HACK!!! ## first preamble ain't equalized .... ## for Milan's SNR estimator ## Outer Receiver ## Make new inner receiver compatible with old outer receiver ## FIXME: renew outer receiver self.ctf = disp_ctf #frame_sampler = ofdm_frame_sampler(options) frame_sampler = fbmc_frame_sampler(options) self.connect( ofdm_blocks, frame_sampler) self.connect( frame_start, (frame_sampler,1) ) # # ft = [0] * config.frame_length # ft[0] = 1 # # # The next block ensures that only complete frames find their way into # # the old outer receiver. The dynamic frame start trigger is hence # # replaced with a static one, fixed to the frame length. # # frame_sampler = ofdm.vector_sampler( gr.sizeof_gr_complex * total_subc, # config.frame_length ) # self.symbol_output = blocks.vector_to_stream( gr.sizeof_gr_complex * total_subc, # config.frame_length ) # delayed_frame_start = blocks.delay( gr.sizeof_char, config.frame_length - 1 ) # damn_static_frame_trigger = blocks.vector_source_b( ft, True ) # # if options.enable_erasure_decision: # frame_gate = vector_sampler( # gr.sizeof_gr_complex * total_subc * config.frame_length, 1 ) # self.connect( ofdm_blocks, frame_sampler, frame_gate, # self.symbol_output ) # else: # self.connect( ofdm_blocks, frame_sampler, self.symbol_output ) # # self.connect( frame_start, delayed_frame_start, ( frame_sampler, 1 ) ) if options.enable_erasure_decision: frame_gate = frame_sampler.frame_gate self.symbol_output = frame_sampler orig_frame_start = frame_start frame_start = (frame_sampler,1) self.frame_trigger = frame_start #terminate_stream(self, self.frame_trigger) ## Pilot block filter pb_filt = self._pilot_block_filter = fbmc_pilot_block_filter() self.connect(self.symbol_output,pb_filt) self.connect(self.frame_trigger,(pb_filt,1)) self.frame_data_trigger = (pb_filt,1) #self.symbol_output = pb_filt #if options.log: #log_to_file(self, pb_filt, "data/pb_filt_out.compl") if config.fbmc: pda_in = pb_filt else: ## Pilot subcarrier filter ps_filt = self._pilot_subcarrier_filter = pilot_subcarrier_filter() self.connect(self.symbol_output,ps_filt) if options.log: log_to_file(self, ps_filt, "data/ps_filt_out.compl") pda_in = ps_filt ## Workaround to avoid periodic structure # for ID decoder seed(1) whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)] if not options.enable_erasure_decision: ## ID Block Filter # Filter ID block, skip data blocks id_bfilt = self._id_block_filter = vector_sampler( gr.sizeof_gr_complex * dsubc, 1 ) if not config.frame_id_blocks == 1: raise SystemExit, "# ID Blocks > 1 not supported" self.connect( pda_in , id_bfilt ) self.connect( self.frame_data_trigger, ( id_bfilt, 1 ) ) # trigger #log_to_file( self, id_bfilt, "data/id_bfilt.compl" ) ## ID Demapper and Decoder, soft decision self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( dsubc, used_id_bits, whitener_pn ) self.connect( id_bfilt, self.id_dec ) print "Using coded BPSK soft decoder for ID detection" else: # options.enable_erasure_decision: id_bfilt = self._id_block_filter = vector_sampler( gr.sizeof_gr_complex * total_subc, config.frame_id_blocks ) id_bfilt_trig_delay = 0 for x in range( config.frame_length ): if x in config.training_data.pilotsym_pos: id_bfilt_trig_delay += 1 else: break print "Position of ID block within complete frame: %d" %(id_bfilt_trig_delay) assert( id_bfilt_trig_delay > 0 ) # else not supported id_bfilt_trig = blocks.delay( gr.sizeof_char, id_bfilt_trig_delay ) self.connect( ofdm_blocks, id_bfilt ) self.connect( orig_frame_start, id_bfilt_trig, ( id_bfilt, 1 ) ) self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( total_subc, used_id_bits, whitener_pn, config.training_data.shifted_pilot_tones ) self.connect( id_bfilt, self.id_dec ) print "Using coded BPSK soft decoder for ID detection" # The threshold block either returns 1.0 if the llr-value from the # id decoder is below the threshold, else 0.0. Hence we convert this # into chars, 0 and 1, and use it as trigger for the sampler. min_llr = ( self.id_dec, 1 ) erasure_threshold = gr.threshold_ff( 10.0, 10.0, 0 ) # FIXME is it the optimal threshold? erasure_dec = gr.float_to_char() id_gate = vector_sampler( gr.sizeof_short, 1 ) ctf_gate = vector_sampler( gr.sizeof_float * total_subc, 1 ) self.connect( self.id_dec , id_gate ) self.connect( self.ctf, ctf_gate ) self.connect( min_llr, erasure_threshold, erasure_dec ) self.connect( erasure_dec, ( frame_gate, 1 ) ) self.connect( erasure_dec, ( id_gate, 1 ) ) self.connect( erasure_dec, ( ctf_gate, 1 ) ) self.id_dec = self._id_decoder = id_gate self.ctf = ctf_gate print "Erasure decision for IDs is enabled" if options.log: id_dec_f = gr.short_to_float() self.connect(self.id_dec,id_dec_f) log_to_file(self, id_dec_f, "data/id_dec_out.float") if options.log: log_to_file(self, id_bfilt, "data/id_blockfilter_out.compl") # TODO: refactor names if options.log: map_src_f = gr.char_to_float(dsubc) self.connect(map_src,map_src_f) log_to_file(self, map_src_f, "data/map_src_out.float") ## Allocation Control if options.static_allocation: #DEBUG if options.coding: mode = 1 # Coding mode 1-9 bitspermode = [0.5,1,1.5,2,3,4,4.5,5,6] # Information bits per mode bitcount_vec = [(int)(config.data_subcarriers*config.frame_data_blocks*bitspermode[mode-1])] bitloading = mode else: bitloading = 1 bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading] #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks] self.bitcount_src = blocks.vector_source_i(bitcount_vec,True,1) # 0s for ID block, then data #bitloading_vec = [0]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2) bitloading_vec = [0]*dsubc+[bitloading]*dsubc bitloading_src = blocks.vector_source_b(bitloading_vec,True,dsubc) power_vec = [1]*config.data_subcarriers power_src = blocks.vector_source_f(power_vec,True,dsubc) else: self.allocation_buffer = ofdm.allocation_buffer(config.data_subcarriers, config.frame_data_blocks, "tcp://"+options.tx_hostname+":3333",config.coding) self.bitcount_src = (self.allocation_buffer,0) bitloading_src = (self.allocation_buffer,1) power_src = (self.allocation_buffer,2) self.connect(self.id_dec, self.allocation_buffer) if options.benchmarking: self.allocation_buffer.set_allocation([4]*config.data_subcarriers,[1]*config.data_subcarriers) if options.log: log_to_file(self, self.bitcount_src, "data/bitcount_src_rx.int") log_to_file(self, bitloading_src, "data/bitloading_src_rx.char") log_to_file(self, power_src, "data/power_src_rx.cmplx") log_to_file(self, self.id_dec, "data/id_dec_rx.short") ## Power Deallocator pda = self._power_deallocator = multiply_frame_fc(config.frame_data_part, dsubc) self.connect(pda_in,(pda,0)) self.connect(power_src,(pda,1)) ## Demodulator # if 0: # ac_vector = [0.0+0.0j]*208 # ac_vector[0] = (2*10**(-0.452)) # ac_vector[3] = (10**(-0.651)) # ac_vector[7] = (10**(-1.151)) # csi_vector_inv=abs(numpy.fft.fft(numpy.sqrt(ac_vector)))**2 # dm_csi = numpy.fft.fftshift(csi_vector_inv) # TODO dm_csi = [1]*dsubc # TODO dm_csi = blocks.vector_source_f(dm_csi,True) ## Depuncturer dp_trig = [0]*(config.frame_data_blocks/2) dp_trig[0] = 1 dp_trig = blocks.vector_source_b(dp_trig,True) # TODO if(options.coding): fo=ofdm.fsm(1,2,[91,121]) if options.interleave: int_object=trellis.interleaver(2000,666) deinterlv = trellis.permutation(int_object.K(),int_object.DEINTER(),1,gr.sizeof_float) demod = self._data_demodulator = generic_softdemapper_vcf(dsubc, config.frame_data_part, config.coding) #self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2)) if(options.ideal): self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2)) else: dm_csi_filter = self.dm_csi_filter = filter.single_pole_iir_filter_ff(0.01,dsubc) self.connect(self.ctf, self.dm_csi_filter,(demod,2)) #log_to_file(self, dm_csi_filter, "data/softs_csi.float") #self.connect(dm_trig,(demod,3)) else: demod = self._data_demodulator = generic_demapper_vcb(dsubc, config.frame_data_part) if options.benchmarking: # Do receiver benchmarking until the number of frames x symbols are collected self.connect(pda,blocks.head(gr.sizeof_gr_complex*dsubc, options.N*config.frame_data_blocks),demod) else: self.connect(pda,demod) self.connect(bitloading_src,(demod,1)) if(options.coding): ## Depuncturing if not options.nopunct: depuncturing = depuncture_ff(dsubc,0) frametrigger_bitmap_filter = blocks.vector_source_b([1,0],True) self.connect(bitloading_src,(depuncturing,1)) self.connect(dp_trig,(depuncturing,2)) ## Decoding chunkdivisor = int(numpy.ceil(config.frame_data_blocks/5.0)) print "Number of chunks at Viterbi decoder: ", chunkdivisor decoding = self._data_decoder = ofdm.viterbi_combined_fb(fo,dsubc,-1,-1,2,chunkdivisor,[-1,-1,-1,1,1,-1,1,1],ofdm.TRELLIS_EUCLIDEAN) if options.log and options.coding: log_to_file(self, decoding, "data/decoded.char") if not options.nopunct: log_to_file(self, depuncturing, "data/vit_in.float") if not options.nopunct: if options.interleave: self.connect(demod,deinterlv,depuncturing,decoding) else: self.connect(demod,depuncturing,decoding) else: self.connect(demod,decoding) self.connect(self.bitcount_src, multiply_const_ii(1./chunkdivisor), (decoding,1)) if options.scatterplot or options.scatter_plot_before_phase_tracking: if self.ideal2 is False: scatter_vec_elem = self._scatter_vec_elem = ofdm.vector_element(dsubc,40) scatter_s2v = self._scatter_s2v = blocks.stream_to_vector(gr.sizeof_gr_complex,config.frame_data_blocks) scatter_id_filt = skip(gr.sizeof_gr_complex*dsubc,config.frame_data_blocks) scatter_id_filt.skip_call(0) scatter_trig = [0]*config.frame_data_part scatter_trig[0] = 1 scatter_trig = blocks.vector_source_b(scatter_trig,True) self.connect(scatter_trig,(scatter_id_filt,1)) self.connect(scatter_vec_elem,scatter_s2v) if not options.scatter_plot_before_phase_tracking: print "Enabling Scatterplot for data subcarriers" self.connect(pda,scatter_id_filt,scatter_vec_elem) # Work on this #scatter_sink = ofdm.scatterplot_sink(dsubc) #self.connect(pda,scatter_sink) #self.connect(map_src,(scatter_sink,1)) #self.connect(dm_trig,(scatter_sink,2)) #print "Enabled scatterplot gui interface" self.zmq_probe_scatter = zeromq.pub_sink(gr.sizeof_gr_complex,config.frame_data_blocks, "tcp://*:5560") self.connect(scatter_s2v, blocks.keep_one_in_n(gr.sizeof_gr_complex*config.frame_data_blocks,20), self.zmq_probe_scatter) else: print "Enabling Scatterplot for data before phase tracking" inner_rx = inner_receiver.before_phase_tracking #scatter_sink2 = ofdm.scatterplot_sink(dsubc,"phase_tracking") op = copy.copy(options) op.enable_erasure_decision = False new_framesampler = ofdm_frame_sampler(op) self.connect( inner_rx, new_framesampler ) self.connect( orig_frame_start, (new_framesampler,1) ) new_ps_filter = pilot_subcarrier_filter() new_pb_filter = fbmc_pilot_block_filter() self.connect( (new_framesampler,1), (new_pb_filter,1) ) self.connect( new_framesampler, new_pb_filter, new_ps_filter, scatter_id_filt, scatter_vec_elem ) #self.connect( new_ps_filter, scatter_sink2 ) #self.connect( map_src, (scatter_sink2,1)) #self.connect( dm_trig, (scatter_sink2,2)) if options.log: if(options.coding): log_to_file(self, demod, "data/data_stream_out.float") else: data_f = gr.char_to_float() self.connect(demod,data_f) log_to_file(self, data_f, "data/data_stream_out.float") if options.sfo_feedback: used_id_bits = 8 rep_id_bits = config.data_subcarriers/used_id_bits seed(1) whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)] id_enc = ofdm.repetition_encoder_sb(used_id_bits,rep_id_bits,whitener_pn) self.connect( self.id_dec, id_enc ) id_mod = ofdm_bpsk_modulator(dsubc) self.connect( id_enc, id_mod ) id_mod_conj = gr.conjugate_cc(dsubc) self.connect( id_mod, id_mod_conj ) id_mult = blocks.multiply_vcc(dsubc) self.connect( id_bfilt, ( id_mult,0) ) self.connect( id_mod_conj, ( id_mult,1) ) # id_mult_avg = filter.single_pole_iir_filter_cc(0.01,dsubc) # self.connect( id_mult, id_mult_avg ) id_phase = gr.complex_to_arg(dsubc) self.connect( id_mult, id_phase ) log_to_file( self, id_phase, "data/id_phase.float" ) est=ofdm.LS_estimator_straight_slope(dsubc) self.connect(id_phase,est) slope=blocks.multiply_const_ff(1e6/2/3.14159265) self.connect( (est,0), slope ) log_to_file( self, slope, "data/slope.float" ) log_to_file( self, (est,1), "data/offset.float" ) # ------------------------------------------------------------------------ # # Display some information about the setup if config._verbose: self._print_verbage() ## debug logging ## if options.log: # log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.compl") # log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.float",mag=True) fftlen = 256 my_window = window.hamming(fftlen) #.blackmanharris(fftlen) rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen) rxs_sampler_vect = concatenate([[1],[0]*49]) rxs_trigger = blocks.vector_source_b(rxs_sampler_vect.tolist(),True) rxs_window = blocks.multiply_const_vcc(my_window) rxs_spectrum = gr.fft_vcc(fftlen,True,[],True) rxs_mag = gr.complex_to_mag(fftlen) rxs_avg = filter.single_pole_iir_filter_ff(0.01,fftlen) #rxs_logdb = blocks.nlog10_ff(20.0,fftlen,-20*log10(fftlen)) rxs_logdb = gr.kludge_copy( gr.sizeof_float * fftlen ) rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,1) self.connect(rxs_trigger,(rxs_sampler,1)) self.connect(self.input,rxs_sampler,rxs_window, rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate) log_to_file( self, rxs_decimate_rate, "data/psd_input.float" ) #output branches self.publish_rx_performance_measure()
def __init__(self, options): gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(0, 0, 0), gr.io_signature(2, 2, gr.sizeof_gr_complex)) common_options.defaults(options) config = self.config = station_configuration() config.data_subcarriers = options.subcarriers config.cp_length = options.cp_length config.frame_data_blocks = options.data_blocks config._verbose = options.verbose config.fft_length = options.fft_length config.training_data = default_block_header(config.data_subcarriers, config.fft_length, options) config.tx_station_id = options.station_id config.coding = options.coding if config.tx_station_id is None: raise SystemError, "Station ID not set" config.frame_id_blocks = 1 # FIXME # digital rms amplitude sent to USRP rms_amp = options.rms_amplitude self._options = copy.copy(options) self.servants = [] # FIXME config.block_length = config.fft_length + config.cp_length config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks config.frame_length = config.frame_data_part + \ config.training_data.no_pilotsyms config.subcarriers = config.data_subcarriers + \ config.training_data.pilot_subcarriers config.virtual_subcarriers = config.fft_length - config.subcarriers # default values if parameters not set if rms_amp is None: rms_amp = math.sqrt(config.subcarriers) config.rms_amplitude = rms_amp # check some bounds if config.fft_length < config.subcarriers: raise SystemError, "Subcarrier number must be less than FFT length" if config.fft_length < config.cp_length: raise SystemError, "Cyclic prefix length must be less than FFT length" ## shortcuts blen = config.block_length flen = config.frame_length dsubc = config.data_subcarriers vsubc = config.virtual_subcarriers # ------------------------------------------------------------------------ # # Adaptive Transmitter Concept used_id_bits = config.used_id_bits = 8 #TODO: no constant in source code rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits #BPSK if config.data_subcarriers % used_id_bits <> 0: raise SystemError, "Data subcarriers need to be multiple of %d" % ( used_id_bits) ## Control Part if options.debug: self._control = ctrl = static_tx_control(options) print "Statix TX Control used" else: self._control = ctrl = corba_tx_control(options) print "CORBA TX Control used" id_src = (ctrl, 0) mux_src = (ctrl, 1) map_src = self._map_src = (ctrl, 2) pa_src = (ctrl, 3) if options.log: id_src_f = gr.short_to_float() self.connect(id_src, id_src_f) log_to_file(self, id_src_f, "data/id_src_out.float") mux_src_f = gr.short_to_float() self.connect(mux_src, mux_src_f) log_to_file(self, mux_src_f, "data/mux_src_out.float") map_src_s = blocks.vector_to_stream(gr.sizeof_char, config.data_subcarriers) map_src_f = gr.char_to_float() self.connect(map_src, map_src_s, map_src_f) ##log_to_file(self, map_src_f, "data/map_src.float") ##log_to_file(self, pa_src, "data/pa_src_out.float") ## Workaround to avoid periodic structure seed(1) whitener_pn = [ randint(0, 1) for i in range(used_id_bits * rep_id_bits) ] ## ID Encoder id_enc = self._id_encoder = repetition_encoder_sb( used_id_bits, rep_id_bits, whitener_pn) self.connect(id_src, id_enc) if options.log: id_enc_f = gr.char_to_float() self.connect(id_enc, id_enc_f) log_to_file(self, id_enc_f, "data/id_enc_out.float") ## Bitmap Update Trigger # TODO #bmaptrig_stream = concatenate([[1, 2],[0]*(config.frame_data_part-7)]) bmaptrig_stream = concatenate([[1, 1], [0] * (config.frame_data_part - 2)]) print "bmaptrig_stream = ", bmaptrig_stream btrig = self._bitmap_trigger = blocks.vector_source_b( bmaptrig_stream.tolist(), True) if options.log: log_to_file(self, btrig, "data/bitmap_trig.char") ## Bitmap Update Trigger for puncturing # TODO if not options.nopunct: #bmaptrig_stream_puncturing = concatenate([[1],[0]*(config.frame_data_part-2)]) bmaptrig_stream_puncturing = concatenate( [[1], [0] * (config.frame_data_blocks / 2 - 1)]) btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b( bmaptrig_stream_puncturing.tolist(), True) bmapsrc_stream_puncturing = concatenate([[1] * dsubc, [2] * dsubc]) bsrc_puncturing = self._bitmap_src_puncturing = blocks.vector_source_b( bmapsrc_stream_puncturing.tolist(), True, dsubc) if options.log and options.coding and not options.nopunct: log_to_file(self, btrig_puncturing, "data/bitmap_trig_puncturing.char") ## Frame Trigger # TODO ftrig_stream = concatenate([[1], [0] * (config.frame_data_part - 1)]) ftrig = self._frame_trigger = blocks.vector_source_b( ftrig_stream.tolist(), True) ## Data Multiplexer # Input 0: control stream # Input 1: encoded ID stream # Inputs 2..n: data streams dmux = self._data_multiplexer = stream_controlled_mux_b() self.connect(mux_src, (dmux, 0)) self.connect(id_enc, (dmux, 1)) self._data_multiplexer_nextport = 2 if options.log: dmux_f = gr.char_to_float() self.connect(dmux, dmux_f) log_to_file(self, dmux_f, "data/dmux_out.float") ## Modulator mod = self._modulator = generic_mapper_bcv(config.data_subcarriers, options.coding) self.connect(dmux, (mod, 0)) self.connect(map_src, (mod, 1)) self.connect(btrig, (mod, 2)) if options.log: log_to_file(self, mod, "data/mod_out.compl") modi = gr.complex_to_imag(config.data_subcarriers) modr = gr.complex_to_real(config.data_subcarriers) self.connect(mod, modi) self.connect(mod, modr) log_to_file(self, modi, "data/mod_imag_out.float") log_to_file(self, modr, "data/mod_real_out.float") ## Power allocator if options.debug: ## static pa = self._power_allocator = power_allocator( config.data_subcarriers) self.connect(mod, (pa, 0)) self.connect(pa_src, (pa, 1)) else: ## with CORBA control event channel ns_ip = ctrl.ns_ip ns_port = ctrl.ns_port evchan = ctrl.evchan pa = self._power_allocator = corba_power_allocator(dsubc, \ evchan, ns_ip, ns_port, True) self.connect(mod, (pa, 0)) self.connect(id_src, (pa, 1)) self.connect(ftrig, (pa, 2)) if options.log: log_to_file(self, pa, "data/pa_out.compl") ## Pilot subcarriers psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter() self.connect(pa, psubc) pilot_subc = config.training_data.shifted_pilot_tones print "pilot_subc", pilot_subc stc = stc_encoder(config.subcarriers, config.frame_data_blocks, pilot_subc) self.connect(psubc, stc) if options.log: log_to_file(self, psubc, "data/psubc_out.compl") log_to_file(self, psubc_2, "data/psubc2_out.compl") log_to_file(self, pa, "data/pa.compl") log_to_file(self, (stc, 0), "data/stc_0.compl") log_to_file(self, (stc, 1), "data/stc_1.compl") ## Add virtual subcarriers if config.fft_length > config.subcarriers: vsubc = self._virtual_subcarrier_extender = \ vector_padding(config.subcarriers, config.fft_length) self.connect(stc, vsubc) vsubc_2 = self._virtual_subcarrier_extender_2 = \ vector_padding(config.subcarriers, config.fft_length) self.connect((stc, 1), vsubc_2) else: vsubc = self._virtual_subcarrier_extender = psubc vsubc_2 = self._virtual_subcarrier_extender_2 = psubc_2 log_to_file(self, psubc, "data/psubc.compl") log_to_file(self, stc, "data/stc1.compl") log_to_file(self, (stc, 1), "data/stc2.compl") if options.log: log_to_file(self, vsubc, "data/vsubc_out.compl") log_to_file(self, vsubc_2, "data/vsubc2_out.compl") ## IFFT, no window, block shift ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [], True) self.connect(vsubc, ifft) ifft_2 = self._ifft_2 = fft_blocks.fft_vcc(config.fft_length, False, [], True) self.connect(vsubc_2, ifft_2) if options.log: log_to_file(self, ifft, "data/ifft_out.compl") log_to_file(self, ifft_2, "data/ifft2_out.compl") ## Pilot blocks (preambles) pblocks = self._pilot_block_inserter = pilot_block_inserter(1, False) self.connect(ifft, pblocks) pblocks_2 = self._pilot_block_inserter_2 = pilot_block_inserter( 2, False) self.connect(ifft_2, pblocks_2) if options.log: log_to_file(self, pblocks, "data/pilot_block_ins_out.compl") log_to_file(self, pblocks_2, "data/pilot_block_ins2_out.compl") ## Cyclic Prefix cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length, config.block_length) self.connect(pblocks, cp) cp_2 = self._cyclic_prefixer_2 = cyclic_prefixer( config.fft_length, config.block_length) self.connect(pblocks_2, cp_2) lastblock = cp lastblock_2 = cp_2 if options.log: log_to_file(self, cp, "data/cp_out.compl") log_to_file(self, cp_2, "data/cp2_out.compl") if options.cheat: ## Artificial Channel # kept to compare with previous system achan_ir = concatenate([[1.0], [0.0] * (config.cp_length - 1)]) achan = self._artificial_channel = gr.fir_filter_ccc(1, achan_ir) self.connect(lastblock, achan) lastblock = achan achan_2 = self._artificial_channel_2 = gr.fir_filter_ccc( 1, achan_ir) self.connect(lastblock_2, achan_2) lastblock_2 = achan_2 ## Digital Amplifier amp = self._amplifier = ofdm.multiply_const_ccf(1.0 / math.sqrt(2)) self.connect(lastblock, amp) amp_2 = self._amplifier_2 = ofdm.multiply_const_ccf(1.0 / math.sqrt(2)) self.connect(lastblock_2, amp_2) self.set_rms_amplitude(rms_amp) if options.log: log_to_file(self, amp, "data/amp_tx_out.compl") log_to_file(self, amp_2, "data/amp_tx2_out.compl") ## Setup Output self.connect(amp, (self, 0)) self.connect(amp_2, (self, 1)) # ------------------------------------------------------------------------ # # Display some information about the setup if config._verbose: self._print_verbage()
def short_to_float(N): op = gr.short_to_float() tb = helper(N, op, gr.sizeof_short, gr.sizeof_float, 1, 1) return tb
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Fm Stereo Tx") ################################################## # Variables ################################################## self.st_gain = st_gain = 10 self.samp_rate = samp_rate = 195.312e3 self.pilot_gain = pilot_gain = 80e-3 self.mpx_rate = mpx_rate = 160e3 self.Mono_gain = Mono_gain = 300e-3 self.FM_freq = FM_freq = 96.5e6 ################################################## # Blocks ################################################## _st_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._st_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_st_gain_sizer, value=self.st_gain, callback=self.set_st_gain, label='st_gain', converter=forms.float_converter(), proportion=0, ) self._st_gain_slider = forms.slider( parent=self.GetWin(), sizer=_st_gain_sizer, value=self.st_gain, callback=self.set_st_gain, minimum=0, maximum=100, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_st_gain_sizer) _pilot_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._pilot_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_pilot_gain_sizer, value=self.pilot_gain, callback=self.set_pilot_gain, label='pilot_gain', converter=forms.float_converter(), proportion=0, ) self._pilot_gain_slider = forms.slider( parent=self.GetWin(), sizer=_pilot_gain_sizer, value=self.pilot_gain, callback=self.set_pilot_gain, minimum=0, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_pilot_gain_sizer) self.notebook_0 = self.notebook_0 = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "FM") self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "audio") self.Add(self.notebook_0) _Mono_gain_sizer = wx.BoxSizer(wx.VERTICAL) self._Mono_gain_text_box = forms.text_box( parent=self.GetWin(), sizer=_Mono_gain_sizer, value=self.Mono_gain, callback=self.set_Mono_gain, label='Mono_gain', converter=forms.float_converter(), proportion=0, ) self._Mono_gain_slider = forms.slider( parent=self.GetWin(), sizer=_Mono_gain_sizer, value=self.Mono_gain, callback=self.set_Mono_gain, minimum=0, maximum=1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_Mono_gain_sizer) _FM_freq_sizer = wx.BoxSizer(wx.VERTICAL) self._FM_freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, label='FM_freq', converter=forms.float_converter(), proportion=0, ) self._FM_freq_slider = forms.slider( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, minimum=88e6, maximum=108e6, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_FM_freq_sizer) self.wxgui_fftsink2_1 = fftsink2.fft_sink_f( self.notebook_0.GetPage(1).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.notebook_0.GetPage(1).Add(self.wxgui_fftsink2_1.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.notebook_0.GetPage(0).GetWin(), baseband_freq=FM_freq, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.notebook_0.GetPage(0).Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_sink_0 = uhd.usrp_sink( device_addr="addr=192.168.10.2", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0) self.uhd_usrp_sink_0.set_gain(0, 0) self.uhd_usrp_sink_0.set_antenna("TX/RX", 0) self.low_pass_filter_0 = gr.fir_filter_fff( 1, firdes.low_pass(Mono_gain, mpx_rate, 15000, 2000, firdes.WIN_HAMMING, 6.76)) self.gr_vector_to_streams_0 = gr.vector_to_streams( gr.sizeof_short * 1, 2) self.gr_sub_xx_0 = gr.sub_ff(1) self.gr_sig_source_x_1 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 19000, pilot_gain, 0) self.gr_sig_source_x_0 = gr.sig_source_f(160000, gr.GR_SIN_WAVE, 38000, 30e-3, 0) self.gr_short_to_float_1 = gr.short_to_float(1, 1) self.gr_short_to_float_0 = gr.short_to_float(1, 1) self.gr_multiply_xx_0 = gr.multiply_vff(1) self.gr_multiply_const_vxx_2 = gr.multiply_const_vcc((32.768e3, )) self.gr_multiply_const_vxx_1 = gr.multiply_const_vff((30e-6, )) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((30e-6, )) self.gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(980e-3) self.gr_file_source_0 = gr.file_source( gr.sizeof_short * 2, "/home/kranthi/Documents/project/FM Transceiver/FM Transmitter/test.raw", True) self.gr_add_xx_1 = gr.add_vff(1) self.gr_add_xx_0 = gr.add_vff(1) self.blks2_rational_resampler_xxx_2 = blks2.rational_resampler_fff( interpolation=4, decimation=1, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_fff( interpolation=5, decimation=1, taps=None, fractional_bw=None, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff( interpolation=5, decimation=1, taps=None, fractional_bw=None, ) self.blks2_fm_preemph_0 = blks2.fm_preemph(fs=mpx_rate, tau=50e-6) self.band_pass_filter_0 = gr.fir_filter_fff( 1, firdes.band_pass(st_gain, mpx_rate, 23000, 53000, 2000, firdes.WIN_HAMMING, 6.76)) ################################################## # Connections ################################################## self.connect((self.gr_file_source_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_multiply_const_vxx_0, 0)) self.connect((self.gr_short_to_float_1, 0), (self.gr_multiply_const_vxx_1, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.blks2_rational_resampler_xxx_1, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.gr_add_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.gr_sub_xx_0, 1)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_sub_xx_0, 0)) self.connect((self.blks2_rational_resampler_xxx_1, 0), (self.gr_add_xx_0, 0)) self.connect((self.gr_add_xx_0, 0), (self.low_pass_filter_0, 0)) self.connect((self.gr_sig_source_x_0, 0), (self.gr_multiply_xx_0, 0)) self.connect((self.gr_sub_xx_0, 0), (self.gr_multiply_xx_0, 1)) self.connect((self.gr_multiply_xx_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.gr_sig_source_x_1, 0), (self.gr_add_xx_1, 0)) self.connect((self.band_pass_filter_0, 0), (self.gr_add_xx_1, 1)) self.connect((self.low_pass_filter_0, 0), (self.gr_add_xx_1, 2)) self.connect((self.gr_add_xx_1, 0), (self.blks2_fm_preemph_0, 0)) self.connect((self.blks2_fm_preemph_0, 0), (self.blks2_rational_resampler_xxx_2, 0)) self.connect((self.blks2_rational_resampler_xxx_2, 0), (self.gr_frequency_modulator_fc_0, 0)) self.connect((self.gr_frequency_modulator_fc_0, 0), (self.gr_multiply_const_vxx_2, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.uhd_usrp_sink_0, 0)) self.connect((self.gr_multiply_const_vxx_2, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.gr_multiply_const_vxx_1, 0), (self.wxgui_fftsink2_1, 0))
def __init__(self, pll_alpha=0.005, satellite='NOAA18', decim=50, gain=25, clock_alpha=0.005, freq=1707e6, deframer_sync_check=True, deframer_insync_frames=2, deframer_outsync_frames=5, symb_rate=600 * 1109, baseband_file=os.environ['HOME'] + '/noaa_hrpt_baseband.dat', frames_file=os.environ['HOME'] + '/noaa_hrpt_frames.hmf'): grc_wxgui.top_block_gui.__init__(self, title="USRP2 NOAA HRPT Receiver") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Parameters ################################################## self.pll_alpha = pll_alpha self.satellite = satellite self.decim = decim self.gain = gain self.clock_alpha = clock_alpha self.freq = freq self.deframer_sync_check = deframer_sync_check self.deframer_insync_frames = deframer_insync_frames self.deframer_outsync_frames = deframer_outsync_frames self.symb_rate = symb_rate self.baseband_file = baseband_file self.frames_file = frames_file ################################################## # Variables ################################################## self.decim_tb = decim_tb = decim self.symb_rate_tb = symb_rate_tb = symb_rate self.samp_rate = samp_rate = 100e6 / decim_tb self.sps = sps = samp_rate / symb_rate_tb self.satellite_text = satellite_text = satellite self.samp_rate_st = samp_rate_st = samp_rate self.pll_alpha_sl = pll_alpha_sl = pll_alpha self.max_clock_offset = max_clock_offset = 0.1 self.max_carrier_offset = max_carrier_offset = 2 * math.pi * 100e3 / samp_rate self.hs = hs = int(sps / 2.0) self.gain_tb = gain_tb = gain self.freq_tb = freq_tb = freq self.frames_file_text_inf = frames_file_text_inf = frames_file self.deframer_sync_after_text = deframer_sync_after_text = deframer_insync_frames self.deframer_nosync_after_text = deframer_nosync_after_text = deframer_outsync_frames self.deframer_check_sync_text = deframer_check_sync_text = deframer_sync_check self.datetime_text = datetime_text = strftime("%A, %B %d %Y %H:%M:%S", localtime()) self.clock_alpha_sl = clock_alpha_sl = clock_alpha self.baseband_file_text_inf = baseband_file_text_inf = baseband_file ################################################## # Notebooks ################################################## self.rx_ntb = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "USRP Receiver") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "PLL demodulator and Clock sync") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Deframer") self.rx_ntb.AddPage(grc_wxgui.Panel(self.rx_ntb), "Output") self.Add(self.rx_ntb) ################################################## # Controls ################################################## self._decim_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.decim_tb, callback=self.set_decim_tb, label="Decimation", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._decim_tb_text_box, 1, 3, 1, 1) self._symb_rate_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), value=self.symb_rate_tb, callback=self.set_symb_rate_tb, label="Symbol rate", converter=forms.int_converter(), ) self.rx_ntb.GetPage(1).GridAdd(self._symb_rate_tb_text_box, 2, 1, 1, 1) self._satellite_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.satellite_text, callback=self.set_satellite_text, label="Sat ", converter=forms.str_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._satellite_text_static_text, 1, 0, 1, 1) self._samp_rate_st_static_text = forms.static_text( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.samp_rate_st, callback=self.set_samp_rate_st, label="Sample rate", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._samp_rate_st_static_text, 1, 4, 1, 1) _pll_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._pll_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, label="PLL Alpha", converter=forms.float_converter(), proportion=0, ) self._pll_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_pll_alpha_sl_sizer, value=self.pll_alpha_sl, callback=self.set_pll_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_pll_alpha_sl_sizer, 1, 0, 1, 1) self._gain_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.gain_tb, callback=self.set_gain_tb, label="RX gain [dB]", converter=forms.int_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._gain_tb_text_box, 1, 2, 1, 1) self._freq_tb_text_box = forms.text_box( parent=self.rx_ntb.GetPage(0).GetWin(), value=self.freq_tb, callback=self.set_freq_tb, label="Frequency", converter=forms.float_converter(), ) self.rx_ntb.GetPage(0).GridAdd(self._freq_tb_text_box, 1, 1, 1, 1) self._frames_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.frames_file_text_inf, callback=self.set_frames_file_text_inf, label="Frames filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._frames_file_text_inf_static_text, 3, 0, 1, 1) self._deframer_sync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.deframer_sync_after_text, callback=self.set_deframer_sync_after_text, label="Deframe sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._deframer_sync_after_text_static_text, 3, 0, 1, 1) self._deframer_nosync_after_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.deframer_nosync_after_text, callback=self.set_deframer_nosync_after_text, label="Deframer out of sync after", converter=forms.float_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._deframer_nosync_after_text_static_text, 4, 0, 1, 1) self._deframer_check_sync_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(2).GetWin(), value=self.deframer_check_sync_text, callback=self.set_deframer_check_sync_text, label="Deframer check sync enable", converter=forms.str_converter(), ) self.rx_ntb.GetPage(2).GridAdd( self._deframer_check_sync_text_static_text, 2, 0, 1, 1) self._datetime_text_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.datetime_text, callback=self.set_datetime_text, label="Local time of aquisition start", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd(self._datetime_text_static_text, 1, 0, 1, 1) _clock_alpha_sl_sizer = wx.BoxSizer(wx.VERTICAL) self._clock_alpha_sl_text_box = forms.text_box( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, label="Clock alpha", converter=forms.float_converter(), proportion=0, ) self._clock_alpha_sl_slider = forms.slider( parent=self.rx_ntb.GetPage(1).GetWin(), sizer=_clock_alpha_sl_sizer, value=self.clock_alpha_sl, callback=self.set_clock_alpha_sl, minimum=0.001, maximum=0.1, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.rx_ntb.GetPage(1).GridAdd(_clock_alpha_sl_sizer, 1, 1, 1, 1) self._baseband_file_text_inf_static_text = forms.static_text( parent=self.rx_ntb.GetPage(3).GetWin(), value=self.baseband_file_text_inf, callback=self.set_baseband_file_text_inf, label="Baseband filename", converter=forms.str_converter(), ) self.rx_ntb.GetPage(3).GridAdd( self._baseband_file_text_inf_static_text, 4, 0, 1, 1) ################################################## # Blocks ################################################## self.gr_agc_xx_0 = gr.agc_cc(10e-6, 1, 1.0 / 32767.0, 1.0) self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb() self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff( sps / 2.0, clock_alpha**2 / 4.0, 0.5, clock_alpha, max_clock_offset) self.gr_file_sink_0_0 = gr.file_sink(gr.sizeof_short * 1, frames_file) self.gr_file_sink_0_0.set_unbuffered(False) self.gr_file_sink_0_1 = gr.file_sink(gr.sizeof_short * 2, baseband_file) self.gr_file_sink_0_1.set_unbuffered(False) self.gr_float_to_complex_0 = gr.float_to_complex(1) self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0 / hs, 4000) self.gr_short_to_float_0 = gr.short_to_float() self.gr_short_to_float_0_0 = gr.short_to_float() self.gr_vector_to_streams_0 = gr.vector_to_streams( gr.sizeof_short * 1, 2) self.noaa_hrpt_decoder_0 = noaa.hrpt_decoder(True, False) self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2 / 4.0, max_carrier_offset) self.poesweather_univ_hrpt_deframer_0 = poesweather.univ_hrpt_deframer( deframer_sync_check, 11090, deframer_insync_frames, deframer_outsync_frames) self.usrp2_source_xxxx2_0 = usrp2.source_16sc() self.usrp2_source_xxxx2_0.set_decim(decim_tb) self.usrp2_source_xxxx2_0.set_center_freq(freq_tb) self.usrp2_source_xxxx2_0.set_gain(gain_tb) self.wxgui_fftsink1 = fftsink2.fft_sink_c( self.rx_ntb.GetPage(0).GetWin(), baseband_freq=freq, y_per_div=5, y_divs=10, ref_level=65, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=30, average=True, avg_alpha=0.1, title="Not filtered spectrum", peak_hold=False, ) self.rx_ntb.GetPage(0).Add(self.wxgui_fftsink1.win) ################################################## # Connections ################################################## self.connect((self.gr_float_to_complex_0, 0), (self.wxgui_fftsink1, 0)) self.connect((self.poesweather_univ_hrpt_deframer_0, 0), (self.noaa_hrpt_decoder_0, 0)) self.connect((self.gr_binary_slicer_fb_0, 0), (self.poesweather_univ_hrpt_deframer_0, 0)) self.connect((self.poesweather_univ_hrpt_deframer_0, 0), (self.gr_file_sink_0_0, 0)) self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0)) self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0)) self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0)) self.connect((self.gr_agc_xx_0, 0), (self.pll, 0)) self.connect((self.gr_float_to_complex_0, 0), (self.gr_agc_xx_0, 0)) self.connect((self.gr_vector_to_streams_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_vector_to_streams_0, 1), (self.gr_short_to_float_0_0, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_vector_to_streams_0, 0)) self.connect((self.usrp2_source_xxxx2_0, 0), (self.gr_file_sink_0_1, 0)) self.connect((self.gr_short_to_float_0_0, 0), (self.gr_float_to_complex_0, 1)) self.connect((self.gr_short_to_float_0, 0), (self.gr_float_to_complex_0, 0))
def short_to_float(N): op = gr.short_to_float() tb = helper(N, op, gr.sizeof_short, gr.sizeof_float, 1, 1) return tb
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Fm Tx Fifo") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 195.312e3 self.FM_freq = FM_freq = 96.5e6 ################################################## # Blocks ################################################## self.notebook_0 = self.notebook_0 = wx.Notebook(self.GetWin(), style=wx.NB_TOP) self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "Audio") self.notebook_0.AddPage(grc_wxgui.Panel(self.notebook_0), "FM") self.Add(self.notebook_0) _FM_freq_sizer = wx.BoxSizer(wx.VERTICAL) self._FM_freq_text_box = forms.text_box( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, label="FM Frequency", converter=forms.float_converter(), proportion=0, ) self._FM_freq_slider = forms.slider( parent=self.GetWin(), sizer=_FM_freq_sizer, value=self.FM_freq, callback=self.set_FM_freq, minimum=87.5e6, maximum=108e6, num_steps=100, style=wx.SL_HORIZONTAL, cast=float, proportion=1, ) self.Add(_FM_freq_sizer) self.wxgui_fftsink2_1 = fftsink2.fft_sink_f( self.notebook_0.GetPage(0).GetWin(), baseband_freq=0, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, win=window.hamming, ) self.notebook_0.GetPage(0).Add(self.wxgui_fftsink2_1.win) self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.notebook_0.GetPage(1).GetWin(), baseband_freq=FM_freq, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=False, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.notebook_0.GetPage(1).Add(self.wxgui_fftsink2_0.win) self.uhd_usrp_sink_0 = uhd.usrp_sink( device_addr="addr=192.168.20.2", stream_args=uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd_usrp_sink_0.set_time_source("mimo", 0) self.uhd_usrp_sink_0.set_samp_rate(samp_rate) self.uhd_usrp_sink_0.set_center_freq(FM_freq, 0) self.uhd_usrp_sink_0.set_gain(0, 0) self.uhd_usrp_sink_0.set_antenna("TX/RX", 0) self.gr_short_to_float_0 = gr.short_to_float(1, 1) self.gr_multiply_const_vxx_0 = gr.multiply_const_vff((400e-6, )) self.gr_file_source_0 = gr.file_source( gr.sizeof_short * 1, "/home/kranthi/documents/project/FM Transceiver Original/test.raw", True) self.blks2_wfm_tx_0 = blks2.wfm_tx( audio_rate=32000, quad_rate=800000, tau=75e-6, max_dev=75e3, ) self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_ccc( interpolation=1, decimation=2, taps=None, fractional_bw=None, ) ################################################## # Connections ################################################## self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.uhd_usrp_sink_0, 0)) self.connect((self.blks2_rational_resampler_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.blks2_wfm_tx_0, 0), (self.blks2_rational_resampler_xxx_0, 0)) self.connect((self.gr_file_source_0, 0), (self.gr_short_to_float_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.blks2_wfm_tx_0, 0)) self.connect((self.gr_multiply_const_vxx_0, 0), (self.wxgui_fftsink2_1, 0)) self.connect((self.gr_short_to_float_0, 0), (self.gr_multiply_const_vxx_0, 0))
def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-a", "--audio-input", type="string", default="") parser.add_option("-A", "--audio-output", type="string", default="") parser.add_option("-f", "--factor", type="eng_float", default=1) parser.add_option("-i", "--do-interp", action="store_true", default=False, help="enable output interpolator") parser.add_option("-s", "--sample-rate", type="int", default=48000, help="input sample rate") parser.add_option("-S", "--stretch", type="int", default=0, help="flex amt") parser.add_option("-y", "--symbol-rate", type="int", default=4800, help="input symbol rate") parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = options.symbol_rate IN = audio.source(sample_rate, options.audio_input) audio_output_rate = 8000 if options.do_interp: audio_output_rate = 48000 OUT = audio.sink(audio_output_rate, options.audio_output) symbol_decim = 1 symbol_coeffs = gr.firdes.root_raised_cosine( 1.0, # gain sample_rate, # sampling rate symbol_rate, # symbol rate 0.2, # width of trans. band 500) # filter type SYMBOL_FILTER = gr.fir_filter_fff(symbol_decim, symbol_coeffs) AMP = gr.multiply_const_ff(options.factor) msgq = gr.msg_queue(2) FSK4 = op25.fsk4_demod_ff(msgq, sample_rate, symbol_rate) levels = levels = [-2.0, 0.0, 2.0, 4.0] SLICER = repeater.fsk4_slicer_fb(levels) framer_msgq = gr.msg_queue(2) DECODE = repeater.p25_frame_assembler( '', # udp hostname 0, # udp port no. options.verbose, #debug True, # do_imbe True, # do_output False, # do_msgq framer_msgq) IMBE = repeater.vocoder( False, # 0=Decode,True=Encode options.verbose, # Verbose flag options.stretch, # flex amount "", # udp ip address 0, # udp port False) # dump raw u vectors CVT = gr.short_to_float() if options.do_interp: interp_taps = gr.firdes.low_pass(1.0, 48000, 4000, 4000 * 0.1, gr.firdes.WIN_HANN) INTERP = gr.interp_fir_filter_fff(48000 // 8000, interp_taps) AMP2 = gr.multiply_const_ff(1.0 / 32767.0) self.connect(IN, AMP, SYMBOL_FILTER, FSK4, SLICER, DECODE, IMBE, CVT, AMP2) if options.do_interp: self.connect(AMP2, INTERP, OUT) else: self.connect(AMP2, OUT)