3 # Copyright 2006, 2007 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING. If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
25 from gnuradio import gr
26 from gnuradio.blks2impl.ofdm_sync_ml import ofdm_sync_ml
27 from gnuradio.blks2impl.ofdm_sync_pn import ofdm_sync_pn
28 from gnuradio.blks2impl.ofdm_sync_pnac import ofdm_sync_pnac
29 from gnuradio.blks2impl.ofdm_sync_fixed import ofdm_sync_fixed
31 class ofdm_receiver(gr.hier_block2):
33 Performs receiver synchronization on OFDM symbols.
35 The receiver performs channel filtering as well as symbol, frequency, and phase synchronization.
36 The synchronization routines are available in three flavors: preamble correlator (Schmidl and Cox),
37 modifid preamble correlator with autocorrelation (not yet working), and cyclic prefix correlator
41 def __init__(self, fft_length, cp_length, occupied_tones, snr, ks, logging=False):
43 Hierarchical block for receiving OFDM symbols.
45 The input is the complex modulated signal at baseband.
46 Synchronized packets are sent back to the demodulator.
48 @param fft_length: total number of subcarriers
50 @param cp_length: length of cyclic prefix as specified in subcarriers (<= fft_length)
52 @param occupied_tones: number of subcarriers used for data
53 @type occupied_tones: int
54 @param snr: estimated signal to noise ratio used to guide cyclic prefix synchronizer
56 @param ks: known symbols used as preambles to each packet
57 @type ks: list of lists
58 @param logging: turn file logging on or off
62 gr.hier_block2.__init__(self, "ofdm_receiver",
63 gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
64 gr.io_signature2(2, 2, gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature
66 bw = (float(occupied_tones) / float(fft_length)) / 2.0
68 chan_coeffs = gr.firdes.low_pass (1.0, # gain
70 bw+tb, # midpoint of trans. band
71 tb, # width of trans. band
72 gr.firdes.WIN_HAMMING) # filter type
73 self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)
75 win = [1 for i in range(fft_length)]
77 zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0))
78 zeros_on_right = fft_length - occupied_tones - zeros_on_left
79 ks0 = zeros_on_left*[0.0,]
81 ks0.extend(zeros_on_right*[0.0,])
83 ks0time = fft.ifft(ks0)
85 ks0time = ks0time.tolist()
89 self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, logging)
91 self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, logging)
93 self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time)
95 self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, logging)
97 self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
98 self.ofdm_frame_acq = gr.ofdm_frame_acquisition(occupied_tones, fft_length,
101 self.connect(self, self.chan_filt)
102 self.connect(self.chan_filt, self.ofdm_sync, self.fft_demod, (self.ofdm_frame_acq,0))
103 self.connect((self.ofdm_frame_acq,0), (self,0))
104 self.connect((self.ofdm_frame_acq,1), (self,1))
107 self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, "chan_filt_c.dat"))
108 self.connect(self.fft_demod, gr.file_sink(gr.sizeof_gr_complex*fft_length, "fft_out_c.dat"))
109 self.connect(self.ofdm_frame_acq,
110 gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_frame_acq_c.dat"))
111 self.connect((self.ofdm_frame_acq,1), gr.file_sink(1, "found_corr_b.dat"))