def test_002_cc(self): N = 10000 # number of samples to use fs = 1000 # baseband sampling rate rrate = 1.123 # resampling rate freq = 10 data = sig_source_c(fs, freq, 1, N) signal = blocks.vector_source_c(data) op = filter.fractional_resampler_cc(0.0, rrate) snk = blocks.vector_sink_c() self.tb.connect(signal, op, snk) self.tb.run() Ntest = 5000 L = len(snk.data()) t = map(lambda x: float(x)/(fs/rrate), xrange(L)) phase = 0.1884 expected_data = map(lambda x: math.cos(2.*math.pi*freq*x+phase) + \ 1j*math.sin(2.*math.pi*freq*x+phase), t) dst_data = snk.data() self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
def test_001_t (self): # set up fg src_data = (0,0,0,0,1,-1j,-1,1j,0,0,0,0, 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4, 0,0,0,0,2,-2j,-2,2j,0,0,0,0, 2,2,2,2,4,4,4,4,6,6,6,6,8,8,8,8) expected_result = (0,0,0,0,1,-1j,-1,1j,0,0,0,0, 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4, 0,0,0,0,2,-2j,-2,2j,0,0,0,0, 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4) src = blocks.vector_source_c(src_data,vlen=4) scp = ofdm.fbmc_subchannel_processing_vcvc(M=4,syms_per_frame=2,preamble=[0,0,0,0,1,-1j,-1,1j,0,0,0,0],sel_eq=0) dst = blocks.vector_sink_c(vlen=4) dst2 = blocks.vector_sink_c(vlen=4) self.tb.connect((src,0),(scp,0)) self.tb.connect((scp,0),dst) self.tb.connect((scp,1),dst2) self.tb.run () # check data result_data = dst.data() result_data2 = dst2.data() for i in range(len(result_data2)): print str(i)+"\t"+str(result_data2[i]) # print result_data self.assertComplexTuplesAlmostEqual(expected_result,result_data,6)
def setUp (self): self.tb = gr.top_block () self.N_rb_dl = N_rb_dl = 6 self.key = "symbol" self.out_key = "subframe" self.msg_buf_name = "cell_id" n_carriers = 12*N_rb_dl n_cfi_vec = 16 intu = np.zeros(n_carriers,dtype=np.complex) self.src0 = blocks.vector_source_c( intu, False, n_carriers) self.src1 = blocks.vector_source_c( intu, False, n_carriers) self.src2 = blocks.vector_source_c( intu, False, n_carriers) self.demux = lte.pcfich_demux_vcvc(N_rb_dl, self.key, self.out_key, self.msg_buf_name) self.snk0 = blocks.vector_sink_c(n_cfi_vec) self.snk1 = blocks.vector_sink_c(n_cfi_vec) self.snk2 = blocks.vector_sink_c(n_cfi_vec) self.tag = blocks.tag_debug(n_cfi_vec * 8, "TAG") self.tb.connect(self.src0, (self.demux,0) ) self.tb.connect( (self.demux,0), self.snk0) self.tb.connect(self.src1, (self.demux,1) ) self.tb.connect( (self.demux,1), self.snk1) self.tb.connect(self.src2, (self.demux,2) ) self.tb.connect( (self.demux,2), self.snk2) self.tb.connect( (self.demux,0), self.tag)
def test_002_t(self): # set up fg M=512 flag = True src_data = list() expected_result0 = list() expected_result1 = list() for i in range(8192*8): src_data.append(int(random.random()*10)) if flag: expected_result0.append(src_data[i]) else: expected_result1.append(src_data[i]) if i%M == M-1: flag = not flag src = blocks.vector_source_c(src_data,vlen=M) sep = ofdm.fbmc_separate_vcvc(M=M,num_output=2) dst0 = blocks.vector_sink_c(vlen=M) dst1 = blocks.vector_sink_c(vlen=M) self.tb.connect(src,sep) self.tb.connect((sep,0),dst0) self.tb.connect((sep,1),dst1) self.tb.run () # check data result0 = dst0.data() result1 = dst1.data() self.assertComplexTuplesAlmostEqual(tuple(result1),tuple(expected_result1),150) self.assertComplexTuplesAlmostEqual(tuple(result0),tuple(expected_result0),150)
def test_002_t (self): # set up fg # purpse is testing fft on high sample rates test_len = 2**19 packet_len = 2**17 min_output_buffer = packet_len*2 samp_rate = 10000000 frequency = 200000 amplitude = 1 src = radar.signal_generator_cw_c(packet_len,samp_rate,(frequency,frequency),amplitude) src.set_min_output_buffer(min_output_buffer) head = blocks.head(8,test_len) head.set_min_output_buffer(min_output_buffer) fft1 = radar.ts_fft_cc(packet_len) fft1.set_min_output_buffer(min_output_buffer) fft2 = radar.ts_fft_cc(packet_len) fft2.set_min_output_buffer(min_output_buffer) snk1 = blocks.vector_sink_c() snk2 = blocks.vector_sink_c() self.tb.connect(src,head,fft1,snk1) self.tb.connect(head,fft2,snk2) self.tb.run () # check both ffts self.assertComplexTuplesAlmostEqual(snk1.data(),snk2.data(),2) # compare both ffts
def test_003_t (self): # test fft against gnuradio fft # set up fg test_len = 1024*2 packet_len = test_len samp_rate = 2000 frequency = (100,100) amplitude = 1 src = radar.signal_generator_cw_c(packet_len,samp_rate,frequency,amplitude) head = blocks.head(8,test_len) tsfft = radar.ts_fft_cc(packet_len) snk1 = blocks.vector_sink_c() self.tb.connect(src,head,tsfft,snk1) s2v = blocks.stream_to_vector(8, packet_len) fft_inbuild = fft.fft_vcc(test_len,True,fft.window_rectangular(0)) snk2 = blocks.vector_sink_c() v2s = blocks.vector_to_stream(8, packet_len); self.tb.connect(head,s2v,fft_inbuild,v2s,snk2) self.tb.run() # compaire ffts data_tsfft = snk1.data() data_fft_inbuild = snk2.data() self.assertComplexTuplesAlmostEqual(data_tsfft,data_fft_inbuild,2) # compare inbuild fft and fft from block
def test_002_t (self): # set up fg # check on reverse by using two times test_len = 12 in_data = range(test_len) vlen_in = 3 vlen_out = 4 src = blocks.vector_source_c(in_data) stv = blocks.stream_to_vector(8,vlen_in) s2ts = blocks.stream_to_tagged_stream(8,vlen_in,test_len/vlen_in,'packet_len') transpose1 = radar.transpose_matrix_vcvc(vlen_in,vlen_out,'packet_len') transpose2 = radar.transpose_matrix_vcvc(vlen_out,vlen_in,'packet_len') vts = blocks.vector_to_stream(8,vlen_in) snk = blocks.vector_sink_c() vts2 = blocks.vector_to_stream(8,vlen_out) snk2 = blocks.vector_sink_c() self.tb.connect(src,stv,s2ts,transpose1,transpose2,vts,snk) self.tb.connect(transpose1,vts2,snk2) self.tb.run() # check data out_data_real = [0]*len(in_data) out_data = snk.data() for k in range(len(in_data)): out_data_real[k] = out_data[k].real print "Input data:", in_data print "Output data:", out_data_real print "Transpose data:", snk2.data() for k in range(len(out_data_real)): self.assertEqual(out_data_real[k],in_data[k])
def __init__(self, fs_in, fs_out, fc, N=10000): gr.top_block.__init__(self) rerate = float(fs_out) / float(fs_in) print "Resampling from %f to %f by %f " %(fs_in, fs_out, rerate) # Creating our own taps taps = filter.firdes.low_pass_2(32, 32, 0.25, 0.1, 80) self.src = analog.sig_source_c(fs_in, analog.GR_SIN_WAVE, fc, 1) #self.src = analog.noise_source_c(analog.GR_GAUSSIAN, 1) self.head = blocks.head(gr.sizeof_gr_complex, N) # A resampler with our taps self.resamp_0 = filter.pfb.arb_resampler_ccf(rerate, taps, flt_size=32) # A resampler that just needs a resampling rate. # Filter is created for us and designed to cover # entire bandwidth of the input signal. # An optional atten=XX rate can be used here to # specify the out-of-band rejection (default=80). self.resamp_1 = filter.pfb.arb_resampler_ccf(rerate) self.snk_in = blocks.vector_sink_c() self.snk_0 = blocks.vector_sink_c() self.snk_1 = blocks.vector_sink_c() self.connect(self.src, self.head, self.snk_in) self.connect(self.head, self.resamp_0, self.snk_0) self.connect(self.head, self.resamp_1, self.snk_1)
def test_003_channel_no_carroffset (self): """ Add a channel, check if it's correctly estimated """ fft_len = 16 carr_offset = 0 sync_symbol1 = (0, 0, 0, 1, 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 0) sync_symbol2 = (0, 0, 0, 1j, -1, 1, -1j, 1j, 0, 1, -1j, -1, -1j, 1, 0, 0) data_symbol = (0, 0, 0, 1, -1, 1, -1, 1, 0, 1, -1, -1, -1, 1, 0, 0) tx_data = sync_symbol1 + sync_symbol2 + data_symbol channel = (0, 0, 0, 2, -2, 2, 3j, 2, 0, 2, 2, 2, 2, 3, 0, 0) src = blocks.vector_source_c(tx_data, False, fft_len) chan = blocks.multiply_const_vcc(channel) chanest = digital.ofdm_chanest_vcvc(sync_symbol1, sync_symbol2, 1) sink = blocks.vector_sink_c(fft_len) sink_chanest = blocks.vector_sink_c(fft_len) self.tb.connect(src, chan, chanest, sink) self.tb.connect((chanest, 1), sink_chanest) self.tb.run() tags = sink.tags() self.assertEqual(shift_tuple(sink.data(), -carr_offset), tuple(numpy.multiply(data_symbol, channel))) for tag in tags: if pmt.symbol_to_string(tag.key) == 'ofdm_sync_carr_offset': self.assertEqual(pmt.to_long(tag.value), carr_offset) if pmt.symbol_to_string(tag.key) == 'ofdm_sync_chan_taps': self.assertEqual(pmt.c32vector_elements(tag.value), channel) self.assertEqual(sink_chanest.data(), channel)
def test_004_channel_no_carroffset_1sym (self): """ Add a channel, check if it's correctly estimated. Only uses 1 synchronisation symbol. """ fft_len = 16 carr_offset = 0 sync_symbol = (0, 0, 0, 1, 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 0) data_symbol = (0, 0, 0, 1, -1, 1, -1, 1, 0, 1, -1, -1, -1, 1, 0, 0) tx_data = sync_symbol + data_symbol channel = (0, 0, 0, 2, 2, 2, 2, 3, 3, 2.5, 2.5, -3, -3, 1j, 1j, 0) #channel = (0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) src = blocks.vector_source_c(tx_data, False, fft_len) chan = blocks.multiply_const_vcc(channel) chanest = digital.ofdm_chanest_vcvc(sync_symbol, (), 1) sink = blocks.vector_sink_c(fft_len) sink_chanest = blocks.vector_sink_c(fft_len) self.tb.connect(src, chan, chanest, sink) self.tb.connect((chanest, 1), sink_chanest) self.tb.run() self.assertEqual(sink_chanest.data(), channel) tags = sink.tags() for tag in tags: if pmt.symbol_to_string(tag.key) == 'ofdm_sync_carr_offset': self.assertEqual(pmt.to_long(tag.value), carr_offset) if pmt.symbol_to_string(tag.key) == 'ofdm_sync_chan_taps': self.assertEqual(pmt.c32vector_elements(tag.value), channel)
def __init__(self, N, sps, rolloff, ntaps, bw, noise, foffset, toffset, poffset): gr.top_block.__init__(self) rrc_taps = filter.firdes.root_raised_cosine( sps, sps, 1.0, rolloff, ntaps) data = 2.0*scipy.random.randint(0, 2, N) - 1.0 data = scipy.exp(1j*poffset) * data self.src = blocks.vector_source_c(data.tolist(), False) self.rrc = filter.interp_fir_filter_ccf(sps, rrc_taps) self.chn = channels.channel_model(noise, foffset, toffset) self.fll = digital.fll_band_edge_cc(sps, rolloff, ntaps, bw) self.vsnk_src = blocks.vector_sink_c() self.vsnk_fll = blocks.vector_sink_c() self.vsnk_frq = blocks.vector_sink_f() self.vsnk_phs = blocks.vector_sink_f() self.vsnk_err = blocks.vector_sink_f() self.connect(self.src, self.rrc, self.chn, self.fll, self.vsnk_fll) self.connect(self.rrc, self.vsnk_src) self.connect((self.fll,1), self.vsnk_frq) self.connect((self.fll,2), self.vsnk_phs) self.connect((self.fll,3), self.vsnk_err)
def test_002_t(self): n_frames = 1 self.gfdm_var = gfdm_var = struct({'subcarriers': 64, 'timeslots': 9, 'alpha': 0.5, 'overlap': 2,}) self.gfdm_constellation = gfdm_constellation = digital.constellation_qpsk().base() self.f_taps = f_taps = filters.get_frequency_domain_filter('rrc', 1.0, gfdm_var.timeslots, gfdm_var.subcarriers, gfdm_var.overlap) self.random_bits = blocks.vector_source_b(map(int, np.random.randint(0, len(gfdm_constellation.points()), n_frames * gfdm_var.timeslots * gfdm_var.subcarriers)), False) self.bits_to_symbols = digital.chunks_to_symbols_bc((gfdm_constellation.points()), 1) self.mod = gfdm.simple_modulator_cc(gfdm_var.timeslots, gfdm_var.subcarriers, gfdm_var.overlap, f_taps) self.demod = gfdm.advanced_receiver_sb_cc(gfdm_var.timeslots, gfdm_var.subcarriers, gfdm_var.overlap, 64, f_taps, gfdm_constellation, np.arange(gfdm_var.subcarriers)) self.tx_symbols = blocks.vector_sink_c() self.rx_symbols = blocks.vector_sink_c() self.tb.connect((self.random_bits, 0), (self.bits_to_symbols, 0)) self.tb.connect((self.bits_to_symbols, 0), (self.tx_symbols, 0)) self.tb.connect((self.bits_to_symbols, 0), (self.mod, 0)) self.tb.connect((self.mod, 0), (self.demod, 0)) self.tb.connect((self.demod, 0), (self.rx_symbols, 0)) self.tb.run() ref = np.array(self.tx_symbols.data()) res = np.array(self.rx_symbols.data()) # more or less make sure all symbols have their correct sign. self.assertComplexTuplesAlmostEqual(ref, res, 2)
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 test_001_t(self): for exponent in range(1,10): in_data = (1+1j, -1, 4-1j, -3-7j) out_data = (in_data[0]**exponent, in_data[1]**exponent, in_data[2]**exponent, in_data[3]**exponent) # Test streaming input source = blocks.vector_source_c(in_data, False, 1) exponentiate_const_cci = blocks.exponentiate_const_cci(exponent) sink = blocks.vector_sink_c(1) self.tb.connect(source, exponentiate_const_cci, sink) self.tb.run() self.assertAlmostEqual(sink.data(), out_data) # Test vector input for vlen in [2, 4]: source = blocks.vector_source_c(in_data, False, 1) s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, vlen) exponentiate_const_cci = blocks.exponentiate_const_cci(exponent, vlen) v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, vlen) sink = blocks.vector_sink_c(1) self.tb.connect(source, s2v, exponentiate_const_cci, v2s, sink) self.tb.run() self.assertAlmostEqual(sink.data(), out_data)
def test_001_t (self): # set up fg samp_cw = 300 samp_up = 200 samp_down = 100 mult = 3 test_len = (samp_cw+samp_up+samp_down)*mult samp_rate = 2000 len_key = "packet_len" packet_parts = (samp_cw, samp_up, samp_down) src = radar.signal_generator_fmcw_c(samp_rate, samp_up, samp_down, samp_cw, 500, 250, 1, len_key); head = blocks.head(8,test_len) split0 = radar.split_cc(0,packet_parts,len_key) split1 = radar.split_cc(1,packet_parts,len_key) split2 = radar.split_cc(2,packet_parts,len_key) snk0 = blocks.vector_sink_c() snk1 = blocks.vector_sink_c() snk2 = blocks.vector_sink_c() self.tb.connect(src,head) self.tb.connect(head,split0,snk0) self.tb.connect(head,split1,snk1) self.tb.connect(head,split2,snk2) self.tb.run () # check data self.assertEqual(len(snk0.data()),mult*samp_cw) # check correct number of samples in every sink self.assertEqual(len(snk1.data()),mult*samp_up) self.assertEqual(len(snk2.data()),mult*samp_down)
def test_001_t (self): # full frames with zeros inbetween print "NOTE: THIS TEST USES THE INSTALLED VERSION OF THE LIBRARY" print "Test complete frames with zeros inbetween" m = ieee802_15_4_installed.css_modulator() bits_in, bb_in = m.modulate_random() sym_in = m.frame_DQPSK print "Number of DQPSK symbols per frame:", len(sym_in) zeros = np.zeros((50,)) data_in = np.concatenate((bb_in, zeros, bb_in, zeros, bb_in, bb_in, bb_in, bb_in)) src = blocks.vector_source_c(data_in) det = ieee802_15_4.simple_chirp_detector_cc(m.chirp_seq, len(m.time_gap_1), len(m.time_gap_2), 38, 0.95) snk_det = blocks.vector_sink_c() costas = ieee802_15_4.costas_loop_cc((1+1j, -1+1j, -1-1j, 1-1j), -1) snk_costas = blocks.vector_sink_c() preamble = ieee802_15_4.preamble_tagger_cc(len(m.preamble)) snk_preamble = blocks.vector_sink_c() frame_buffer = ieee802_15_4.frame_buffer_cc(len(sym_in)) snk_framebuffer = blocks.vector_sink_c() self.tb.connect(src, det, costas, preamble, frame_buffer) self.tb.connect(det, snk_det) self.tb.connect(costas, snk_costas) self.tb.connect(preamble, snk_preamble) self.tb.connect(frame_buffer, snk_framebuffer) self.tb.run() ref = np.concatenate((sym_in, sym_in, sym_in)) # det_out = snk_det.data()[:len(sym_in)*3] # # plt.plot(abs(det_out - ref)) # # plt.title("post chirp detector") # # plt.show() # self.assertComplexTuplesAlmostEqual(det_out, ref, 5) # costas_out = snk_costas.data()[:len(sym_in)*3] # # plt.plot(abs(costas_out - ref)) # # plt.title("post costas loop") # # plt.show() # self.assertComplexTuplesAlmostEqual(costas_out, ref, 5) # preamble_out = snk_preamble.data()[:len(sym_in)*3] framebuffer_out = snk_framebuffer.data()[:len(sym_in)*3] # print "len(data_in):", len(data_in) # print "len(det_out):", len(det_out) # print "len(costas_out):", len(costas_out) # print "len(preamble_out):", len(preamble_out) # print "len(framebuffer_out):", len(framebuffer_out) # f, axarr = plt.subplots(3,1) # axarr[0].plot(abs(framebuffer_out - ref)) # axarr[0].set_title("diff preamble ref (abs)") # axarr[1].plot(np.real(det_out)) # axarr[1].set_title("real part of chirp det output") # axarr[2].plot(np.real(framebuffer_out)) # axarr[2].set_title("real part of frambuffer output") # plt.suptitle("post framebuffer") # plt.show() self.assertComplexTuplesAlmostEqual(framebuffer_out, ref, 5)
def test_001_t (self): # set up fg fft_len = 256 cp_len = 32 samp_rate = 32000 data = np.random.choice([-1, 1], [100, fft_len]) timefreq = np.fft.ifft(data, axis=0) #add cp timefreq = np.hstack((timefreq[:, -cp_len:], timefreq)) # msg (only 4th and 5th tuples are needed) id1 = pmt.make_tuple(pmt.intern("Signal"), pmt.from_uint64(0)) name = pmt.make_tuple(pmt.intern("OFDM"), pmt.from_float(1.0)); id2 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(0.0)) id3 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(0.0)) id4 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(256)) id5 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(32)) msg = pmt.make_tuple(id1, name, id2, id3, id4, id5) tx = np.reshape(timefreq, (1, -1)) # GR time! src = blocks.vector_source_c(tx[0].tolist(), True, 1, []) freq_offset = analog.sig_source_c(1, analog.GR_SIN_WAVE, 50.0/samp_rate, 1.0, 0.0) mixer = blocks.multiply_cc() sync = inspector.ofdm_synchronizer_cc(4096) dst = blocks.vector_sink_c() dst2 = blocks.vector_sink_c() msg_src = blocks.message_strobe(msg, 0) # connect self.tb.connect(src, (mixer, 0)) self.tb.connect(freq_offset, (mixer, 1)) self.tb.connect(mixer, sync) self.tb.msg_connect((msg_src, 'strobe'), (sync, 'ofdm_in')) self.tb.connect(sync, dst) self.tb.connect(src, dst2) self.tb.start() time.sleep(0.1) self.tb.stop() self.tb.wait() # check data output = dst.data() expect = dst2.data() # block outputs 0j until it has enough OFDM symbols to perform estimations k = (k for k in range(len(output)) if output[k] != 0j).next() # use 10,000 samples for comparison since block fails sometimes # for one work function output = output[k:k+10000] expect = expect[k:k+10000] self.assertComplexTuplesAlmostEqual2(expect, output, abs_eps = 0.001, rel_eps=10)
def __init__(self, N, sps, rolloff, ntaps, bw, noise, foffset, toffset, poffset, mode=0): gr.top_block.__init__(self) rrc_taps = filter.firdes.root_raised_cosine( sps, sps, 1.0, rolloff, ntaps) gain = bw nfilts = 32 rrc_taps_rx = filter.firdes.root_raised_cosine( nfilts, sps*nfilts, 1.0, rolloff, ntaps*nfilts) data = 2.0*scipy.random.randint(0, 2, N) - 1.0 data = scipy.exp(1j*poffset) * data self.src = blocks.vector_source_c(data.tolist(), False) self.rrc = filter.interp_fir_filter_ccf(sps, rrc_taps) self.chn = channels.channel_model(noise, foffset, toffset) self.off = filter.fractional_resampler_cc(0.20, 1.0) if mode == 0: self.clk = digital.pfb_clock_sync_ccf(sps, gain, rrc_taps_rx, nfilts, nfilts//2, 1) self.taps = self.clk.taps() self.dtaps = self.clk.diff_taps() self.delay = int(scipy.ceil(((len(rrc_taps)-1)/2 + (len(self.taps[0])-1)/2)/float(sps))) + 1 self.vsnk_err = blocks.vector_sink_f() self.vsnk_rat = blocks.vector_sink_f() self.vsnk_phs = blocks.vector_sink_f() self.connect((self.clk,1), self.vsnk_err) self.connect((self.clk,2), self.vsnk_rat) self.connect((self.clk,3), self.vsnk_phs) else: # mode == 1 mu = 0.5 gain_mu = bw gain_omega = 0.25*gain_mu*gain_mu omega_rel_lim = 0.02 self.clk = digital.clock_recovery_mm_cc(sps, gain_omega, mu, gain_mu, omega_rel_lim) self.vsnk_err = blocks.vector_sink_f() self.connect((self.clk,1), self.vsnk_err) self.vsnk_src = blocks.vector_sink_c() self.vsnk_clk = blocks.vector_sink_c() self.connect(self.src, self.rrc, self.chn, self.off, self.clk, self.vsnk_clk) self.connect(self.src, self.vsnk_src)
def test_003_t (self): # late entry print "NOTE: THIS TEST USES THE INSTALLED VERSION OF THE LIBRARY" print "Test late entry" m = ieee802_15_4_installed.css_modulator() bits_in1, bb_in1 = m.modulate_random() sym_in1 = m.frame_DQPSK bits_in2, bb_in2 = m.modulate_random() sym_in2 = m.frame_DQPSK bits_in3, bb_in3 = m.modulate_random() sym_in3 = m.frame_DQPSK print "Number of DQPSK symbols per frame:", len(sym_in1) zeros = np.zeros((50,)) nsym_early = 9 # data_part = np.concatenate((bb_in1[-nsym_early*192/4:], bb_in1, bb_in2, bb_in3, bb_in3, bb_in3)) data_part = np.concatenate((bb_in1[-2*192-70-38-10:], bb_in1, bb_in2, bb_in3, bb_in3, bb_in3)) ncopies = 1 data = np.tile(data_part, (ncopies,)) data_in = np.concatenate((data, bb_in3, bb_in3, bb_in3)) src = blocks.vector_source_c(data_in) det = ieee802_15_4.simple_chirp_detector_cc(m.chirp_seq, len(m.time_gap_1), len(m.time_gap_2), 38, 0.95) snk_det = blocks.vector_sink_c() costas = ieee802_15_4.costas_loop_cc((1+1j, -1+1j, -1-1j, 1-1j), -1) snk_costas = blocks.vector_sink_c() preamble = ieee802_15_4.preamble_tagger_cc(len(m.preamble)) snk_preamble = blocks.vector_sink_c() frame_buffer = ieee802_15_4.frame_buffer_cc(len(sym_in1)) snk_framebuffer = blocks.vector_sink_c() self.tb.connect(src, det, costas, preamble, frame_buffer) self.tb.connect(det, snk_det) self.tb.connect(costas, snk_costas) self.tb.connect(preamble, snk_preamble) self.tb.connect(frame_buffer, snk_framebuffer) self.tb.run() ref_len = (len(sym_in1)*3 + nsym_early)*ncopies det_out = snk_det.data()[:ref_len] ref_det_part = np.concatenate((sym_in1[-nsym_early:], sym_in1, sym_in2, sym_in3)) ref_det = np.tile(ref_det_part, (ncopies,)) self.assertComplexTuplesAlmostEqual(det_out, ref_det, 5) costas_out = snk_costas.data()[:ref_len] ref_costas = ref_det self.assertComplexTuplesAlmostEqual(costas_out, ref_costas, 5) preamble_out = snk_preamble.data()[:ref_len] ref_preamble = ref_costas self.assertComplexTuplesAlmostEqual(preamble_out, ref_preamble, 5) framebuffer_out = snk_framebuffer.data()[:ref_len-ncopies*nsym_early] ref_framebuffer_part = np.concatenate((sym_in1, sym_in2, sym_in3)) ref_framebuffer = np.tile(ref_framebuffer_part, (ncopies,)) self.assertComplexTuplesAlmostEqual(framebuffer_out, ref_framebuffer, 5)
def test_005_t (self): print "NOTE: THIS TEST USES THE INSTALLED VERSION OF THE LIBRARY" print "Test interrupted frames at symbol boundary with zeros inbetween" m = ieee802_15_4_installed.css_modulator() bits_in1, bb_in1 = m.modulate_random() len_bb = len(bb_in1) sym_in1 = m.frame_DQPSK len_frame = len(sym_in1) bits_in2, bb_in2 = m.modulate_random() sym_in2 = m.frame_DQPSK bits_in3, bb_in3 = m.modulate_random() sym_in3 = m.frame_DQPSK print "Number of DQPSK symbols per frame:", len(sym_in1) zeros = np.zeros((100,)) data_part = np.concatenate((bb_in1, bb_in2[:192*30], zeros, bb_in2[192*30:], bb_in3)) ncopies = 10 data = np.tile(data_part, (ncopies,)) data_in = np.concatenate((data, bb_in3, bb_in3, bb_in3)) # pad some frames src = blocks.vector_source_c(data_in) det = ieee802_15_4.simple_chirp_detector_cc(m.chirp_seq, len(m.time_gap_1), len(m.time_gap_2), 38, 0.999) snk_det = blocks.vector_sink_c() costas = ieee802_15_4.costas_loop_cc((1+1j, -1+1j, -1-1j, 1-1j), -1) snk_costas = blocks.vector_sink_c() preamble = ieee802_15_4.preamble_tagger_cc(len(m.preamble)) snk_preamble = blocks.vector_sink_c() frame_buffer = ieee802_15_4.frame_buffer_cc(len(sym_in1)) snk_framebuffer = blocks.vector_sink_c() self.tb.connect(src, det, costas, preamble, frame_buffer) self.tb.connect(det, snk_det) self.tb.connect(costas, snk_costas) self.tb.connect(preamble, snk_preamble) self.tb.connect(frame_buffer, snk_framebuffer) self.tb.run() ref_len = len_frame*3*ncopies det_out = snk_det.data()[:ref_len] ref_det_part = np.concatenate((sym_in1, sym_in2, sym_in3)) ref_det = np.tile(ref_det_part, (ncopies,)) self.assertComplexTuplesAlmostEqual(det_out, ref_det, 5) costas_out = snk_costas.data()[:ref_len] ref_costas = ref_det self.assertComplexTuplesAlmostEqual(costas_out, ref_costas, 5) preamble_out = snk_preamble.data()[:ref_len] ref_preamble = ref_costas self.assertComplexTuplesAlmostEqual(preamble_out, ref_preamble, 5) framebuffer_out = snk_framebuffer.data()[:ref_len] ref_framebuffer_part = np.concatenate((sym_in1, sym_in2, sym_in3)) ref_framebuffer = np.tile(ref_framebuffer_part, (ncopies,)) self.assertComplexTuplesAlmostEqual(framebuffer_out, ref_framebuffer, 5)
def test_003_small_frame_mod(self): num_frames = 300 total_subcarriers = 8 used_subcarriers = 4 channel_map = np.array((0, 0, 1, 1, 1, 1, 0, 0)) #ft.get_channel_map(used_subcarriers, total_subcarriers) payload_symbols = 8 overlap = 4 taps = ft.generate_phydyas_filter(total_subcarriers, overlap) preamble = ft.get_preamble(total_subcarriers) num_preamble_symbols = len(preamble) // total_subcarriers payload = ft.get_payload(payload_symbols, used_subcarriers) payload = np.tile(payload, num_frames).flatten() src = blocks.vector_source_b(payload, repeat=False) framer = fbmc.frame_generator_bvc(used_subcarriers, total_subcarriers, payload_symbols, overlap, channel_map, preamble) snk_frame = blocks.vector_sink_c(total_subcarriers) # a debug output mod = fbmc.tx_sdft_vcc(taps, total_subcarriers) demod = fbmc.rx_sdft_cvc(taps, total_subcarriers) skipper = blocks.skiphead(8 * total_subcarriers, 4) snk_rx = blocks.vector_sink_c(total_subcarriers) deframer = fbmc.deframer_vcb(used_subcarriers, total_subcarriers, num_preamble_symbols, payload_symbols, overlap, channel_map) snk = blocks.vector_sink_b(1) self.tb.connect(src, framer, mod, demod, skipper, deframer, snk) self.tb.connect(framer, snk_frame) self.tb.connect(skipper, snk_rx) self.tb.run() res = np.array(snk.data()) print "len(res) = ", len(res), ", len(payload) = ", len(payload) print "ref: ", payload print "res: ", res moddata = np.array(snk_frame.data()) print "len(moddata) = ", len(moddata) rxdata = np.array(snk_rx.data()) print "len(rxdata) = ", len(rxdata), " diff: ", len(moddata) - len(rxdata) # plt.plot(rxdata.real * 0.03) # for i in range(len(moddata)): # if (i + 1) % total_subcarriers == 0: # plt.axvline(i) # plt.plot(moddata.real) # plt.grid() # plt.show() print "len(payload) = ", len(payload) print "len(result ) = ", len(res) self.assertTupleEqual(tuple(payload[:len(res)]), tuple(res))
def test_004_config_frame_mod(self): num_frames = 10 cfg = fbmc.fbmc_config(num_used_subcarriers=20, num_payload_sym=16, num_overlap_sym=4, modulation="QPSK", preamble="IAM", samp_rate=250000) total_subcarriers = cfg.num_total_subcarriers() # 8 used_subcarriers = cfg.num_used_subcarriers() # 4 channel_map = cfg.channel_map() # ft.get_channel_map(used_subcarriers, total_subcarriers) payload_symbols = cfg.num_payload_sym() # 8 overlap = cfg.num_overlap_sym() # 4 taps = cfg.phydyas_impulse_taps(cfg.num_total_subcarriers(), cfg.num_overlap_sym()) # ft.generate_phydyas_filter(total_subcarriers, overlap) preamble = ft.get_preamble(total_subcarriers) num_preamble_symbols = len(preamble) // total_subcarriers payload = ft.get_payload(payload_symbols, used_subcarriers) payload = np.tile(payload, num_frames).flatten() src = blocks.vector_source_b(payload, repeat=False) framer = fbmc.frame_generator_bvc(used_subcarriers, total_subcarriers, payload_symbols, overlap, channel_map, preamble) snk_frame = blocks.vector_sink_c(total_subcarriers) # a debug output mod = fbmc.tx_sdft_vcc(taps, total_subcarriers) demod = fbmc.rx_sdft_cvc(taps, total_subcarriers) skipper = blocks.skiphead(8 * total_subcarriers, 4) snk_rx = blocks.vector_sink_c(total_subcarriers) deframer = fbmc.deframer_vcb(used_subcarriers, total_subcarriers, num_preamble_symbols, payload_symbols, overlap, channel_map) snk = blocks.vector_sink_b(1) self.tb.connect(src, framer, mod, demod, skipper, deframer, snk) self.tb.connect(framer, snk_frame) self.tb.connect(skipper, snk_rx) self.tb.run() res = np.array(snk.data()) print res print payload moddata = np.array(snk_frame.data()) print "len(moddata) = ", len(moddata) rxdata = np.array(snk_rx.data()) print "len(rxdata) = ", len(rxdata) # plt.plot(rxdata.real * 0.03) # for i in range(len(moddata)): # if (i + 1) % total_subcarriers == 0: # plt.axvline(i) # plt.plot(moddata.real) # plt.grid() # plt.show() print "len(payload) = ", len(payload) print "len(result) = ", len(res) self.assertTupleEqual(tuple(payload[:len(res)]), tuple(res))
def test_004_connect(self): """ Advanced test: - Allocator -> IFFT -> Frequency offset -> FFT -> Serializer - FFT does shift (moves DC to middle) - Make sure input == output - Frequency offset is -2 carriers """ fft_len = 8 n_syms = 1 carr_offset = -2 freq_offset = 1.0 / fft_len * carr_offset # Normalized frequency occupied_carriers = ((-2, -1, 1, 2),) pilot_carriers = ((-3,), (3,)) pilot_symbols = ((1j,), (-1j,)) tx_data = (1, 2, 3, 4) tag_name = "len" tag = gr.tag_t() tag.offset = 0 tag.key = pmt.string_to_symbol(tag_name) tag.value = pmt.from_long(len(tx_data)) offsettag = gr.tag_t() offsettag.offset = 0 offsettag.key = pmt.string_to_symbol("ofdm_sync_carr_offset") offsettag.value = pmt.from_long(carr_offset) src = blocks.vector_source_c(tx_data, False, 1, (tag, offsettag)) alloc = digital.ofdm_carrier_allocator_cvc( fft_len, occupied_carriers, pilot_carriers, pilot_symbols, (), tag_name ) tx_ifft = fft.fft_vcc(fft_len, False, (1.0 / fft_len,) * fft_len, True) oscillator = analog.sig_source_c(1.0, analog.GR_COS_WAVE, freq_offset, 1.0 / fft_len) mixer = blocks.multiply_cc() rx_fft = fft.fft_vcc(fft_len, True, (), True) sink2 = blocks.vector_sink_c(fft_len) self.tb.connect(rx_fft, sink2) serializer = digital.ofdm_serializer_vcc(alloc, "", 0, "ofdm_sync_carr_offset", True) sink = blocks.vector_sink_c() self.tb.connect( src, alloc, tx_ifft, blocks.vector_to_stream(gr.sizeof_gr_complex, fft_len), (mixer, 0), blocks.stream_to_vector(gr.sizeof_gr_complex, fft_len), rx_fft, serializer, sink, ) self.tb.connect(oscillator, (mixer, 1)) self.tb.run() self.assertComplexTuplesAlmostEqual(sink.data()[-len(occupied_carriers[0]) :], tx_data, places=4)
def __init__(self): gr.top_block.__init__(self) self._N = 2000000 # number of samples to use self._fs = 1000 # initial sampling rate self._M = M = 9 # Number of channels to channelize self._ifs = M*self._fs # initial sampling rate # Create a set of taps for the PFB channelizer self._taps = filter.firdes.low_pass_2(1, self._ifs, 475.50, 50, attenuation_dB=100, window=filter.firdes.WIN_BLACKMAN_hARRIS) # Calculate the number of taps per channel for our own information tpc = scipy.ceil(float(len(self._taps)) / float(self._M)) print "Number of taps: ", len(self._taps) print "Number of channels: ", self._M print "Taps per channel: ", tpc # Create a set of signals at different frequencies # freqs lists the frequencies of the signals that get stored # in the list "signals", which then get summed together self.signals = list() self.add = blocks.add_cc() freqs = [-70, -50, -30, -10, 10, 20, 40, 60, 80] for i in xrange(len(freqs)): f = freqs[i] + (M/2-M+i+1)*self._fs self.signals.append(analog.sig_source_c(self._ifs, analog.GR_SIN_WAVE, f, 1)) self.connect(self.signals[i], (self.add,i)) self.head = blocks.head(gr.sizeof_gr_complex, self._N) # Construct the channelizer filter self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps, 1) # Construct a vector sink for the input signal to the channelizer self.snk_i = blocks.vector_sink_c() # Connect the blocks self.connect(self.add, self.head, self.pfb) self.connect(self.add, self.snk_i) # Use this to play with the channel mapping #self.pfb.set_channel_map([5,6,7,8,0,1,2,3,4]) # Create a vector sink for each of M output channels of the filter and connect it self.snks = list() for i in xrange(self._M): self.snks.append(blocks.vector_sink_c()) self.connect((self.pfb, i), self.snks[i])
def __init__(self): gr.top_block.__init__(self) self._N = 200000 # number of samples to use self._fs = 9000 # initial sampling rate self._M = 9 # Number of channels to channelize # Create a set of taps for the PFB channelizer self._taps = filter.firdes.low_pass_2(1, self._fs, 500, 20, attenuation_dB=10, window=filter.firdes.WIN_BLACKMAN_hARRIS) # Calculate the number of taps per channel for our own information tpc = scipy.ceil(float(len(self._taps)) / float(self._M)) print "Number of taps: ", len(self._taps) print "Number of channels: ", self._M print "Taps per channel: ", tpc repeated = True if(repeated): self.vco_input = analog.sig_source_f(self._fs, analog.GR_SIN_WAVE, 0.25, 110) else: amp = 100 data = scipy.arange(0, amp, amp/float(self._N)) self.vco_input = blocks.vector_source_f(data, False) # Build a VCO controlled by either the sinusoid or single chirp tone # Then convert this to a complex signal self.vco = blocks.vco_f(self._fs, 225, 1) self.f2c = blocks.float_to_complex() self.head = blocks.head(gr.sizeof_gr_complex, self._N) # Construct the channelizer filter self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps) # Construct a vector sink for the input signal to the channelizer self.snk_i = blocks.vector_sink_c() # Connect the blocks self.connect(self.vco_input, self.vco, self.f2c) self.connect(self.f2c, self.head, self.pfb) self.connect(self.f2c, self.snk_i) # Create a vector sink for each of M output channels of the filter and connect it self.snks = list() for i in xrange(self._M): self.snks.append(blocks.vector_sink_c()) self.connect((self.pfb, i), self.snks[i])
def test_003_go_big(self): print "test_003_go_big -> try out!" # set up fg L = 32 overlap = 4 multiple = 8 taps = ft.prototype_fsamples(overlap, False) print taps # data = np.arange(1, multiple * L + 1, dtype=np.complex) data = np.zeros(L, dtype=np.complex) data[0] = np.complex(1, 0) data[L / 2] = np.complex(1, 0) data[L / 4] = np.complex(1, -1) data[L / 8] = np.complex(1, 0) data[3 * L / 4] = np.complex(1, 1) # print data # print np.reshape(data, (L, -1)) data = np.repeat(np.reshape(data, (L, -1)), multiple, axis=1) data = data.T.flatten()#np.reshape(data, (L, -1)) print "shape(data) = ", np.shape(data) # print data # get blocks for test src = blocks.vector_source_c(data, vlen=1) rx_domain = fbmc.rx_domain_cvc(taps.tolist(), L) impulse_taps = ft.generate_phydyas_filter(L, overlap) print "fft_size: ", rx_domain.fft_size() snk = blocks.vector_sink_c(vlen=L) pfb = fbmc.rx_polyphase_cvc(impulse_taps.tolist(), L) snk1 = blocks.vector_sink_c(vlen=L) # connect and run self.tb.connect(src, rx_domain, snk) self.tb.connect(src, pfb, snk1) self.tb.run() # check data ref = ft.rx_fdomain(data, taps, L).T.flatten() res = np.array(snk.data()) res1 = np.array(snk1.data()) # print "ref: ", np.shape(ref) # print "res: ", np.shape(res) # print np.reshape(res, (-1, L)).T # mat1 = np.reshape(res1, (L, -1)).T # print np.shape(mat1) self.assertComplexTuplesAlmostEqual(ref, res, 5)
def test_003_block_pinching(self): n_reps = 1 n_subcarriers = 8 n_timeslots = 8 block_len = n_subcarriers * n_timeslots cp_len = 8 ramp_len = 4 cs_len = ramp_len * 2 window_len = get_window_len(cp_len, n_timeslots, n_subcarriers, cs_len) window_taps = get_raised_cosine_ramp(ramp_len, window_len) data = np.arange(block_len, dtype=np.complex) + 1 ref = add_cyclic_starfix(data, cp_len, cs_len) ref = pinch_block(ref, window_taps) data = np.tile(data, n_reps) ref = np.tile(ref, n_reps) print "input is: ", len(data), " -> " , len(ref) # short_window = np.concatenate((window_taps[0:ramp_len], window_taps[-ramp_len:])) prefixer = gfdm.cyclic_prefixer_cc(block_len, cp_len, cs_len, ramp_len, window_taps) src = blocks.vector_source_c(data) dst = blocks.vector_sink_c() self.tb.connect(src, prefixer, dst) self.tb.run() res = np.array(dst.data()) print ref[-10:] print res[-10:] self.assertComplexTuplesAlmostEqual(res, ref, 4)
def test_001_diff_phasor_vcc(self): a = [1+2j,2+3.5j,3.5+4j,4+5j,5+6j] b = [1j,1j,1j,1j,1j] c = [-1j+3,1j,-7+0j,2.5j+0.333,3.2j] d = [(0.35979271051026462+0.89414454782483865j), (0.19421665709046287+0.024219594550527801j), (0.12445564785882557+0.40766238899138718j), (0.041869638845043688+0.97860437393366329j), (0.068927762235083234+0.16649764877365247j)] e = [(0.16207552830286298+0.435385030608331j), (0.47195779613669675+0.37824764113272558j), (0.13911998015446148+0.6585095669811617j), (0.093510743358783954+0.98446560079828938j), (0.86036393297704694+0.72043005342024602j)] multconj = lambda x,y: x.conjugate()*y src_data = a+b+c+d+e expected_result = [0j,0j,0j,0j,0j]+map(multconj,a,b)+map(multconj,b,c)+map(multconj,c,d)+map(multconj,d,e) src = blocks.vector_source_c(src_data) s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 5) diff_phasor_vcc = grdab.diff_phasor_vcc(5) v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, 5) dst = blocks.vector_sink_c() self.tb.connect(src, s2v, diff_phasor_vcc, v2s, dst) self.tb.run() result_data = dst.data() # print expected_result # print result_data self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6)
def test_1seg_mode3 (self): # set up fg total_segments = 1; mode = 3; total_carriers = total_segments*96*2**(mode-1) deinterleaver_1seg = isdbt.frequency_deinterleaver_1seg(mode=3) # the random array of indices src_data = (249, 272, 269, 137, 309, 24, 255, 327, 294, 197, 364, 3, 160, 1, 46, 354, 104, 113, 195, 193, 59, 236, 90, 288, 292, 224, 258, 382, 163, 85, 153, 89, 350, 277, 298, 237, 230, 345, 135, 127, 340, 349, 366, 77, 180, 25, 11, 333, 332, 157, 239, 383, 91, 18, 314, 185, 10, 43, 102, 169, 162, 37, 0, 194, 117, 290, 233, 270, 278, 343, 338, 204, 317, 130, 273, 336, 377, 55, 315, 51, 304, 72, 23, 208, 266, 98, 174, 209, 35, 303, 82, 379, 9, 365, 295, 378, 257, 78, 225, 134, 48, 76, 84, 265, 337, 284, 240, 238, 114, 179, 341, 280, 58, 109, 101, 56, 96, 141, 281, 107, 12, 188, 253, 44, 232, 22, 32, 375, 120, 73, 215, 320, 326, 176, 356, 28, 248, 228, 212, 66, 282, 30, 80, 62, 371, 106, 344, 339, 328, 145, 200, 149, 63, 139, 210, 42, 368, 81, 131, 252, 216, 155, 361, 306, 19, 293, 275, 105, 330, 235, 171, 289, 16, 26, 348, 13, 158, 95, 61, 41, 316, 170, 29, 71, 52, 53, 261, 21, 254, 119, 192, 100, 69, 111, 276, 283, 99, 260, 103, 60, 259, 227, 285, 358, 65, 50, 251, 321, 45, 359, 144, 199, 268, 143, 83, 64, 219, 152, 211, 229, 7, 325, 296, 222, 331, 167, 8, 47, 267, 164, 201, 203, 112, 36, 67, 17, 220, 118, 299, 124, 198, 150, 357, 133, 380, 108, 116, 308, 196, 38, 367, 175, 244, 305, 223, 205, 74, 183, 27, 287, 190, 88, 243, 246, 33, 165, 302, 279, 182, 213, 376, 245, 355, 31, 381, 191, 132, 57, 217, 313, 307, 291, 319, 115, 256, 4, 34, 136, 166, 142, 312, 286, 370, 94, 373, 110, 97, 362, 14, 329, 226, 93, 122, 86, 351, 92, 324, 352, 221, 70, 40, 49, 353, 335, 75, 140, 318, 186, 271, 172, 123, 151, 156, 184, 79, 231, 242, 363, 54, 374, 138, 297, 202, 241, 154, 125, 5, 147, 369, 148, 263, 173, 274, 322, 177, 262, 161, 128, 214, 264, 206, 129, 15, 234, 347, 207, 126, 334, 68, 159, 189, 178, 310, 87, 300, 6, 250, 39, 20, 181, 323, 2, 247, 121, 342, 346, 301, 218, 372, 311, 360, 187, 168, 146) src_data = src_data*total_segments*3 expected_result = range(96*2**(mode-1))*total_segments*3 src = blocks.vector_source_c(src_data, False, total_carriers) dst = blocks.vector_sink_c(total_carriers) self.tb.connect(src,deinterleaver_1seg) self.tb.connect(deinterleaver_1seg,dst) self.tb.run() # check data actual_result = dst.data() # print "src data: ", src_data # print "actual result: ", actual_result # print "expected result: ", expected_result self.assertFloatTuplesAlmostEqual(expected_result, actual_result)
def test_1seg_mode2 (self): # set up fg total_segments = 1; mode = 2; total_carriers = total_segments*96*2**(mode-1) deinterleaver_1seg = isdbt.frequency_deinterleaver_1seg(mode) # the random array of indices src_data = (78, 120, 35, 91, 150, 6, 129, 160, 159, 169, 59, 148, 114, 154, 37, 123, 162, 5, 139, 70, 89, 136, 106, 128, 69, 65, 163, 190, 26, 184, 170, 151, 155, 50, 182, 1, 25, 16, 57, 73, 153, 158, 47, 12, 166, 55, 42, 28, 15, 112, 147, 61, 97, 186, 10, 156, 131, 71, 107, 191, 101, 83, 121, 175, 168, 100, 119, 2, 41, 17, 140, 72, 33, 8, 13, 84, 21, 74, 27, 23, 126, 165, 85, 111, 53, 77, 36, 105, 76, 66, 143, 187, 95, 7, 30, 142, 125, 49, 0, 132, 108, 86, 117, 167, 179, 48, 178, 20, 185, 145, 189, 109, 45, 81, 40, 181, 3, 62, 88, 127, 94, 92, 44, 133, 146, 67, 172, 99, 29, 141, 38, 104, 113, 102, 51, 4, 90, 135, 134, 68, 82, 110, 34, 11, 161, 137, 116, 103, 174, 144, 19, 39, 149, 98, 18, 115, 63, 171, 180, 157, 96, 64, 79, 31, 118, 14, 130, 58, 9, 188, 54, 177, 152, 164, 87, 24, 22, 52, 122, 173, 46, 80, 124, 43, 32, 138, 183, 56, 176, 60, 93, 75) src_data = src_data*total_segments expected_result = range(96*2**(mode-1))*total_segments src = blocks.vector_source_c(src_data, False, total_carriers) dst = blocks.vector_sink_c(total_carriers) self.tb.connect(src,deinterleaver_1seg) self.tb.connect(deinterleaver_1seg,dst) self.tb.run() # check data actual_result = dst.data() # print "src data: ", src_data # print "actual result: ", actual_result # print "expected result: ", expected_result self.assertFloatTuplesAlmostEqual(expected_result, actual_result)
def test_001_t(self): # set up fg fft_len = 256 cp_len = 32 samp_rate = 32000 data = np.random.choice([-1, 1], [100, fft_len]) timefreq = np.fft.ifft(data, axis=0) #add cp timefreq = np.hstack((timefreq[:, -cp_len:], timefreq)) # msg (only 4th and 5th tuples are needed) id1 = pmt.make_tuple(pmt.intern("Signal"), pmt.from_uint64(0)) name = pmt.make_tuple(pmt.intern("OFDM"), pmt.from_float(1.0)) id2 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(0.0)) id3 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(0.0)) id4 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(256)) id5 = pmt.make_tuple(pmt.intern("xxx"), pmt.from_float(32)) msg = pmt.make_tuple(id1, name, id2, id3, id4, id5) tx = np.reshape(timefreq, (1, -1)) # GR time! src = blocks.vector_source_c(tx[0].tolist(), True, 1, []) freq_offset = analog.sig_source_c(1, analog.GR_SIN_WAVE, 50.0 / samp_rate, 1.0, 0.0) mixer = blocks.multiply_cc() sync = inspector.ofdm_synchronizer_cc(4096) dst = blocks.vector_sink_c() dst2 = blocks.vector_sink_c() msg_src = blocks.message_strobe(msg, 0) # connect self.tb.connect(src, (mixer, 0)) self.tb.connect(freq_offset, (mixer, 1)) self.tb.connect(mixer, sync) self.tb.msg_connect((msg_src, 'strobe'), (sync, 'ofdm_in')) self.tb.connect(sync, dst) self.tb.connect(src, dst2) self.tb.start() time.sleep(0.1) self.tb.stop() self.tb.wait() # check data output = dst.data() expect = dst2.data() # block outputs 0j until it has enough OFDM symbols to perform estimations k = (k for k in range(len(output)) if output[k] != 0j).next() # use 10,000 samples for comparison since block fails sometimes # for one work function output = output[k:k + 10000] expect = expect[k:k + 10000] self.assertComplexTuplesAlmostEqual2(expect, output, abs_eps=0.001, rel_eps=10)
def test_001(self): ''' Test the complex AGC loop (single rate input) ''' tb = self.tb expected_result = ( (100.000244140625 + 7.2191943445432116e-07j), (72.892257690429688 + 52.959323883056641j), (25.089065551757812 + 77.216217041015625j), (-22.611061096191406 + 69.589706420898438j), (-53.357715606689453 + 38.766635894775391j), (-59.458671569824219 + 3.4792964243024471e-07j), (-43.373462677001953 - 31.512666702270508j), (-14.94139289855957 - 45.984889984130859j), (13.478158950805664 - 41.48150634765625j), (31.838506698608398 - 23.132022857666016j), (35.519271850585938 - 3.1176801940091536e-07j), (25.942903518676758 + 18.848621368408203j), (8.9492912292480469 + 27.5430908203125j), (-8.0852642059326172 + 24.883890151977539j), (-19.131628036499023 + 13.899936676025391j), (-21.383295059204102 + 3.1281737733479531e-07j), (-15.650330543518066 - 11.370632171630859j), (-5.4110145568847656 - 16.65339469909668j), (4.9008159637451172 - 15.083160400390625j), (11.628337860107422 - 8.4484796524047852j), (13.036135673522949 - 2.288476110834381e-07j), (9.5726661682128906 + 6.954948902130127j), (3.3216962814331055 + 10.223132133483887j), (-3.0204284191131592 + 9.2959251403808594j), (-7.1977195739746094 + 5.2294478416442871j), (-8.1072216033935547 + 1.8976157889483147e-07j), (-5.9838657379150391 - 4.3475332260131836j), (-2.0879747867584229 - 6.4261269569396973j), (1.9100792407989502 - 5.8786196708679199j), (4.5814824104309082 - 3.3286411762237549j), (5.1967458724975586 - 1.3684227440080576e-07j), (3.8647139072418213 + 2.8078789710998535j), (1.3594740629196167 + 4.1840314865112305j), (-1.2544282674789429 + 3.8607344627380371j), (-3.0366206169128418 + 2.2062335014343262j), (-3.4781389236450195 + 1.1194014604143376e-07j), (-2.6133756637573242 - 1.8987287282943726j), (-0.9293016791343689 - 2.8600969314575195j), (0.86727333068847656 - 2.6691930294036865j), (2.1243946552276611 - 1.5434627532958984j), (2.4633183479309082 - 8.6486437567145913e-08j), (1.8744727373123169 + 1.3618841171264648j), (0.67528903484344482 + 2.0783262252807617j), (-0.63866174221038818 + 1.965599536895752j), (-1.5857341289520264 + 1.152103066444397j), (-1.8640764951705933 + 7.6355092915036948e-08j), (-1.4381576776504517 - 1.0448826551437378j), (-0.52529704570770264 - 1.6166983842849731j), (0.50366902351379395 - 1.5501341819763184j), (1.26766037940979 - 0.92100900411605835j)) sampling_freq = 100 src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, sampling_freq * 0.10, 100.0) dst1 = blocks.vector_sink_c() head = blocks.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) agc = analog.agc_cc(1e-3, 1, 1) tb.connect(src1, head) tb.connect(head, agc) tb.connect(agc, dst1) tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4)
def test_001_t(self): preamble = ( 1.00000000000000 + 0.00000000000000j, -0.0198821876650702 - 0.999802329770066j, 0.0596151251698190 + 0.998221436781933j, -0.992892073701974 + 0.119018191801903j, -0.980297366804636 + 0.197527397177953j, 0.293850274337919 + 0.955851461405761j, -0.405525320812986 - 0.914083811354038j, 0.848983362091364 - 0.528419578452620j, 0.754564620158230 - 0.656225749270376j, -0.780057308185211 - 0.625708075660561j, 0.888282612749130 + 0.459297289222982j, -0.255616632440464 + 0.966778225458040j, -0.0198821876650804 + 0.999802329770065j, 0.971669340040416 - 0.236344438532879j, -0.869320274439587 + 0.494249188616716j, -0.727878810369485 - 0.685705795086423j, -0.905840393665518 - 0.423619146408540j, -0.0992537989080696 + 0.995062150522427j, -0.255616632440477 - 0.966778225458036j, 0.804316565270771 - 0.594201028971703j, 0.511435479103437 - 0.859321680579653j, -0.992892073701971 - 0.119018191801923j, 0.949820131727787 - 0.312796607022213j, 0.700042074569421 + 0.714101599096754j, 0.949820131727768 + 0.312796607022273j, -0.177997895677522 - 0.984030867978426j, 0.641093637592130 + 0.767462668693983j, -0.331619278552096 + 0.943413299722125j, 0.216978808106213 + 0.976176314419074j, 0.700042074569433 - 0.714101599096743j, -0.177997895677626 + 0.984030867978407j, -0.905840393665558 + 0.423619146408453j, -0.476867501428628 + 0.878975190822367j, 0.987375341936355 - 0.158398024407083j, -0.671098428359002 + 0.741368261698650j, -0.999209397227295 - 0.0397565150970890j, -0.780057308185194 + 0.625708075660582j, 0.987375341936324 + 0.158398024407273j, -0.827304032543040 + 0.561754428320796j, -0.980297366804605 - 0.197527397178109j, -0.827304032543027 + 0.561754428320816j, 0.987375341936332 + 0.158398024407226j, -0.780057308185292 + 0.625708075660460j, -0.999209397227299 - 0.0397565150969950j, -0.671098428359083 + 0.741368261698577j, 0.987375341936350 - 0.158398024407110j, -0.476867501428484 + 0.878975190822446j, -0.905840393665478 + 0.423619146408624j, -0.177997895677642 + 0.984030867978404j, 0.700042074569508 - 0.714101599096669j, 0.216978808106132 + 0.976176314419092j, -0.331619278552151 + 0.943413299722105j, 0.641093637592190 + 0.767462668693933j, -0.177997895677511 - 0.984030867978428j, 0.949820131727754 + 0.312796607022316j, 0.700042074569284 + 0.714101599096888j, 0.949820131727893 - 0.312796607021891j, -0.992892073701961 - 0.119018191802010j, 0.511435479103736 - 0.859321680579474j, 0.804316565270626 - 0.594201028971898j, -0.255616632440350 - 0.966778225458070j, -0.0992537989081486 + 0.995062150522419j, -0.905840393665482 - 0.423619146408617j, -0.727878810369385 - 0.685705795086529j, -0.869320274439717 + 0.494249188616486j, 0.971669340040621 - 0.236344438532038j, -0.0198821876652695 + 0.999802329770062j, -0.255616632440926 + 0.966778225457918j, 0.888282612749188 + 0.459297289222869j, -0.780057308185057 - 0.625708075660753j, 0.754564620158670 - 0.656225749269870j, 0.848983362091728 - 0.528419578452034j, -0.405525320812299 - 0.914083811354343j, 0.293850274337947 + 0.955851461405753j, -0.980297366804665 + 0.197527397177809j, -0.992892073702018 + 0.119018191801536j, 0.0596151251691726 + 0.998221436781972j, -0.0198821876650031 - 0.999802329770067j, 1.00000000000000 + 4.46840285540623e-13j) src_data = np.array([], dtype=np.complex64) expected_result = np.array([], dtype=np.complex64) np.append(src_data, np.zeros(100)) for i in range(10): np.append(src_data, preamble) np.append(expected_result, preamble) np.append(src_data, np.zeros(100)) np.append(expected_result, np.zeros(100)) random_comp = np.random.rand(700) + 1j * np.random.rand(700) np.append(src_data, random_comp) np.append(expected_result, random_comp) np.append(src_data, np.zeros(2000)) # set up fg src = blocks.vector_source_c(src_data) corr = digital.corr_est_cc(preamble, 1, 0, 1e-1) iso = learning.packet_isolator_c(600, 180, 200, "corr_est") dst = blocks.vector_sink_c() self.tb.connect(src, corr) self.tb.connect(corr, iso) self.tb.connect(iso, dst) self.tb.run() # check data result_data = dst.data() self.assertTrue(len(expected_result) == len(result_data)) self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6)
def test_007_256QAM(self): src_data = [] for i in range(0, 256): src_data.append(i) #print("test lista --->", src_data) # "Number of symbols" map_order = 6 # "Determine the expected result" expected_result = ( -15 - 15j, -15 - 13j, -15 - 9j, -15 - 11j, #0, 1, 2, 3 -15 - 1j, -15 - 3j, -15 - 7j, -15 - 5j, #4, 5, 6, 7 -15 + 15j, -15 + 13j, -15 + 9j, -15 + 11j, #8, 9, 10, 11 -15 + 1j, -15 + 3j, -15 + 7j, -15 + 5j, #12, 13, 14, 15 -13 - 15j, -13 - 13j, -13 - 9j, -13 - 11j, #16, 17, 18, 19 -13 - 1j, -13 - 3j, -13 - 7j, -13 - 5j, #20, 21, 22, 23 -13 + 15j, -13 + 13j, -13 + 9j, -13 + 11j, #24, 25, 26, 27 -13 + 1j, -13 + 3j, -13 + 7j, -13 + 5j, #28, 29, 30, 31 -9 - 15j, -9 - 13j, -9 - 9j, -9 - 11j, #32, 33, 34, 35 -9 - 1j, -9 - 3j, -9 - 7j, -9 - 5j, #36, 37, 38, 39 -9 + 15j, -9 + 13j, -9 + 9j, -9 + 11j, #40, 41, 42, 43 -9 + 1j, -9 + 3j, -9 + 7j, -9 + 5j, #44, 45, 46, 47 -11 - 15j, -11 - 13j, -11 - 9j, -11 - 11j, #48, 49, 50, 51 -11 - 1j, -11 - 3j, -11 - 7j, -11 - 5j, #52, 53, 54, 55 -11 + 15j, -11 + 13j, -11 + 9j, -11 + 11j, #56, 57, 58, 59 -11 + 1j, -11 + 3j, -11 + 7j, -11 + 5j, #60, 61, 62, 63 -1 - 15j, -1 - 13j, -1 - 9j, -1 - 11j, #64, 65, 66, 67 -1 - 1j, -1 - 3j, -1 - 7j, -1 - 5j, #68, 69, 70, 71 -1 + 15j, -1 + 13j, -1 + 9j, -1 + 11j, #72, 73, 74, 75 -1 + 1j, -1 + 3j, -1 + 7j, -1 + 5j, #76, 77, 78, 79 -3 - 15j, -3 - 13j, -3 - 9j, -3 - 11j, #80, 81, 82, 83 -3 - 1j, -3 - 3j, -3 - 7j, -3 - 5j, #84, 85, 86, 87 -3 + 15j, -3 + 13j, -3 + 9j, -3 + 11j, #88, 89, 90, 91 -3 + 1j, -3 + 3j, -3 + 7j, -3 + 5j, #92, 93, 94, 95 -7 - 15j, -7 - 13j, -7 - 9j, -7 - 11j, #96, 97, 98, 99 -7 - 1j, -7 - 3j, -7 - 7j, -7 - 5j, #100, 101, 102, 103 -7 + 15j, -7 + 13j, -7 + 9j, -7 + 11j, #104, 105, 106, 107 -7 + 1j, -7 + 3j, -7 + 7j, -7 + 5j, #108, 109, 110, 111 -5 - 15j, -5 - 13j, -5 - 9j, -5 - 11j, #112, 113, 114, 115 -5 - 1j, -5 - 3j, -5 - 7j, -5 - 5j, #116, 117, 118, 119 -5 + 15j, -5 + 13j, -5 + 9j, -5 + 11j, #120, 121, 122, 123 -5 + 1j, -5 + 3j, -5 + 7j, -5 + 5j, #124, 125, 126, 127 15 - 15j, 15 - 13j, 15 - 9j, 15 - 11j, #128, 129, 130, 131 15 - 1j, 15 - 3j, 15 - 7j, 15 - 5j, #132, 133, 134, 135 15 + 15j, 15 + 13j, 15 + 9j, 15 + 11j, #136, 137, 138, 139 15 + 1j, 15 + 3j, 15 + 7j, 15 + 5j, #140, 141, 142, 143 13 - 15j, 13 - 13j, 13 - 9j, 13 - 11j, #144, 145, 146, 147 13 - 1j, 13 - 3j, 13 - 7j, 13 - 5j, #148, 149, 150, 151 13 + 15j, 13 + 13j, 13 + 9j, 13 + 11j, #152, 153, 154, 155 13 + 1j, 13 + 3j, 13 + 7j, 13 + 5j, #156, 157, 158, 159 9 - 15j, 9 - 13j, 9 - 9j, 9 - 11j, #160, 161, 162, 163 9 - 1j, 9 - 3j, 9 - 7j, 9 - 5j, #164, 165, 166, 167 9 + 15j, 9 + 13j, 9 + 9j, 9 + 11j, #168, 169, 170, 171 9 + 1j, 9 + 3j, 9 + 7j, 9 + 5j, #172, 173, 174, 175 11 - 15j, 11 - 13j, 11 - 9j, 11 - 11j, #176, 177, 178, 179 11 - 1j, 11 - 3j, 11 - 7j, 11 - 5j, #180, 181, 182, 183 11 + 15j, 11 + 13j, 11 + 9j, 11 + 11j, #184, 185, 186, 187 11 + 1j, 11 + 3j, 11 + 7j, 11 + 5j, #188, 189, 190, 191 1 - 15j, 1 - 13j, 1 - 9j, 1 - 11j, #192, 193, 194, 195 1 - 1j, 1 - 3j, 1 - 7j, 1 - 5j, #196, 197, 198, 199 1 + 15j, 1 + 13j, 1 + 9j, 1 + 11j, #200, 201, 202, 203 1 + 1j, 1 + 3j, 1 + 7j, 1 + 5j, #204, 205, 206, 207 3 - 15j, 3 - 13j, 3 - 9j, 3 - 11j, #208, 209, 210, 211 3 - 1j, 3 - 3j, 3 - 7j, 3 - 5j, #212, 213, 214, 215 3 + 15j, 3 + 13j, 3 + 9j, 3 + 11j, #216, 217, 218, 219 3 + 1j, 3 + 3j, 3 + 7j, 3 + 5j, #220, 221, 222, 223 7 - 15j, 7 - 13j, 7 - 9j, 7 - 11j, #224, 225, 226, 227 7 - 1j, 7 - 3j, 7 - 7j, 7 - 5j, #228, 229, 230, 231 7 + 15j, 7 + 13j, 7 + 9j, 7 + 11j, #232, 233, 234, 235 7 + 1j, 7 + 3j, 7 + 7j, 7 + 5j, #236, 237, 238, 239 5 - 15j, 5 - 13j, 5 - 9j, 5 - 11j, #240, 241, 242, 243 5 - 1j, 5 - 3j, 5 - 7j, 5 - 5j, #244, 245, 246, 247 5 + 15j, 5 + 13j, 5 + 9j, 5 + 11j, #248, 249, 250, 251 5 + 1j, 5 + 3j, 5 + 7j, 5 + 5j) #252, 253, 254, 255 # "Create a complex vector source" src = blocks.vector_source_b(src_data) # "Instantiate the test module" qam_map = mqam_map_bc(map_order) # "Instantiate the binary sink" dst = blocks.vector_sink_c() # "Construct the flowgraph" self.tb.connect(src, qam_map) self.tb.connect(qam_map, dst) # "Create the flow graph" self.tb.run() # check data result_data = dst.data() #print("result data", result_data) self.assertTupleEqual(expected_result, result_data) self.assertEqual(len(expected_result), len(result_data)) print("test 256QAM")
def test_wo_tags_2s_rolloff_multiple_cps(self): "Two CP lengths, 2-sample rolloff and no tags." fft_len = 8 cp_lengths = (3, 2, 2) rolloff = 2 expected_result = [ 6.0 / 2, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, #1 7.0 / 2 + 1.0 / 2, 8, 1, 2, 3, 4, 5, 6, 7, 8, #2 7.0 / 2 + 1.0 / 2, 8, 1, 2, 3, 4, 5, 6, 7, 8, #3 6.0 / 2 + 1.0 / 2, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, #4 7.0 / 2 + 1.0 / 2, 8, 1, 2, 3, 4, 5, 6, 7, 8 #5 ] src = blocks.vector_source_c( list(range(1, fft_len + 1)) * 5, False, fft_len) cp = digital.ofdm_cyclic_prefixer(fft_len, cp_lengths, rolloff) sink = blocks.vector_sink_c() self.tb.connect(src, cp, sink) self.tb.run() self.assertEqual(sink.data(), expected_result)
def test_001(self): N = 1000 outfile = "test_out.dat" detached = False samp_rate = 200000 key = pmt.intern("samp_rate") val = pmt.from_double(samp_rate) extras = pmt.make_dict() extras = pmt.dict_add(extras, key, val) data = sig_source_c(samp_rate, 1000, 1, N) src = blocks.vector_source_c(data) fsnk = blocks.file_meta_sink(gr.sizeof_gr_complex, outfile, samp_rate, 1, blocks.GR_FILE_FLOAT, True, 1000000, extras, detached) fsnk.set_unbuffered(True) self.tb.connect(src, fsnk) self.tb.run() fsnk.close() handle = open(outfile, "rb") header_str = handle.read(parse_file_metadata.HEADER_LENGTH) if (len(header_str) == 0): self.assertFalse() try: header = pmt.deserialize_str(header_str) except RuntimeError: self.assertFalse() info = parse_file_metadata.parse_header(header, False) extra_str = handle.read(info["extra_len"]) self.assertEqual(len(extra_str) > 0, True) handle.close() try: extra = pmt.deserialize_str(extra_str) except RuntimeError: self.assertFalse() extra_info = parse_file_metadata.parse_extra_dict(extra, info, False) self.assertEqual(info['rx_rate'], samp_rate) self.assertEqual(pmt.to_double(extra_info['samp_rate']), samp_rate) # Test file metadata source src.rewind() fsrc = blocks.file_meta_source(outfile, False) vsnk = blocks.vector_sink_c() tsnk = blocks.tag_debug(gr.sizeof_gr_complex, "QA") ssnk = blocks.vector_sink_c() self.tb.disconnect(src, fsnk) self.tb.connect(fsrc, vsnk) self.tb.connect(fsrc, tsnk) self.tb.connect(src, ssnk) self.tb.run() fsrc.close() # Test to make sure tags with 'samp_rate' and 'rx_rate' keys # were generated and received correctly. tags = tsnk.current_tags() for t in tags: if (pmt.eq(t.key, pmt.intern("samp_rate"))): self.assertEqual(pmt.to_double(t.value), samp_rate) elif (pmt.eq(t.key, pmt.intern("rx_rate"))): self.assertEqual(pmt.to_double(t.value), samp_rate) # Test that the data portion was extracted and received correctly. self.assertComplexTuplesAlmostEqual(vsnk.data(), ssnk.data(), 5) os.remove(outfile)
def __init__(self): gr.top_block.__init__(self) self._nsamples = 1000000 self._audio_rate = 8000 # Set up N channels with their own baseband and IF frequencies self._N = 5 chspacing = 16000 freq = [10, 20, 30, 40, 50] f_lo = [ 0, 1 * chspacing, -1 * chspacing, 2 * chspacing, -2 * chspacing ] self._if_rate = 4 * self._N * self._audio_rate # Create a signal source and frequency modulate it self.sum = blocks.add_cc() for n in range(self._N): sig = analog.sig_source_f(self._audio_rate, analog.GR_SIN_WAVE, freq[n], 0.5) fm = fmtx(f_lo[n], self._audio_rate, self._if_rate) self.connect(sig, fm) self.connect(fm, (self.sum, n)) self.head = blocks.head(gr.sizeof_gr_complex, self._nsamples) self.snk_tx = blocks.vector_sink_c() self.channel = channels.channel_model(0.1) self.connect(self.sum, self.head, self.channel, self.snk_tx) # Design the channlizer self._M = 10 bw = chspacing / 2.0 t_bw = chspacing / 10.0 self._chan_rate = self._if_rate / self._M self._taps = filter.firdes.low_pass_2( 1, self._if_rate, bw, t_bw, attenuation_dB=100, window=filter.firdes.WIN_BLACKMAN_hARRIS) tpc = math.ceil(float(len(self._taps)) / float(self._M)) print("Number of taps: ", len(self._taps)) print("Number of channels: ", self._M) print("Taps per channel: ", tpc) self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps) self.connect(self.channel, self.pfb) # Create a file sink for each of M output channels of the filter and connect it self.fmdet = list() self.squelch = list() self.snks = list() for i in range(self._M): self.fmdet.append(analog.nbfm_rx(self._audio_rate, self._chan_rate)) self.squelch.append(analog.standard_squelch(self._audio_rate * 10)) self.snks.append(blocks.vector_sink_f()) self.connect((self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i])
def test_pll_carriertracking(self): expected_result = ( (1.000002384185791 + 7.219194575469601e-09j), (0.9980257153511047 + 0.06279045343399048j), (0.992796003818512 + 0.11979719996452332j), (0.9852395057678223 + 0.17117266356945038j), (0.9761406779289246 + 0.2171468883752823j), (0.9661445617675781 + 0.25799843668937683j), (0.9557913541793823 + 0.29403796792030334j), (0.9455097317695618 + 0.3255884349346161j), (0.935634434223175 + 0.35297322273254395j), (0.9264140129089355 + 0.37650591135025024j), (0.918036699295044 + 0.3964899182319641j), (0.9106329679489136 + 0.4132115840911865j), (0.9042812585830688 + 0.42693787813186646j), (0.899017333984375 + 0.4379141628742218j), (0.89484703540802 + 0.4463684558868408j), (0.891755223274231 + 0.45251286029815674j), (0.8897027969360352 + 0.4565400779247284j), (0.8886303901672363 + 0.45862627029418945j), (0.8884686827659607 + 0.4589335024356842j), (0.8891477584838867 + 0.4576151967048645j), (0.8905870318412781 + 0.4548112750053406j), (0.8927018642425537 + 0.4506511092185974j), (0.8954030275344849 + 0.4452534019947052j), (0.898613452911377 + 0.43873584270477295j), (0.9022520780563354 + 0.4312065541744232j), (0.9062415361404419 + 0.42276597023010254j), (0.9104995131492615 + 0.4135076403617859j), (0.9149653315544128 + 0.4035266935825348j), (0.9195748567581177 + 0.3929111361503601j), (0.9242699146270752 + 0.3817441761493683j), (0.9289909601211548 + 0.37010061740875244j), (0.9336962103843689 + 0.3580598831176758j), (0.9383456707000732 + 0.3456934690475464j), (0.9429033994674683 + 0.3330692648887634j), (0.9473329186439514 + 0.3202497363090515j), (0.9516113996505737 + 0.3072968125343323j), (0.9557210206985474 + 0.2942683696746826j), (0.9596443772315979 + 0.2812172472476959j), (0.963365912437439 + 0.2681918740272522j), (0.9668760299682617 + 0.2552390694618225j), (0.9701738357543945 + 0.24240154027938843j), (0.9732568264007568 + 0.22971850633621216j), (0.9761228561401367 + 0.21722495555877686j), (0.9787704944610596 + 0.20495179295539856j), (0.9812103509902954 + 0.1929289996623993j), (0.98344886302948 + 0.18118229508399963j), (0.9854917526245117 + 0.1697331666946411j), (0.9873413443565369 + 0.1586003601551056j), (0.989014744758606 + 0.147801473736763j), (0.9905213713645935 + 0.1373506784439087j), (0.9918720126152039 + 0.12725868821144104j), (0.9930678606033325 + 0.1175333634018898j), (0.9941287040710449 + 0.10818269848823547j), (0.9950648546218872 + 0.0992119163274765j), (0.995887041091919 + 0.09062285721302032j), (0.9965973496437073 + 0.08241605758666992j), (0.9972119927406311 + 0.07459107041358948j), (0.997741162776947 + 0.06714606285095215j), (0.9981945753097534 + 0.06007742881774902j), (0.9985741376876831 + 0.05337977409362793j), (0.9988903999328613 + 0.04704824090003967j), (0.9991542100906372 + 0.04107558727264404j), (0.9993717074394226 + 0.03545379638671875j), (0.9995449185371399 + 0.03017553687095642j), (0.9996798634529114 + 0.025230854749679565j), (0.999785304069519 + 0.02061113715171814j), (0.9998669624328613 + 0.01630493998527527j), (0.9999253749847412 + 0.012303531169891357j), (0.999961256980896 + 0.008596181869506836j), (0.9999842047691345 + 0.005170613527297974j), (0.9999972581863403 + 0.0020167529582977295j), (1.0000011920928955 - 0.0008766651153564453j), (0.9999923706054688 - 0.0035211145877838135j), (0.999980092048645 - 0.00592736154794693j), (0.9999660849571228 - 0.008106544613838196j), (0.9999516606330872 - 0.010069712996482849j), (0.9999289512634277 - 0.011828280985355377j), (0.9999079704284668 - 0.013392657041549683j), (0.9998894333839417 - 0.01477348804473877j), (0.9998739957809448 - 0.015980780124664307j), (0.9998545050621033 - 0.017024904489517212j), (0.9998371601104736 - 0.017916440963745117j), (0.9998237490653992 - 0.01866436004638672j), (0.999815046787262 - 0.01927858591079712j), (0.9998044967651367 - 0.019767403602600098j), (0.9997949600219727 - 0.020140081644058228j), (0.9997900128364563 - 0.020405471324920654j), (0.9997888207435608 - 0.020570307970046997j), (0.9997872114181519 - 0.020643681287765503j), (0.9997851848602295 - 0.020633310079574585j), (0.9997866153717041 - 0.020545780658721924j), (0.9997920989990234 - 0.020388543605804443j), (0.9997975826263428 - 0.02016708254814148j), (0.9998003840446472 - 0.019888341426849365j), (0.99980628490448 - 0.019558459520339966j), (0.9998152256011963 - 0.019182950258255005j), (0.9998254179954529 - 0.01876668632030487j), (0.9998309016227722 - 0.01831553876399994j), (0.999838650226593 - 0.017833217978477478j), (0.9998488426208496 - 0.017324130982160568j)) sampling_freq = 10e3 freq = sampling_freq / 100 loop_bw = math.pi / 100.0 maxf = 1 minf = -1 src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) pll = analog.pll_carriertracking_cc(loop_bw, maxf, minf) head = blocks.head(gr.sizeof_gr_complex, int(freq)) dst = blocks.vector_sink_c() self.tb.connect(src, pll, head) self.tb.connect(head, dst) self.tb.run() dst_data = dst.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5)
tx_len = int(20e3) if mod_type.modname == "QAM64": tx_len = int(30e3) src = source_alphabet(alphabet_type, tx_len, True) mod = mod_type() fD = 1 delays = [0.0, 0.9, 1.7] mags = [1, 0.8, 0.3] ntaps = 8 noise_amp = 10**(-snr / 10.0) chan = channels.dynamic_channel_model(200e3, 0.01, 50, .01, 0.5e3, 8, fD, True, 4, delays, mags, ntaps, noise_amp, 0x1337) snk = blocks.vector_sink_c() tb = gr.top_block() # connect blocks if apply_channel: tb.connect(src, mod, chan, snk) else: tb.connect(src, mod, snk) tb.run() raw_output_vector = np.array(snk.data(), dtype=np.complex64) # start the sampler some random time after channel model transients (arbitrary values here) sampler_indx = random.randint(50, 500) while sampler_indx + vec_length < len( raw_output_vector) and modvec_indx < nvecs_per_key:
def test_001_t (self): # Create filters filters_cc = [] lms_filter_cc = adapt.lms_filter_cc(self.first_input, self.n_taps, self.mu_lms, self.skip, self.decimation, self.adapt, self.reset) filters_cc.append(lms_filter_cc) nlms_filter_cc = adapt.nlms_filter_cc(self.first_input, self.n_taps, self.mu_nlms, self.skip, self.decimation, self.adapt, self.reset) filters_cc.append(nlms_filter_cc) rls_filter_cc = adapt.rls_filter_cc(self.first_input, self.n_taps, self.delta_rls, self.lambda_rls, self.skip, self.decimation, self.adapt, self.reset) filters_cc.append(rls_filter_cc) qrd_rls_filter_cc = adapt.qrd_rls_filter_cc(self.n_taps, self.delta_qrd_rls, self.lambda_qrd_rls, self.skip, self.decimation, self.adapt, self.reset) filters_cc.append(qrd_rls_filter_cc) iqrd_rls_filter_cc = adapt.iqrd_rls_filter_cc(self.n_taps, self.delta_iqrd_rls, self.lambda_iqrd_rls, self.skip, self.decimation, self.adapt, self.reset) filters_cc.append(iqrd_rls_filter_cc) y_sink = blocks.vector_sink_c() e_sink = blocks.vector_sink_c() results = [] names = [] # Channel model W = 3.1 h = np.zeros(4) h[1:4] = 0.5 * (1 + np.cos(2*np.pi/W * np.linspace(-1,1,3))) # Some useful signal to be transmitted np.random.seed(2701) d = np.empty(self.n_samples, dtype=np.complex64) d.real = np.random.randint(2,size=self.n_samples)*2-1 # Random bipolar (-1,1) sequence d.imag = np.random.randint(2,size=self.n_samples)*2-1 u = np.convolve(d, h, mode='valid') # Distorted signal u += np.random.normal(0, np.sqrt(0.001), u.size) # Received signal for filter_cc in filters_cc: d_source = blocks.vector_source_c(d.tolist()) u_source = blocks.vector_source_c(u.tolist()) self.tb.connect(d_source, (filter_cc, 0)) self.tb.connect(u_source, (filter_cc, 1)) self.tb.connect((filter_cc, 0), y_sink) self.tb.connect((filter_cc, 1), e_sink) self.tb.run() results.append(filter_cc.pc_throughput_avg() / 1e6) names.append(str(filter_cc.__class__.__name__).replace('_sptr','')) self.tb.disconnect(filter_cc) if self.plot_enabled: # plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b', 'k']))) fig, ax = plt.subplots(figsize=(5,4)) index = np.arange(len(names)) # the x locations for the groups width = 0.6 # the width of the bars rects = ax.bar(index+width/2, results, width, width, label='Complex (n={})'.format(self.n_taps)) ax.set_ylabel('Throughput (MSPS)') ax.set_title('Throughput for different algorithms\n{}'.format(cpuinfo.get_cpu_info()['brand'])) ax.set_xticks(index + width / 2) ax.set_xticklabels(names, rotation=45, ha="right") ax.legend() xpos = 'center' xpos = xpos.lower() # normalize the case of the parameter ha = {'center': 'center', 'right': 'left', 'left': 'right'} offset = {'center': 0.5, 'right': 0.57, 'left': 0.43} # x_txt = x + w*off for rect in rects: height = rect.get_height() ax.text(rect.get_x() + rect.get_width()*offset[xpos], 1.01*height, '{0:.2f}'.format(height), ha=ha[xpos], va='bottom') fig.tight_layout() plt.show()
def __init__( self, target_freq, samp_rate=DEFAULT_SAMPLE_RATE, low_pass_filter_cutoff_freq=DEFAULT_LOW_PASS_FILTER_CUTOFF_FREQ, low_pass_filter_trans_width=DEFAULT_LOW_PASS_FILTER_TRANS_WIDTH, volume=DEFAULT_OUTPUT_SIGNAL_GAIN): gr.top_block.__init__(self, "FM receiver without GUI") self.counter = 0 ################################################## # Variables ################################################## self.wbfm_freq = 0 self.heterodyne_freq = 0 self.center_sdr_hardware_freq = 0 self.samp_rate = samp_rate self.low_pass_filter_cutoff_freq = low_pass_filter_cutoff_freq self.low_pass_filter_trans_width = low_pass_filter_trans_width self.output_audio_gain = volume if (0 == samp_rate): self.samp_rate = DEFAULT_SAMPLE_RATE if (0 == low_pass_filter_cutoff_freq): self.low_pass_filter_cutoff_freq = DEFAULT_LOW_PASS_FILTER_CUTOFF_FREQ if (0 == low_pass_filter_trans_width): self.low_pass_filter_trans_width = DEFAULT_LOW_PASS_FILTER_TRANS_WIDTH if (0 == volume): self.output_audio_gain = DEFAULT_OUTPUT_SIGNAL_GAIN self.calculate_frequencies(target_freq) ################################################## # Blocks ################################################## if ((self.audio_freq < 20e3) or (0 != self.samp_rate % self.wbfm_freq)): self.samp_rate = DEFAULT_SAMPLE_RATE self.wbfm_freq = DEFAULT_SAMPLE_RATE / 10 print("Error! Sample rate % WBFM frequency should be == 0\n" + "Using default values: Sample rate = " + "%.1E" % (self.samp_rate) + " Hz\nWBFM frequency = " + "%.1E" % (self.wbfm_freq) + " Hz\n") if ((self.audio_freq < 20e3) or (0 != self.wbfm_freq % self.audio_freq)): self.wbfm_freq = self.samp_rate / 10 self.audio_freq = self.wbfm_freq / 10 print( "Error! WBFM frequency % audio final frequency should be == 0\n" + "Using default values:\nWBFM frequency = " + "%.1E" % (self.wbfm_freq) + " Hz\nAudio final frequency = " + "%.1E" % (self.audio_freq) + " Hz\n") print("Your FM radio settings:\nTarget frequency = " + "%.5g" % (target_freq) + " Hz\nSample rate = " + "%.3g" % (self.samp_rate) + " Hz \nLow pass filter cutoff frequency = " + "%.3g" % (self.low_pass_filter_cutoff_freq) + " Hz \nLow pass filter transition width = " + "%.3g" % (self.low_pass_filter_trans_width) + " Hz \nOutput signal gain (volume) = " + str(self.output_audio_gain) + "\n") self.wbfm_receive = analog.wfm_rcv( quad_rate=self.wbfm_freq, audio_decimation=int(self.wbfm_freq / self.audio_freq), ) self.vector_sink_if = blocks.vector_sink_c(1, 1024) self.src_heterodyne = analog.sig_source_c(self.samp_rate, analog.GR_COS_WAVE, self.heterodyne_freq, 1, 0) self.src_hackrf = osmosdr.source(args="numchan=" + str(1) + " " + '') self.src_hackrf.set_sample_rate(self.samp_rate) self.src_hackrf.set_center_freq(self.center_sdr_hardware_freq, 0) self.src_hackrf.set_freq_corr(0, 0) self.src_hackrf.set_dc_offset_mode(0, 0) self.src_hackrf.set_iq_balance_mode(0, 0) self.src_hackrf.set_gain_mode(False, 0) self.src_hackrf.set_gain(10, 0) self.src_hackrf.set_if_gain(20, 0) self.src_hackrf.set_bb_gain(30, 0) self.src_hackrf.set_antenna('', 0) self.src_hackrf.set_bandwidth(0, 0) self.output_audio_final = audio.sink(int(self.audio_freq), '', True) self.multiply_output_volume = blocks.multiply_const_vff( (self.output_audio_gain, )) self.low_pass_filter = filter.fir_filter_ccf( int(self.samp_rate / self.wbfm_freq), firdes.low_pass(1, self.samp_rate, self.low_pass_filter_cutoff_freq, self.low_pass_filter_trans_width, firdes.WIN_HAMMING, 6.76)) self.IF_mixer = blocks.multiply_vcc(1) ################################################## # Connections ################################################## self.connect((self.IF_mixer, 0), (self.low_pass_filter, 0)) self.connect((self.IF_mixer, 0), (self.vector_sink_if, 0)) self.connect((self.low_pass_filter, 0), (self.wbfm_receive, 0)) self.connect((self.multiply_output_volume, 0), (self.output_audio_final, 0)) self.connect((self.src_hackrf, 0), (self.IF_mixer, 1)) self.connect((self.src_heterodyne, 0), (self.IF_mixer, 0)) self.connect((self.wbfm_receive, 0), (self.multiply_output_volume, 0))
def test_001_t (self): ''' Simulate convergence for different channel models. :return: ''' # Channel model W = [2.9, 3.1, 3.3, 3.5] h = np.zeros((len(W), 4)) for j, Wj in enumerate(W): h[j][1:4] = 0.5 * (1 + np.cos(2*np.pi/Wj * np.linspace(-1,1,3))) # Filters qrd_rls_filter_cc = [] y_sink_qrd_rls = [] e_sink_qrd_rls = [] for j, _ in enumerate(W): qrd_rls_filter_cc.append(adapt.qrd_rls_filter_cc(self.n_taps, self.delta, self._lambda, self.skip, self.decimation, self.adapt, self.reset)) y_sink_qrd_rls.append(blocks.vector_sink_c()) e_sink_qrd_rls.append(blocks.vector_sink_c()) self.tb.connect((qrd_rls_filter_cc[j], 0), y_sink_qrd_rls[j]) self.tb.connect((qrd_rls_filter_cc[j], 1), e_sink_qrd_rls[j]) for i in range(0, self.n_ensemble): # Set taps to zero for j in range(0, len(W)): qrd_rls_filter_cc[j].set_taps(np.zeros(self.n_taps, dtype=np.complex128)) # Some useful signal to be transmitted np.random.seed(i) d = np.zeros(self.n_samples, dtype=np.complex128) d.real = np.random.randint(2, size=self.n_samples)*2-1 # Random bipolar (-1,1) sequence d.imag = np.random.randint(2, size=self.n_samples)*2-1 d_source = blocks.vector_source_c(d.tolist()) u = [] u_source = [] for j in range(0, len(W)): u.append(np.convolve(d, h[j], mode='valid')) # Distorted signal u[j] += np.random.normal(0, np.sqrt(0.001), u[j].size) # Received signal u_source.append(blocks.vector_source_c(u[j].tolist())) self.tb.connect(d_source, (qrd_rls_filter_cc[j], 0)) self.tb.connect(u_source[j], (qrd_rls_filter_cc[j], 1)) self.tb.run() for j in range(0, len(W)): self.tb.disconnect(d_source, (qrd_rls_filter_cc[j], 0)) self.tb.disconnect(u_source[j], (qrd_rls_filter_cc[j], 1)) e_data_qrd_rls = [] for j in range(0, len(W)): e_data_qrd_rls.append((np.abs(e_sink_qrd_rls[j].data()) ** 2).reshape((self.n_ensemble, self.n_samples-h[j].size*1))) e_data_qrd_rls[j] = np.mean(e_data_qrd_rls[j], axis=0) if self.plot_enabled: plt.figure(figsize=(5, 4)) plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b', 'k']))) plt.title("Learning curves for QRD-RLS algorithm") plt.xlabel("Number of iterations") plt.ylabel("Ensemble-averaged square error") for j in range(0, len(W)): plt.semilogy(e_data_qrd_rls[j], label="W={}".format(W[j])) plt.legend() plt.grid() plt.tight_layout() plt.show()
def configure(self, initial=False): """Configure or reconfigure the flowgraph""" self.lock() if self.usrp.apply_cfg(self.pending_cfg): self.pending_cfg = copy(self.usrp.get_cfg()) # Apply any pending configuration changes cfg = self.cfg = copy(self.pending_cfg) if not initial: self.disconnect_all() self.msg_disconnect(self.plot, "gui_busy_notifier", self.copy_if_gui_idle, "en") self.ctrl = usrp_controller_cc(self.usrp.uhd, cfg.center_freqs, cfg.lo_offset, cfg.skip_initial, cfg.tune_delay, cfg.fft_size * cfg.nframes) if cfg.continuous_run: self.set_continuous_run() else: self.set_single_run() self.scaleV = blocks.multiply_const_cc(cfg.scale) timedata_vlen = 1 self.timedata_sink = blocks.vector_sink_c(timedata_vlen) stream_to_fft_vec = blocks.stream_to_vector(gr.sizeof_gr_complex, cfg.fft_size) forward = True shift = True self.fft = fft.fft_vcc(cfg.fft_size, forward, cfg.window_coefficients, shift) freqdata_vlen = cfg.fft_size self.freqdata_sink = blocks.vector_sink_c(freqdata_vlen) c2mag_sq = blocks.complex_to_mag_squared(cfg.fft_size) stats = bin_statistics_ff(cfg.fft_size, cfg.nframes, cfg.detector) power = sum(tap * tap for tap in cfg.window_coefficients) # Divide magnitude-square by a constant to obtain power # in Watts. Assumes unit of USRP source is volts. impedance = 50.0 # ohms Vsq2W_dB = -10.0 * math.log10(cfg.fft_size * power * impedance) # Convert from Watts to dBm. W2dBm = blocks.nlog10_ff(10.0, cfg.fft_size, 30 + Vsq2W_dB) stitch = stitch_fft_segments_ff(cfg.fft_size, cfg.n_segments, cfg.overlap) fft_vec_to_stream = blocks.vector_to_stream(gr.sizeof_float, cfg.fft_size) n_valid_bins = cfg.fft_size - (cfg.fft_size * (cfg.overlap / 2) * 2) # FIXME: think about whether to cast to int vs round vs... stitch_vec_len = int(cfg.n_segments * cfg.fft_size) stream_to_stitch_vec = blocks.stream_to_vector(gr.sizeof_float, stitch_vec_len) plot_vec_len = int(cfg.n_segments * n_valid_bins) # Only copy sample to plot if enabled to avoid overwhelming gui thread self.copy_if_gui_idle = blocks.copy(gr.sizeof_float * plot_vec_len) self.plot = plotter_f(self, plot_vec_len) # Create the flowgraph: # # USRP - hardware source output stream of 32bit complex floats # ctrl - copy N samples then call retune callback and loop # scaleV - scale voltage by scalar to get calibrated output # fft - compute forward FFT, complex in complex out # mag^2 - convert vectors from complex to real by taking mag squared # stats - linear average or peak detect vectors if nframes > 1 # W2dBm - convert volt to dBm # stitch - overlap FFT segments by a certain number of bins # copy - copy if gui thread is idle, else drop # plot - plot data # # USRP > ctrl > fft > mag^2 > stats > W2dBm > stitch > copy > plot self.connect(self.usrp.uhd, self.ctrl, self.scaleV) if self.single_run.is_set(): self.logger.debug("Connected timedata_sink") self.connect((self.scaleV, 0), self.timedata_sink) else: self.logger.debug("Disconnected timedata_sink") self.connect((self.scaleV, 0), stream_to_fft_vec, self.fft) if self.single_run.is_set(): self.logger.debug("Connected freqdata_sink") self.connect((self.fft, 0), self.freqdata_sink) else: self.logger.debug("Disconnected freqdata_sink") self.connect((self.fft, 0), c2mag_sq, stats, W2dBm, fft_vec_to_stream) self.connect(fft_vec_to_stream, stream_to_stitch_vec, stitch) self.connect(stitch, self.copy_if_gui_idle, self.plot) self.msg_connect(self.plot, "gui_busy_notifier", self.copy_if_gui_idle, "en") self.unlock()
def test_006_t (self): print "NOTE: THIS TEST USES THE INSTALLED VERSION OF THE LIBRARY" print "Test interrupted frames during chirp ramp with zeros inbetween (fading)" m = ieee802_15_4_installed.css_modulator() bits_in1, bb_in1 = m.modulate_random() len_bb = len(bb_in1) sym_in1 = m.frame_DQPSK len_frame = len(sym_in1) bits_in2, bb_in2 = m.modulate_random() sym_in2 = m.frame_DQPSK bits_in3, bb_in3 = m.modulate_random() sym_in3 = m.frame_DQPSK print "Number of DQPSK symbols per frame:", len(sym_in1) zeros = np.ones((5000,)) data_in = np.concatenate((bb_in1[:192*30-25], zeros, bb_in1[192*30+24:], bb_in2, bb_in1, bb_in2, bb_in3, bb_in3, bb_in3)) src = blocks.vector_source_c(data_in) det = ieee802_15_4.simple_chirp_detector_cc(m.chirp_seq, len(m.time_gap_1), len(m.time_gap_2), 38, 0.999) snk_det = blocks.vector_sink_c() costas = ieee802_15_4.costas_loop_cc((1+1j, -1+1j, -1-1j, 1-1j), -1) snk_costas = blocks.vector_sink_c() preamble = ieee802_15_4.preamble_tagger_cc(len(m.preamble)) snk_preamble = blocks.vector_sink_c() frame_buffer = ieee802_15_4.frame_buffer_cc(len(sym_in1)) snk_framebuffer = blocks.vector_sink_c() self.tb.connect(src, det, costas, preamble, frame_buffer) self.tb.connect(det, snk_det) self.tb.connect(costas, snk_costas) self.tb.connect(preamble, snk_preamble) self.tb.connect(frame_buffer, snk_framebuffer) self.tb.run() ref_len = len_frame*3 det_out = snk_det.data()[:ref_len] ref_det = np.concatenate((sym_in1, sym_in2, sym_in1, sym_in2))[:ref_len+1] ref_det = np.delete(ref_det, 120) self.assertComplexTuplesAlmostEqual(det_out, ref_det, 5) costas_out = snk_costas.data()[:ref_len] ref_costas = ref_det self.assertComplexTuplesAlmostEqual(costas_out, ref_costas, 5) preamble_out = snk_preamble.data()[:ref_len] ref_preamble = ref_costas self.assertComplexTuplesAlmostEqual(preamble_out, ref_preamble, 5) framebuffer_out = snk_framebuffer.data()[:ref_len] ref_framebuffer = np.concatenate((sym_in2, sym_in1, sym_in2)) # f, axarr = plt.subplots(3,1) # axarr[0].plot(abs(ref_framebuffer - framebuffer_out)) # axarr[0].set_title('diff abs') # axarr[1].plot(np.real(ref_framebuffer)) # axarr[1].plot(np.imag(ref_framebuffer)) # axarr[1].set_title('ref') # axarr[2].plot(np.real(framebuffer_out)) # axarr[2].plot(np.imag(framebuffer_out)) # axarr[2].set_title('framebuffer out') # plt.suptitle('framebuffer output') # plt.show() self.assertComplexTuplesAlmostEqual(framebuffer_out, ref_framebuffer, 5)
def test_001(self): ''' Test the complex AGC loop (single rate input) ''' tb = self.tb expected_result = ( (100 + 0j), (72.89209747314453 + 52.9592170715332j), (25.089027404785156 + 77.2160873413086j), (-22.611034393310547 + 69.58960723876953j), (-53.35764694213867 + 38.766597747802734j), (-59.4586067199707 - 2.7399494229030097e-06j), (-43.3734245300293 - 31.51263999938965j), (-14.941386222839355 - 45.984867095947266j), (13.478157997131348 - 41.48149490356445j), (31.838510513305664 - 23.13202476501465j), (35.51927947998047 + 3.3255341804760974e-06j), (25.94291114807129 + 18.848634719848633j), (8.949296951293945 + 27.543113708496094j), (-8.085277557373047 + 24.883914947509766j), (-19.13165283203125 + 13.899954795837402j), (-21.383323669433594 - 2.987417019539862e-06j), (-15.65035343170166 - 11.370650291442871j), (-5.4110236167907715 - 16.653427124023438j), (4.900828838348389 - 15.083191871643066j), (11.62836742401123 - 8.448498725891113j), (13.036169052124023 + 2.4410530841123546e-06j), (9.572690963745117 + 6.954970359802246j), (3.3217051029205322 + 10.223164558410645j), (-3.0204410552978516 + 9.295955657958984j), (-7.197745323181152 + 5.229465007781982j), (-8.107251167297363 - 1.8916969111160142e-06j), (-5.983887195587158 - 4.347550392150879j), (-2.087981939315796 - 6.426152229309082j), (1.9100888967514038 - 5.87864351272583j), (4.581503391265869 - 3.3286550045013428j), (5.196768760681152 + 1.4596606661143596e-06j), (3.864729881286621 + 2.807892322540283j), (1.359479308128357 + 4.184051513671875j), (-1.2544355392456055 + 3.8607518672943115j), (-3.036635398864746 + 2.2062432765960693j), (-3.4781548976898193 - 1.137218077928992e-06j), (-2.613386869430542 - 1.8987380266189575j), (-0.9293051958084106 - 2.8601105213165283j), (0.8672783374786377 - 2.6692051887512207j), (2.1244049072265625 - 1.5434693098068237j), (2.463329315185547 + 9.225283861269418e-07j), (1.8744803667068481 + 1.3618910312652588j), (0.6752913594245911 + 2.078335762023926j), (-0.6386655569076538 + 1.9656078815460205j), (-1.5857415199279785 + 1.1521075963974j), (-1.864084243774414 - 7.840082503207668e-07j), (-1.438162922859192 - 1.0448874235153198j), (-0.5252984762191772 - 1.6167048215866089j), (0.5036717653274536 - 1.5501397848129272j), (1.2676655054092407 - 0.9210119843482971j)) sampling_freq = 100 src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, sampling_freq * 0.10, 100.0) dst1 = blocks.vector_sink_c() head = blocks.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) agc = analog.agc_cc(1e-3, 1, 1) tb.connect(src1, head) tb.connect(head, agc) tb.connect(agc, dst1) tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4)
def test_005(self): ''' Test the complex AGC loop (attack and decay rate inputs) ''' tb = self.tb expected_result = \ ((100.000244140625+7.2191943445432116e-07j), (0.80881959199905396+0.58764183521270752j), (0.30894950032234192+0.95084899663925171j), (-0.30895623564720154+0.95086973905563354j), (-0.80887287855148315+0.58768033981323242j), (-0.99984413385391235+5.850709250410091e-09j), (-0.80889981985092163-0.58770018815994263j), (-0.30897706747055054-0.95093393325805664j), (0.30898112058639526-0.95094609260559082j), (0.80893135070800781-0.58772283792495728j), (0.99990922212600708-8.7766354184282136e-09j), (0.80894720554351807+0.58773452043533325j), (0.30899339914321899+0.95098406076431274j), (-0.30899572372436523+0.95099133253097534j), (-0.80896598100662231+0.58774799108505249j), (-0.99994778633117676+1.4628290578855285e-08j), (-0.80897533893585205-0.58775502443313599j), (-0.30900305509567261-0.95101380348205566j), (0.30900448560714722-0.95101797580718994j), (0.80898630619049072-0.58776277303695679j), (0.99997037649154663-1.7554345532744264e-08j), (0.80899184942245483+0.58776694536209106j), (0.30900871753692627+0.95103120803833008j), (-0.30900952219963074+0.95103377103805542j), (-0.8089984655380249+0.58777159452438354j), (-0.99998390674591064+2.3406109050938539e-08j), (-0.809001624584198-0.58777409791946411j), (-0.30901208519935608-0.95104163885116577j), (0.30901262164115906-0.95104306936264038j), (0.80900543928146362-0.587776780128479j), (0.99999171495437622-2.6332081404234486e-08j), (0.80900734663009644+0.58777821063995361j), (0.30901408195495605+0.95104765892028809j), (-0.30901429057121277+0.95104855298995972j), (-0.80900967121124268+0.58777981996536255j), (-0.99999648332595825+3.2183805842578295e-08j), (-0.80901080369949341-0.58778077363967896j), (-0.30901527404785156-0.95105135440826416j), (0.30901545286178589-0.95105189085006714j), (0.80901217460632324-0.58778166770935059j), (0.99999916553497314-3.5109700036173308e-08j), (0.809012770652771+0.58778214454650879j), (0.30901595950126648+0.9510534405708313j), (-0.30901598930358887+0.95105385780334473j), (-0.80901366472244263+0.58778274059295654j), (-1.0000008344650269+4.0961388947380328e-08j), (-0.8090139627456665-0.58778303861618042j), (-0.30901634693145752-0.95105475187301636j), (0.30901640653610229-0.95105493068695068j), (0.80901449918746948-0.5877833366394043j)) sampling_freq = 100 src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, sampling_freq * 0.10, 100) dst1 = blocks.vector_sink_c() head = blocks.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) agc = analog.agc2_cc(1e-2, 1e-3, 1, 1) tb.connect(src1, head) tb.connect(head, agc) tb.connect(agc, dst1) tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4)
def main(): N = 1000000 fs = 8000 freqs = [100, 200, 300, 400, 500] nchans = 7 sigs = list() fmtx = list() for fi in freqs: s = analog.sig_source_f(fs, analog.GR_SIN_WAVE, fi, 1) fm = analog.nbfm_tx(fs, 4 * fs, max_dev=10000, tau=75e-6, fh=0.925 * (4 * fs) / 2.0) sigs.append(s) fmtx.append(fm) syntaps = filter.firdes.low_pass_2(len(freqs), fs, fs / float(nchans) / 2, 100, 100) print("Synthesis Num. Taps = %d (taps per filter = %d)" % (len(syntaps), len(syntaps) / nchans)) chtaps = filter.firdes.low_pass_2(len(freqs), fs, fs / float(nchans) / 2, 100, 100) print("Channelizer Num. Taps = %d (taps per filter = %d)" % (len(chtaps), len(chtaps) / nchans)) filtbank = filter.pfb_synthesizer_ccf(nchans, syntaps) channelizer = filter.pfb.channelizer_ccf(nchans, chtaps) noise_level = 0.01 head = blocks.head(gr.sizeof_gr_complex, N) noise = analog.noise_source_c(analog.GR_GAUSSIAN, noise_level) addnoise = blocks.add_cc() snk_synth = blocks.vector_sink_c() tb = gr.top_block() tb.connect(noise, (addnoise, 0)) tb.connect(filtbank, head, (addnoise, 1)) tb.connect(addnoise, channelizer) tb.connect(addnoise, snk_synth) snk = list() for i, si in enumerate(sigs): tb.connect(si, fmtx[i], (filtbank, i)) for i in range(nchans): snk.append(blocks.vector_sink_c()) tb.connect((channelizer, i), snk[i]) tb.run() if 1: channel = 1 data = snk[channel].data()[1000:] f1 = pyplot.figure(1) s1 = f1.add_subplot(1, 1, 1) s1.plot(data[10000:10200]) s1.set_title(("Output Signal from Channel %d" % channel)) fftlen = 2048 winfunc = numpy.blackman #winfunc = numpy.hamming f2 = pyplot.figure(2) s2 = f2.add_subplot(1, 1, 1) s2.psd(data, NFFT=fftlen, Fs=nchans * fs, noverlap=fftlen / 4, window=lambda d: d * winfunc(fftlen)) s2.set_title(("Output PSD from Channel %d" % channel)) f3 = pyplot.figure(3) s3 = f3.add_subplot(1, 1, 1) s3.psd(snk_synth.data()[1000:], NFFT=fftlen, Fs=nchans * fs, noverlap=fftlen / 4, window=lambda d: d * winfunc(fftlen)) s3.set_title("Output of Synthesis Filter") pyplot.show()
def test_005_64QAM(self): src_data = [] for i in range(0, 64): src_data.append(i) #print("test lista --->", src_data) # "Number of symbols" map_order = 4 # "Determine the expected result" expected_result = ( -7 - 7j, -7 - 5j, -7 - 1j, -7 - 3j, #0, 1, 2, 3 -7 + 7j, -7 + 5j, -7 + 1j, -7 + 3j, #4, 5, 6, 7 -5 - 7j, -5 - 5j, -5 - 1j, -5 - 3j, #8, 9, 10, 11 -5 + 7j, -5 + 5j, -5 + 1j, -5 + 3j, #12, 13, 14, 15 -1 - 7j, -1 - 5j, -1 - 1j, -1 - 3j, #16, 17, 18, 19 -1 + 7j, -1 + 5j, -1 + 1j, -1 + 3j, #20, 21, 22, 23 -3 - 7j, -3 - 5j, -3 - 1j, -3 - 3j, #24, 25, 26, 27 -3 + 7j, -3 + 5j, -3 + 1j, -3 + 3j, #28, 29, 30, 31 7 - 7j, 7 - 5j, 7 - 1j, 7 - 3j, #32, 33, 34, 35 7 + 7j, 7 + 5j, 7 + 1j, 7 + 3j, #36, 37, 38, 39 5 - 7j, 5 - 5j, 5 - 1j, 5 - 3j, #40, 41, 42, 43 5 + 7j, 5 + 5j, 5 + 1j, 5 + 3j, #44, 45, 46, 47 1 - 7j, 1 - 5j, 1 - 1j, 1 - 3j, #48, 49, 50, 51 1 + 7j, 1 + 5j, 1 + 1j, 1 + 3j, #52, 53, 54, 55 3 - 7j, 3 - 5j, 3 - 1j, 3 - 3j, #56, 57, 58, 59 3 + 7j, 3 + 5j, 3 + 1j, 3 + 3j) #60, 61, 62, 63 # "Create a complex vector source" src = blocks.vector_source_b(src_data) # "Instantiate the test module" qam_map = mqam_map_bc(map_order) # "Instantiate the binary sink" dst = blocks.vector_sink_c() # "Construct the flowgraph" self.tb.connect(src, qam_map) self.tb.connect(qam_map, dst) # "Create the flow graph" self.tb.run() # check data result_data = dst.data() #print("result data", result_data) self.assertTupleEqual(expected_result, result_data) self.assertEqual(len(expected_result), len(result_data)) print("test 64QAM")
def __init__(self): gr.top_block.__init__(self) self._N = 100000 # number of samples to use self._fs = 2000 # initial sampling rate self._interp = 5 # Interpolation rate for PFB interpolator self._ainterp = 5.5 # Resampling rate for the PFB arbitrary resampler # Frequencies of the signals we construct freq1 = 100 freq2 = 200 # Create a set of taps for the PFB interpolator # This is based on the post-interpolation sample rate self._taps = filter.firdes.low_pass_2( self._interp, self._interp * self._fs, freq2 + 50, 50, attenuation_dB=120, window=filter.firdes.WIN_BLACKMAN_hARRIS) # Create a set of taps for the PFB arbitrary resampler # The filter size is the number of filters in the filterbank; 32 will give very low side-lobes, # and larger numbers will reduce these even farther # The taps in this filter are based on a sampling rate of the filter size since it acts # internally as an interpolator. flt_size = 32 self._taps2 = filter.firdes.low_pass_2( flt_size, flt_size * self._fs, freq2 + 50, 150, attenuation_dB=120, window=filter.firdes.WIN_BLACKMAN_hARRIS) # Calculate the number of taps per channel for our own information tpc = scipy.ceil(float(len(self._taps)) / float(self._interp)) print "Number of taps: ", len(self._taps) print "Number of filters: ", self._interp print "Taps per channel: ", tpc # Create a couple of signals at different frequencies self.signal1 = analog.sig_source_c(self._fs, analog.GR_SIN_WAVE, freq1, 0.5) self.signal2 = analog.sig_source_c(self._fs, analog.GR_SIN_WAVE, freq2, 0.5) self.signal = blocks.add_cc() self.head = blocks.head(gr.sizeof_gr_complex, self._N) # Construct the PFB interpolator filter self.pfb = filter.pfb.interpolator_ccf(self._interp, self._taps) # Construct the PFB arbitrary resampler filter self.pfb_ar = filter.pfb.arb_resampler_ccf(self._ainterp, self._taps2, flt_size) self.snk_i = blocks.vector_sink_c() #self.pfb_ar.pfb.print_taps() #self.pfb.pfb.print_taps() # Connect the blocks self.connect(self.signal1, self.head, (self.signal, 0)) self.connect(self.signal2, (self.signal, 1)) self.connect(self.signal, self.pfb) self.connect(self.signal, self.pfb_ar) self.connect(self.signal, self.snk_i) # Create the sink for the interpolated signals self.snk1 = blocks.vector_sink_c() self.snk2 = blocks.vector_sink_c() self.connect(self.pfb, self.snk1) self.connect(self.pfb_ar, self.snk2)
def test_004_t(self): ''' Check if decimation works. :return: ''' # Overwrite variables self.n_samples = 1024 self.decimation = 2 # Create signal Fs = 2e6 Fc = 100e3 phaseAcc = 0 phaseInc = 2 * np.pi * Fc / Fs phaseAccNext = phaseAcc + self.n_samples * phaseInc d = 1 * np.sin(np.linspace(phaseAcc, phaseAccNext, self.n_samples)).astype(np.float32) # Channel model W = 2.9 h = np.zeros(4) h[1:4] = 0.5 * (1 + np.cos(2 * np.pi / W * np.linspace(-1, 1, 3))) u = np.convolve(d, h, mode='valid') # Distorted signal u += np.random.normal(0, np.sqrt(0.001), u.size) # Received signal d_source = blocks.vector_source_c(d.tolist()) u_source = blocks.vector_source_c(u.tolist()) lms_filter_cc = adapt.lms_filter_cc(True, self.n_taps, self.mu, self.skip, self.decimation, self.adapt, self.reset) y_sink = blocks.vector_sink_c() e_sink = blocks.vector_sink_c() self.tb.connect(d_source, (lms_filter_cc, 0)) self.tb.connect(u_source, (lms_filter_cc, 1)) self.tb.connect((lms_filter_cc, 0), y_sink) self.tb.connect((lms_filter_cc, 1), e_sink) self.tb.run() y_data = np.array(y_sink.data()) e_data = np.abs(e_sink.data()) m = np.median(e_data[e_data > 0]) e_data[e_data == 0] = m plt.figure(figsize=(15, 9)) plt.subplot(211) plt.title("Adaptation") plt.xlabel("samples - k") plt.plot(np.delete(d, np.arange(0, d.size, 2)), "b", label="d - reference") plt.plot(np.delete(u, np.arange(0, u.size, 2)), "r", label="u - input") plt.plot(y_data, "g", label="y - output") plt.legend() plt.subplot(212) plt.title("Filter error") plt.xlabel("samples - k") plt.plot(10 * np.log10(e_data**2), "r", label="e - error [dB]") plt.legend() plt.tight_layout() plt.show()
def test_wo_tags_no_rolloff_multiple_cps(self): "Two CP lengths, no rolloff and no tags." fft_len = 8 cp_lengths = (3, 2, 2) expected_result = [ 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, # 1 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, # 2 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, # 3 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, # 4 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, # 5 ] src = blocks.vector_source_c(list(range(fft_len)) * 5, False, fft_len) cp = digital.ofdm_cyclic_prefixer(fft_len, cp_lengths) sink = blocks.vector_sink_c() self.tb.connect(src, cp, sink) self.tb.run() self.assertEqual(sink.data(), expected_result)
def test_001_t(self): """test_001_t: CNR with fixed noise bandwidth""" tb = self.tb param = namedtuple( 'param', 'signal_amp' 'noise_amp' 'samp_rate' 'freq_sine' 'signal_bw' 'noise_bw' 'fft') param.samp_rate = 32000 items = param.samp_rate * 4 # 2 seconds of simulation param.signal_bw = 10 param.noise_bw = 2000 param.signal_amp = 1 param.noise_amp = 1 param.freq_sine = 2000 param.fft = 4096 print_parameters(param) dst_src = blocks.vector_sink_c() dst_noise = blocks.vector_sink_c() dst_noise_bw = blocks.vector_sink_c() dst_input = blocks.vector_sink_c() dst_out = blocks.vector_sink_f() head1 = blocks.head(gr.sizeof_gr_complex, items) head2 = blocks.head(gr.sizeof_gr_complex, items) src = analog.sig_source_c(param.samp_rate, analog.GR_SIN_WAVE, param.freq_sine, param.signal_amp, 0) noise = analog.noise_source_c(analog.GR_GAUSSIAN, param.noise_amp, 0) throttle1 = blocks.throttle(gr.sizeof_gr_complex * 1, param.samp_rate, True) throttle2 = blocks.throttle(gr.sizeof_gr_complex * 1, param.samp_rate, True) bpf_signal = filter.fir_filter_ccc( 1, firdes.complex_band_pass(1, param.samp_rate, (param.freq_sine - param.signal_bw / 2), (param.freq_sine + param.signal_bw / 2), 1, firdes.WIN_HAMMING, 6.76)) bpf_noise = filter.fir_filter_ccc( 1, firdes.complex_band_pass(1, param.samp_rate, (param.freq_sine - param.noise_bw / 2), (param.freq_sine + param.noise_bw / 2), 1, firdes.WIN_HAMMING, 6.76)) snr = snr_estimator_cf(auto_carrier=True, carrier=True, all_spectrum=False, freq_central=param.freq_sine, samp_rate=param.samp_rate, nintems=param.fft, signal_bw=param.signal_bw, noise_bw=param.noise_bw, avg_alpha=1.0, average=False, win=window.blackmanharris) adder = blocks.add_vcc(1) tb.connect(src, (adder, 1)) tb.connect(noise, (adder, 0)) tb.connect(src, bpf_signal) tb.connect(bpf_signal, dst_src) tb.connect(noise, bpf_noise) tb.connect(bpf_noise, dst_noise) tb.connect(adder, head1) tb.connect(head1, snr) tb.connect(snr, dst_out) tb.run() data_src = dst_src.data() data_noise = dst_noise.data() # data_input = dst_input.data() data_out = dst_out.data() print("SNR evaluated with variance:", 10 * math.log10(np.var(data_src) / np.var(data_noise))) print("SNR estimated:", np.mean(data_out))
def test_006_128QAM(self): src_data = [] for i in range(0, 128): src_data.append(i) #print("test lista --->", src_data) # "Number of symbols" map_order = 5 # "Determine the expected result" expected_result = ( -7 + 9j, -7 + 11j, -1 + 9j, -1 + 11j, #0, 1, 2, 3 -7 - 9j, -7 - 11j, -1 - 9j, -1 - 11j, #4, 5, 6, 7 -5 + 9j, -5 + 11j, -3 + 9j, -3 + 11j, #8, 9, 10, 11 -5 - 9j, -5 - 11j, -3 - 9j, -3 - 11j, #12, 13, 14, 15 -9 + 7j, -9 + 5j, -9 + 1j, -9 + 3j, #16, 17, 18, 19 -9 - 7j, -9 - 5j, -9 - 1j, -9 - 3j, #20, 21, 22, 23 -11 + 7j, -11 + 5j, -11 + 1j, -11 + 3j, #24, 25, 26, 27 -11 - 7j, -11 - 5j, -11 - 1j, -11 - 3j, #28, 29, 30, 31 -1 + 7j, -1 + 5j, -1 + 1j, -1 + 3j, #32, 33, 34, 35 -1 - 7j, -1 - 5j, -1 - 1j, -1 - 3j, #36, 37, 38, 39 -3 + 7j, -3 + 5j, -3 + 1j, -3 + 3j, #40, 41, 42, 43 -3 - 7j, -3 - 5j, -3 - 1j, -3 - 3j, #44, 45, 46, 47 -7 + 7j, -7 + 5j, -7 + 1j, -7 + 3j, #48, 49, 50, 51 -7 - 7j, -7 - 5j, -7 - 1j, -7 - 3j, #52, 53, 54, 55 -5 + 7j, -5 + 5j, -5 + 1j, -5 + 3j, #56, 57, 58, 59 -5 - 7j, -5 - 5j, -5 - 1j, -5 - 3j, #60, 61, 62, 63 +7 + 9j, 7 + 11j, 1 + 9j, 1 + 11j, #64, 65, 66, 67 +7 - 9j, 7 - 11j, 1 - 9j, 1 - 11j, #68, 69, 70, 71 +5 + 9j, 5 + 11j, 3 + 9j, 3 + 11j, #72, 73, 74, 75 +5 - 9j, 5 - 11j, 3 - 9j, 3 - 11j, #76, 77, 78, 79 +9 + 7j, 9 + 5j, 9 + 1j, 9 + 3j, #80, 81, 82, 83 +9 - 7j, 9 - 5j, 9 - 1j, 9 - 3j, #84, 85, 86, 87 +11 + 7j, 11 + 5j, 11 + 1j, 11 + 3j, #88, 89, 90, 91 +11 - 7j, 11 - 5j, 11 - 1j, 11 - 3j, #92, 93, 94, 95 +1 + 7j, 1 + 5j, 1 + 1j, 1 + 3j, #96, 97, 98, 99 +1 - 7j, 1 - 5j, 1 - 1j, 1 - 3j, #100, 101, 102, 103 +3 + 7j, 3 + 5j, 3 + 1j, 3 + 3j, #104, 105, 106, 107 +3 - 7j, 3 - 5j, 3 - 1j, 3 - 3j, #108, 109, 110, 111 +7 + 7j, 7 + 5j, 7 + 1j, 7 + 3j, #112, 113, 114, 115 +7 - 7j, 7 - 5j, 7 - 1j, 7 - 3j, #116, 117, 118, 119 +5 + 7j, 5 + 5j, 5 + 1j, 5 + 3j, #120, 121, 122, 123 +5 - 7j, 5 - 5j, 5 - 1j, 5 - 3j) #124, 125, 126, 127 # "Create a complex vector source" src = blocks.vector_source_b(src_data) # "Instantiate the test module" qam_map = mqam_map_bc(map_order) # "Instantiate the binary sink" dst = blocks.vector_sink_c() # "Construct the flowgraph" self.tb.connect(src, qam_map) self.tb.connect(qam_map, dst) # "Create the flow graph" self.tb.run() # check data result_data = dst.data() #print("result data", result_data) self.assertTupleEqual(expected_result, result_data) self.assertEqual(len(expected_result), len(result_data)) print("test 128QAM")
def genenrate(snr, nvecs_per_key=1000, vec_length=1024): apply_channel = True dataset = {} # The output format looks like this # {('mod type', SNR): np.array(nvecs_per_key, 2, vec_length), etc} # CIFAR-10 has 6000 samples/class. CIFAR-100 has 600. Somewhere in there seems like right order of magnitude #print "snr is ", snr for alphabet_type in transmitters.keys(): for i,mod_type in enumerate(transmitters[alphabet_type]): dataset[(mod_type.modname, snr)] = np.zeros([nvecs_per_key, 2, vec_length], dtype=np.float32) # moar vectors! insufficient_modsnr_vectors = True modvec_indx = 0 while insufficient_modsnr_vectors: tx_len = int(10e3) if mod_type.modname == "QAM16": tx_len = int(20e3) if mod_type.modname == "QAM64": tx_len = int(30e3) src = source_alphabet(alphabet_type, tx_len, True) mod = mod_type() fD = 1 delays = [0.0, 0.9, 1.7] mags = [1, 0.8, 0.3] ntaps = 8 noise_amp = 10**(-snr/10.0) seed = np.int64(time.time()) chan = channels.dynamic_channel_model( 200e3, 0.01, 50, .01, 0.5e3, 8, fD, True, 4, delays, mags, ntaps, noise_amp, seed ) snk = blocks.vector_sink_c() tb = gr.top_block() # connect blocks if apply_channel: tb.connect(src, mod, chan, snk) else: tb.connect(src, mod, snk) tb.run() raw_output_vector = np.array(snk.data(), dtype=np.complex64) # start the sampler some random time after channel model transients (arbitrary values here) sampler_indx = random.randint(50, 500) while sampler_indx + vec_length < len(raw_output_vector) and modvec_indx < nvecs_per_key: sampled_vector = raw_output_vector[sampler_indx:sampler_indx+vec_length] # Normalize the energy in this vector to be 1 energy = np.sum((np.abs(sampled_vector))) sampled_vector = sampled_vector / energy dataset[(mod_type.modname, snr)][modvec_indx,0,:] = np.real(sampled_vector) dataset[(mod_type.modname, snr)][modvec_indx,1,:] = np.imag(sampled_vector) # bound the upper end very high so it's likely we get multiple passes through # independent channels sampler_indx += random.randint(vec_length, round(len(raw_output_vector)*.05)) modvec_indx += 1 if modvec_indx == nvecs_per_key: # we're all done insufficient_modsnr_vectors = False return dataset
def test_accumulator_gain(self, param): """this function run the defined test, for easier understanding""" tb = self.tb data_pc = namedtuple('data_pc', 'src_rad src_int64 out carrier phase time') data_fft = namedtuple('data_fft', 'out cnr_out bins') # src_ramp = analog.sig_source_f(param.samp_rate, analog.GR_SAW_WAVE, (param.samp_rate * 0.5 / param.items), (2.0 * param.items), (- param.items)) # src_phase_acc =blocks.vector_source_f((np.linspace(0, param.step * param.items, param.items, endpoint=True)), False, 1, []) src = analog.sig_source_c(param.samp_rate, analog.GR_COS_WAVE, param.freq, 1, 0) arg = blocks.complex_to_arg(1) throttle = blocks.throttle(gr.sizeof_float * 1, param.samp_rate, True) head = blocks.head(gr.sizeof_float, int(param.items)) dst_src_rad = blocks.vector_sink_f() dst_src_pa = flaress.vector_sink_int64() dst_out_cpm = blocks.vector_sink_c() snr_estimator = flaress.snr_estimator_cfv(auto_carrier=True, carrier=True, all_spectrum=True, freq_central=0, samp_rate=param.samp_rate, nintems=param.fft_size, signal_bw=0, noise_bw=param.noise_bw, avg_alpha=1.0, average=False, win=window.blackmanharris) dst_out_fft = blocks.vector_sink_f(param.fft_size, param.items) dst_out_cnr = blocks.vector_sink_f() dst_freq_det = blocks.vector_sink_f() dst_phase = blocks.vector_sink_f() phase = blocks.complex_to_arg(1) pc = ecss.phase_converter(param.N) cpm = ecss.coherent_phase_modulator(param.N) gain = ecss.gain_phase_accumulator(False, param.uplink, param.downlink) tb.connect(src, arg) tb.connect(arg, head) tb.connect(head, dst_src_rad) tb.connect(head, pc) tb.connect(pc, dst_src_pa) tb.connect(pc, gain) tb.connect(gain, cpm) tb.connect(cpm, snr_estimator) tb.connect((snr_estimator, 0), dst_out_cnr) tb.connect((snr_estimator, 1), dst_out_fft) tb.connect(cpm, dst_out_cpm) tb.connect(cpm, phase) tb.connect(phase, dst_phase) self.tb.run() data_pc.src_rad = dst_src_rad.data() data_pc.src_int64 = dst_src_pa.data() data_pc.out = dst_out_cpm.data() data_pc.time = np.linspace(0, (param.items * 1.0 / param.samp_rate), param.items, endpoint=False) data_pc.phase = dst_phase.data() out = dst_out_fft.data() cnr_out = dst_out_cnr.data() # data_fft.out = out[param.items - (param.fft_size / 2) : param.items] + out[param.items - param.fft_size : param.items - (param.fft_size / 2)] #take the last fft_size elements data_fft.out = out[param.items - param.fft_size: param.items] #take the last fft_size elements data_fft.cnr_out = cnr_out[-1] #take the last element data_fft.bins = np.linspace(-(param.samp_rate / 2.0), (param.samp_rate / 2.0), param.fft_size, endpoint=True) return data_pc, data_fft
def test_005(self): ''' Test the complex AGC loop (attack and decay rate inputs) ''' tb = self.tb expected_result = \ ((100+0j), (0.8090173602104187 + 0.5877856016159058j), (0.3090175688266754 + 0.9510582685470581j), (-0.309017539024353 + 0.9510582089424133j), (-0.8090170621871948 + 0.5877852439880371j), (-1.000004529953003 - 4.608183701293456e-08j), (-0.8090165853500366 - 0.587785005569458j), (-0.3090173006057739 - 0.9510576725006104j), (0.3090173900127411 - 0.951057493686676j), (0.8090166449546814 - 0.5877848863601685j), (1.0000040531158447 + 9.362654651567937e-08j), (0.809016227722168 + 0.5877848267555237j), (0.3090171217918396 + 0.9510573148727417j), (-0.3090173006057739 + 0.9510571360588074j), (-0.8090163469314575 + 0.5877846479415894j), (-1.000003695487976 - 1.39708305368913e-07j), (-0.8090159296989441 - 0.5877846479415894j), (-0.30901697278022766 - 0.951056957244873j), (0.30901727080345154 - 0.9510568976402283j), (0.809016227722168 - 0.5877844095230103j), (1.000003457069397 + 1.87252979344521e-07j), (0.809015691280365 + 0.5877845287322998j), (0.3090168535709381 + 0.9510567784309387j), (-0.30901727080345154 + 0.951056718826294j), (-0.8090161085128784 + 0.5877842903137207j), (-1.0000033378601074 - 2.3333473109232727e-07j), (-0.8090156316757202 - 0.5877845287322998j), (-0.3090168237686157 - 0.9510566592216492j), (0.3090173006057739 - 0.9510565400123596j), (0.8090160489082336 - 0.5877842307090759j), (1.0000032186508179 + 2.8087941927879e-07j), (0.8090155124664307 + 0.5877845287322998j), (0.30901676416397095 + 0.9510567784309387j), (-0.3090173006057739 + 0.9510565400123596j), (-0.8090160489082336 + 0.5877841711044312j), (-1.0000033378601074 - 3.2696124208086985e-07j), (-0.8090155124664307 - 0.5877845883369446j), (-0.30901673436164856 - 0.9510567784309387j), (0.3090173602104187 - 0.9510565400123596j), (0.8090160489082336 - 0.5877841114997864j), (1.0000033378601074 + 3.745059302673326e-07j), (0.8090154528617859 + 0.5877846479415894j), (0.3090166747570038 + 0.9510567784309387j), (-0.3090174198150635 + 0.9510565400123596j), (-0.8090161681175232 + 0.5877841114997864j), (-1.0000032186508179 - 4.2058766780428414e-07j), (-0.8090154528617859 - 0.5877846479415894j), (-0.309016615152359 - 0.9510567784309387j), (0.30901747941970825 - 0.9510564804077148j), (0.8090161681175232 - 0.5877840518951416j)) sampling_freq = 100 src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, sampling_freq * 0.10, 100) dst1 = blocks.vector_sink_c() head = blocks.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) agc = analog.agc2_cc(1e-2, 1e-3, 1, 1) tb.connect(src1, head) tb.connect(head, agc) tb.connect(agc, dst1) tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4)
def __init__(self, N, sps, rolloff, ntaps, bw, noise, foffset, toffset, poffset, mode=0): gr.top_block.__init__(self) rrc_taps = filter.firdes.root_raised_cosine(sps, sps, 1.0, rolloff, ntaps) gain = bw nfilts = 32 rrc_taps_rx = filter.firdes.root_raised_cosine(nfilts, sps * nfilts, 1.0, rolloff, ntaps * nfilts) data = 2.0 * scipy.random.randint(0, 2, N) - 1.0 data = scipy.exp(1j * poffset) * data self.src = blocks.vector_source_c(data.tolist(), False) self.rrc = filter.interp_fir_filter_ccf(sps, rrc_taps) self.chn = channels.channel_model(noise, foffset, toffset) self.off = filter.fractional_resampler_cc(0.20, 1.0) if mode == 0: self.clk = digital.pfb_clock_sync_ccf(sps, gain, rrc_taps_rx, nfilts, nfilts // 2, 1) self.taps = self.clk.taps() self.dtaps = self.clk.diff_taps() self.delay = int( scipy.ceil(((len(rrc_taps) - 1) / 2 + (len(self.taps[0]) - 1) / 2) / float(sps))) + 1 self.vsnk_err = blocks.vector_sink_f() self.vsnk_rat = blocks.vector_sink_f() self.vsnk_phs = blocks.vector_sink_f() self.connect((self.clk, 1), self.vsnk_err) self.connect((self.clk, 2), self.vsnk_rat) self.connect((self.clk, 3), self.vsnk_phs) else: # mode == 1 mu = 0.5 gain_mu = bw gain_omega = 0.25 * gain_mu * gain_mu omega_rel_lim = 0.02 self.clk = digital.clock_recovery_mm_cc(sps, gain_omega, mu, gain_mu, omega_rel_lim) self.vsnk_err = blocks.vector_sink_f() self.connect((self.clk, 1), self.vsnk_err) self.vsnk_src = blocks.vector_sink_c() self.vsnk_clk = blocks.vector_sink_c() self.connect(self.src, self.rrc, self.chn, self.off, self.clk, self.vsnk_clk) self.connect(self.src, self.vsnk_src)
def apply_framing_and_offsets(args): params = args['parameters'] ### get dependency file, and create a new stage_data object multi_stage_data = ssa.MultiStageSignalData.load_pkl(args) ### Read parameters time_offset = params['time_offset'] section_size = params['section_size'] num_sections = params['num_sections'] noise_voltage = 0 #params.get('noise_voltage',0) freq_offset = params.get('frequency_offset', 0) soft_gain = params.get('soft_gain', 1) num_samples = int(num_sections * section_size) hist_len = 3 # compensate for block history# channel is hier block with taps in it ### Create preamble and frame structure # TODO: Make this happen in another part of the code multi_stage_data.session_data['frame_params'] = { 'section_size': section_size, 'num_sections': num_sections } fparams = preamble_utils.get_session_frame_params( multi_stage_data) #filedata.get_frame_params(stage_data) sframer = preamble_utils.SignalFramer(fparams) ### Read IQsamples twin = (time_offset - fparams.guard_len - hist_len, time_offset + num_samples + fparams.guard_len) assert twin[0] >= 0 xsections_with_hist = multi_stage_data.read_stage_samples( )[twin[0]:twin[1]] ### Create GR flowgraph that picks read samples, applies freq_offset, scaling, and stores in a vector_sink tb = gr.top_block() source = blocks.vector_source_c(xsections_with_hist, True) soft_amp = blocks.multiply_const_cc(np.sqrt(soft_gain) + 0 * 1j) channel = channels.channel_model(noise_voltage, freq_offset) assert len(channel.taps()) + 1 == hist_len head = blocks.head(gr.sizeof_gr_complex, xsections_with_hist.size - hist_len) dst = blocks.vector_sink_c() tb.connect(source, soft_amp) tb.connect(soft_amp, channel) tb.connect(channel, head) tb.connect(head, dst) logger.info('Starting Tx parameter transformation script') tb.run() logger.info('GR script finished successfully') gen_data = np.array(dst.data()) xsections = xsections_with_hist[hist_len::] # plt.plot(np.abs(gen_data)) # plt.plot(np.abs(xsections),'r') # plt.show() assert gen_data.size == xsections.size ### Create preamble structure and frame the signal y, section_bounds = sframer.frame_signal(gen_data, num_sections) num_samples_with_framing = preamble_utils.get_num_samples_with_framing( fparams, num_sections) assert y.size == num_samples_with_framing prev_stage_metadata = multi_stage_data.get_stage_derived_params( 'spectrogram_img') prev_boxes = prev_stage_metadata.tfreq_boxes # intersect the boxes with the section boundaries try: box_list = compute_new_bounding_boxes(time_offset, num_samples, freq_offset, prev_boxes) except AssertionError: err_msg = 'These were the original stage params {}'.format(params) logger.error(err_msg) raise section_boxes = partition_boxes_into_sections(box_list, section_size, fparams.guard_len, num_sections) # print 'these are the boxes divided by section:',[[b.__str__() for b in s] for s in section_boxes] # fill new file l = [] sig2img_params = multi_stage_data.get_stage_args('signal_representation') signalimgmetadata = imgrep.get_signal_to_img_converter(sig2img_params) for i in range(len(section_bounds)): assert section_bounds[i][1] - section_bounds[i][0] == section_size assert all(s.label() is not None for s in section_boxes[i]) l.append( signalimgmetadata(section_boxes[i], section_bounds[i], prev_stage_metadata.input_params) ) #specimgmetadata.input_params)) assert y.size >= np.max([s[1] for s in section_bounds]) for i in range(num_sections): # plt.plot(y[section_bounds[i][0]:section_bounds[i][1]]) # plt.plot(gen_data[guard_band+i*section_size:guard_band+(i+1)*section_size],'r:') # plt.show() assert np.max( np.abs(y[section_bounds[i][0]:section_bounds[i][1]] - gen_data[ (fparams.guard_len + i * section_size):fparams.guard_len + (i + 1) * section_size])) < 0.0001 new_stage_data = ssa.StageSignalData(args, {'spectrogram_img': l}, y) multi_stage_data.set_stage_data(new_stage_data) multi_stage_data.save_pkl()
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 xrange(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 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 = 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, n_written_samples, n_offset_samples, encoding=0, pdu_length=500, pad_interval=1000, linear_gain=1.0): super(GrWifiFlowgraph, self).__init__() # params self.n_written_samples = int(n_written_samples) self.n_offset_samples = int( n_offset_samples ) if n_offset_samples is not None else np.random.randint( 0, self.n_written_samples) self.linear_gain = float(linear_gain) self.pdu_length = pdu_length # size of the message passed to the WiFi [1,1500] assert isinstance(encoding, (int, str)) self.encoding = encoding if isinstance( encoding, int) else GrWifiFlowgraph.encoding_labels.index(encoding) if isinstance(pad_interval, tuple): self.distname = pad_interval[0] self.pad_interval = pad_interval[1] else: self.distname = 'constant' self.pad_interval = tuple(pad_interval) # phy self.wifi_phy_hier = wifi_phy_hier( bandwidth=20e6, # NOTE: used by the Rx only chan_est=0, # NOTE: used by the Rx only encoding=self.encoding, frequency=5.89e9, # NOTE: Rx only sensitivity=0.56, # NOTE: Rx only ) self.packet_pad = specmonitor.foo_random_burst_shaper_cc( False, False, 0, self.distname, self.pad_interval, 100, [0]) self.packet_pad.set_min_output_buffer(1000000) # self.foo_packet_pad2 = foo.packet_pad2( # False, # Debug # False, 0.01, # 100, # Before padding # self.pad_interval) # After padding # self.foo_packet_pad2.set_min_output_buffer( # 96000) # CHECK: What does this do? # # self.time_plot = gr_qtgui_utils.make_time_sink_c(1024, 20.0e6, "", 1) self.blocks_null_source = blocks.null_source(gr.sizeof_gr_complex * 1) self.skiphead = blocks.skiphead(gr.sizeof_gr_complex, self.n_offset_samples) self.head = blocks.head(gr.sizeof_gr_complex, self.n_written_samples) self.dst = blocks.vector_sink_c() # dst = blocks.file_sink(gr.sizeof_gr_complex,args['targetfolder']+'/tmp.bin') # mac self.ieee802_11_mac = ieee802_11.mac( ([0x23, 0x23, 0x23, 0x23, 0x23, 0x23]), ([0x42, 0x42, 0x42, 0x42, 0x42, 0x42]), ([0xff, 0xff, 0xff, 0xff, 0xff, 255])) pmt_message = pmt.intern("".join("x" for i in range(self.pdu_length))) # self.message_strobe = foo.periodic_msg_source(pmt_message, # self.interval_ms, self.num_msg, True, False) self.message_strobe = blocks.message_strobe( pmt.intern("".join("x" for i in range(self.pdu_length))), 0) # NOTE: This sends a message periodically # self.message_debug = blocks.message_debug() self.setup_flowgraph()