def test_complex_taps(self): """ Load some complex taps. """ # Parameters path = "test_taps_complex" # For sanity reasons work with absolute path here. c_path = os.path.dirname( os.path.abspath(inspect.getfile( inspect.currentframe()))) + "/" + path test_file_content = ( "restype,fir\n" "fs,320000.0\n" "pbend,100000.0\n" "gain,2.0\n" "filttype,cbpf\n" "atten,10.0\n" "ntaps,15\n" "tb,10000.0\n" "wintype,0\n" "pbstart,50000.0\n" "taps,(0.00151832250413-0.0018500800943j),(-0.00244879024103-0.00163623178378j)," "(0.0109249493107-0.0204391144216j),(0.0673716515303+0.0279062893242j)," "(-0.0446246191859+0.147107481956j),(-0.243210762739-0.0483776889741j)," "(0.031814865768-0.323020994663j),(0.354127079248+8.44304750558e-08j)," "(0.0318147130311+0.323020994663j),(-0.243210792542+0.0483775734901j)," "(-0.0446245521307-0.147107496858j),(0.0673716664314-0.0279062557966j)," "(0.0109249399975+0.0204391200095j),(-0.00244879163802+0.00163622945547j)," "(0.0015183207579+0.0018500816077j)\n") test_file = open(c_path, 'w') test_file.write(test_file_content) test_file.close() verbose = False ftl = filter.file_taps_loader(c_path, verbose) os.remove(c_path) expected_taps = tuple( np.array(((0.0015183225041255355 - 0.0018500800943002105j), (-0.002448790241032839 - 0.0016362317837774754j), (0.010924949310719967 - 0.020439114421606064j), (0.06737165153026581 + 0.02790628932416439j), (-0.04462461918592453 + 0.14710748195648193j), (-0.24321076273918152 - 0.048377688974142075j), (0.03181486576795578 - 0.3230209946632385j), (0.35412707924842834 + 8.44304750557967e-08j), (0.03181471303105354 + 0.3230209946632385j), (-0.2432107925415039 + 0.04837757349014282j), (-0.04462455213069916 - 0.14710749685764313j), (0.067371666431427 - 0.027906255796551704j), (0.01092493999749422 + 0.02043912000954151j), (-0.0024487916380167007 + 0.0016362294554710388j), (0.001518320757895708 + 0.0018500816076993942j)), dtype=complex)) # Verify types self.assertEqual(type(ftl.get_taps()), type(expected_taps)) self.assertEqual(type(ftl.get_taps()[0]), type(expected_taps[0])) # Look for data self.assertComplexTuplesAlmostEqual(expected_taps, ftl.get_taps(), 6) # Try to use taps in a block filter.fft_filter_ccc(1, ftl.get_taps())
def __init__(self, N, fs, bw0, bw1, tw, atten, D): gr.top_block.__init__(self) self._nsamps = N self._fs = fs self._bw0 = bw0 self._bw1 = bw1 self._tw = tw self._at = atten self._decim = D taps = filter.firdes.complex_band_pass_2(1, self._fs, self._bw0, self._bw1, self._tw, self._at) print "Num. Taps: ", len(taps) self.src = analog.noise_source_c(analog.GR_GAUSSIAN, 1) self.head = blocks.head(gr.sizeof_gr_complex, self._nsamps) self.filt0 = filter.fft_filter_ccc(self._decim, taps) self.vsnk_src = blocks.vector_sink_c() self.vsnk_out = blocks.vector_sink_c() self.connect(self.src, self.head, self.vsnk_src) self.connect(self.head, self.filt0, self.vsnk_out)
def __init__(self, demod_class, rx_callback, options): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) options = copy.copy(options) # make a copy so we can destructively modify self._verbose = options.verbose self._bitrate = options.bitrate # desired bit rate self._rx_callback = rx_callback # this callback is fired when a packet arrives self._demod_class = demod_class # the demodulator_class we're using self._chbw_factor = options.chbw_factor # channel filter bandwidth factor # Get demod_kwargs demod_kwargs = self._demod_class.extract_kwargs_from_options(options) # Build the demodulator self.demodulator = self._demod_class(**demod_kwargs) # Make sure the channel BW factor is between 1 and sps/2 # or the filter won't work. if(self._chbw_factor < 1.0 or self._chbw_factor > self.samples_per_symbol()/2): sys.stderr.write("Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n".format(self._chbw_factor, self.samples_per_symbol()/2)) sys.exit(1) # Design filter to get actual channel we want sw_decim = 1 chan_coeffs = filter.firdes.low_pass(1.0, # gain sw_decim * self.samples_per_symbol(), # sampling rate self._chbw_factor, # midpoint of trans. band 0.5, # width of trans. band filter.firdes.WIN_HANN) # filter type self.channel_filter = filter.fft_filter_ccc(sw_decim, chan_coeffs) # receiver self.packet_receiver = \ digital.demod_pkts(self.demodulator, access_code=None, callback=self._rx_callback, threshold=-1) # Carrier Sensing Blocks alpha = 0.001 thresh = 30 # in dB, will have to adjust self.probe = analog.probe_avg_mag_sqrd_c(thresh,alpha) # Display some information about the setup if self._verbose: self._print_verbage() # connect block input to channel filter self.connect(self, self.channel_filter) # connect the channel input filter to the carrier power detector self.connect(self.channel_filter, self.probe) # connect channel filter to the packet receiver self.connect(self.channel_filter, self.packet_receiver)
def __init__(self): gr.top_block.__init__(self) Rs = 8000 f1 = 1000 f2 = 2000 npts = 2048 self.qapp = QtGui.QApplication(sys.argv) self.filt_taps = [ 1, ] src1 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f1, 0.1, 0) src2 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f2, 0.1, 0) src = blocks.add_cc() channel = channels.channel_model(0.01) self.filt = filter.fft_filter_ccc(1, self.filt_taps) thr = blocks.throttle(gr.sizeof_gr_complex, 100 * npts) self.snk1 = qtgui.freq_sink_c(npts, filter.firdes.WIN_BLACKMAN_hARRIS, 0, Rs, "Complex Freq Example", 1) self.connect(src1, (src, 0)) self.connect(src2, (src, 1)) self.connect(src, channel, thr, self.filt, (self.snk1, 0)) # Get the reference pointer to the SpectrumDisplayForm QWidget pyQt = self.snk1.pyqwidget() # Wrap the pointer as a PyQt SIP object # This can now be manipulated as a PyQt4.QtGui.QWidget pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) pyWin.show()
def __init__(self, demod_class, rx_callback, options): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0)) options = copy.copy(options) # make a copy so we can destructively modify self._verbose = options.verbose self._bitrate = options.bitrate # desired bit rate self._rx_callback = rx_callback # this callback is fired when a packet arrives self._demod_class = demod_class # the demodulator_class we're using self._chbw_factor = options.chbw_factor # channel filter bandwidth factor # Get demod_kwargs demod_kwargs = self._demod_class.extract_kwargs_from_options(options) # Build the demodulator self.demodulator = self._demod_class(**demod_kwargs) # Make sure the channel BW factor is between 1 and sps/2 # or the filter won't work. if(self._chbw_factor < 1.0 or self._chbw_factor > self.samples_per_symbol()/2): sys.stderr.write("Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n".format(self._chbw_factor, self.samples_per_symbol()/2)) sys.exit(1) # Design filter to get actual channel we want sw_decim = 1 chan_coeffs = filter.firdes.low_pass(1.0, # gain sw_decim * self.samples_per_symbol(), # sampling rate self._chbw_factor, # midpoint of trans. band 0.5, # width of trans. band gr.firdes.WIN_HANN) # filter type self.channel_filter = filter.fft_filter_ccc(sw_decim, chan_coeffs) # receiver self.packet_receiver = \ digital.demod_pkts(self.demodulator, access_code=None, callback=self._rx_callback, threshold=-1) # Carrier Sensing Blocks alpha = 0.001 thresh = 30 # in dB, will have to adjust self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha) # Display some information about the setup if self._verbose: self._print_verbage() # connect block input to channel filter self.connect(self, self.channel_filter) # connect the channel input filter to the carrier power detector self.connect(self.channel_filter, self.probe) # connect channel filter to the packet receiver self.connect(self.channel_filter, self.packet_receiver)
def __init__(self, n_fzc=255, q=7): gr.hier_block2.__init__(self, "FZC Correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) ################################################## # Parameters ################################################## self.q = q self.n_fzc = n_fzc ################################################## # Variables ################################################## self.fzc_sequence = pycor.corrsounder.sequence_frank_zadoff_chu(sequence_length=n_fzc, q=q) ################################################## # Blocks ################################################## self.fir = filter.fft_filter_ccc(1, (np.conj(self.fzc_sequence[::-1])), 1) self.fir.declare_sample_delay(0) self.norm = blocks.multiply_const_vcc((1. / n_fzc,)) ################################################## # Connections ################################################## self.connect((self.norm, 0), (self, 0)) self.connect((self.fir, 0), (self.norm, 0)) self.connect((self, 0), (self.fir, 0))
def __init__(self): gr.top_block.__init__(self) Rs = 8000 f1 = 1000 f2 = 2000 npts = 2048 self.qapp = QtGui.QApplication(sys.argv) self.filt_taps = [1,] src1 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f1, 0.1, 0) src2 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f2, 0.1, 0) src = blocks.add_cc() channel = channels.channel_model(0.01) self.filt = filter.fft_filter_ccc(1, self.filt_taps) thr = blocks.throttle(gr.sizeof_gr_complex, 100*npts) self.snk1 = qtgui.freq_sink_c(npts, filter.firdes.WIN_BLACKMAN_hARRIS, 0, Rs, "Complex Freq Example", 1) self.connect(src1, (src,0)) self.connect(src2, (src,1)) self.connect(src, channel, thr, self.filt, (self.snk1, 0)) # Get the reference pointer to the SpectrumDisplayForm QWidget pyQt = self.snk1.pyqwidget() # Wrap the pointer as a PyQt SIP object # This can now be manipulated as a PyQt4.QtGui.QWidget pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) pyWin.show()
def __init__(self, sps=2.0, rolloff=0.35, preamble=[0,0,0,0,0,0,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0], modtype=mapper.QPSK, greymap=[0,1,3,2] ): gr.hier_block2.__init__(self, "preamble_correlator", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(1,1,gr.sizeof_float)) #gr.io_signature(0,0,0)) # vet preamble bits for b in preamble: assert(b >= 0 and b<=1); tb = gr.top_block(); vs = blocks.vector_source_b( preamble ); mp = mapper.mapper(modtype, greymap); it = filter.interp_fir_filter_ccf(2, firdes.root_raised_cosine(1, 1.0, 1.0/sps, rolloff, 21)) vk = blocks.vector_sink_c(); tb.connect(vs,mp,it,vk); tb.run(); self.taps = list(vk.data()); self.taps.reverse(); self.taps = map(lambda x: x.conjugate(), self.taps); self.flt = filter.fft_filter_ccc(1, self.taps); self.mag = blocks.complex_to_mag_squared(); self.connect(self, self.flt, self.mag); # connect output self.connect(self.mag, self);
def create_demux_input_blocks(self): bw = (float(self.used_carriers) / float(self.fft_len)) / 2.0 tbw = bw * 0.08 filter_taps = firdes.low_pass(1.0, 1, bw + tbw, tbw, firdes.WIN_HAMMING, 6.76) self.fft_filter = filter.fft_filter_ccc(1, filter_taps, 1) self.delay = blocks.delay(gr.sizeof_gr_complex, self.fft_len + self.cp_len) self.ofdm_sync = digital.ofdm_sync_sc_cfb(self.fft_len, self.cp_len, False) self.freq_modulator = analog.frequency_modulator_fc(-2.0 / self.fft_len) self.multiply = blocks.multiply_vcc(1) header_len = 3 #In OFDM Symbols self.header_payload_demux = digital.header_payload_demux( header_len, self.fft_len, self.cp_len, self.rx_length_tag_key, "", True, gr.sizeof_gr_complex, "rx_time", self.samp_rate, (), 0, )
def main(args): nargs = len(args) if nargs == 1: infile = args[0] outfile = None elif nargs == 2: infile = args[0] outfile = args[1] else: sys.stderr.write("Usage: atsc-blade.py input_file [output_file]\n") sys.exit(1) symbol_rate = 4500000.0 / 286 * 684 pilot_freq = 309441 center_freq = 441000000 txvga1_gain = -4 txvga2_gain = 25 tb = gr.top_block() src = blocks.file_source(gr.sizeof_char, infile, True) pad = atsc.pad() rand = atsc.randomizer() rs_enc = atsc.rs_encoder() inter = atsc.interleaver() trell = atsc.trellis_encoder() fsm = atsc.field_sync_mux() v2s = blocks.vector_to_stream(gr.sizeof_char, 1024) minn = blocks.keep_m_in_n(gr.sizeof_char, 832, 1024, 4) c2sym = digital.chunks_to_symbols_bc( ([symbol + 1.25 for symbol in [-7, -5, -3, -1, 1, 3, 5, 7]]), 1) offset = analog.sig_source_c(symbol_rate, analog.GR_COS_WAVE, -3000000 + pilot_freq, 0.9, 0) mix = blocks.multiply_vcc(1) rrc = filter.fft_filter_ccc( 1, firdes.root_raised_cosine(0.1, symbol_rate, symbol_rate / 2, 0.1152, 100)) out = osmosdr.sink(args="bladerf=0,buffers=128,buflen=32768") out.set_sample_rate(symbol_rate) out.set_center_freq(center_freq, 0) out.set_freq_corr(0, 0) out.set_gain(txvga2_gain, 0) out.set_bb_gain(txvga1_gain, 0) out.set_bandwidth(6000000, 0) tb.connect(src, pad, rand, rs_enc, inter, trell, fsm, v2s, minn, c2sym) tb.connect((c2sym, 0), (mix, 0)) tb.connect((offset, 0), (mix, 1)) tb.connect(mix, rrc, out) if outfile: dst = blocks.file_sink(gr.sizeof_gr_complex, outfile) tb.connect(rrc, dst) tb.run()
def test_fft_filter_ccc(): top = gr.top_block() src = blocks.null_source(gr.sizeof_gr_complex) firfilter = filter.fft_filter_ccc(1, [complex(random.random(), random.random()) for _ in range(128)]) probe = blocks.probe_rate(gr.sizeof_gr_complex) top.connect(src, firfilter, probe) return top, probe
def main(args): nargs = len(args) if nargs == 1: port = int(args[0]) outfile = None elif nargs == 2: port = int(args[0]) outfile = args[1] else: sys.stderr.write("Usage: atsc-blade.py port [output_file]\n"); sys.exit(1) symbol_rate = 4500000.0 / 286 * 684 pilot_freq = 309441 center_freq = 441000000 tx_gain = 83 # max 89.5 tb = gr.top_block() out = uhd.usrp_sink( device_addr="recv_frame_size=65536,num_recv_frames=128,send_frame_size=65536,num_send_frames=128,master_clock_rate=" + str(symbol_rate*4), stream_args=uhd.stream_args( cpu_format="fc32", otw_format="sc16", channels=range(1), ), ) out.set_samp_rate(symbol_rate) out.set_center_freq(center_freq, 0) out.set_gain(tx_gain, 0) #src = blocks.udp_source(gr.sizeof_char*1, "127.0.0.1", port, 18800, True) src = grc_blks2.tcp_source(gr.sizeof_char*1, "127.0.0.1", port, True) pad = atsc.pad() rand = atsc.randomizer() rs_enc = atsc.rs_encoder() inter = atsc.interleaver() trell = atsc.trellis_encoder() fsm = atsc.field_sync_mux() v2s = blocks.vector_to_stream(gr.sizeof_char, 1024) minn = blocks.keep_m_in_n(gr.sizeof_char, 832, 1024, 4) c2sym = digital.chunks_to_symbols_bc(([symbol + 1.25 for symbol in [-7,-5,-3,-1,1,3,5,7]]), 1) offset = analog.sig_source_c(symbol_rate, analog.GR_COS_WAVE, -3000000 + pilot_freq, 0.9, 0) mix = blocks.multiply_vcc(1) rrc = filter.fft_filter_ccc(1, firdes.root_raised_cosine(0.1, symbol_rate, symbol_rate/2, 0.1152, 100)) tb.connect(src, pad, rand, rs_enc, inter, trell, fsm, v2s, minn, c2sym) tb.connect((c2sym, 0), (mix, 0)) tb.connect((offset, 0), (mix, 1)) tb.connect(mix, rrc, out) if outfile: dst = blocks.file_sink(gr.sizeof_gr_complex, outfile) tb.connect(rrc, dst) tb.run()
def __init__(self): gr.top_block.__init__(self, "Tx Wav") Qt.QWidget.__init__(self) self.setWindowTitle("Tx Wav") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "tx_wav") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 48e3 self.freq = freq = samp_rate/4 self.amp = amp = 3 ################################################## # Blocks ################################################## self._freq_range = Range(1e2, samp_rate/2, 1, samp_rate/4, 200) self._freq_win = RangeWidget(self._freq_range, self.set_freq, "freq", "counter_slider", float) self.top_layout.addWidget(self._freq_win) self._amp_range = Range(-40, 20, 1, 3, 200) self._amp_win = RangeWidget(self._amp_range, self.set_amp, "amp", "counter_slider", float) self.top_layout.addWidget(self._amp_win) self.fft_filter_xxx_0 = filter.fft_filter_ccc(1, (firdes.complex_band_pass(pow(10.0,amp/10.0),samp_rate,-3000,-300,100,firdes.WIN_BLACKMAN)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_complex_to_float_0 = blocks.complex_to_float(1) self.blocks_add_const_vxx_0 = blocks.add_const_vcc((0, )) self.audio_sink_0 = audio.sink(int(samp_rate), '', True) self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, freq, 0.1, 0) self.analog_noise_source_x_0 = analog.noise_source_c(analog.GR_GAUSSIAN, pow(10.0,amp/10.0), 0) ################################################## # Connections ################################################## self.connect((self.analog_noise_source_x_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.analog_sig_source_x_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.blocks_add_const_vxx_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.blocks_complex_to_float_0, 1), (self.audio_sink_0, 1)) self.connect((self.blocks_complex_to_float_0, 0), (self.audio_sink_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_float_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.blocks_add_const_vxx_0, 0))
def create_block(self, taps): assert taps is not None if self.freq_xlating: return grfilter.freq_xlating_fir_filter_ccc( self.decimation, taps, 0, self.input_rate) else: if len(taps) > 10: return grfilter.fft_filter_ccc(self.decimation, taps, 1) else: return grfilter.fir_filter_ccc(self.decimation, taps)
def test_float_taps(self): """ Load some float taps. """ # Parameters path = "test_taps_float" # For sanity reasons work with absolute path here. c_path = os.path.dirname( os.path.abspath(inspect.getfile( inspect.currentframe()))) + "/" + path test_file_content = ( "restype,fir\n" "fs,320000.\n" "pbend,50000.0\n" "gain,2.0\n" "sbstart,100000.0\n" "filttype,lpf\n" "atten,40.0\n" "wintype,0\n" "ntaps,11\n" "taps,-0.010157553479075432,-0.01920645497739315,0.01674678549170494," "0.20396660268306732,0.49091556668281555,0.6354700922966003," "0.49091556668281555,0.20396660268306732,0.01674678549170494," "-0.01920645497739315,-0.010157553479075432\n") test_file = open(c_path, 'w') test_file.write(test_file_content) test_file.close() verbose = False ftl = filter.file_taps_loader(c_path, verbose) os.remove(c_path) expected_taps = tuple( np.array((-0.01015755, -0.01920645, 0.01674679, 0.2039666, 0.49091557, 0.63547009, 0.49091557, 0.2039666, 0.01674679, -0.01920645, -0.01015755), dtype=float)) # Verify types self.assertEqual(type(ftl.get_taps()), type(expected_taps)) self.assertEqual(type(ftl.get_taps()[0]), type(expected_taps[0])) # Look for data self.assertFloatTuplesAlmostEqual(expected_taps, ftl.get_taps(), 6) # Test taps with a gr-filter block. filter.fft_filter_ccc(1, ftl.get_taps())
def test_ccc_get0(self): random.seed(0) for i in xrange(25): ntaps = int(random.uniform(2, 100)) taps = make_random_complex_tuple(ntaps) op = filter.fft_filter_ccc(1, taps) result_data = op.taps() #print result_data self.assertComplexTuplesAlmostEqual(taps, result_data, 4)
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Dvbs2 Tx") ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 5000000 self.taps = taps = 100 self.samp_rate = samp_rate = symbol_rate * 2 self.rolloff = rolloff = 0.2 self.frequency = frequency = 1280e6 ################################################## # Blocks ################################################## self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=frequency, 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=True, avg_alpha=0.13333, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.fft_filter_xxx_0 = filter.fft_filter_ccc(1, (firdes.root_raised_cosine(1.0, samp_rate, samp_rate/2, rolloff, taps)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.dtv_dvbs2_physical_cc_0 = dtv.dvbs2_physical_cc(dtv.FECFRAME_NORMAL, dtv.C9_10, dtv.MOD_16APSK, dtv.PILOTS_ON, 0) self.dtv_dvbs2_modulator_bc_0 = dtv.dvbs2_modulator_bc(dtv.FECFRAME_NORMAL, dtv.C9_10, dtv.MOD_16APSK, dtv.INTERPOLATION_OFF) self.dtv_dvbs2_interleaver_bb_0 = dtv.dvbs2_interleaver_bb(dtv.FECFRAME_NORMAL, dtv.C_OTHER, dtv.MOD_16APSK) self.dtv_dvb_ldpc_bb_0 = dtv.dvb_ldpc_bb(dtv.STANDARD_DVBS2, dtv.FECFRAME_NORMAL, dtv.C9_10, dtv.MOD_OTHER) self.dtv_dvb_bch_bb_0 = dtv.dvb_bch_bb(dtv.STANDARD_DVBS2, dtv.FECFRAME_NORMAL, dtv.C9_10, ) self.dtv_dvb_bbscrambler_bb_0 = dtv.dvb_bbscrambler_bb(dtv.STANDARD_DVBS2, dtv.FECFRAME_NORMAL, dtv.C9_10, ) self.dtv_dvb_bbheader_bb_0 = dtv.dvb_bbheader_bb(dtv.STANDARD_DVBS2, dtv.FECFRAME_NORMAL, dtv.C9_10, dtv.RO_0_20, dtv.INPUTMODE_NORMAL, dtv.INBAND_OFF, 168, 4000000) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char*1, "/Volumes/work/run/shm/adv16apsk910.ts", True) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.dtv_dvb_bbheader_bb_0, 0)) self.connect((self.dtv_dvb_bbheader_bb_0, 0), (self.dtv_dvb_bbscrambler_bb_0, 0)) self.connect((self.dtv_dvb_bbscrambler_bb_0, 0), (self.dtv_dvb_bch_bb_0, 0)) self.connect((self.dtv_dvb_bch_bb_0, 0), (self.dtv_dvb_ldpc_bb_0, 0)) self.connect((self.dtv_dvb_ldpc_bb_0, 0), (self.dtv_dvbs2_interleaver_bb_0, 0)) self.connect((self.dtv_dvbs2_interleaver_bb_0, 0), (self.dtv_dvbs2_modulator_bc_0, 0)) self.connect((self.dtv_dvbs2_modulator_bc_0, 0), (self.dtv_dvbs2_physical_cc_0, 0)) self.connect((self.dtv_dvbs2_physical_cc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0))
def __init__(self, demod_class, rx_callback, options): gr.hier_block2.__init__( self, "receive_path", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(0, 0, 0)) # Output signature options = copy.copy( options) # make a copy so we can destructively modify self._verbose = options.verbose self._bitrate = options.bitrate # desired bit rate self._samples_per_symbol = options.samples_per_symbol # desired samples/symbol self._rx_callback = rx_callback # this callback is fired when there's a packet available self._demod_class = demod_class # the demodulator_class we're using # Get demod_kwargs demod_kwargs = self._demod_class.extract_kwargs_from_options(options) # Design filter to get actual channel we want sw_decim = 1 chan_coeffs = filter.firdes.low_pass( 1.0, # gain sw_decim * self._samples_per_symbol, # sampling rate 1.0, # midpoint of trans. band 0.5, # width of trans. band filter.firdes.WIN_HANN) # filter type self.channel_filter = filter.fft_filter_ccc(sw_decim, chan_coeffs) # receiver self.packet_receiver = \ digital.demod_pkts(self._demod_class(**demod_kwargs), access_code=None, callback=self._rx_callback, threshold=-1) # Carrier Sensing Blocks alpha = 0.001 thresh = 30 # in dB, will have to adjust self.probe = analog.probe_avg_mag_sqrd_c(thresh, alpha) # Display some information about the setup if self._verbose: self._print_verbage() # connect block input to channel filter self.connect(self, self.channel_filter) # connect the channel input filter to the carrier power detector self.connect(self.channel_filter, self.probe) # connect channel filter to the packet receiver self.connect(self.channel_filter, self.packet_receiver)
def test_ccc_get0(self): random.seed(0) for i in range(25): ntaps = int(random.uniform(2, 100)) taps = make_random_complex_tuple(ntaps) op = filter.fft_filter_ccc(1, taps) result_data = op.taps() #print result_data self.assertComplexTuplesAlmostEqual(taps, result_data, 4)
def main(args): nargs = len(args) if nargs == 1: infile = args[0] outfile = None elif nargs == 2: infile = args[0] outfile = args[1] else: sys.stderr.write("Usage: atsc-blade.py input_file [output_file]\n"); sys.exit(1) symbol_rate = 4500000.0 / 286 * 684 pilot_freq = 309441 center_freq = 441000000 txvga1_gain = -4 txvga2_gain = 25 tb = gr.top_block() src = blocks.file_source(gr.sizeof_char, infile, True) pad = atsc.pad() rand = atsc.randomizer() rs_enc = atsc.rs_encoder() inter = atsc.interleaver() trell = atsc.trellis_encoder() fsm = atsc.field_sync_mux() v2s = blocks.vector_to_stream(gr.sizeof_char, 1024) minn = blocks.keep_m_in_n(gr.sizeof_char, 832, 1024, 4) c2sym = digital.chunks_to_symbols_bc(([symbol + 1.25 for symbol in [-7,-5,-3,-1,1,3,5,7]]), 1) offset = analog.sig_source_c(symbol_rate, analog.GR_COS_WAVE, -3000000 + pilot_freq, 0.9, 0) mix = blocks.multiply_vcc(1) rrc = filter.fft_filter_ccc(1, firdes.root_raised_cosine(0.1, symbol_rate, symbol_rate/2, 0.1152, 100)) out = osmosdr.sink(args="bladerf=0,buffers=128,buflen=32768") out.set_sample_rate(symbol_rate) out.set_center_freq(center_freq, 0) out.set_freq_corr(0, 0) out.set_gain(txvga2_gain, 0) out.set_bb_gain(txvga1_gain, 0) out.set_bandwidth(6000000, 0) tb.connect(src, pad, rand, rs_enc, inter, trell, fsm, v2s, minn, c2sym) tb.connect((c2sym, 0), (mix, 0)) tb.connect((offset, 0), (mix, 1)) tb.connect(mix, rrc, out) if outfile: dst = blocks.file_sink(gr.sizeof_gr_complex, outfile) tb.connect(rrc, dst) tb.run()
def __init__(self, fft_length, occupied_tones, carrier_map_bin): """ Hierarchical block for receiving OFDM symbols. """ gr.hier_block2.__init__(self, "ncofdm_filt", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Input signature # fft length, e.g. 256 self._fft_length = fft_length # the number of used subcarriers, e.g. 240 self._occupied_tones = occupied_tones # a binary array indicates the used subcarriers self._carrier_map_bin = carrier_map_bin # setup filter banks self.chan_filt_low = filter.fft_filter_ccc(1,[1]) self.chan_filt_high1 = filter.fft_filter_ccc(1,[1]) self.chan_filt_high2 = filter.fft_filter_ccc(1,[1]) self.chan_filt_high3 = filter.fft_filter_ccc(1,[1]) self.chan_filt_high4 = filter.fft_filter_ccc(1,[1]) self.chan_filt_high5 = filter.fft_filter_ccc(1,[1]) # calculate the filter taps filt_num = self.calc_filter_taps(2, 0) # signals run into a serial of filters, one lowpass filter and 5 highpass filters self.connect(self, self.chan_filt_high1, self.chan_filt_high2, self.chan_filt_high3, self.chan_filt_high4, self.chan_filt_high5, self.chan_filt_low, self)
def __init__(self, fft_length, occupied_tones, carrier_map_bin): """ Hierarchical block for receiving OFDM symbols. """ gr.hier_block2.__init__( self, "ncofdm_filt", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Input signature # fft length, e.g. 256 self._fft_length = fft_length # the number of used subcarriers, e.g. 240 self._occupied_tones = occupied_tones # a binary array indicates the used subcarriers self._carrier_map_bin = carrier_map_bin # setup filter banks self.chan_filt_low = filter.fft_filter_ccc(1, [1]) self.chan_filt_high1 = filter.fft_filter_ccc(1, [1]) self.chan_filt_high2 = filter.fft_filter_ccc(1, [1]) self.chan_filt_high3 = filter.fft_filter_ccc(1, [1]) self.chan_filt_high4 = filter.fft_filter_ccc(1, [1]) self.chan_filt_high5 = filter.fft_filter_ccc(1, [1]) # calculate the filter taps filt_num = self.calc_filter_taps(2, 0) # signals run into a serial of filters, one lowpass filter and 5 highpass filters self.connect(self, self.chan_filt_high1, self.chan_filt_high2, self.chan_filt_high3, self.chan_filt_high4, self.chan_filt_high5, self.chan_filt_low, self)
def test_ccc_001(self): tb = gr.top_block() src_data = (0,1,2,3,4,5,6,7) taps = (1,) expected_result = tuple([complex(x) for x in (0,1,2,3,4,5,6,7)]) src = blocks.vector_source_c(src_data) op = filter.fft_filter_ccc(1, taps) dst = blocks.vector_sink_c() tb.connect(src, op, dst) tb.run() result_data = dst.data() #print 'expected:', expected_result #print 'results: ', result_data self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
def test_ccc_003(self): tb = gr.top_block() src_data = (0,1,2,3,4,5,6,7) taps = (2,) expected_result = tuple([2 * complex(x) for x in (0,1,2,3,4,5,6,7)]) src = blocks.vector_source_c(src_data) op = filter.fft_filter_ccc(1, taps) dst = blocks.vector_sink_c() tb.connect(src, op, dst) tb.run() result_data = dst.data() #print 'expected:', expected_result #print 'results: ', result_data self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
def __init__(self): gr.top_block.__init__(self) Rs = 8000 f1 = 100 f2 = 2000 npts = 2048 taps = filter.firdes.complex_band_pass_2(1, Rs, 1500, 2500, 100, 60) self.qapp = QtWidgets.QApplication(sys.argv) ss = open(gr.prefix() + '/share/gnuradio/themes/dark.qss') sstext = ss.read() ss.close() self.qapp.setStyleSheet(sstext) src1 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f1, 0.1, 0) src2 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f2, 0.1, 0) src = blocks.add_cc() channel = channels.channel_model(0.01) thr = blocks.throttle(gr.sizeof_gr_complex, 100 * npts) filt = filter.fft_filter_ccc(1, taps) self.snk1 = qtgui.waterfall_sink_c(npts, filter.firdes.WIN_BLACKMAN_hARRIS, 0, Rs, "Complex Waterfall Example", 2) self.snk1.set_color_map(0, qtgui.INTENSITY_COLOR_MAP_TYPE_COOL) self.snk1.set_color_map(1, qtgui.INTENSITY_COLOR_MAP_TYPE_COOL) self.connect(src1, (src, 0)) self.connect(src2, (src, 1)) self.connect(src, channel, thr, (self.snk1, 0)) self.connect(thr, filt, (self.snk1, 1)) self.ctrl_win = control_box() self.ctrl_win.attach_signal1(src1) self.ctrl_win.attach_signal2(src2) # Get the reference pointer to the SpectrumDisplayForm QWidget pyQt = self.snk1.pyqwidget() # Wrap the pointer as a PyQt SIP object # This can now be manipulated as a PyQt5.QtWidgets.QWidget pyWin = sip.wrapinstance(pyQt, QtWidgets.QWidget) #pyWin.show() self.main_box = dialog_box(pyWin, self.ctrl_win) self.main_box.show()
def __init__(self): gr.top_block.__init__(self) Rs = 8000 f1 = 100 f2 = 2000 npts = 2048 taps = filter.firdes.complex_band_pass_2(1, Rs, 1500, 2500, 100, 60) self.qapp = QtGui.QApplication(sys.argv) ss = open(gr.prefix() + '/share/gnuradio/themes/dark.qss') sstext = ss.read() ss.close() self.qapp.setStyleSheet(sstext) src1 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f1, 0.1, 0) src2 = analog.sig_source_c(Rs, analog.GR_SIN_WAVE, f2, 0.1, 0) src = blocks.add_cc() channel = channels.channel_model(0.01) thr = blocks.throttle(gr.sizeof_gr_complex, 100*npts) filt = filter.fft_filter_ccc(1, taps) self.snk1 = qtgui.waterfall_sink_c(npts, filter.firdes.WIN_BLACKMAN_hARRIS, 0, Rs, "Complex Waterfall Example", 2) self.connect(src1, (src,0)) self.connect(src2, (src,1)) self.connect(src, channel, thr, (self.snk1, 0)) self.connect(thr, filt, (self.snk1, 1)) self.ctrl_win = control_box() self.ctrl_win.attach_signal1(src1) self.ctrl_win.attach_signal2(src2) # Get the reference pointer to the SpectrumDisplayForm QWidget pyQt = self.snk1.pyqwidget() # Wrap the pointer as a PyQt SIP object # This can now be manipulated as a PyQt4.QtGui.QWidget pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) #pyWin.show() self.main_box = dialog_box(pyWin, self.ctrl_win) self.main_box.show()
def __init__(self, error_term_forward_transmission_tracking): gr.hier_block2.__init__( self, "error_correction_cc", gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex * 1)) # Output signature ################################################## # Blocks ################################################## self.fir = filter.fft_filter_ccc( 1, error_term_forward_transmission_tracking, 1) ################################################## # Connections ################################################## self.connect(self, self.fir, self)
def test_ccc_004(self): random.seed(0) for i in range(25): # sys.stderr.write("\n>>> Loop = %d\n" % (i,)) src_len = 4*1024 src_data = make_random_complex_tuple(src_len) ntaps = int(random.uniform(2, 1000)) taps = make_random_complex_tuple(ntaps) expected_result = reference_filter_ccc(1, taps, src_data) src = blocks.vector_source_c(src_data) op = filter.fft_filter_ccc(1, taps) dst = blocks.vector_sink_c() tb = gr.top_block() tb.connect(src, op, dst) tb.run() result_data = dst.data() del tb self.assert_fft_ok2(expected_result, result_data)
def test_ccc_004(self): random.seed(0) for i in xrange(25): # sys.stderr.write("\n>>> Loop = %d\n" % (i,)) src_len = 4*1024 src_data = make_random_complex_tuple(src_len) ntaps = int(random.uniform(2, 1000)) taps = make_random_complex_tuple(ntaps) expected_result = reference_filter_ccc(1, taps, src_data) src = blocks.vector_source_c(src_data) op = filter.fft_filter_ccc(1, taps) dst = blocks.vector_sink_c() tb = gr.top_block() tb.connect(src, op, dst) tb.run() result_data = dst.data() del tb self.assert_fft_ok2(expected_result, result_data)
def test_ccf_006(self): # Test decimating with nthreads=2 random.seed(0) nthreads = 2 for i in range(25): # sys.stderr.write("\n>>> Loop = %d\n" % (i,)) dec = i + 1 src_len = 4*1024 src_data = make_random_complex_tuple(src_len) ntaps = int(random.uniform(2, 100)) taps = make_random_float_tuple(ntaps) expected_result = reference_filter_ccf(dec, taps, src_data) src = blocks.vector_source_c(src_data) op = filter.fft_filter_ccc(dec, taps, nthreads) dst = blocks.vector_sink_c() tb = gr.top_block() tb.connect(src, op, dst) tb.run() del tb result_data = dst.data() self.assert_fft_ok2(expected_result, result_data)
def __init__(self, sps=2.0, rolloff=0.35, preamble=[ 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 ], modtype=mapper.QPSK, greymap=[0, 1, 3, 2]): gr.hier_block2.__init__(self, "preamble_correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) #gr.io_signature(0,0,0)) # vet preamble bits for b in preamble: assert (b >= 0 and b <= 1) tb = gr.top_block() vs = blocks.vector_source_b(preamble) mp = mapper.mapper(modtype, greymap) it = filter.interp_fir_filter_ccf( 2, firdes.root_raised_cosine(1, 1.0, 1.0 / sps, rolloff, 21)) vk = blocks.vector_sink_c() tb.connect(vs, mp, it, vk) tb.run() self.taps = list(vk.data()) self.taps.reverse() self.taps = map(lambda x: x.conjugate(), self.taps) self.flt = filter.fft_filter_ccc(1, self.taps) self.mag = blocks.complex_to_mag_squared() self.connect(self, self.flt, self.mag) # connect output self.connect(self.mag, self)
def __init__(self, name='Multistage Channel Filter', input_rate=0, output_rate=0, cutoff_freq=0, transition_width=0, center_freq=0): assert input_rate > 0 assert output_rate > 0 assert cutoff_freq > 0 assert transition_width > 0 # cf. firdes.sanity_check_1f (which is private) # TODO better errors for other cases if cutoff_freq > output_rate / 2: # early check for better errors since our cascaded filters might be cryptically nonsense raise ValueError('cutoff_freq (%s) is too high for output_rate (%s)' % (cutoff_freq, output_rate)) gr.hier_block2.__init__( self, name, gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.cutoff_freq = cutoff_freq self.transition_width = transition_width total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least(input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() self.stages = [] # loop variables prev_block = self stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages # TODO: consider using rotator block instead (has different API) self.freq_filter_block = grfilter.freq_xlating_fir_filter_ccc( 1, [1], center_freq, stage_input_rate) self.connect(prev_block, self.freq_filter_block) prev_block = self.freq_filter_block else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation if i == 0: stage_filter = grfilter.freq_xlating_fir_filter_ccc( stage_decimation, [0], # placeholder center_freq, stage_input_rate) self.freq_filter_block = stage_filter else: taps = self.__stage_taps(i == last_index, stage_input_rate, next_rate) if len(taps) > 10: stage_filter = grfilter.fft_filter_ccc(stage_decimation, taps, 1) else: stage_filter = grfilter.fir_filter_ccc(stage_decimation, taps) self.stages.append((stage_filter, stage_input_rate, next_rate)) self.connect(prev_block, stage_filter) prev_block = stage_filter stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed self.connect(prev_block, self) self.__resampler_explanation = 'No final resampler stage.' else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int(stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common self.__resampler_explanation = 'rational_resampler by %s/%s (stage rates %s/%s)' % (interpolation, decimation, output_rate, stage_input_rate) resampler = rational_resampler.rational_resampler_ccf( interpolation=interpolation, decimation=decimation) else: # TODO: cache filter computation as optfir is used and takes a noticeable time self.__resampler_explanation = 'arb_resampler %s/%s = %s' % (output_rate, stage_input_rate, float(output_rate) / stage_input_rate) resampler = pfb.arb_resampler_ccf(float(output_rate) / stage_input_rate) self.connect( prev_block, resampler, self) # TODO: Shouldn't be necessary since we compute the taps in the loop above... self.__do_taps()
def __init__(self): gr.top_block.__init__(self, "Merapi Vco") Qt.QWidget.__init__(self) self.setWindowTitle("Merapi Vco") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "merapi_vco") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.samp_rate = samp_rate = 2.4e6 self.filt_len = filt_len = 1e6 self.ch_bw = ch_bw = 30e3 self.bb_rate = bb_rate = 192e3 self.audio_rate = audio_rate = 48e3 ################################################## # Blocks ################################################## self.rational_resampler_xxx_0 = filter.rational_resampler_ccc( interpolation=int(bb_rate), decimation=int(samp_rate), taps=None, fractional_bw=None, ) self.qtgui_time_sink_x_2 = qtgui.time_sink_f( 8192 * 8, #size audio_rate, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_2.set_update_time(0.10) self.qtgui_time_sink_x_2.set_y_axis(-10, 10) self.qtgui_time_sink_x_2.set_y_label('Amplitude', "") self.qtgui_time_sink_x_2.enable_tags(-1, True) self.qtgui_time_sink_x_2.set_trigger_mode(qtgui.TRIG_MODE_NORM, qtgui.TRIG_SLOPE_POS, 8, 0, 0, "") self.qtgui_time_sink_x_2.enable_autoscale(False) self.qtgui_time_sink_x_2.enable_grid(False) self.qtgui_time_sink_x_2.enable_axis_labels(True) self.qtgui_time_sink_x_2.enable_control_panel(False) if not True: self.qtgui_time_sink_x_2.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue" ] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_time_sink_x_2.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_2.set_line_label(i, labels[i]) self.qtgui_time_sink_x_2.set_line_width(i, widths[i]) self.qtgui_time_sink_x_2.set_line_color(i, colors[i]) self.qtgui_time_sink_x_2.set_line_style(i, styles[i]) self.qtgui_time_sink_x_2.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_2.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_2_win = sip.wrapinstance( self.qtgui_time_sink_x_2.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_2_win) self.qtgui_time_sink_x_1 = qtgui.time_sink_f( 8192 * 8, #size audio_rate, #samp_rate "", #name 2 #number of inputs ) self.qtgui_time_sink_x_1.set_update_time(0.10) self.qtgui_time_sink_x_1.set_y_axis(-1, 1) self.qtgui_time_sink_x_1.set_y_label('Amplitude', "") self.qtgui_time_sink_x_1.enable_tags(-1, True) self.qtgui_time_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_1.enable_autoscale(False) self.qtgui_time_sink_x_1.enable_grid(False) self.qtgui_time_sink_x_1.enable_axis_labels(True) self.qtgui_time_sink_x_1.enable_control_panel(False) if not True: self.qtgui_time_sink_x_1.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue" ] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(2): if len(labels[i]) == 0: self.qtgui_time_sink_x_1.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_1.set_line_label(i, labels[i]) self.qtgui_time_sink_x_1.set_line_width(i, widths[i]) self.qtgui_time_sink_x_1.set_line_color(i, colors[i]) self.qtgui_time_sink_x_1.set_line_style(i, styles[i]) self.qtgui_time_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_1_win = sip.wrapinstance( self.qtgui_time_sink_x_1.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_1_win) self.qtgui_time_sink_x_0 = qtgui.time_sink_c( 1024, #size audio_rate, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(0.10) self.qtgui_time_sink_x_0.set_y_axis(-1, 1) self.qtgui_time_sink_x_0.set_y_label('Amplitude', "") self.qtgui_time_sink_x_0.enable_tags(-1, True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(False) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_axis_labels(True) self.qtgui_time_sink_x_0.enable_control_panel(False) if not True: self.qtgui_time_sink_x_0.disable_legend() labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue" ] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(2 * 1): if len(labels[i]) == 0: if (i % 2 == 0): self.qtgui_time_sink_x_0.set_line_label( i, "Re{{Data {0}}}".format(i / 2)) else: self.qtgui_time_sink_x_0.set_line_label( i, "Im{{Data {0}}}".format(i / 2)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance( self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_time_sink_x_0_win) self.qtgui_freq_sink_x_1 = qtgui.freq_sink_c( 8192, #size firdes.WIN_BLACKMAN_hARRIS, #wintype 0, #fc bb_rate, #bw "", #name 1 #number of inputs ) self.qtgui_freq_sink_x_1.set_update_time(0.10) self.qtgui_freq_sink_x_1.set_y_axis(-100, -20) self.qtgui_freq_sink_x_1.set_y_label('Relative Gain', 'dB') self.qtgui_freq_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "") self.qtgui_freq_sink_x_1.enable_autoscale(False) self.qtgui_freq_sink_x_1.enable_grid(False) self.qtgui_freq_sink_x_1.set_fft_average(0.2) self.qtgui_freq_sink_x_1.enable_axis_labels(True) self.qtgui_freq_sink_x_1.enable_control_panel(False) if not True: self.qtgui_freq_sink_x_1.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_freq_sink_x_1.set_plot_pos_half(not True) labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "dark blue" ] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_freq_sink_x_1.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_freq_sink_x_1.set_line_label(i, labels[i]) self.qtgui_freq_sink_x_1.set_line_width(i, widths[i]) self.qtgui_freq_sink_x_1.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_freq_sink_x_1_win = sip.wrapinstance( self.qtgui_freq_sink_x_1.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_freq_sink_x_1_win) self.osmosdr_source_0 = osmosdr.source(args="numchan=" + str(1) + " " + '') self.osmosdr_source_0.set_sample_rate(samp_rate) self.osmosdr_source_0.set_center_freq(166.3e6, 0) self.osmosdr_source_0.set_freq_corr(0, 0) self.osmosdr_source_0.set_dc_offset_mode(0, 0) self.osmosdr_source_0.set_iq_balance_mode(0, 0) self.osmosdr_source_0.set_gain_mode(False, 0) self.osmosdr_source_0.set_gain(49, 0) self.osmosdr_source_0.set_if_gain(20, 0) self.osmosdr_source_0.set_bb_gain(20, 0) self.osmosdr_source_0.set_antenna('', 0) self.osmosdr_source_0.set_bandwidth(0, 0) self.fft_filter_xxx_3 = filter.fft_filter_fff( 1, (firdes.low_pass(1, audio_rate, 100, 100, firdes.WIN_BLACKMAN)), 1) self.fft_filter_xxx_3.declare_sample_delay(0) self.fft_filter_xxx_2 = filter.fft_filter_ccc( 1, (firdes.complex_band_pass(1, audio_rate, 360, 2360, 1e3, firdes.WIN_BLACKMAN)), 1) self.fft_filter_xxx_2.declare_sample_delay(0) self.fft_filter_xxx_1 = filter.fft_filter_ccc(1, (firdes.low_pass( 1, bb_rate, ch_bw / 2, ch_bw / 10, firdes.WIN_BLACKMAN)), 1) self.fft_filter_xxx_1.declare_sample_delay(0) self.fft_filter_xxx_0 = filter.fft_filter_ccc(1, (firdes.low_pass( 1, samp_rate, bb_rate / 2, bb_rate / 10, firdes.WIN_BLACKMAN)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.blocks_sub_xx_0 = blocks.sub_ff(1) self.blocks_rotator_cc_0 = blocks.rotator_cc(502e3 / samp_rate * 2 * math.pi) self.blocks_moving_average_xx_0 = blocks.moving_average_ff( int(filt_len), 1 / filt_len, 4000) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf( audio_rate / (2 * math.pi * 1e3 / 8.0)) self.analog_nbfm_rx_0 = analog.nbfm_rx( audio_rate=int(audio_rate), quad_rate=int(bb_rate), tau=75e-6, max_dev=5e3, ) ################################################## # Connections ################################################## self.connect((self.analog_nbfm_rx_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_moving_average_xx_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.fft_filter_xxx_2, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_sub_xx_0, 1)) self.connect((self.blocks_rotator_cc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.fft_filter_xxx_3, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.qtgui_time_sink_x_1, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.fft_filter_xxx_1, 0), (self.analog_nbfm_rx_0, 0)) self.connect((self.fft_filter_xxx_2, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.fft_filter_xxx_3, 0), (self.qtgui_time_sink_x_1, 1)) self.connect((self.fft_filter_xxx_3, 0), (self.qtgui_time_sink_x_2, 0)) self.connect((self.osmosdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.fft_filter_xxx_1, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.qtgui_freq_sink_x_1, 0))
def main(): N = 10000 fs = 2000.0 Ts = 1.0/fs t = scipy.arange(0, N*Ts, Ts) # When playing with the number of channels, be careful about the filter # specs and the channel map of the synthesizer set below. nchans = 10 # Build the filter(s) bw = 1000 tb = 400 proto_taps = filter.firdes.low_pass_2(1, nchans*fs, bw, tb, 80, filter.firdes.WIN_BLACKMAN_hARRIS) print "Filter length: ", len(proto_taps) # Create a modulated signal npwr = 0.01 data = scipy.random.randint(0, 256, N) rrc_taps = filter.firdes.root_raised_cosine(1, 2, 1, 0.35, 41) src = gr.vector_source_b(data.astype(scipy.uint8).tolist(), False) mod = digital.bpsk_mod(samples_per_symbol=2) chan = filter.channel_model(npwr) rrc = filter.fft_filter_ccc(1, rrc_taps) # Split it up into pieces channelizer = filter.pfb.channelizer_ccf(nchans, proto_taps, 2) # Put the pieces back together again syn_taps = [nchans*t for t in proto_taps] synthesizer = filter.pfb_synthesizer_ccf(nchans, syn_taps, True) src_snk = gr.vector_sink_c() snk = gr.vector_sink_c() # Remap the location of the channels # Can be done in synth or channelizer (watch out for rotattions in # the channelizer) synthesizer.set_channel_map([ 0, 1, 2, 3, 4, 15, 16, 17, 18, 19]) tb = gr.top_block() tb.connect(src, mod, chan, rrc, channelizer) tb.connect(rrc, src_snk) vsnk = [] for i in xrange(nchans): tb.connect((channelizer,i), (synthesizer, i)) vsnk.append(gr.vector_sink_c()) tb.connect((channelizer,i), vsnk[i]) tb.connect(synthesizer, snk) tb.run() sin = scipy.array(src_snk.data()[1000:]) sout = scipy.array(snk.data()[1000:]) # Plot original signal fs_in = nchans*fs f1 = pylab.figure(1, figsize=(16,12), facecolor='w') s11 = f1.add_subplot(2,2,1) s11.psd(sin, NFFT=fftlen, Fs=fs_in) s11.set_title("PSD of Original Signal") s11.set_ylim([-200, -20]) s12 = f1.add_subplot(2,2,2) s12.plot(sin.real[1000:1500], "o-b") s12.plot(sin.imag[1000:1500], "o-r") s12.set_title("Original Signal in Time") start = 1 skip = 4 s13 = f1.add_subplot(2,2,3) s13.plot(sin.real[start::skip], sin.imag[start::skip], "o") s13.set_title("Constellation") s13.set_xlim([-2, 2]) s13.set_ylim([-2, 2]) # Plot channels nrows = int(scipy.sqrt(nchans)) ncols = int(scipy.ceil(float(nchans)/float(nrows))) f2 = pylab.figure(2, figsize=(16,12), facecolor='w') for n in xrange(nchans): s = f2.add_subplot(nrows, ncols, n+1) s.psd(vsnk[n].data(), NFFT=fftlen, Fs=fs_in) s.set_title("Channel {0}".format(n)) s.set_ylim([-200, -20]) # Plot reconstructed signal fs_out = 2*nchans*fs f3 = pylab.figure(3, figsize=(16,12), facecolor='w') s31 = f3.add_subplot(2,2,1) s31.psd(sout, NFFT=fftlen, Fs=fs_out) s31.set_title("PSD of Reconstructed Signal") s31.set_ylim([-200, -20]) s32 = f3.add_subplot(2,2,2) s32.plot(sout.real[1000:1500], "o-b") s32.plot(sout.imag[1000:1500], "o-r") s32.set_title("Reconstructed Signal in Time") start = 2 skip = 4 s33 = f3.add_subplot(2,2,3) s33.plot(sout.real[start::skip], sout.imag[start::skip], "o") s33.set_title("Constellation") s33.set_xlim([-2, 2]) s33.set_ylim([-2, 2]) pylab.show()
def __init__(self): gr.top_block.__init__(self, "Dvbs2 Tx") Qt.QWidget.__init__(self) self.setWindowTitle("Dvbs2 Tx") qtgui.util.check_set_qss() try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "dvbs2_tx") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 5000000 self.vga2_gain = vga2_gain = 10 self.vga1_gain = vga1_gain = -8 self.tx_gain = tx_gain = 50 self.taps = taps = 100 self.samp_rate = samp_rate = symbol_rate * 2 self.rolloff = rolloff = 0.2 self.center_freq = center_freq = 1280e6 ################################################## # Blocks ################################################## self._vga2_gain_range = Range(0, 25, 1, 10, 200) self._vga2_gain_win = RangeWidget(self._vga2_gain_range, self.set_vga2_gain, "vga2_gain", "counter_slider", int) self.top_layout.addWidget(self._vga2_gain_win) self._vga1_gain_range = Range(-35, -4, 1, -8, 200) self._vga1_gain_win = RangeWidget(self._vga1_gain_range, self.set_vga1_gain, "vga1_gain", "counter_slider", int) self.top_layout.addWidget(self._vga1_gain_win) self._tx_gain_range = Range(0, 89, 1, 50, 200) self._tx_gain_win = RangeWidget(self._tx_gain_range, self.set_tx_gain, "tx_gain", "counter_slider", float) self.top_layout.addWidget(self._tx_gain_win) self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( 1024, #size firdes.WIN_BLACKMAN_hARRIS, #wintype center_freq, #fc samp_rate, #bw "", #name 1 #number of inputs ) self.qtgui_freq_sink_x_0.set_update_time(0.10) self.qtgui_freq_sink_x_0.set_y_axis(-140, 10) self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB') self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "") self.qtgui_freq_sink_x_0.enable_autoscale(False) self.qtgui_freq_sink_x_0.enable_grid(True) self.qtgui_freq_sink_x_0.set_fft_average(0.2) self.qtgui_freq_sink_x_0.enable_axis_labels(True) self.qtgui_freq_sink_x_0.enable_control_panel(False) if not True: self.qtgui_freq_sink_x_0.disable_legend() if "complex" == "float" or "complex" == "msg_float": self.qtgui_freq_sink_x_0.set_plot_pos_half(not True) labels = ['', '', '', '', '', '', '', '', '', ''] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = [ "blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "dark blue" ] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_freq_sink_x_0.set_line_label( i, "Data {0}".format(i)) else: self.qtgui_freq_sink_x_0.set_line_label(i, labels[i]) self.qtgui_freq_sink_x_0.set_line_width(i, widths[i]) self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_freq_sink_x_0_win = sip.wrapinstance( self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win) self.osmosdr_sink_0 = osmosdr.sink( args="numchan=" + str(1) + " " + 'bladerf=0,buffers=128,buflen=32768') self.osmosdr_sink_0.set_sample_rate(samp_rate) self.osmosdr_sink_0.set_center_freq(center_freq, 0) self.osmosdr_sink_0.set_freq_corr(0, 0) self.osmosdr_sink_0.set_gain(vga2_gain, 0) self.osmosdr_sink_0.set_if_gain(0, 0) self.osmosdr_sink_0.set_bb_gain(vga1_gain, 0) self.osmosdr_sink_0.set_antenna('', 0) self.osmosdr_sink_0.set_bandwidth(6000000, 0) self.fft_filter_xxx_0 = filter.fft_filter_ccc( 1, (firdes.root_raised_cosine(1.0, samp_rate, samp_rate / 2, rolloff, taps)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.dvbs2_physical_cc_0 = dvbs2.physical_cc(dvbs2.FECFRAME_NORMAL, dvbs2.C9_10, dvbs2.MOD_16APSK, dvbs2.PILOTS_ON, 0) self.dvbs2_modulator_bc_0 = dvbs2.modulator_bc(dvbs2.FECFRAME_NORMAL, dvbs2.C9_10, dvbs2.MOD_16APSK) self.dvbs2_ldpc_bb_0 = dvbs2.ldpc_bb(dvbs2.FECFRAME_NORMAL, dvbs2.C9_10, dvbs2.MOD_OTHER) self.dvbs2_interleaver_bb_0 = dvbs2.interleaver_bb( dvbs2.FECFRAME_NORMAL, dvbs2.C9_10, dvbs2.MOD_16APSK) self.dvbs2_bch_bb_0 = dvbs2.bch_bb(dvbs2.FECFRAME_NORMAL, dvbs2.C9_10) self.dvbs2_bbscrambler_bb_0 = dvbs2.bbscrambler_bb( dvbs2.FECFRAME_NORMAL, dvbs2.C9_10) self.dvbs2_bbheader_bb_0 = dvbs2.bbheader_bb(dvbs2.FECFRAME_NORMAL, dvbs2.C9_10, dvbs2.RO_0_20) self.blocks_file_source_0 = blocks.file_source( gr.sizeof_char * 1, '/run/shm/adv16apsk910.ts', True) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.dvbs2_bbheader_bb_0, 0)) self.connect((self.dvbs2_bbheader_bb_0, 0), (self.dvbs2_bbscrambler_bb_0, 0)) self.connect((self.dvbs2_bbscrambler_bb_0, 0), (self.dvbs2_bch_bb_0, 0)) self.connect((self.dvbs2_bch_bb_0, 0), (self.dvbs2_ldpc_bb_0, 0)) self.connect((self.dvbs2_interleaver_bb_0, 0), (self.dvbs2_modulator_bc_0, 0)) self.connect((self.dvbs2_ldpc_bb_0, 0), (self.dvbs2_interleaver_bb_0, 0)) self.connect((self.dvbs2_modulator_bc_0, 0), (self.dvbs2_physical_cc_0, 0)) self.connect((self.dvbs2_physical_cc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.osmosdr_sink_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.qtgui_freq_sink_x_0, 0))
def __init__(self, antenna=satnogs.not_set_antenna, bb_gain=satnogs.not_set_rx_bb_gain, decoded_data_file_path='/tmp/.satnogs/data/noaa', dev_args=satnogs.not_set_dev_args, doppler_correction_per_sec=20, enable_iq_dump=0, file_path='/tmp/test.ogg', flip_images=0, if_gain=satnogs.not_set_rx_if_gain, iq_file_path='/tmp/iq.dat', lo_offset=100e3, ppm=0, rf_gain=satnogs.not_set_rx_rf_gain, rigctl_port=4532, rx_freq=90.4e6, rx_sdr_device='usrpb200', sync=1, waterfall_file_path='/tmp/waterfall.dat'): gr.top_block.__init__(self, "NOAA APT Decoder") ################################################## # Parameters ################################################## self.antenna = antenna self.bb_gain = bb_gain self.decoded_data_file_path = decoded_data_file_path self.dev_args = dev_args self.doppler_correction_per_sec = doppler_correction_per_sec self.enable_iq_dump = enable_iq_dump self.file_path = file_path self.flip_images = flip_images self.if_gain = if_gain self.iq_file_path = iq_file_path self.lo_offset = lo_offset self.ppm = ppm self.rf_gain = rf_gain self.rigctl_port = rigctl_port self.rx_freq = rx_freq self.rx_sdr_device = rx_sdr_device self.sync = sync self.waterfall_file_path = waterfall_file_path ################################################## # Variables ################################################## self.samp_rate_rx = samp_rate_rx = satnogs.hw_rx_settings[rx_sdr_device]['samp_rate'] self.first_stage_decimation = first_stage_decimation = 4 self.noaa_filter_taps = noaa_filter_taps = firdes.low_pass(1.0, samp_rate_rx /first_stage_decimation, 16.5e3, 4e3, firdes.WIN_HAMMING, 6.76) self.initial_bandwidth = initial_bandwidth = 100e3 self.first_stage_filter_taps = first_stage_filter_taps = firdes.low_pass(1.0, 1.0, 0.2, 0.1, firdes.WIN_HAMMING, 6.76) self.audio_decimation = audio_decimation = 2 ################################################## # Blocks ################################################## self.satnogs_waterfall_sink_0 = satnogs.waterfall_sink(samp_rate_rx /first_stage_decimation, 0.0, 8, 1024, waterfall_file_path, 0) self.satnogs_tcp_rigctl_msg_source_0 = satnogs.tcp_rigctl_msg_source("127.0.0.1", rigctl_port, False, 1000/doppler_correction_per_sec, 1500) self.satnogs_ogg_encoder_0 = satnogs.ogg_encoder(file_path, 48000, 0.8) self.satnogs_noaa_apt_sink_0 = satnogs.noaa_apt_sink(decoded_data_file_path, 2080, 1800, bool(sync), bool(flip_images)) self.satnogs_iq_sink_0 = satnogs.iq_sink(32767, iq_file_path, False, enable_iq_dump) self.satnogs_coarse_doppler_correction_cc_0 = satnogs.coarse_doppler_correction_cc(rx_freq, samp_rate_rx /first_stage_decimation) self.rational_resampler_xxx_2 = filter.rational_resampler_ccc( interpolation=48000, decimation=int(samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation), taps=None, fractional_bw=None, ) self.rational_resampler_xxx_1 = filter.rational_resampler_fff( interpolation=48000, decimation=int(samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation), taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0_0 = filter.rational_resampler_fff( interpolation=1, decimation=4, taps=None, fractional_bw=None, ) self.rational_resampler_xxx_0 = filter.rational_resampler_fff( interpolation=4*4160, decimation=int((samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation)/2), taps=None, fractional_bw=None, ) self.osmosdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + satnogs.handle_rx_dev_args(rx_sdr_device, dev_args) ) self.osmosdr_source_0.set_sample_rate(samp_rate_rx) self.osmosdr_source_0.set_center_freq(rx_freq - lo_offset, 0) self.osmosdr_source_0.set_freq_corr(ppm, 0) self.osmosdr_source_0.set_dc_offset_mode(2, 0) self.osmosdr_source_0.set_iq_balance_mode(0, 0) self.osmosdr_source_0.set_gain_mode(False, 0) self.osmosdr_source_0.set_gain(satnogs.handle_rx_rf_gain(rx_sdr_device, rf_gain), 0) self.osmosdr_source_0.set_if_gain(satnogs.handle_rx_if_gain(rx_sdr_device, if_gain), 0) self.osmosdr_source_0.set_bb_gain(satnogs.handle_rx_bb_gain(rx_sdr_device, bb_gain), 0) self.osmosdr_source_0.set_antenna(satnogs.handle_rx_antenna(rx_sdr_device, antenna), 0) self.osmosdr_source_0.set_bandwidth(samp_rate_rx, 0) self.hilbert_fc_0 = filter.hilbert_fc(65, firdes.WIN_HAMMING, 6.76) self.freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(first_stage_decimation, (first_stage_filter_taps), lo_offset, samp_rate_rx) self.fir_filter_xxx_1 = filter.fir_filter_fff(2, ([0.5, 0.5])) self.fir_filter_xxx_1.declare_sample_delay(0) self.fft_filter_xxx_0 = filter.fft_filter_ccc(int(samp_rate_rx/ first_stage_decimation / initial_bandwidth), (noaa_filter_taps), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.band_pass_filter_0 = filter.fir_filter_fff(1, firdes.band_pass( 6, samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)) / audio_decimation, 500, 4.2e3, 200, firdes.WIN_HAMMING, 6.76)) self.analog_wfm_rcv_0 = analog.wfm_rcv( quad_rate=samp_rate_rx/ ( first_stage_decimation * int(samp_rate_rx/ first_stage_decimation / initial_bandwidth)), audio_decimation=audio_decimation, ) ################################################## # Connections ################################################## self.msg_connect((self.satnogs_tcp_rigctl_msg_source_0, 'freq'), (self.satnogs_coarse_doppler_correction_cc_0, 'freq')) self.connect((self.analog_wfm_rcv_0, 0), (self.band_pass_filter_0, 0)) self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_1, 0)) self.connect((self.band_pass_filter_0, 0), (self.fir_filter_xxx_1, 0)) self.connect((self.blocks_complex_to_mag_0, 0), (self.rational_resampler_xxx_0_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.analog_wfm_rcv_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.rational_resampler_xxx_2, 0)) self.connect((self.fir_filter_xxx_1, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0, 0), (self.satnogs_coarse_doppler_correction_cc_0, 0)) self.connect((self.hilbert_fc_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.osmosdr_source_0, 0), (self.freq_xlating_fir_filter_xxx_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.hilbert_fc_0, 0)) self.connect((self.rational_resampler_xxx_0_0, 0), (self.satnogs_noaa_apt_sink_0, 0)) self.connect((self.rational_resampler_xxx_1, 0), (self.satnogs_ogg_encoder_0, 0)) self.connect((self.rational_resampler_xxx_2, 0), (self.satnogs_iq_sink_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.satnogs_coarse_doppler_correction_cc_0, 0), (self.satnogs_waterfall_sink_0, 0))
def __init__(self, cp_len=32, fft_len=64, max_fft_shift=4, occupied_carriers=48, ports=2): gr.hier_block2.__init__( self, "OFDM Mutichannel Recover", gr.io_signaturev(2, 2, [gr.sizeof_gr_complex*1, gr.sizeof_gr_complex*1]), gr.io_signaturev(2, 2, [gr.sizeof_gr_complex*occupied_carriers, gr.sizeof_gr_complex*occupied_carriers]), ) self.message_port_register_hier_out("packet") self.message_port_register_hier_out("header_dfe") ################################################## # Parameters ################################################## self.cp_len = cp_len self.fft_len = fft_len self.max_fft_shift = max_fft_shift self.occupied_carriers = occupied_carriers self.ports = ports ################################################## # Variables ################################################## self.rcvd_pktq = rcvd_pktq = gr.msg_queue() self.modulation = modulation = 'bpsk' self.mods = mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} self.bw = bw = (float(occupied_carriers) / float(fft_len)) / 2.0 self.watcher = watcher = pp._queue_watcher_thread(rcvd_pktq) self.tb = tb = bw*0.08 self.samp_rate = samp_rate = 32000 self.rotated_const = rotated_const = gp.gen_framer_info(modulation) self.phgain = phgain = 0.25 self.arity = arity = mods[modulation] ################################################## # Blocks ################################################## self.ofdm_sync_channel_0 = ofdm_sync_channel( cp_len=cp_len, fftlen=fft_len, max_fft_shift=max_fft_shift, occupied_carriers=occupied_carriers, ) self.ofdm_packet_sync_0 = ofdm_packet_sync( cp_len=cp_len, fft_len=fft_len, ) self.fft_filter_xxx_0 = filter.fft_filter_ccc(1, (filter.firdes.low_pass (1.0, 1.0, bw+tb, tb, filter.firdes.WIN_HAMMING)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.ofdm_ofdm_mrx_frame_sink_0 = ofdm.ofdm_mrx_frame_sink(rotated_const, range(arity), rcvd_pktq, occupied_carriers, phgain, phgain*phgain /4.0, ports) for p in range(ports-1): # Add OFDM Sync Channel object_name_osc = 'ofdm_sync_channel_'+str(p+1) setattr(self, object_name_osc, ofdm_sync_channel( cp_len=cp_len, fftlen=fft_len, max_fft_shift=max_fft_shift, occupied_carriers=occupied_carriers, )) # Add FFT Filter object_name_ft = 'fft_filter_ccc_'+str(p+1) setattr(self, object_name_ft, filter.fft_filter_ccc(1, (filter.firdes.low_pass (1.0, 1.0, bw+tb, tb, filter.firdes.WIN_HAMMING)), 1) ) # self.fft_filter_xxx_0_0.declare_sample_delay(0) setattr(getattr(self,object_name_ft),'declare_sample_delay',0) # Add null sink object_name_ns = 'blocks_null_sink_'+str(p+1) setattr(self, object_name_ns, blocks.null_sink(gr.sizeof_char*1) ) ### Connections # Pad to FFT Filter self.connect( (self, p+1), (getattr(self,object_name_ft), 0)) # FFT Filt to OFS self.connect( (getattr(self,object_name_ft), 0), (getattr(self,object_name_osc), 0) ) # PS To OFDM SC self.connect( (self.ofdm_packet_sync_0, 0), (getattr(self,object_name_osc), 2)) self.connect( (self.ofdm_packet_sync_0, 1), (getattr(self,object_name_osc), 1)) # OSC To OFDM Frame Sink self.connect((getattr(self,object_name_osc), 1), (self.ofdm_sync_channel_0, p+2)) # OSC To Null Sink self.connect((getattr(self,object_name_osc), 0), (self.blocks_null_sink_0, 0)) # OFDM Frame Sink to Pad self.connect((self.ofdm_ofdm_mrx_frame_sink_0, p), (self, p)) ################################################## # Connections ################################################## self.connect((self, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.ofdm_packet_sync_0, 0)) self.connect((self.ofdm_packet_sync_0, 0), (self.ofdm_sync_channel_0, 2)) self.connect((self.ofdm_packet_sync_0, 1), (self.ofdm_sync_channel_0, 1)) self.connect((self.ofdm_packet_sync_0, 2), (self.ofdm_sync_channel_0, 0)) self.connect((self.ofdm_sync_channel_0, 0), (self.ofdm_ofdm_mrx_frame_sink_0, 0)) # Flag self.connect((self.ofdm_sync_channel_0, 1), (self.ofdm_ofdm_mrx_frame_sink_0, 1)) self.msg_connect((self.ofdm_ofdm_mrx_frame_sink_0, 'packet'), (self, 'packet')) self.msg_connect((self.ofdm_ofdm_mrx_frame_sink_0, 'header_dfe'), (self, 'header_dfe'))
def __init__(self): gr.top_block.__init__(self, "Cross Correlation Test") ################################################## # Variables ################################################## self.samp_rate = samp_rate = 46e6 self.stage1_decimation = stage1_decimation = int(samp_rate / 500e3) self.max_search = max_search = 400 self.lag = lag = 10 self.gain = gain = 32 self.delay_0 = delay_0 = 0 self.corr_frame_size = corr_frame_size = 8192 self.corr_frame_decim = corr_frame_decim = 200 self.center_freq = center_freq = 95.7e6 ################################################## # Blocks ################################################## self.xcorrelate_ExtractDelay_0 = xcorrelate.ExtractDelay( 0, self.set_delay_0, False) self.uhd_usrp_source_0 = uhd.usrp_source( ",".join(("", "num_recv_frames=128")), uhd.stream_args( cpu_format="fc32", args='', channels=list(range(0, 1)), ), ) self.uhd_usrp_source_0.set_center_freq(center_freq, 0) self.uhd_usrp_source_0.set_rx_agc(False, 0) self.uhd_usrp_source_0.set_gain(gain, 0) self.uhd_usrp_source_0.set_antenna('RX2', 0) self.uhd_usrp_source_0.set_samp_rate(samp_rate) # No synchronization enforced. self.uhd_usrp_source_0.set_processor_affinity([0]) self.rational_resampler_xxx_0_0 = filter.rational_resampler_fff( interpolation=48, decimation=50, taps=None, fractional_bw=None) self.lfast_low_pass_filter_0_0 = filter.fft_filter_ccc( 1, firdes.low_pass(1, samp_rate, 100e3, 10e3, firdes.WIN_HAMMING, 6.76), 1) self.lfast_low_pass_filter_0_0.set_processor_affinity([1]) self.clenabled_XCorrelate_0 = clenabled.clXCorrelate( 1, 1, 0, 0, False, 2, 8192, 2, gr.sizeof_float, 512, 4, True) self.blocks_keep_one_in_n_0 = blocks.keep_one_in_n( gr.sizeof_gr_complex * 1, stage1_decimation) self.blocks_delay_0_0_0 = blocks.delay(gr.sizeof_gr_complex * 1, delay_0) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex * 1, lag) self.blocks_complex_to_mag_0_0 = blocks.complex_to_mag(1) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.blocks_add_xx_0 = blocks.add_vcc(1) self.audio_sink_0 = audio.sink(48000, '', True) self.audio_sink_0.set_processor_affinity([2]) self.analog_wfm_rcv_0 = analog.wfm_rcv( quad_rate=500e3, audio_decimation=10, ) ################################################## # Connections ################################################## self.msg_connect((self.clenabled_XCorrelate_0, 'corr'), (self.xcorrelate_ExtractDelay_0, 'corr')) self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_0_0, 0)) self.connect((self.blocks_add_xx_0, 0), (self.blocks_keep_one_in_n_0, 0)) self.connect((self.blocks_complex_to_mag_0, 0), (self.clenabled_XCorrelate_0, 0)) self.connect((self.blocks_complex_to_mag_0_0, 0), (self.clenabled_XCorrelate_0, 1)) self.connect((self.blocks_delay_0, 0), (self.blocks_complex_to_mag_0_0, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_delay_0_0_0, 0)) self.connect((self.blocks_delay_0_0_0, 0), (self.blocks_add_xx_0, 1)) self.connect((self.blocks_keep_one_in_n_0, 0), (self.analog_wfm_rcv_0, 0)) self.connect((self.lfast_low_pass_filter_0_0, 0), (self.blocks_add_xx_0, 0)) self.connect((self.lfast_low_pass_filter_0_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.lfast_low_pass_filter_0_0, 0), (self.blocks_delay_0, 0)) self.connect((self.rational_resampler_xxx_0_0, 0), (self.audio_sink_0, 0)) self.connect((self.uhd_usrp_source_0, 0), (self.lfast_low_pass_filter_0_0, 0))
def __init__(self, fft_length, cp_length, occupied_tones, snr, ks, logging=False): """ Hierarchical block for receiving OFDM symbols. The input is the complex modulated signal at baseband. Synchronized packets are sent back to the demodulator. Args: fft_length: total number of subcarriers (int) cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length) (int) occupied_tones: number of subcarriers used for data (int) snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer (float) ks: known symbols used as preambles to each packet (list of lists) logging: turn file logging on or off (bool) """ gr.hier_block2.__init__(self, "ofdm_receiver", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature bw = (float(occupied_tones) / float(fft_length)) / 2.0 tb = bw*0.08 chan_coeffs = filter.firdes.low_pass (1.0, # gain 1.0, # sampling rate bw+tb, # midpoint of trans. band tb, # width of trans. band filter.firdes.WIN_HAMMING) # filter type self.chan_filt = filter.fft_filter_ccc(1, chan_coeffs) win = [1 for i in range(fft_length)] zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0)) ks0 = fft_length*[0,] ks0[zeros_on_left : zeros_on_left + occupied_tones] = ks[0] ks0 = fft.ifftshift(ks0) ks0time = fft.ifft(ks0) # ADD SCALING FACTOR ks0time = ks0time.tolist() SYNC = "pn" if SYNC == "ml": nco_sensitivity = -1.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, ks0time, logging) elif SYNC == "pn": nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, logging) elif SYNC == "pnac": nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time, logging) # for testing only; do not user over the air # remove filter and filter delay for this elif SYNC == "fixed": self.chan_filt = blocks.multiply_const_cc(1.0) nsymbols = 18 # enter the number of symbols per packet freq_offset = 0.0 # if you use a frequency offset, enter it here nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, nsymbols, freq_offset, logging) # Set up blocks self.nco = analog.frequency_modulator_fc(nco_sensitivity) # generate a signal proportional to frequency error of sync block self.sigmix = blocks.multiply_cc() self.sampler = digital.ofdm_sampler(fft_length, fft_length+cp_length) self.fft_demod = gr_fft.fft_vcc(fft_length, True, win, True) self.ofdm_frame_acq = digital.ofdm_frame_acquisition(occupied_tones, fft_length, cp_length, ks[0]) self.connect(self, self.chan_filt) # filter the input channel self.connect(self.chan_filt, self.ofdm_sync) # into the synchronization alg. self.connect((self.ofdm_sync,0), self.nco, (self.sigmix,1)) # use sync freq. offset output to derotate input signal self.connect(self.chan_filt, (self.sigmix,0)) # signal to be derotated self.connect(self.sigmix, (self.sampler,0)) # sample off timing signal detected in sync alg self.connect((self.ofdm_sync,1), (self.sampler,1)) # timing signal to sample at self.connect((self.sampler,0), self.fft_demod) # send derotated sampled signal to FFT self.connect(self.fft_demod, (self.ofdm_frame_acq,0)) # find frame start and equalize signal self.connect((self.sampler,1), (self.ofdm_frame_acq,1)) # send timing signal to signal frame start self.connect((self.ofdm_frame_acq,0), (self,0)) # finished with fine/coarse freq correction, self.connect((self.ofdm_frame_acq,1), (self,1)) # frame and symbol timing, and equalization if logging: self.connect(self.chan_filt, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat")) self.connect(self.fft_demod, blocks.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-fft_out_c.dat")) self.connect(self.ofdm_frame_acq, blocks.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_receiver-frame_acq_c.dat")) self.connect((self.ofdm_frame_acq,1), blocks.file_sink(1, "ofdm_receiver-found_corr_b.dat")) self.connect(self.sampler, blocks.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-sampler_c.dat")) self.connect(self.sigmix, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-sigmix_c.dat")) self.connect(self.nco, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
def main(args): nargs = len(args) if nargs == 1: port = int(args[0]) outfile = None elif nargs == 2: port = int(args[0]) outfile = args[1] else: sys.stderr.write("Usage: atsc-blade.py port [output_file]\n") sys.exit(1) symbol_rate = 4500000.0 / 286 * 684 pilot_freq = 309441 center_freq = 441000000 tx_gain = 83 # max 89.5 tb = gr.top_block() out = uhd.usrp_sink( device_addr= "recv_frame_size=65536,num_recv_frames=128,send_frame_size=65536,num_send_frames=128,master_clock_rate=" + str(symbol_rate * 4), stream_args=uhd.stream_args( cpu_format="fc32", otw_format="sc16", channels=range(1), ), ) out.set_samp_rate(symbol_rate) out.set_center_freq(center_freq, 0) out.set_gain(tx_gain, 0) #src = blocks.udp_source(gr.sizeof_char*1, "127.0.0.1", port, 18800, True) src = grc_blks2.tcp_source(gr.sizeof_char * 1, "127.0.0.1", port, True) pad = atsc.pad() rand = atsc.randomizer() rs_enc = atsc.rs_encoder() inter = atsc.interleaver() trell = atsc.trellis_encoder() fsm = atsc.field_sync_mux() v2s = blocks.vector_to_stream(gr.sizeof_char, 1024) minn = blocks.keep_m_in_n(gr.sizeof_char, 832, 1024, 4) c2sym = digital.chunks_to_symbols_bc( ([symbol + 1.25 for symbol in [-7, -5, -3, -1, 1, 3, 5, 7]]), 1) offset = analog.sig_source_c(symbol_rate, analog.GR_COS_WAVE, -3000000 + pilot_freq, 0.9, 0) mix = blocks.multiply_vcc(1) rrc = filter.fft_filter_ccc( 1, firdes.root_raised_cosine(0.1, symbol_rate, symbol_rate / 2, 0.1152, 100)) tb.connect(src, pad, rand, rs_enc, inter, trell, fsm, v2s, minn, c2sym) tb.connect((c2sym, 0), (mix, 0)) tb.connect((offset, 0), (mix, 1)) tb.connect(mix, rrc, out) if outfile: dst = blocks.file_sink(gr.sizeof_gr_complex, outfile) tb.connect(rrc, dst) tb.run()
def __init__(self, fft_length, cp_length, occupied_tones, snr, ks, carrier_map_bin, nc_filter, logging=False): """ Hierarchical block for receiving OFDM symbols. The input is the complex modulated signal at baseband. Synchronized packets are sent back to the demodulator. @param fft_length: total number of subcarriers @type fft_length: int @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length) @type cp_length: int @param occupied_tones: number of subcarriers used for data @type occupied_tones: int @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer @type snr: float @param ks: known symbols used as preambles to each packet @type ks: list of lists @param logging: turn file logging on or off @type logging: bool """ gr.hier_block2.__init__(self, "ofdm_receiver", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature bw = (float(occupied_tones) / float(fft_length)) / 2.0 tb = bw*0.04 print "ofdm_receiver:__init__:occupied_tones %s fft_length %d " % (occupied_tones, fft_length) chan_coeffs = filter.firdes.low_pass (1.0, # gain 1.0, # sampling rate bw+tb, # midpoint of trans. band tb, # width of trans. band filter.firdes.WIN_HAMMING) # filter type self.chan_filt = filter.fft_filter_ccc(1, chan_coeffs) # linklab, get ofdm parameters self._fft_length = fft_length self._occupied_tones = occupied_tones self._cp_length = cp_length self._nc_filter = nc_filter self._carrier_map_bin = carrier_map_bin win = [1 for i in range(fft_length)] # linklab, initialization function self.initialize(ks, self._carrier_map_bin) zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0)) ks0 = fft_length*[0,] ks0[zeros_on_left : zeros_on_left + occupied_tones] = ks[0] ks0 = np_fft.ifftshift(ks0) ks0time = np_fft.ifft(ks0) # ADD SCALING FACTOR ks0time = ks0time.tolist() SYNC = "pn" if SYNC == "ml": nco_sensitivity = -1.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, ks0time, logging) elif SYNC == "pn": nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, logging) elif SYNC == "pnac": nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time, logging) # for testing only; do not user over the air # remove filter and filter delay for this elif SYNC == "fixed": self.chan_filt = gr.multiply_const_cc(1.0) nsymbols = 18 # enter the number of symbols per packet freq_offset = 0.0 # if you use a frequency offset, enter it here nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, nsymbols, freq_offset, logging) # Set up blocks # Create a delay line, linklab self.delay = blocks.delay(gr.sizeof_gr_complex, fft_length) self.nco = analog.frequency_modulator_fc(nco_sensitivity) # generate a signal proportional to frequency error of sync block self.sigmix = blocks.multiply_cc() self.sampler = gr_papyrus.ofdm_sampler(fft_length, fft_length+cp_length) self.fft_demod = gr_fft.fft_vcc(fft_length, True, win, True) self.ofdm_frame_acq = gr_papyrus.ofdm_frame_acquisition(occupied_tones, fft_length, cp_length, ks[0]) # linklab, check current mode: non-contiguous OFDM or not if self._nc_filter: print '\nMulti-band Filter Turned ON!' # linklab, non-contiguous filter self.ncofdm_filt = ncofdm_filt(self._fft_length, self._occupied_tones, self._carrier_map_bin) self.connect(self, self.chan_filt, self.ncofdm_filt) self.connect(self.ncofdm_filt, self.ofdm_sync) # into the synchronization alg. self.connect((self.ofdm_sync,0), self.nco, (self.sigmix,1)) # use sync freq. offset output to derotate input signal self.connect(self.ncofdm_filt, self.delay, (self.sigmix,0)) # signal to be derotated else : print '\nMulti-band Filter Turned OFF!' self.connect(self, self.chan_filt) self.connect(self.chan_filt, self.ofdm_sync) # into the synchronization alg. self.connect((self.ofdm_sync,0), self.nco, (self.sigmix,1)) # use sync freq. offset output to derotate input signal self.connect(self.chan_filt, self.delay, (self.sigmix,0)) # signal to be derotated self.connect(self.sigmix, (self.sampler,0)) # sample off timing signal detected in sync alg self.connect((self.ofdm_sync,1), (self.sampler,1)) # timing signal to sample at self.connect((self.sampler,0), self.fft_demod) # send derotated sampled signal to FFT self.connect(self.fft_demod, (self.ofdm_frame_acq,0)) # find frame start and equalize signal self.connect((self.sampler,1), (self.ofdm_frame_acq,1)) # send timing signal to signal frame start self.connect((self.ofdm_frame_acq,0), (self,0)) # finished with fine/coarse freq correction, self.connect((self.ofdm_frame_acq,1), (self,1)) # frame and symbol timing, and equalization if logging: self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat")) self.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-fft_out_c.dat")) self.connect(self.ofdm_frame_acq, gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_receiver-frame_acq_c.dat")) self.connect((self.ofdm_frame_acq,1), gr.file_sink(1, "ofdm_receiver-found_corr_b.dat")) self.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-sampler_c.dat")) self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-sigmix_c.dat")) self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Dvbs Tx") _icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png" self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 1000000 self.username = username = os.environ.get('USER') self.samp_rate = samp_rate = symbol_rate * 2 self.rrc_taps = rrc_taps = 100 self.frequency = frequency = 2440000000 ################################################## # Blocks ################################################## self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=frequency, 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=True, avg_alpha=0.13333, title='FFT Plot', peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.trellis_encoder_xx_0 = trellis.encoder_bb( trellis.fsm(1, 2, (0171, 0133)), 0, 0) if False else trellis.encoder_bb( trellis.fsm(1, 2, (0171, 0133)), 0) self._symbol_rate_chooser = forms.radio_buttons( parent=self.GetWin(), value=self.symbol_rate, callback=self.set_symbol_rate, label='symbol_rate', choices=[250000, 333000, 500000, 1000000, 1200000, 1500000], labels=[ "250kS/s", "333kS/s", "500 kS/s", "1000kS/s", "1200kS/s", "1500kS/s" ], style=wx.RA_HORIZONTAL, ) self.Add(self._symbol_rate_chooser) self.pluto_sink_0 = iio.pluto_sink('', frequency, samp_rate, 20000000, 0x8000, False, 10.0, '', True) self.fft_filter_xxx_0 = filter.fft_filter_ccc( 1, (firdes.root_raised_cosine(1.0, samp_rate, samp_rate / 2, 0.35, rrc_taps)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.fec_puncture_xx_0 = fec.puncture_bb(14, 0b11010101100110, 0) self.dtv_dvbt_reed_solomon_enc_0 = dtv.dvbt_reed_solomon_enc( 2, 8, 0x11d, 255, 239, 8, 51, 8) self.dtv_dvbt_energy_dispersal_0 = dtv.dvbt_energy_dispersal(1) self.dtv_dvbt_convolutional_interleaver_0 = dtv.dvbt_convolutional_interleaver( 136, 12, 17) self.dtv_dvbs2_modulator_bc_0 = dtv.dvbs2_modulator_bc( dtv.FECFRAME_NORMAL, dtv.C5_6, dtv.MOD_QPSK, dtv.INTERPOLATION_ON) self.blocks_unpack_k_bits_bb_0 = blocks.unpack_k_bits_bb(2) self.blocks_packed_to_unpacked_xx_0 = blocks.packed_to_unpacked_bb( 1, gr.GR_MSB_FIRST) self.blocks_pack_k_bits_bb_0 = blocks.pack_k_bits_bb(2) self.blocks_file_source_0 = blocks.file_source( gr.sizeof_char * 1, "/media/" + username + "/PlutoSDR/rpidatv.ts", True) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.dtv_dvbt_energy_dispersal_0, 0)) self.connect((self.blocks_pack_k_bits_bb_0, 0), (self.dtv_dvbs2_modulator_bc_0, 0)) self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.fec_puncture_xx_0, 0)) self.connect((self.dtv_dvbs2_modulator_bc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.dtv_dvbt_convolutional_interleaver_0, 0), (self.blocks_packed_to_unpacked_xx_0, 0)) self.connect((self.dtv_dvbt_energy_dispersal_0, 0), (self.dtv_dvbt_reed_solomon_enc_0, 0)) self.connect((self.dtv_dvbt_reed_solomon_enc_0, 0), (self.dtv_dvbt_convolutional_interleaver_0, 0)) self.connect((self.fec_puncture_xx_0, 0), (self.blocks_pack_k_bits_bb_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.pluto_sink_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.blocks_unpack_k_bits_bb_0, 0))
def main(args): nargs = len(args) if nargs == 1: infile = args[0] outfile = None elif nargs == 2: infile = args[0] outfile = args[1] else: sys.stderr.write("Usage: dvbs2-blade.py input_file [output_file]\n"); sys.exit(1) symbol_rate = 5000000 samp_rate = symbol_rate * 2 frame_size = dvbs2.FECFRAME_NORMAL constellation = dvbs2.MOD_16APSK code_rate = dvbs2.C9_10 pilots = dvbs2.PILOTS_ON rolloff = dvbs2.RO_0_20 gold_code = 0 rrc_taps = 50 center_freq = 1280000000 txvga1_gain = -10 txvga2_gain = 15 bandwidth = 6000000 if constellation == dvbs2.MOD_QPSK: if ( code_rate == dvbs2.C1_4 or code_rate == dvbs2.C1_3 or code_rate == dvbs2.C2_5 or code_rate == dvbs2.C1_2 or code_rate == dvbs2.C3_5 or code_rate == dvbs2.C2_3 or code_rate == dvbs2.C3_4 or code_rate == dvbs2.C4_5 or code_rate == dvbs2.C5_6 or code_rate == dvbs2.C8_9 or code_rate == dvbs2.C9_10 or code_rate == dvbs2.C13_45 or code_rate == dvbs2.C9_20 or code_rate == dvbs2.C11_20 or code_rate == dvbs2.C11_45 or code_rate == dvbs2.C4_15 or code_rate == dvbs2.C14_45 or code_rate == dvbs2.C7_15 or code_rate == dvbs2.C8_15 or code_rate == dvbs2.C32_45): pass else: sys.stderr.write("Invalid code rate for QPSK\n"); sys.exit(1) if constellation == dvbs2.MOD_8PSK: if ( code_rate == dvbs2.C3_5 or code_rate == dvbs2.C2_3 or code_rate == dvbs2.C3_4 or code_rate == dvbs2.C5_6 or code_rate == dvbs2.C8_9 or code_rate == dvbs2.C9_10 or code_rate == dvbs2.C23_36 or code_rate == dvbs2.C25_36 or code_rate == dvbs2.C13_18 or code_rate == dvbs2.C7_15 or code_rate == dvbs2.C8_15 or code_rate == dvbs2.C26_45 or code_rate == dvbs2.C32_45): pass else: sys.stderr.write("Invalid code rate for 8PSK\n"); sys.exit(1) if constellation == dvbs2.MOD_8APSK: if ( code_rate == dvbs2.C100_180 or code_rate == dvbs2.C104_180): pass else: sys.stderr.write("Invalid code rate for 8APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_16APSK: if ( code_rate == dvbs2.C2_3 or code_rate == dvbs2.C3_4 or code_rate == dvbs2.C4_5 or code_rate == dvbs2.C5_6 or code_rate == dvbs2.C8_9 or code_rate == dvbs2.C9_10 or code_rate == dvbs2.C26_45 or code_rate == dvbs2.C3_5 or code_rate == dvbs2.C28_45 or code_rate == dvbs2.C23_36 or code_rate == dvbs2.C25_36 or code_rate == dvbs2.C13_18 or code_rate == dvbs2.C140_180 or code_rate == dvbs2.C154_180 or code_rate == dvbs2.C7_15 or code_rate == dvbs2.C8_15 or code_rate == dvbs2.C26_45 or code_rate == dvbs2.C3_5 or code_rate == dvbs2.C32_45): pass else: sys.stderr.write("Invalid code rate for 16APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_8_8APSK: if ( code_rate == dvbs2.C90_180 or code_rate == dvbs2.C96_180 or code_rate == dvbs2.C100_180 or code_rate == dvbs2.C18_30 or code_rate == dvbs2.C20_30): pass else: sys.stderr.write("Invalid code rate for 8+8APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_32APSK: if ( code_rate == dvbs2.C3_4 or code_rate == dvbs2.C4_5 or code_rate == dvbs2.C5_6 or code_rate == dvbs2.C8_9 or code_rate == dvbs2.C9_10): pass else: sys.stderr.write("Invalid code rate for 32APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_4_12_16APSK: if ( code_rate == dvbs2.C2_3 or code_rate == dvbs2.C32_45): pass else: sys.stderr.write("Invalid code rate for 4+12+16rbAPSK\n"); sys.exit(1) if constellation == dvbs2.MOD_4_8_4_16APSK: if ( code_rate == dvbs2.C128_180 or code_rate == dvbs2.C132_180 or code_rate == dvbs2.C140_180): pass else: sys.stderr.write("Invalid code rate for 4+8+4+16APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_64APSK: if ( code_rate == dvbs2.C128_180): pass else: sys.stderr.write("Invalid code rate for 64APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_4_12_20_28APSK: if ( code_rate == dvbs2.C132_180): pass else: sys.stderr.write("Invalid code rate for 4+12+20+28APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_8_16_20_20APSK: if ( code_rate == dvbs2.C7_9 or code_rate == dvbs2.C4_5 or code_rate == dvbs2.C5_6): pass else: sys.stderr.write("Invalid code rate for 8+16+20+20APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_128APSK: if ( code_rate == dvbs2.C135_180 or code_rate == dvbs2.C140_180): pass else: sys.stderr.write("Invalid code rate for 128APSK\n"); sys.exit(1) if constellation == dvbs2.MOD_256APSK: if ( code_rate == dvbs2.C20_30 or code_rate == dvbs2.C22_30 or code_rate == dvbs2.C116_180 or code_rate == dvbs2.C124_180 or code_rate == dvbs2.C128_180 or code_rate == dvbs2.C135_180): pass else: sys.stderr.write("Invalid code rate for 256APSK\n"); sys.exit(1) if rolloff == dvbs2.RO_0_05: rrc_rolloff = 0.05 elif rolloff == dvbs2.RO_0_10: rrc_rolloff = 0.10 elif rolloff == dvbs2.RO_0_15: rrc_rolloff = 0.15 elif rolloff == dvbs2.RO_0_20: rrc_rolloff = 0.20 elif rolloff == dvbs2.RO_0_25: rrc_rolloff = 0.25 elif rolloff == dvbs2.RO_0_35: rrc_rolloff = 0.35 if ( code_rate == dvbs2.C3_5 or code_rate == dvbs2.C4_5 or code_rate == dvbs2.C5_6 or code_rate == dvbs2.C7_9 or code_rate == dvbs2.C13_18 or code_rate == dvbs2.C23_36 or code_rate == dvbs2.C25_36 or code_rate == dvbs2.C26_45 or code_rate == dvbs2.C28_45 or code_rate == dvbs2.C90_180 or code_rate == dvbs2.C96_180 or code_rate == dvbs2.C100_180 or code_rate == dvbs2.C116_180 or code_rate == dvbs2.C124_180 or code_rate == dvbs2.C128_180 or code_rate == dvbs2.C135_180 or code_rate == dvbs2.C140_180): code_rate_interleaver = code_rate else: code_rate_interleaver = dvbs2.C_OTHER if ( code_rate == dvbs2.C2_3 or code_rate == dvbs2.C3_4 or code_rate == dvbs2.C4_5 or code_rate == dvbs2.C5_6 or code_rate == dvbs2.C8_9 or code_rate == dvbs2.C9_10 or code_rate == dvbs2.C90_180 or code_rate == dvbs2.C96_180 or code_rate == dvbs2.C100_180 or code_rate == dvbs2.C104_180 or code_rate == dvbs2.C26_45 or code_rate == dvbs2.C18_30 or code_rate == dvbs2.C28_45 or code_rate == dvbs2.C23_36 or code_rate == dvbs2.C116_180 or code_rate == dvbs2.C20_30 or code_rate == dvbs2.C124_180 or code_rate == dvbs2.C25_36 or code_rate == dvbs2.C128_180 or code_rate == dvbs2.C13_18 or code_rate == dvbs2.C132_180 or code_rate == dvbs2.C22_30 or code_rate == dvbs2.C135_180 or code_rate == dvbs2.C140_180 or code_rate == dvbs2.C7_9 or code_rate == dvbs2.C154_180): code_rate_modulator = code_rate else: code_rate_modulator = dvbs2.C_OTHER if constellation == dvbs2.MOD_128APSK: constellation_ldpc = constellation else: constellation_ldpc = dvbs2.MOD_OTHER tb = gr.top_block() src = blocks.file_source(gr.sizeof_char, infile, True) dvbs2_bbheader = dvbs2.bbheader_bb(code_rate, rolloff, frame_size) dvbs2_bbscrambler = dvbs2.bbscrambler_bb(code_rate, frame_size) dvbs2_bch = dvbs2.bch_bb(code_rate, frame_size) dvbs2_ldpc = dvbs2.ldpc_bb(code_rate, frame_size, constellation) dvbs2_interleaver = dvbs2.interleaver_bb(constellation, code_rate_interleaver, frame_size) dvbs2_modulator = dvbs2.modulator_bc(constellation, code_rate_modulator, frame_size) dvbs2_physical = dvbs2.physical_cc(constellation, code_rate, pilots, frame_size, gold_code) fft_filter = filter.fft_filter_ccc(1, (firdes.root_raised_cosine(1, samp_rate, samp_rate/2, rrc_rolloff, rrc_taps)), 1) fft_filter.declare_sample_delay(0) out = osmosdr.sink(args="bladerf=0,buffers=128,buflen=32768") out.set_sample_rate(samp_rate) out.set_center_freq(center_freq, 0) out.set_freq_corr(0, 0) out.set_gain(txvga2_gain, 0) out.set_bb_gain(txvga1_gain, 0) out.set_bandwidth(bandwidth, 0) tb.connect(src, dvbs2_bbheader) tb.connect(dvbs2_bbheader, dvbs2_bbscrambler) tb.connect(dvbs2_bbscrambler, dvbs2_bch) tb.connect(dvbs2_bch, dvbs2_ldpc) tb.connect(dvbs2_ldpc, dvbs2_interleaver) tb.connect(dvbs2_interleaver, dvbs2_modulator) tb.connect(dvbs2_modulator, dvbs2_physical) tb.connect(dvbs2_physical, fft_filter) tb.connect(fft_filter, out) if outfile: dst = blocks.file_sink(gr.sizeof_gr_complex, outfile) tb.connect(fft_filter, dst) tb.run()
def raw_fft_filter(self, const, filters, transition): return filter.fft_filter_ccc(const, filters, transition)
def __init__(self, fft_length, cp_length, logging=False): """ OFDM synchronization using PN Correlation: T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchonization for OFDM," IEEE Trans. Communications, vol. 45, no. 12, 1997. """ gr.hier_block2.__init__(self, "ofdm_sync_pn", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) # PN Sync # Create a delay line self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2) # Correlation from ML Sync self.conjg = gr.conjugate_cc(); self.corr = gr.multiply_cc(); # Create a moving sum filter for the corr output if 1: moving_sum_taps = [1.0 for i in range(fft_length//2)] self.moving_sum_filter = filter.fir_filter_ccf(1,moving_sum_taps) else: moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)] self.moving_sum_filter = filter.fft_filter_ccc(1,moving_sum_taps) # Create a moving sum filter for the input self.inputmag2 = gr.complex_to_mag_squared() movingsum2_taps = [1.0 for i in range(fft_length//2)] if 1: self.inputmovingsum = filter.fir_filter_fff(1,movingsum2_taps) else: self.inputmovingsum = filter.fft_filter_fff(1,movingsum2_taps) self.square = gr.multiply_ff() self.normalize = gr.divide_ff() # Get magnitude (peaks) and angle (phase/freq error) self.c2mag = gr.complex_to_mag_squared() self.angle = gr.complex_to_arg() self.sample_and_hold = gr.sample_and_hold_ff() #ML measurements input to sampler block and detect self.sub1 = gr.add_const_ff(-1) self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001) #self.pk_detect = gr.peak_detector2_fb(9) self.connect(self, self.input) # Calculate the frequency offset from the correlation of the preamble self.connect(self.input, self.delay) self.connect(self.input, (self.corr,0)) self.connect(self.delay, self.conjg) self.connect(self.conjg, (self.corr,1)) self.connect(self.corr, self.moving_sum_filter) self.connect(self.moving_sum_filter, self.c2mag) self.connect(self.moving_sum_filter, self.angle) self.connect(self.angle, (self.sample_and_hold,0)) # Get the power of the input signal to normalize the output of the correlation self.connect(self.input, self.inputmag2, self.inputmovingsum) self.connect(self.inputmovingsum, (self.square,0)) self.connect(self.inputmovingsum, (self.square,1)) self.connect(self.square, (self.normalize,1)) self.connect(self.c2mag, (self.normalize,0)) # Create a moving sum filter for the corr output matched_filter_taps = [1.0/cp_length for i in range(cp_length)] self.matched_filter = filter.fir_filter_fff(1,matched_filter_taps) self.connect(self.normalize, self.matched_filter) self.connect(self.matched_filter, self.sub1, self.pk_detect) #self.connect(self.matched_filter, self.pk_detect) self.connect(self.pk_detect, (self.sample_and_hold,1)) # Set output signals # Output 0: fine frequency correction value # Output 1: timing signal self.connect(self.sample_and_hold, (self,0)) self.connect(self.pk_detect, (self,1)) if logging: self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-mf_f.dat")) self.connect(self.normalize, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-theta_f.dat")) self.connect(self.angle, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-epsilon_f.dat")) self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "ofdm_sync_pn-peaks_b.dat")) self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat")) self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_pn-input_c.dat"))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Dvbs2 Tx") ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 5000000 self.taps = taps = 50 self.samp_rate = samp_rate = symbol_rate * 2 self.rolloff = rolloff = 0.2 ################################################## # Blocks ################################################## self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=1280000000, 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=True, avg_alpha=0.13333, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.osmosdr_sink_0 = osmosdr.sink(args="numchan=" + str(1) + " " + "bladerf=0,buffers=128,buflen=32768") self.osmosdr_sink_0.set_sample_rate(samp_rate) self.osmosdr_sink_0.set_center_freq(1280e6, 0) self.osmosdr_sink_0.set_freq_corr(0, 0) self.osmosdr_sink_0.set_gain(15, 0) self.osmosdr_sink_0.set_if_gain(0, 0) self.osmosdr_sink_0.set_bb_gain(-10, 0) self.osmosdr_sink_0.set_antenna("", 0) self.osmosdr_sink_0.set_bandwidth(6000000, 0) self.fft_filter_xxx_0 = filter.fft_filter_ccc( 1, (firdes.root_raised_cosine(1, samp_rate, samp_rate / 2, rolloff, taps)), 1 ) self.fft_filter_xxx_0.declare_sample_delay(0) self.dvbs2_physical_cc_0 = dvbs2.physical_cc( dvbs2.MOD_16APSK, dvbs2.C9_10, dvbs2.PILOTS_ON, dvbs2.FECFRAME_NORMAL, 0 ) self.dvbs2_modulator_bc_0 = dvbs2.modulator_bc(dvbs2.MOD_16APSK, dvbs2.C9_10, dvbs2.FECFRAME_NORMAL) self.dvbs2_ldpc_bb_0 = dvbs2.ldpc_bb(dvbs2.C9_10, dvbs2.FECFRAME_NORMAL, dvbs2.MOD_OTHER) self.dvbs2_interleaver_bb_0 = dvbs2.interleaver_bb(dvbs2.MOD_16APSK, dvbs2.C_OTHER, dvbs2.FECFRAME_NORMAL) self.dvbs2_bch_bb_0 = dvbs2.bch_bb(dvbs2.C9_10, dvbs2.FECFRAME_NORMAL) self.dvbs2_bbscrambler_bb_0 = dvbs2.bbscrambler_bb(dvbs2.C9_10, dvbs2.FECFRAME_NORMAL) self.dvbs2_bbheader_bb_0 = dvbs2.bbheader_bb(dvbs2.C9_10, dvbs2.RO_0_20, dvbs2.FECFRAME_NORMAL) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char * 1, "/run/shm/adv16apsk910.ts", True) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.dvbs2_bbheader_bb_0, 0)) self.connect((self.dvbs2_bbheader_bb_0, 0), (self.dvbs2_bbscrambler_bb_0, 0)) self.connect((self.dvbs2_bbscrambler_bb_0, 0), (self.dvbs2_bch_bb_0, 0)) self.connect((self.dvbs2_bch_bb_0, 0), (self.dvbs2_ldpc_bb_0, 0)) self.connect((self.dvbs2_ldpc_bb_0, 0), (self.dvbs2_interleaver_bb_0, 0)) self.connect((self.dvbs2_interleaver_bb_0, 0), (self.dvbs2_modulator_bc_0, 0)) self.connect((self.dvbs2_modulator_bc_0, 0), (self.dvbs2_physical_cc_0, 0)) self.connect((self.dvbs2_physical_cc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.osmosdr_sink_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0))
def __init__(self, dab_params, rx_params, verbose=False, debug=False): """ Hierarchical block for OFDM demodulation @param dab_params DAB parameter object (dab.parameters.dab_parameters) @param rx_params RX parameter object (dab.parameters.receiver_parameters) @param debug enables debug output to files @param verbose whether to produce verbose messages """ self.dp = dp = dab_params self.rp = rp = rx_params self.verbose = verbose if self.rp.softbits: gr.hier_block2.__init__(self,"ofdm_demod", gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_float*self.dp.num_carriers*2, gr.sizeof_char)) # output signature else: gr.hier_block2.__init__(self,"ofdm_demod", gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_char*self.dp.num_carriers/4, gr.sizeof_char)) # output signature # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) #self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.input = blocks.multiply_const_cc(1.0) # FIXME self.connect(self, self.input) # input filtering if self.rp.input_fft_filter: if verbose: print "--> RX filter enabled" lowpass_taps = filter.firdes_low_pass(1.0, # gain dp.sample_rate, # sampling rate rp.filt_bw, # cutoff frequency rp.filt_tb, # width of transition band filter.firdes.WIN_HAMMING) # Hamming window self.fft_filter = filter.fft_filter_ccc(1, lowpass_taps) # correct sample rate offset, if enabled if self.rp.autocorrect_sample_rate: if verbose: print "--> dynamic sample rate correction enabled" self.rate_detect_ns = dab.detect_null(dp.ns_length, False) self.rate_estimator = dab.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length) self.rate_prober = blocks.probe_signal_f() self.connect(self.input, self.rate_detect_ns, self.rate_estimator, self.rate_prober) # self.resample = gr.fractional_interpolator_cc(0, 1) self.resample = dab.fractional_interpolator_triggered_update_cc(0,1) self.connect(self.rate_detect_ns, (self.resample,1)) self.updater = Timer(0.1,self.update_correction) # self.updater = threading.Thread(target=self.update_correction) self.run_interpolater_update_thread = True self.updater.setDaemon(True) self.updater.start() else: self.run_interpolater_update_thread = False if self.rp.sample_rate_correction_factor != 1: if verbose: print "--> static sample rate correction enabled" self.resample = gr.fractional_interpolator_cc(0, self.rp.sample_rate_correction_factor) # timing and fine frequency synchronisation self.sync = dab.ofdm_sync_dab2(self.dp, self.rp, debug) # ofdm symbol sampler self.sampler = dab.ofdm_sampler(dp.fft_length, dp.cp_length, dp.symbols_per_frame, rp.cp_gap) # fft for symbol vectors self.fft = fft.fft_vcc(dp.fft_length, True, [], True) # coarse frequency synchronisation self.cfs = dab.ofdm_coarse_frequency_correct(dp.fft_length, dp.num_carriers, dp.cp_length) # diff phasor self.phase_diff = dab.diff_phasor_vcc(dp.num_carriers) # remove pilot symbol self.remove_pilot = dab.ofdm_remove_first_symbol_vcc(dp.num_carriers) # magnitude equalisation if self.rp.equalize_magnitude: if verbose: print "--> magnitude equalization enabled" self.equalizer = dab.magnitude_equalizer_vcc(dp.num_carriers, rp.symbols_for_magnitude_equalization) # frequency deinterleaving self.deinterleave = dab.frequency_interleaver_vcc(dp.frequency_deinterleaving_sequence_array) # symbol demapping self.demapper = dab.qpsk_demapper_vcb(dp.num_carriers) # # connect everything # if self.rp.autocorrect_sample_rate or self.rp.sample_rate_correction_factor != 1: self.connect(self.input, self.resample) self.input2 = self.resample else: self.input2 = self.input if self.rp.input_fft_filter: self.connect(self.input2, self.fft_filter, self.sync) else: self.connect(self.input2, self.sync) # data stream self.connect((self.sync, 0), (self.sampler, 0), self.fft, (self.cfs, 0), self.phase_diff, (self.remove_pilot,0)) if self.rp.equalize_magnitude: self.connect((self.remove_pilot,0), (self.equalizer,0), self.deinterleave) else: self.connect((self.remove_pilot,0), self.deinterleave) if self.rp.softbits: if verbose: print "--> using soft bits" self.softbit_interleaver = dab.complex_to_interleaved_float_vcf(self.dp.num_carriers) self.connect(self.deinterleave, self.softbit_interleaver, (self,0)) else: self.connect(self.deinterleave, self.demapper, (self,0)) # control stream self.connect((self.sync, 1), (self.sampler, 1), (self.cfs, 1), (self.remove_pilot,1)) if self.rp.equalize_magnitude: self.connect((self.remove_pilot,1), (self.equalizer,1), (self,1)) else: self.connect((self.remove_pilot,1), (self,1)) # calculate an estimate of the SNR self.phase_var_decim = blocks.keep_one_in_n(gr.sizeof_gr_complex*self.dp.num_carriers, self.rp.phase_var_estimate_downsample) self.phase_var_arg = blocks.complex_to_arg(dp.num_carriers) self.phase_var_v2s = blocks.vector_to_stream(gr.sizeof_float, dp.num_carriers) self.phase_var_mod = dab.modulo_ff(pi/2) self.phase_var_avg_mod = filter.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) self.phase_var_sub_avg = blocks.sub_ff() self.phase_var_sqr = blocks.multiply_ff() self.phase_var_avg = filter.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) self.probe_phase_var = blocks.probe_signal_f() self.connect((self.remove_pilot,0), self.phase_var_decim, self.phase_var_arg, self.phase_var_v2s, self.phase_var_mod, (self.phase_var_sub_avg,0), (self.phase_var_sqr,0)) self.connect(self.phase_var_mod, self.phase_var_avg_mod, (self.phase_var_sub_avg,1)) self.connect(self.phase_var_sub_avg, (self.phase_var_sqr,1)) self.connect(self.phase_var_sqr, self.phase_var_avg, self.probe_phase_var) # measure processing rate self.measure_rate = dab.measure_processing_rate(gr.sizeof_gr_complex, 2000000) self.connect(self.input, self.measure_rate) # debugging if debug: self.connect(self.fft, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/ofdm_after_fft.dat")) self.connect((self.cfs,0), blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_after_cfs.dat")) self.connect(self.phase_diff, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_diff_phasor.dat")) self.connect((self.remove_pilot,0), blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_pilot_removed.dat")) self.connect((self.remove_pilot,1), blocks.file_sink(gr.sizeof_char, "debug/ofdm_after_cfs_trigger.dat")) self.connect(self.deinterleave, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_deinterleaved.dat")) if self.rp.equalize_magnitude: self.connect(self.equalizer, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_equalizer.dat")) if self.rp.softbits: self.connect(self.softbit_interleaver, blocks.file_sink(gr.sizeof_float*dp.num_carriers*2, "debug/softbits.dat"))
def main(): N = 10000 fs = 2000.0 Ts = 1.0 / fs t = scipy.arange(0, N*Ts, Ts) # When playing with the number of channels, be careful about the filter # specs and the channel map of the synthesizer set below. nchans = 10 # Build the filter(s) bw = 1000 tb = 400 proto_taps = filter.firdes.low_pass_2(1, nchans*fs, bw, tb, 80, filter.firdes.WIN_BLACKMAN_hARRIS) print("Filter length: ", len(proto_taps)) # Create a modulated signal npwr = 0.01 data = scipy.random.randint(0, 256, N) rrc_taps = filter.firdes.root_raised_cosine(1, 2, 1, 0.35, 41) src = blocks.vector_source_b(data.astype(scipy.uint8).tolist(), False) mod = digital.bpsk_mod(samples_per_symbol=2) chan = channels.channel_model(npwr) rrc = filter.fft_filter_ccc(1, rrc_taps) # Split it up into pieces channelizer = filter.pfb.channelizer_ccf(nchans, proto_taps, 2) # Put the pieces back together again syn_taps = [nchans*t for t in proto_taps] synthesizer = filter.pfb_synthesizer_ccf(nchans, syn_taps, True) src_snk = blocks.vector_sink_c() snk = blocks.vector_sink_c() # Remap the location of the channels # Can be done in synth or channelizer (watch out for rotattions in # the channelizer) synthesizer.set_channel_map([ 0, 1, 2, 3, 4, 15, 16, 17, 18, 19]) tb = gr.top_block() tb.connect(src, mod, chan, rrc, channelizer) tb.connect(rrc, src_snk) vsnk = [] for i in range(nchans): tb.connect((channelizer,i), (synthesizer, i)) vsnk.append(blocks.vector_sink_c()) tb.connect((channelizer,i), vsnk[i]) tb.connect(synthesizer, snk) tb.run() sin = scipy.array(src_snk.data()[1000:]) sout = scipy.array(snk.data()[1000:]) # Plot original signal fs_in = nchans*fs f1 = pylab.figure(1, figsize=(16,12), facecolor='w') s11 = f1.add_subplot(2,2,1) s11.psd(sin, NFFT=fftlen, Fs=fs_in) s11.set_title("PSD of Original Signal") s11.set_ylim([-200, -20]) s12 = f1.add_subplot(2,2,2) s12.plot(sin.real[1000:1500], "o-b") s12.plot(sin.imag[1000:1500], "o-r") s12.set_title("Original Signal in Time") start = 1 skip = 2 s13 = f1.add_subplot(2,2,3) s13.plot(sin.real[start::skip], sin.imag[start::skip], "o") s13.set_title("Constellation") s13.set_xlim([-2, 2]) s13.set_ylim([-2, 2]) # Plot channels nrows = int(scipy.sqrt(nchans)) ncols = int(scipy.ceil(float(nchans) / float(nrows))) f2 = pylab.figure(2, figsize=(16,12), facecolor='w') for n in range(nchans): s = f2.add_subplot(nrows, ncols, n+1) s.psd(vsnk[n].data(), NFFT=fftlen, Fs=fs_in) s.set_title("Channel {0}".format(n)) s.set_ylim([-200, -20]) # Plot reconstructed signal fs_out = 2*nchans*fs f3 = pylab.figure(3, figsize=(16,12), facecolor='w') s31 = f3.add_subplot(2,2,1) s31.psd(sout, NFFT=fftlen, Fs=fs_out) s31.set_title("PSD of Reconstructed Signal") s31.set_ylim([-200, -20]) s32 = f3.add_subplot(2,2,2) s32.plot(sout.real[1000:1500], "o-b") s32.plot(sout.imag[1000:1500], "o-r") s32.set_title("Reconstructed Signal in Time") start = 0 skip = 4 s33 = f3.add_subplot(2,2,3) s33.plot(sout.real[start::skip], sout.imag[start::skip], "o") s33.set_title("Constellation") s33.set_xlim([-2, 2]) s33.set_ylim([-2, 2]) pylab.show()
def __init__(self, rx_channels, fft_length, cp_length, occupied_tones, snr, ks, logging=False): """ Hierarchical block for receiving OFDM symbols. The input is the complex modulated signal at baseband. Synchronized packets are sent back to the demodulator. Args: fft_length: total number of subcarriers (int) cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length) (int) occupied_tones: number of subcarriers used for data (int) snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer (float) ks: known symbols used as preambles to each packet (list of lists) logging: turn file logging on or off (bool) """ self.rx_channels = rx_channels gr.hier_block2.__init__(self, "ofdm_receiver", gr.io_signaturev(self.rx_channels, self.rx_channels, gen_multiple_ios(self.rx_channels)), # Input signature gr.io_signaturev(self.rx_channels*2, self.rx_channels*2, gen_multiple_ios_out(self.rx_channels-1,occupied_tones,fft_length) )) # Output signature bw = (float(occupied_tones) / float(fft_length)) / 2.0 tb = bw*0.08 chan_coeffs = filter.firdes.low_pass (1.0, # gain 1.0, # sampling rate bw+tb, # midpoint of trans. band tb, # width of trans. band filter.firdes.WIN_HAMMING) # filter type self.chan_filt = filter.fft_filter_ccc(1, chan_coeffs) win = [1 for i in range(fft_length)] zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0)) ks0 = fft_length*[0,] ks0[zeros_on_left : zeros_on_left + occupied_tones] = ks[0] ks0 = fft.ifftshift(ks0) ks0time = fft.ifft(ks0) # ADD SCALING FACTOR ks0time = ks0time.tolist() SYNC = "pn" if SYNC == "ml": nco_sensitivity = -1.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, ks0time, logging) elif SYNC == "pn": # Schmidl & Cox Method nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, logging) elif SYNC == "pnac": nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time, logging) # for testing only; do not user over the air # remove filter and filter delay for this elif SYNC == "fixed": self.chan_filt = blocks.multiply_const_cc(1.0) nsymbols = 18 # enter the number of symbols per packet freq_offset = 0.0 # if you use a frequency offset, enter it here nco_sensitivity = -2.0/fft_length # correct for fine frequency self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, nsymbols, freq_offset, logging) # Set up blocks self.nco = analog.frequency_modulator_fc(nco_sensitivity) # generate a signal proportional to frequency error of sync block self.sigmix = blocks.multiply_cc() self.sampler = digital.ofdm_sampler(fft_length, fft_length+cp_length) self.fft_demod = gr_fft.fft_vcc(fft_length, True, win, True) self.ofdm_frame_acq = digital.ofdm_frame_acquisition(occupied_tones,fft_length,cp_length, ks[0]) # Setup Connections for synchronization path self.connect((self,0), self.chan_filt) # filter the input channel self.connect(self.chan_filt, self.ofdm_sync) # into the synchronization alg. self.connect((self.ofdm_sync,0), self.nco, (self.sigmix,1)) # use sync freq. offset output to derotate input signal self.connect(self.chan_filt, (self.sigmix,0)) # signal to be derotated self.connect(self.sigmix, (self.sampler,0)) # sample off timing signal detected in sync alg self.connect((self.ofdm_sync,1), (self.sampler,1)) # timing signal to sample at self.connect((self.sampler,0), self.fft_demod) # send derotated sampled signal to FFT self.connect(self.fft_demod, (self.ofdm_frame_acq,0)) # find frame start and equalize signal self.connect((self.sampler,1), (self.ofdm_frame_acq,1)) # send timing signal to signal frame start self.connect((self.ofdm_frame_acq,0), (self,0)) # finished with fine/coarse freq correction, self.connect((self.ofdm_frame_acq,1), (self,1)) # frame and symbol timing, and equalization # Debugging # self.connect(self.fft_demod, (self,2)) # Output unequalized signal ############ BLOCK OUTPUTS # ofdm_frame_acquisition (0,occupied carriers) # ofdm_frame_acquisition (1,flag) # .... Repeats for each input ########################## # Add additional channels for each radio output = 2 for p in range(1,self.rx_channels): print "ofdm_receiver: "+str(p) # Add channel filter object_name_cf = 'chan_filter_'+str(p) setattr(self, object_name_cf, filter.fft_filter_ccc(1, chan_coeffs) ) # Connect hier to channel filter self.connect((self,p), (getattr(self,object_name_cf), 0)) # Add Mixer object_name_sm = 'sigmix_'+str(p) setattr(self, object_name_sm, blocks.multiply_cc()) # Connect channel filter to mixer self.connect((getattr(self,object_name_cf), 0), (getattr(self,object_name_sm), 0)) # Connect nco to mixer self.connect( self.nco, (getattr(self,object_name_sm), 1) ) # Add ofdm sampler object_name_sp = 'sampler_'+str(p) # setattr(self, object_name_sp, copy.copy(self.sampler)) # not copiable setattr(self, object_name_sp, digital.ofdm_sampler(fft_length, fft_length+cp_length)) # Connect mixer to sampler self.connect((getattr(self,object_name_sm), 0), (getattr(self,object_name_sp), 0)) # Connect timing signal to sampler self.connect((self.ofdm_sync,1), (getattr(self,object_name_sp), 1)) # Add FFT object_name_fft = 'fft_'+str(p) # setattr(self, object_name_fft, copy.copy(self.fft_demod)) setattr(self, object_name_fft, gr_fft.fft_vcc(fft_length, True, win, True)) # Connect sampler to FFT self.connect((getattr(self,object_name_sp), 0), (getattr(self,object_name_fft), 0)) # Add frame acquistion object_name_fa = 'ofdm_frame_ac_'+str(p) setattr(self, object_name_fa, digital.ofdm_frame_acquisition(occupied_tones,fft_length,cp_length, ks[0])) # Connect FFT to frame acquistion self.connect((getattr(self,object_name_fft), 0), (getattr(self,object_name_fa), 0)) # Connect sampler to frame acquistion self.connect((getattr(self,object_name_sp), 1), (getattr(self,object_name_fa), 1)) # Add frame acquistion outputs to hier self.connect((getattr(self,object_name_fa), 0), (self, output)) output = output + 1 self.connect((getattr(self,object_name_fa), 1), (self, output)) output = output + 1 # ############# NULLS ############# # # Add Null sink for unused inputs # object_name_nb = 'null_sink_'+str(p) # setattr(self, object_name_nb, blocks.null_sink(gr.sizeof_gr_complex*1)) # # Connect # self.connect((self, p+1), (getattr(self,object_name_nb), 0)) if logging: self.connect(self.chan_filt, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-chan_filt_c.dat")) self.connect(self.fft_demod, blocks.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-fft_out_c.dat")) self.connect(self.ofdm_frame_acq, blocks.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_receiver-frame_acq_c.dat")) self.connect((self.ofdm_frame_acq,1), blocks.file_sink(1, "ofdm_receiver-found_corr_b.dat")) self.connect(self.sampler, blocks.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_receiver-sampler_c.dat")) self.connect(self.sigmix, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-sigmix_c.dat")) self.connect(self.nco, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_receiver-nco_c.dat"))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Dvbs Tx") ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 4500000 self.samp_rate = samp_rate = symbol_rate * 2 self.rrc_taps = rrc_taps = 20 ################################################## # Blocks ################################################## self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=435000000, 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=True, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.trellis_encoder_xx_0 = trellis.encoder_bb(trellis.fsm(1, 2, (0171, 0133)), 0) self.osmosdr_sink_0 = osmosdr.sink( args="numchan=" + str(1) + " " + "" ) self.osmosdr_sink_0.set_sample_rate(samp_rate) self.osmosdr_sink_0.set_center_freq(435e6, 0) self.osmosdr_sink_0.set_freq_corr(0, 0) self.osmosdr_sink_0.set_gain(2, 0) self.osmosdr_sink_0.set_if_gain(0, 0) self.osmosdr_sink_0.set_bb_gain(-4, 0) self.osmosdr_sink_0.set_antenna("", 0) self.osmosdr_sink_0.set_bandwidth(6000000, 0) self.fft_filter_xxx_0 = filter.fft_filter_ccc(1, (firdes.root_raised_cosine(1.79, samp_rate, samp_rate/2, 0.35, rrc_taps)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.dvbs_reed_solomon_enc_bb_0 = dvbs.reed_solomon_enc_bb() self.dvbs_randomizer_bb_0 = dvbs.randomizer_bb() self.dvbs_puncture_bb_0 = dvbs.puncture_bb(dvbs.C1_2) self.dvbs_modulator_bc_0 = dvbs.modulator_bc() self.dvbs_interleaver_bb_0 = dvbs.interleaver_bb() self.blocks_unpack_k_bits_bb_0 = blocks.unpack_k_bits_bb(2) self.blocks_packed_to_unpacked_xx_0 = blocks.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) self.blocks_pack_k_bits_bb_0 = blocks.pack_k_bits_bb(2) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char*1, "/home/re/xfer/adv.ts", False) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.dvbs_randomizer_bb_0, 0)) self.connect((self.dvbs_randomizer_bb_0, 0), (self.dvbs_reed_solomon_enc_bb_0, 0)) self.connect((self.dvbs_reed_solomon_enc_bb_0, 0), (self.dvbs_interleaver_bb_0, 0)) self.connect((self.dvbs_interleaver_bb_0, 0), (self.blocks_packed_to_unpacked_xx_0, 0)) self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.blocks_unpack_k_bits_bb_0, 0)) self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.dvbs_puncture_bb_0, 0)) self.connect((self.dvbs_puncture_bb_0, 0), (self.blocks_pack_k_bits_bb_0, 0)) self.connect((self.dvbs_modulator_bc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.blocks_pack_k_bits_bb_0, 0), (self.dvbs_modulator_bc_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.osmosdr_sink_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0))
def main(args): nargs = len(args) if nargs == 1: infile = args[0] outfile = None elif nargs == 2: infile = args[0] outfile = args[1] else: sys.stderr.write("Usage: dvbs-blade.py input_file [output_file]\n") sys.exit(1) symbol_rate = 4500000 samp_rate = symbol_rate * 2 code_rate = dvbs.C1_2 rrc_taps = 20 center_freq = 435000000 txvga1_gain = -4 txvga2_gain = 1 bandwidth = 6000000 tb = gr.top_block() src = blocks.file_source(gr.sizeof_char, infile, True) dvbs_randomizer = dvbs.randomizer_bb() dvbs_reed_solomon_enc = dvbs.reed_solomon_enc_bb() dvbs_interleaver = dvbs.interleaver_bb() blocks_packed_to_unpacked = blocks.packed_to_unpacked_bb( 1, gr.GR_MSB_FIRST) trellis_encoder = trellis.encoder_bb(trellis.fsm(1, 2, (0171, 0133)), 0) blocks_unpack_k_bits = blocks.unpack_k_bits_bb(2) dvbs_puncture = dvbs.puncture_bb(code_rate) blocks_pack_k_bits = blocks.pack_k_bits_bb(2) dvbs_modulator = dvbs.modulator_bc() fft_filter = filter.fft_filter_ccc(1, (firdes.root_raised_cosine( 1.79, samp_rate, samp_rate / 2, 0.35, rrc_taps)), 1) fft_filter.declare_sample_delay(0) out = osmosdr.sink(args="bladerf=0,buffers=128,buflen=32768") out.set_sample_rate(samp_rate) out.set_center_freq(center_freq, 0) out.set_freq_corr(0, 0) out.set_gain(txvga2_gain, 0) out.set_bb_gain(txvga1_gain, 0) out.set_bandwidth(bandwidth, 0) tb.connect(src, dvbs_randomizer) tb.connect(dvbs_randomizer, dvbs_reed_solomon_enc) tb.connect(dvbs_reed_solomon_enc, dvbs_interleaver) tb.connect(dvbs_interleaver, blocks_packed_to_unpacked) tb.connect(blocks_packed_to_unpacked, trellis_encoder) tb.connect(trellis_encoder, blocks_unpack_k_bits) tb.connect(blocks_unpack_k_bits, dvbs_puncture) tb.connect(dvbs_puncture, blocks_pack_k_bits) tb.connect(blocks_pack_k_bits, dvbs_modulator) tb.connect(dvbs_modulator, fft_filter) tb.connect(fft_filter, out) if outfile: dst = blocks.file_sink(gr.sizeof_gr_complex, outfile) tb.connect(fft_filter, dst) tb.run()
def __init__(self, cp_len=32, fft_len=64, max_fft_shift=4, occupied_carriers=48, ports=2): gr.hier_block2.__init__( self, "OFDM Mutichannel Recover", gr.io_signaturev( 2, 2, [gr.sizeof_gr_complex * 1, gr.sizeof_gr_complex * 1]), gr.io_signaturev(2, 2, [ gr.sizeof_gr_complex * occupied_carriers, gr.sizeof_gr_complex * occupied_carriers ]), ) self.message_port_register_hier_out("packet") self.message_port_register_hier_out("header_dfe") ################################################## # Parameters ################################################## self.cp_len = cp_len self.fft_len = fft_len self.max_fft_shift = max_fft_shift self.occupied_carriers = occupied_carriers self.ports = ports ################################################## # Variables ################################################## self.rcvd_pktq = rcvd_pktq = gr.msg_queue() self.modulation = modulation = 'bpsk' self.mods = mods = { "bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256 } self.bw = bw = (float(occupied_carriers) / float(fft_len)) / 2.0 self.watcher = watcher = pp._queue_watcher_thread(rcvd_pktq) self.tb = tb = bw * 0.08 self.samp_rate = samp_rate = 32000 self.rotated_const = rotated_const = gp.gen_framer_info(modulation) self.phgain = phgain = 0.25 self.arity = arity = mods[modulation] ################################################## # Blocks ################################################## self.ofdm_sync_channel_0 = ofdm_sync_channel( cp_len=cp_len, fftlen=fft_len, max_fft_shift=max_fft_shift, occupied_carriers=occupied_carriers, ) self.ofdm_packet_sync_0 = ofdm_packet_sync( cp_len=cp_len, fft_len=fft_len, ) self.fft_filter_xxx_0 = filter.fft_filter_ccc( 1, (filter.firdes.low_pass(1.0, 1.0, bw + tb, tb, filter.firdes.WIN_HAMMING)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.ofdm_ofdm_mrx_frame_sink_0 = ofdm.ofdm_mrx_frame_sink( rotated_const, range(arity), rcvd_pktq, occupied_carriers, phgain, phgain * phgain / 4.0, ports) for p in range(ports - 1): # Add OFDM Sync Channel object_name_osc = 'ofdm_sync_channel_' + str(p + 1) setattr( self, object_name_osc, ofdm_sync_channel( cp_len=cp_len, fftlen=fft_len, max_fft_shift=max_fft_shift, occupied_carriers=occupied_carriers, )) # Add FFT Filter object_name_ft = 'fft_filter_ccc_' + str(p + 1) setattr( self, object_name_ft, filter.fft_filter_ccc(1, (filter.firdes.low_pass( 1.0, 1.0, bw + tb, tb, filter.firdes.WIN_HAMMING)), 1)) # self.fft_filter_xxx_0_0.declare_sample_delay(0) setattr(getattr(self, object_name_ft), 'declare_sample_delay', 0) # Add null sink object_name_ns = 'blocks_null_sink_' + str(p + 1) setattr(self, object_name_ns, blocks.null_sink(gr.sizeof_char * 1)) ### Connections # Pad to FFT Filter self.connect((self, p + 1), (getattr(self, object_name_ft), 0)) # FFT Filt to OFS self.connect((getattr(self, object_name_ft), 0), (getattr(self, object_name_osc), 0)) # PS To OFDM SC self.connect((self.ofdm_packet_sync_0, 0), (getattr(self, object_name_osc), 2)) self.connect((self.ofdm_packet_sync_0, 1), (getattr(self, object_name_osc), 1)) # OSC To OFDM Frame Sink self.connect((getattr(self, object_name_osc), 1), (self.ofdm_sync_channel_0, p + 2)) # OSC To Null Sink self.connect((getattr(self, object_name_osc), 0), (self.blocks_null_sink_0, 0)) # OFDM Frame Sink to Pad self.connect((self.ofdm_ofdm_mrx_frame_sink_0, p), (self, p)) ################################################## # Connections ################################################## self.connect((self, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.ofdm_packet_sync_0, 0)) self.connect((self.ofdm_packet_sync_0, 0), (self.ofdm_sync_channel_0, 2)) self.connect((self.ofdm_packet_sync_0, 1), (self.ofdm_sync_channel_0, 1)) self.connect((self.ofdm_packet_sync_0, 2), (self.ofdm_sync_channel_0, 0)) self.connect((self.ofdm_sync_channel_0, 0), (self.ofdm_ofdm_mrx_frame_sink_0, 0)) # Flag self.connect((self.ofdm_sync_channel_0, 1), (self.ofdm_ofdm_mrx_frame_sink_0, 1)) self.msg_connect((self.ofdm_ofdm_mrx_frame_sink_0, 'packet'), (self, 'packet')) self.msg_connect((self.ofdm_ofdm_mrx_frame_sink_0, 'header_dfe'), (self, 'header_dfe'))
def __init__( self, carrier, sideband, transition, sps, interpolation, lomicdev, listen=False): gr.top_block.__init__(self, "Receive block") ################################################## # Variables ################################################## self.samp_rate = SAMPLE_RATE self.carrier = carrier self.sideband = sideband self.transition = transition self.sps = sps self.interpolation = interpolation ################################################## # Blocks ################################################## self.rational_resampler_xxx_0_0_0 = filter.rational_resampler_ccc( interpolation=1, decimation=interpolation, taps=None, fractional_bw=None, ) self.freq_xlating_fir_filter_xxx_0_0 = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1,SAMPLE_RATE,sideband,transition)), carrier, SAMPLE_RATE) self.digital_gfsk_demod_0 = digital.gfsk_demod( samples_per_symbol=sps, sensitivity=1.0, gain_mu=0.175, mu=0.5, omega_relative_limit=0.005, freq_error=0.0, verbose=False, log=False, ) self.blocks_float_to_complex_0 = blocks.float_to_complex(1) self.blks2_packet_decoder_0 = grc_blks2.packet_demod_b(grc_blks2.packet_decoder( access_code="", threshold=-1, callback=lambda ok, payload: self.blks2_packet_decoder_0.recv_pkt(ok, payload), ), ) self.audio_source_0 = audio.source(SAMPLE_RATE, lomicdev, True) if listen: self.audio_sink_0_tmp = audio.sink(SAMPLE_RATE, 'plughw:0,0', True) self.fft_filter_xxx_1 = filter.fft_filter_ccc(1, (firdes.complex_band_pass_2(1.0,SAMPLE_RATE,carrier-sideband,carrier+sideband,transition,100,firdes.WIN_HAMMING,6.76)), 1) self.fft_filter_xxx_1.declare_sample_delay(0) self.sink_queue = gr.msg_queue() self.msg_sink = blocks.message_sink(gr.sizeof_char, self.sink_queue, False) ################################################## # Connections ################################################## self.connect((self.blks2_packet_decoder_0, 0), (self.msg_sink, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0_0, 0), (self.rational_resampler_xxx_0_0_0, 0)) self.connect((self.digital_gfsk_demod_0, 0), (self.blks2_packet_decoder_0, 0)) self.connect((self.audio_source_0, 0), (self.blocks_float_to_complex_0, 0)) self.connect((self.blocks_float_to_complex_0, 0), (self.fft_filter_xxx_1, 0)) self.connect((self.fft_filter_xxx_1, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) self.connect((self.rational_resampler_xxx_0_0_0, 0), (self.digital_gfsk_demod_0, 0)) # sound playback if listen: self.connect((self.audio_source_0, 0), (self.audio_sink_0_tmp, 0))
def __init__(self, constellation, frame_type, code_rate): gr.top_block.__init__(self, "Dvbs2 Tx") ################################################## # Parameters ################################################## # Header is 10 bytes try: frame_length = 1.0 * BBFRAME_LENGTH[frame_type][code_rate] - 80 except KeyError: raise UnknownFrameLength(frame_type, code_rate) # print("Base frame length: %s" % frame_length) frame_length /= 8 # print("Base frame length: %s" % frame_length) assert int( frame_length ) == 1.0 * frame_length, "Frame length {0} won't work because {0}/8 = {1}!".format( frame_length, frame_length / 8.0) frame_length = int(frame_length) self.frame_length = frame_length bits_per_input, bits_per_output = get_ratio(constellation) ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 5000000 self.taps = taps = 100 self.samp_rate = samp_rate = symbol_rate * 2 self.rolloff = rolloff = 0.2 self.noise = noise = 0 self.gain = gain = 1 self.center_freq = center_freq = 1280e6 ################################################## # Blocks ################################################## self.ldpc_encoder_input = blocks.file_sink(gr.sizeof_char * 1, 'ldpc_encoder_input.bin', False) self.ldpc_encoder_input.set_unbuffered(False) self.fir_filter_xxx_0_0 = filter.fir_filter_ccc( 1, (numpy.conj([ 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j ] + [ 0, ] * (89 - 32)))) self.fir_filter_xxx_0_0.declare_sample_delay(0) self.fir_filter_xxx_0 = filter.fir_filter_ccc(1, (numpy.conj([ 0, ] * (89 - 25) + [ 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 - 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 1.00000j, 0.00000 + 0.00000j ]))) self.fir_filter_xxx_0.declare_sample_delay(0) self.fft_filter_xxx_0 = filter.fft_filter_ccc( 1, (firdes.root_raised_cosine(1.0, samp_rate, samp_rate / 2, rolloff, taps)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.dtv_dvbs2_physical_cc_0 = dtv.dvbs2_physical_cc( frame_type, code_rate, dtv.MOD_BPSK, dtv.PILOTS_ON, 0) self.dtv_dvbs2_modulator_bc_0 = dtv.dvbs2_modulator_bc( frame_type, code_rate, dtv.MOD_BPSK, dtv.INTERPOLATION_OFF) self.dtv_dvbs2_interleaver_bb_0 = dtv.dvbs2_interleaver_bb( frame_type, code_rate, constellation) self.dtv_dvb_ldpc_bb_0 = dtv.dvb_ldpc_bb(dtv.STANDARD_DVBS2, frame_type, code_rate, dtv.MOD_OTHER) self.dtv_dvb_bch_bb_0 = dtv.dvb_bch_bb(dtv.STANDARD_DVBS2, frame_type, code_rate) self.dtv_dvb_bbscrambler_bb_0 = dtv.dvb_bbscrambler_bb( dtv.STANDARD_DVBS2, frame_type, code_rate) self.dtv_dvb_bbheader_bb_0 = dtv.dvb_bbheader_bb( dtv.STANDARD_DVBS2, frame_type, code_rate, dtv.RO_0_20, dtv.INPUTMODE_NORMAL, dtv.INBAND_OFF, 168, 4000000) self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf( 2, math.pi / 100.0, (firdes.root_raised_cosine( 2 * 32, 32, 1.0 / float(2), 0.35, 11 * 2 * 32)), 32, 16, 1.5, 1) self.digital_costas_loop_cc_0 = digital.costas_loop_cc( math.pi / 100.0, 4, False) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float * 1, samp_rate / 10, True) self.blocks_sub_xx_0 = blocks.sub_cc(1) self.blocks_repack_bits_bb_0 = blocks.repack_bits_bb( bits_per_input, bits_per_output, "", False, gr.GR_MSB_FIRST) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vcc((gain, )) self.blocks_max_xx_0 = blocks.max_ff(1, 1) self.blocks_file_sink_1 = blocks.file_sink(gr.sizeof_float * 1, 'output.bin', False) self.blocks_file_sink_1.set_unbuffered(False) self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex * 1, 1) self.blocks_conjugate_cc_0 = blocks.conjugate_cc() self.blocks_complex_to_mag_0_0 = blocks.complex_to_mag(1) self.blocks_complex_to_mag_0 = blocks.complex_to_mag(1) self.blocks_add_xx_2 = blocks.add_vcc(1) self.blocks_add_xx_0 = blocks.add_vcc(1) self.bit_interleaver_output_packed = blocks.file_sink( gr.sizeof_char * 1, 'bit_interleaver_output_packed.bin', False) self.bit_interleaver_output_packed.set_unbuffered(False) self.bit_interleaver_output = blocks.file_sink( gr.sizeof_char * 1, 'bit_interleaver_output.bin', False) self.bit_interleaver_output.set_unbuffered(False) self.bit_interleaver_input = blocks.file_sink( gr.sizeof_char * 1, 'bit_interleaver_input.bin', False) self.bit_interleaver_input.set_unbuffered(False) self.bch_encoder_input = blocks.file_sink(gr.sizeof_char * 1, 'bch_encoder_input.bin', False) self.bch_encoder_input.set_unbuffered(False) self.bb_scrambler_input_0 = blocks.file_sink(gr.sizeof_char * 1, 'bb_scrambler_input.bin', False) self.bb_scrambler_input_0.set_unbuffered(False) self.analog_random_source_x_0 = blocks.vector_source_b( map(int, numpy.random.randint(0, 255, frame_length)), False) self.analog_noise_source_x_1 = analog.noise_source_c( analog.GR_GAUSSIAN, noise, 0) self.analog_agc_xx_0 = analog.agc_cc(1e-4, 1.0, 1.0) self.analog_agc_xx_0.set_max_gain(8192) ################################################## # Connections ################################################## self.connect((self.analog_agc_xx_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) self.connect((self.analog_noise_source_x_1, 0), (self.blocks_add_xx_2, 1)) self.connect((self.analog_random_source_x_0, 0), (self.dtv_dvb_bbheader_bb_0, 0)) self.connect((self.blocks_add_xx_0, 0), (self.blocks_complex_to_mag_0, 0)) self.connect((self.blocks_add_xx_2, 0), (self.analog_agc_xx_0, 0)) self.connect((self.blocks_complex_to_mag_0, 0), (self.blocks_max_xx_0, 1)) self.connect((self.blocks_complex_to_mag_0_0, 0), (self.blocks_max_xx_0, 0)) self.connect((self.blocks_conjugate_cc_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.blocks_max_xx_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.fir_filter_xxx_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.fir_filter_xxx_0_0, 0)) self.connect((self.blocks_repack_bits_bb_0, 0), (self.bit_interleaver_output_packed, 0)) self.connect((self.blocks_sub_xx_0, 0), (self.blocks_complex_to_mag_0_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.blocks_file_sink_1, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.blocks_conjugate_cc_0, 0)) self.connect((self.digital_costas_loop_cc_0, 0), (self.blocks_delay_0, 0)) self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_costas_loop_cc_0, 0)) self.connect((self.dtv_dvb_bbheader_bb_0, 0), (self.bb_scrambler_input_0, 0)) self.connect((self.dtv_dvb_bbheader_bb_0, 0), (self.dtv_dvb_bbscrambler_bb_0, 0)) self.connect((self.dtv_dvb_bbscrambler_bb_0, 0), (self.bch_encoder_input, 0)) self.connect((self.dtv_dvb_bbscrambler_bb_0, 0), (self.dtv_dvb_bch_bb_0, 0)) self.connect((self.dtv_dvb_bch_bb_0, 0), (self.dtv_dvb_ldpc_bb_0, 0)) self.connect((self.dtv_dvb_bch_bb_0, 0), (self.ldpc_encoder_input, 0)) self.connect((self.dtv_dvb_ldpc_bb_0, 0), (self.bit_interleaver_input, 0)) self.connect((self.dtv_dvb_ldpc_bb_0, 0), (self.dtv_dvbs2_interleaver_bb_0, 0)) self.connect((self.dtv_dvbs2_interleaver_bb_0, 0), (self.bit_interleaver_output, 0)) self.connect((self.dtv_dvbs2_interleaver_bb_0, 0), (self.blocks_repack_bits_bb_0, 0)) self.connect((self.dtv_dvbs2_interleaver_bb_0, 0), (self.dtv_dvbs2_modulator_bc_0, 0)) self.connect((self.dtv_dvbs2_modulator_bc_0, 0), (self.dtv_dvbs2_physical_cc_0, 0)) self.connect((self.dtv_dvbs2_physical_cc_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.blocks_add_xx_2, 0)) self.connect((self.fir_filter_xxx_0, 0), (self.blocks_add_xx_0, 0)) self.connect((self.fir_filter_xxx_0, 0), (self.blocks_sub_xx_0, 0)) self.connect((self.fir_filter_xxx_0_0, 0), (self.blocks_add_xx_0, 1)) self.connect((self.fir_filter_xxx_0_0, 0), (self.blocks_sub_xx_0, 1))
def __init__(self, principal_gui, rx_callback, options): gr.hier_block2.__init__(self, "receive_path", gr.io_signature(0,0,0), # the 1,1 indicate the minimum, maximum stream in input gr.io_signature(0,0,0)) # the 0,0 indicate the minimum, maximum stream in output #local setup usrp source creat self.usrp source self._setup_usrp_source(options) options = copy.copy(options) # Make copy of the received options self._verbose = options.verbose self._bitrate = options.data_rate # The bit rate transmission self._samples_per_symbol= options.samples_per_symbol # samples/sample self._rx_callback = rx_callback #This callback is fired (declanche) when there's packet is available self.demodulator = bpsk_demodulator(principal_gui, options) #The demodulator used #Designe filter to get actual channel we want sw_decim = 1 #Create the low pass filter chan_coeffs = filter.firdes.low_pass (1.0, #gain sw_decim * self._samples_per_symbol, #sampling rate 1.0, #midpoint of trans band 0.5, #width of trans band filter.firdes.WIN_HAMMING) #filter type self.channel_filter = filter.fft_filter_ccc(sw_decim, chan_coeffs) self.packet_receiver = ieee_pkt_receiver.ieee_pkt_receiver_868_915(self, gui = principal_gui, demodulator = self.demodulator, callback = rx_callback, sps = self._samples_per_symbol, symbol_rate = self._bitrate, threshold = -1) #Carrier Sensing Block (ecoute du canal) alpha = 0.001 # Carrier Sensing with dB, will have to adjust thresh = 30 #construct analyser of carrier (c'est un sink) # self.probe = gr.probe_avg_mag_sqrd_c(thresh, alpha) #display information about the setup if self._verbose: self._print_verbage() #self.squelch = gr.pwr_squelch_cc(50, 1, 0, True) #connect the input block to channel filter #connect the blocks with usrp, the self.usrp is created in _setup_usrp_source self.squelch = analog.pwr_squelch_cc(50, 1, 0, True) # self.wxgui_constellationsink2_0_0 = constsink_gl.const_sink_c( # principal_gui.GetWin(), # title="Constellation Plot", # sample_rate= options.samp_rate, # frame_rate=5, # const_size=2048, # M=2, # theta=0, # loop_bw=6.28/100.0, # fmax=0.05, # mu=0.5, # gain_mu=0.001, # symbol_rate=options.samp_rate/options.samples_per_symbol, # omega_limit=0.0001, # ) # principal_gui.Add(self.wxgui_constellationsink2_0_0.win) '''For stream of bits''' # self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( # principal_gui.GetWin(), # baseband_freq=options.freq, # y_per_div=10, # y_divs=10, # ref_level=10, # ref_scale=2.0, # sample_rate= 0.5e6, # fft_size=1024, # fft_rate=30, # average=False, # avg_alpha=None, # title="FFT Plot", # peak_hold=False, # ) # principal_gui.Add(self.wxgui_fftsink2_0.win) #self.connect(self.u, self.demodulator, self.wxgui_fftsink2_0) '''End for stream of bits''' #Reception of packets self.connect(self.u, self.packet_receiver)