Example #1
0
	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)
Example #2
0
	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"))