GNU Radio 3.6.5 C++ API
|
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