diff options
Diffstat (limited to 'gnuradio-core')
-rw-r--r-- | gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py index a93852623..59c4913d1 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2007 Free Software Foundation, Inc. +# Copyright 2007,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -24,21 +24,16 @@ import math from gnuradio import gr class ofdm_sync_ml(gr.hier_block2): - def __init__(self, fft_length, cp_length, snr, logging): + def __init__(self, fft_length, cp_length, snr, kstime, logging): ''' Maximum Likelihood OFDM synchronizer: J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation of Time and Frequency Offset in OFDM Systems," IEEE Trans. Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997. ''' - # FIXME: change the output signature - # should be the output of the divider (the normalized peaks) and - # the angle value out of the sample and hold block - # move sampler out of this block - gr.hier_block2.__init__(self, "ofdm_sync_ml", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex*fft_length)) # Output signature + gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_char)) # Output signature self.input = gr.add_const_cc(0) @@ -92,19 +87,9 @@ class ofdm_sync_ml(gr.hier_block2): self.connect(self.moving_sum_filter,(self.diff,1)) #ML measurements input to sampler block and detect - nco_sensitivity = -1.0/fft_length self.f2c = gr.float_to_complex() - self.sampler = gr.ofdm_sampler(fft_length,symbol_length) self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005) - #self.pk_detect = gr.peak_detector2_fb() self.sample_and_hold = gr.sample_and_hold_ff() - self.nco = gr.frequency_modulator_fc(nco_sensitivity) - self.sigmix = gr.multiply_cc() - - # Mix the signal with an NCO controlled by the sync loop - self.connect(self.input, (self.sigmix,0)) - self.connect(self.nco, (self.sigmix,1)) - self.connect(self.sigmix, (self.sampler,0)) # use the sync loop values to set the sampler and the NCO # self.diff = theta @@ -112,20 +97,47 @@ class ofdm_sync_ml(gr.hier_block2): self.connect(self.diff, self.pk_detect) + # The DPLL corrects for timing differences between CP correlations use_dpll = 1 if use_dpll: self.dpll = gr.dpll_bb(float(symbol_length),0.01) self.connect(self.pk_detect, self.dpll) - self.connect(self.dpll, (self.sampler,1)) self.connect(self.dpll, (self.sample_and_hold,1)) else: - self.connect(self.pk_detect, (self.sampler,1)) self.connect(self.pk_detect, (self.sample_and_hold,1)) self.connect(self.angle, (self.sample_and_hold,0)) - self.connect(self.sample_and_hold, self.nco) - self.connect(self.sampler, self) + ################################ + # correlate against known symbol + # This gives us the same timing signal as the PN sync block only on the preamble + # we don't use the signal generated from the CP correlation because we don't want + # to readjust the timing in the middle of the packet or we ruin the equalizer settings. + kstime = [k.conjugate() for k in kstime] + kstime.reverse() + self.kscorr = gr.fir_filter_ccc(1, kstime) + self.corrmag = gr.complex_to_mag_squared() + + # The output signature of the correlation has a few spikes because the rest of the + # system uses the repeated preamble symbol. It needs to work that generically if + # anyone wants to use this against a WiMAX-like signal since it, too, repeats + # This slicing against a threshold will __not__ work over the air unless the + # received power is at just the right point. It __does__ work under the normal + # conditions of the loopback model. + self.slice = gr.threshold_ff(700000, 700000, 0) + self.f2b = gr.float_to_char() + + self.connect(self.input, self.kscorr, self.corrmag, self.slice) + self.connect(self.kscorr, gr.file_sink(gr.sizeof_gr_complex, "kscorr.dat")) + self.connect(self.corrmag, gr.file_sink(gr.sizeof_float, "kscorrmag.dat")) + self.connect(self.slice, gr.file_sink(gr.sizeof_float, "kspeak.dat")) + + # Set output signals + # Output 0: fine frequency correction value + # Output 1: timing signal + self.connect(self.sample_and_hold, (self,0)) + self.connect(self.slice, self.f2b, (self,1)) + if logging: self.connect(self.diff, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-theta_f.dat")) @@ -134,9 +146,6 @@ class ofdm_sync_ml(gr.hier_block2): if use_dpll: self.connect(self.dpll, gr.file_sink(gr.sizeof_char, "ofdm_sync_ml-dpll_b.dat")) - self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-sigmix_c.dat")) - self.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_ml-sampler_c.dat")) self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat")) - self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-nco_c.dat")) self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "ofdm_sync_ml-input_c.dat")) |