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.
23 #ifndef INCLUDED_GR_OFDM_CORRELATOR_H
24 #define INCLUDED_GR_OFDM_CORRELATOR_H
30 class gr_ofdm_correlator;
31 typedef boost::shared_ptr<gr_ofdm_correlator> gr_ofdm_correlator_sptr;
33 gr_ofdm_correlator_sptr
34 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
36 const std::vector<gr_complex> &known_symbol1,
37 const std::vector<gr_complex> &known_symbol2,
38 unsigned int max_fft_shift_len=10);
41 * \brief take a vector of complex constellation points in from an FFT
42 * and performs a correlation and equalization.
45 * This block takes the output of an FFT of a received OFDM symbol and finds the
46 * start of a frame based on two known symbols. It also looks at the surrounding
47 * bins in the FFT output for the correlation in case there is a large frequency
48 * shift in the data. This block assumes that the fine frequency shift has already
49 * been corrected and that the samples fall in the middle of one FFT bin.
51 * It then uses one of those known
52 * symbols to estimate the channel response over all subcarriers and does a simple
53 * 1-tap equalization on all subcarriers. This corrects for the phase and amplitude
54 * distortion caused by the channel.
57 class gr_ofdm_correlator : public gr_block
60 * \brief Build an OFDM correlator and equalizer.
61 * \param occupied_carriers The number of subcarriers with data in the received symbol
62 * \param fft_length The size of the FFT vector (occupied_carriers + unused carriers)
63 * \param known_symbol1 A vector of complex numbers representing a known symbol at the
64 * start of a frame (usually a BPSK PN sequence)
65 * \param known_symbol2 A vector of complex numbers representing a known symbol at the
66 * start of a frame after known_symbol1 (usually a BPSK PN sequence).
67 * Both of these start symbols are differentially correlated to compensate
68 * for phase changes between symbols.
69 * \param max_fft_shift_len Set's the maximum distance you can look between bins for correlation
71 friend gr_ofdm_correlator_sptr
72 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
74 const std::vector<gr_complex> &known_symbol1,
75 const std::vector<gr_complex> &known_symbol2,
76 unsigned int max_fft_shift_len);
79 gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
81 const std::vector<gr_complex> &known_symbol1,
82 const std::vector<gr_complex> &known_symbol2,
83 unsigned int max_fft_shift_len);
86 unsigned char slicer(gr_complex x);
87 bool correlate(const gr_complex *previous, const gr_complex *current, int zeros_on_left);
88 void calculate_equalizer(const gr_complex *previous,
89 const gr_complex *current, int zeros_on_left);
90 gr_complex coarse_freq_comp(int freq_delta, int count);
92 unsigned int d_occupied_carriers; // !< \brief number of subcarriers with data
93 unsigned int d_fft_length; // !< \brief length of FFT vector
94 unsigned int d_cplen; // !< \brief length of cyclic prefix in samples
95 unsigned int d_freq_shift_len; // !< \brief number of surrounding bins to look at for correlation
96 std::vector<gr_complex> d_known_symbol1, d_known_symbol2; // !< \brief known symbols at start of frame
97 std::vector<gr_complex> d_diff_corr_factor; // !< \brief factor used in correlation
98 std::vector<gr_complex> d_hestimate; // !< channel estimate
99 signed int d_coarse_freq; // !< \brief search distance in number of bins
100 unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction
101 float d_snr_est; // !< an estimation of the signal to noise ratio
103 gr_complex *d_phase_lut; // !< look-up table for coarse frequency compensation
105 void forecast(int noutput_items, gr_vector_int &ninput_items_required);
109 * \brief Return an estimate of the SNR of the channel
111 float snr() { return d_snr_est; }
113 ~gr_ofdm_correlator(void);
114 int general_work(int noutput_items,
115 gr_vector_int &ninput_items,
116 gr_vector_const_void_star &input_items,
117 gr_vector_void_star &output_items);