3 # Copyright 2004,2005,2006 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 2, 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.
23 from gnuradio import gr
24 from optparse import OptionParser
25 from ofdm_receiver import ofdm_receiver
27 class ofdm_mod(gr.hier_block):
28 def __init__(self, fg, options):
30 self._occupied_tones = options.occupied_tones
31 self._fft_length = options.fft_length
32 self._cp_length = options.cp_length
33 self._mtu = options.mtu
35 symbol_length = self._fft_length + self._cp_length
37 if self._fft_length < self._occupied_tones:
38 sys.stderr.write("occupied tones must be less than FFT length\n")
40 if self._fft_length < self._cp_length:
41 sys.stderr.write("cyclic prefix length must be less than FFT length\n")
44 win = [] #[1 for i in range(self._fft_length)]
46 # hard-coded known symbol
47 #ks = self._occupied_tones*[1,]
48 ks1 = known_symbols_200_1
49 ks2 = known_symbols_200_2
51 self.ofdm = gr.ofdm_bpsk_mapper(self._mtu, self._occupied_tones, self._fft_length, ks1, ks2)
52 self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
53 self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length, symbol_length)
58 self.fg.connect(self.ofdm, self.ifft, self.cp_adder)
59 gr.hier_block.__init__(self, self.fg, self.ofdm, self.cp_adder)
61 def samples_per_symbol(self):
67 def bits_per_symbol(self=None): # staticmethod that's also callable on an instance
69 bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM
71 def add_options(normal, expert):
73 Adds OFDM-specific options to the Options Parser
75 expert.add_option("", "--mtu", type="int", default=1500,
76 help="set maximum transmit unit [default=%default]")
77 expert.add_option("", "--fft-length", type="intx", default=512,
78 help="set the number of FFT bins [default=%default]")
79 expert.add_option("", "--occupied-tones", type="intx", default=200,
80 help="set the number of occupied FFT bins [default=%default]")
81 expert.add_option("", "--cp-length", type="intx", default=128,
82 help="set the number of bits in the cyclic prefix [default=%default]")
83 # Make a static method to call before instantiation
84 add_options = staticmethod(add_options)
86 def _print_verbage(self):
88 Prints information about the OFDM modulator
90 print "\nOFDM Modulator:"
91 print "FFT length: %3d" % (self._fft_length)
92 print "Occupied Tones: %3d" % (self._occupied_tones)
93 print "CP length: %3d" % (self._cp_length)
96 class ofdm_demod(gr.hier_block):
97 def __init__(self, fg, options):
99 self._occupied_tones = options.occupied_tones
100 self._fft_length = options.fft_length
101 self._cp_length = options.cp_length
102 self._snr = options.snr
104 symbol_length = self._fft_length + self._cp_length
106 win = [1 for i in range(self._fft_length)]
108 # hard-coded known symbol
109 ks1 = known_symbols_200_1
110 ks2 = known_symbols_200_2
113 self.ofdm_sync = ofdm_receiver(self.fg, self._fft_length, symbol_length, self._snr)
116 self.fft_demod = gr.fft_vcc(self._fft_length, True, win, True)
117 self.ofdm_corr = gr.ofdm_correlator(self._occupied_tones, self._fft_length,
118 self._cp_length, ks1, ks2)
119 self.ofdm_demod = gr.ofdm_bpsk_demapper(self._occupied_tones)
123 self._print_verbage()
125 self.fg.connect(self.ofdm_sync, self.fft_demod, self.ofdm_corr, self.ofdm_demod)
126 gr.hier_block.__init__(self, self.fg, self.ofdm_sync, self.ofdm_demod)
128 def bits_per_symbol(self=None): # staticmethod that's also callable on an instance
130 bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM
132 def add_options(normal, expert):
134 Adds OFDM-specific options to the Options Parser
136 expert.add_option("", "--fft-length", type="intx", default=512,
137 help="set the number of FFT bins [default=%default]")
138 expert.add_option("", "--occupied-tones", type="intx", default=200,
139 help="set the number of occupied FFT bins [default=%default]")
140 expert.add_option("", "--cp-length", type="intx", default=128,
141 help="set the number of bits in the cyclic prefix [default=%default]")
142 # Make a static method to call before instantiation
143 add_options = staticmethod(add_options)
145 def _print_verbage(self):
147 Prints information about the OFDM demodulator
149 print "\nOFDM Demodulator:"
150 print "FFT length: %3d" % (self._fft_length)
151 print "Occupied Tones: %3d" % (self._occupied_tones)
152 print "CP length: %3d" % (self._cp_length)
155 # generated in python using:
157 # pn = [2.0*random.randint(0,1)-1.0 for i in range(self._occupied_tones)]
159 known_symbols_200_1 = [1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0]
161 known_symbols_200_2 = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]