def test_001_ofdm_ffe_all_in_one(self): symbol_length = 5 num_symbols = 2 fft_length = 3 alpha = 0.1 src_data0 = [77*cmath.exp(2j*pi*x/20) for x in range(0,20)] src_data0[4] = 100 # should not matter, as this area of the symbol is not evaluated src_data0[12:19] = [100] * 7 # should not matter, as only the first two symbols are evaluated src_data1 = (0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) d = -2*pi/20 # phase diff between two consective samples expected_result = (0,0,0,0,0,0,0,0,0,0,0,0,d,d,d,d,d,d,d,d) src0 = gr.vector_source_c(src_data0) src1 = gr.vector_source_b(src_data1) ffe = dab_swig.ofdm_ffe_all_in_one(symbol_length, fft_length, num_symbols, alpha, 10) dst0 = gr.vector_sink_f() self.tb.connect(src0, (ffe,0)) self.tb.connect(src1, (ffe,1)) self.tb.connect(ffe, dst0) self.tb.run() result_data0 = dst0.data() # print expected_result # print result_data0 self.assertFloatTuplesAlmostEqual(expected_result, result_data0, 3)
def __init__(self, dab_params, rx_params, debug=False): """ OFDM time and coarse frequency synchronisation for DAB @param mode DAB mode (1-4) @param debug if True: write data streams out to files """ dp = dab_params rp = rx_params gr.hier_block2.__init__(self,"ofdm_sync_dab", gr.io_signature(1, 1, gr.sizeof_gr_complex), # input signature gr.io_signature2(2, 2, gr.sizeof_gr_complex, gr.sizeof_char)) # output signature # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.connect(self, self.input) # # null-symbol detection # # (outsourced to detect_zero.py) self.ns_detect = detect_null.detect_null(dp.ns_length, debug) self.connect(self.input, self.ns_detect) # # fine frequency synchronisation # # the code for fine frequency synchronisation is adapted from # ofdm_sync_ml.py; it abuses the cyclic prefix to find the fine # frequency error, as suggested in "ML Estimation of Timing and # Frequency Offset in OFDM Systems", by Jan-Jaap van de Beek, # Magnus Sandell, Per Ola Börjesson, see # http://www.sm.luth.se/csee/sp/research/report/bsb96r.html self.ffe = dab_swig.ofdm_ffe_all_in_one(dp.symbol_length, dp.fft_length, rp.symbols_for_ffs_estimation, rp.ffs_alpha, dp.sample_rate) if rp.correct_ffe: self.ffs_delay_input_for_correction = gr.delay(gr.sizeof_gr_complex, dp.symbol_length*rp.symbols_for_ffs_estimation) # by delaying the input, we can use the ff offset estimation from the first symbol to correct the first symbol itself self.ffs_delay_frame_start = gr.delay(gr.sizeof_char, dp.symbol_length*rp.symbols_for_ffs_estimation) # sample the value at the end of the symbol .. self.ffs_nco = gr.frequency_modulator_fc(1) # ffs_sample_and_hold directly outputs phase error per sample self.ffs_mixer = gr.multiply_cc() # calculate fine frequency error self.connect(self.input, (self.ffe, 0)) self.connect(self.ns_detect, (self.ffe, 1)) if rp.correct_ffe: # do the correction self.connect(self.ffe, self.ffs_nco, (self.ffs_mixer, 0)) self.connect(self.input, self.ffs_delay_input_for_correction, (self.ffs_mixer, 1)) # output - corrected signal and start of DAB frames self.connect(self.ffs_mixer, (self, 0)) self.connect(self.ns_detect, self.ffs_delay_frame_start, (self, 1)) else: # just patch the signal through self.connect(self.ffe, gr.null_sink(gr.sizeof_float)) self.connect(self.input, (self,0)) # frame start still needed .. self.connect(self.ns_detect, (self,1)) if debug: self.connect(self.ffe, gr.multiply_const_ff(1./(dp.T*2*pi)), gr.file_sink(gr.sizeof_float, "debug/ofdm_sync_dab_fine_freq_err_f.dat")) self.connect(self.ffs_mixer, gr.file_sink(gr.sizeof_gr_complex, "debug/ofdm_sync_dab_fine_freq_corrected_c.dat"))