GNU Radio 3.6.5 C++ API

digital_ofdm_chanest_vcvc.h

Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /* Copyright 2012 Free Software Foundation, Inc.
00003  * 
00004  * This file is part of GNU Radio
00005  * 
00006  * GNU Radio is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 3, or (at your option)
00009  * any later version.
00010  * 
00011  * GNU Radio is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with GNU Radio; see the file COPYING.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street,
00019  * Boston, MA 02110-1301, USA.
00020  */
00021 
00022 #ifndef INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H
00023 #define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H
00024 
00025 #include <digital_api.h>
00026 #include <gr_block.h>
00027 
00028 class digital_ofdm_chanest_vcvc;
00029 
00030 typedef boost::shared_ptr<digital_ofdm_chanest_vcvc> digital_ofdm_chanest_vcvc_sptr;
00031 
00032 /*
00033  * \param sync_symbol1 First synchronisation symbol in the frequency domain. Its length must be
00034  *                     the FFT length. For Schmidl & Cox synchronisation, every second sub-carrier
00035  *                     has to be zero.
00036  * \param sync_symbol2 Second synchronisation symbol in the frequency domain. Must be equal to
00037  *                     the FFT length, or zero length if only one synchronisation symbol is used.
00038  *                     Using this symbol is how synchronisation is described in [1]. Leaving this
00039  *                     empty forces us to interpolate the equalizer taps.
00040  *                     If you are using an unusual sub-carrier configuration (e.g. because of OFDMA),
00041  *                     this sync symbol is used to identify the active sub-carriers. If you only
00042  *                     have one synchronisation symbol, set the active sub-carriers to a non-zero
00043  *                     value in here, and also set \p force_one_sync_symbol parameter to true.
00044  * \param n_data_symbols The number of data symbols following each set of synchronisation symbols.
00045  *                       Must be at least 1.
00046  * \param eq_noise_red_len If non-zero, noise reduction for the equalizer taps is done according
00047  *                         to [2]. In this case, it is the channel influence time in number of
00048  *                         samples. A good value is usually the length of the cyclic prefix.
00049  * \param max_carr_offset Limit the number of sub-carriers the frequency offset can maximally be.
00050  *                        Leave this zero to try all possibilities.
00051  * \param force_one_sync_symbol See \p sync_symbol2.
00052  */
00053 DIGITAL_API digital_ofdm_chanest_vcvc_sptr
00054 digital_make_ofdm_chanest_vcvc (
00055                 const std::vector<gr_complex> &sync_symbol1,
00056                 const std::vector<gr_complex> &sync_symbol2,
00057                 int n_data_symbols,
00058                 int eq_noise_red_len=0,
00059                 int max_carr_offset=-1,
00060                 bool force_one_sync_symbol=false);
00061 
00062 /*!
00063  * \brief Estimate channel and coarse frequency offset for OFDM from preambles
00064  * \ingroup ofdm_blk
00065  * \ingroup syncronizers_blk
00066  *
00067  * Input: OFDM symbols (in frequency domain). The first one (or two) symbols are expected
00068  *        to be synchronisation symbols, which are used to estimate the coarse freq offset
00069  *        and the initial equalizer taps (these symbols are removed from the stream).
00070  *        The following \p n_data_symbols are passed through unmodified (the actual equalisation
00071  *        must be done elsewhere).
00072  * Output: The data symbols, without the synchronisation symbols.
00073  *         The first data symbol passed through has two tags:
00074  *         'ofdm_sync_carr_offset' (integer), the coarse frequency offset as number of carriers,
00075  *         and 'ofdm_sync_eq_taps' (complex vector).
00076  *         Any tags attached to the synchronisation symbols are attached to the first data
00077  *         symbol. All other tags are propagated as expected.
00078  *
00079  * Note: The vector on ofdm_sync_eq_taps is already frequency-corrected, whereas the rest is not.
00080  *
00081  * This block assumes the frequency offset is even (i.e. an integer multiple of 2).
00082  *
00083  * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM",
00084  *     Communications, IEEE Transactions on, 1997.
00085  * [2] K.D. Kammeyer, "Nachrichtenuebertragung," Chapter. 16.3.2.
00086  */
00087 class DIGITAL_API digital_ofdm_chanest_vcvc : public gr_block
00088 {
00089  private:
00090   friend DIGITAL_API digital_ofdm_chanest_vcvc_sptr digital_make_ofdm_chanest_vcvc (const std::vector<gr_complex> &sync_symbol1, const std::vector<gr_complex> &sync_symbol2, int n_data_symbols, int eq_noise_red_len, int max_carr_offset, bool force_one_sync_symbol);
00091 
00092   int d_fft_len; //! FFT length
00093   int d_n_data_syms; //! Number of data symbols following the sync symbol(s)
00094   int d_n_sync_syms; //! Number of sync symbols (1 or 2)
00095   //! 0 if no noise reduction is done for the initial channel state estimation. Otherwise, the maximum length of the channel delay in samples.
00096   int d_eq_noise_red_len;
00097   //! Is sync_symbol1 if d_n_sync_syms == 1, otherwise sync_symbol2. Used as a reference symbol to estimate the channel.
00098   std::vector<gr_complex> d_ref_sym;
00099   //! If d_n_sync_syms == 2 this is used as a differential correlation vector (called 'v' in [1]).
00100   std::vector<gr_complex> d_corr_v;
00101   //! If d_n_sync_syms == 1 we use this instead of d_corr_v to estimate the coarse freq. offset
00102   std::vector<float> d_known_symbol_diffs;
00103   //! If d_n_sync_syms == 1 we use this instead of d_corr_v to estimate the coarse freq. offset (temp. variable)
00104   std::vector<float> d_new_symbol_diffs;
00105   //! The index of the first carrier with data (index 0 is not DC here, but the lowest frequency)
00106   int d_first_active_carrier;
00107   //! The index of the last carrier with data
00108   int d_last_active_carrier;
00109   //! If true, the channel estimation must be interpolated
00110   bool d_interpolate;
00111   //! Maximum carrier offset (negative value!)
00112   int d_max_neg_carr_offset;
00113   //! Maximum carrier offset (positive value!)
00114   int d_max_pos_carr_offset;
00115 
00116 
00117   digital_ofdm_chanest_vcvc(const std::vector<gr_complex> &sync_symbol1, const std::vector<gr_complex> &sync_symbol2, int n_data_symbols, int eq_noise_red_len, int max_carr_offset, bool force_one_sync_symbol);
00118 
00119   //! Calculate the coarse frequency offset in number of carriers
00120   int get_carr_offset(const gr_complex *sync_sym1, const gr_complex *sync_sym2);
00121   //! Estimate the channel (phase and amplitude offset per carrier)
00122   void get_chan_taps(const gr_complex *sync_sym1, const gr_complex *sync_sym2, int carr_offset, std::vector<gr_complex> &taps);
00123 
00124  public:
00125   ~digital_ofdm_chanest_vcvc();
00126 
00127   void forecast (int noutput_items, gr_vector_int &ninput_items_required);
00128   int general_work (int noutput_items,
00129                   gr_vector_int &ninput_items,
00130                   gr_vector_const_void_star &input_items,
00131                   gr_vector_void_star &output_items);
00132 };
00133 
00134 #endif /* INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H */
00135