diff options
author | Martin Braun <martin.braun@kit.edu> | 2013-03-17 02:26:39 +0100 |
---|---|---|
committer | Martin Braun <martin.braun@kit.edu> | 2013-03-17 15:54:24 +0100 |
commit | 046f442fe430a7f8d9b7c1d48422e72aeeeeab13 (patch) | |
tree | 111ee1c6bf463a333d63d10ac8954eb34651e528 /gr-digital | |
parent | f15400470ce5cb68f5339ead7af726b8bbafd364 (diff) |
digital: pimplified old blocks
Diffstat (limited to 'gr-digital')
59 files changed, 2112 insertions, 2425 deletions
diff --git a/gr-digital/CMakeLists.txt b/gr-digital/CMakeLists.txt index 7d3046dc50..ab29c6d183 100644 --- a/gr-digital/CMakeLists.txt +++ b/gr-digital/CMakeLists.txt @@ -38,10 +38,10 @@ GR_REGISTER_COMPONENT("gr-digital" ENABLE_GR_DIGITAL ENABLE_GR_FILTER ) -GR_SET_GLOBAL(GR_DIGITAL_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include -) +#GR_SET_GLOBAL(GR_DIGITAL_INCLUDE_DIRS + #${CMAKE_CURRENT_SOURCE_DIR}/include + #${CMAKE_CURRENT_BINARY_DIR}/include +#) GR_SET_GLOBAL(GR_DIGITAL_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig @@ -91,7 +91,6 @@ CPACK_COMPONENT("digital_swig" ######################################################################## # Add subdirectories ######################################################################## -add_subdirectory(include) add_subdirectory(include/digital) add_subdirectory(lib) add_subdirectory(doc) diff --git a/gr-digital/grc/digital_scale_tags.xml b/gr-digital/grc/digital_scale_tags.xml deleted file mode 100644 index 3e80ee21fe..0000000000 --- a/gr-digital/grc/digital_scale_tags.xml +++ /dev/null @@ -1,31 +0,0 @@ -<block> - <name>Tag Scaler</name> - <key>digital_scale_tags</key> - <category>digital</category> - <import>from gnuradio import digital</import> - <make>digital.scale_tags($item_size, $tag_name, $scale_factor)</make> - <param> - <name>Item size</name> - <key>item_size</key> - <type>int</type> - </param> - <param> - <name>Tag Name</name> - <key>tag_name</key> - <type>string</type> - </param> - <param> - <name>Scale Factor</name> - <key>scale_factor</key> - <type>real</type> - </param> - <!--FIXME type should be choosable--> - <sink> - <name>in</name> - <type>byte</type> - </sink> - <source> - <name>out</name> - <type>byte</type> - </source> -</block> diff --git a/gr-digital/include/CMakeLists.txt b/gr-digital/include/CMakeLists.txt deleted file mode 100644 index a32f11ed4d..0000000000 --- a/gr-digital/include/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2011,2012 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. - -######################################################################## -# Install header files -######################################################################## -install(FILES - digital_crc32_bb.h - digital_ofdm_carrier_allocator_cvc.h - digital_ofdm_chanest_vcvc.h - digital_ofdm_cyclic_prefixer.h - digital_ofdm_equalizer_base.h - digital_ofdm_equalizer_simpledfe.h - digital_ofdm_equalizer_static.h - digital_ofdm_sync_sc_cfb.h - DESTINATION ${GR_INCLUDE_DIR}/gnuradio - COMPONENT "digital_devel" -) diff --git a/gr-digital/include/digital/CMakeLists.txt b/gr-digital/include/digital/CMakeLists.txt index 06438c092b..84f0ef50d0 100644 --- a/gr-digital/include/digital/CMakeLists.txt +++ b/gr-digital/include/digital/CMakeLists.txt @@ -89,6 +89,7 @@ install(FILES costas_loop_cc.h cpmmod_bc.h crc32.h + crc32_bb.h descrambler_bb.h diff_decoder_bb.h diff_encoder_bb.h @@ -107,7 +108,12 @@ install(FILES mpsk_receiver_cc.h mpsk_snr_est.h mpsk_snr_est_cc.h + ofdm_carrier_allocator_cvc.h + ofdm_chanest_vcvc.h ofdm_cyclic_prefixer.h + ofdm_equalizer_base.h + ofdm_equalizer_simpledfe.h + ofdm_equalizer_static.h ofdm_frame_acquisition.h ofdm_frame_equalizer_vcvc.h ofdm_frame_sink.h @@ -115,6 +121,7 @@ install(FILES ofdm_mapper_bcv.h ofdm_sampler.h ofdm_serializer_vcc.h + ofdm_sync_sc_cfb.h packet_header_default.h packet_header_ofdm.h packet_headergenerator_bb.h @@ -135,3 +142,4 @@ install(FILES DESTINATION ${GR_INCLUDE_DIR}/gnuradio/digital COMPONENT "digital_devel" ) + diff --git a/gr-digital/include/digital/crc32_bb.h b/gr-digital/include/digital/crc32_bb.h new file mode 100644 index 0000000000..4bfac76070 --- /dev/null +++ b/gr-digital/include/digital/crc32_bb.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITAL_CRC32_BB_H +#define INCLUDED_DIGITAL_CRC32_BB_H + +#include <digital/api.h> +#include <gr_tagged_stream_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Byte-stream CRC block + * \ingroup digital + * + * Input: stream of bytes, which form a packet. The first byte of the packet + * has a tag with key "length" and the value being the number of bytes in the + * packet. + * + * Output: The same bytes as incoming, but trailing a CRC32 of the packet. + * The tag is re-set to the new length. + */ + class DIGITAL_API crc32_bb : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<crc32_bb> sptr; + + /*! + * \param check Set to true if you want to check CRC, false to create CRC. + * \param lengthtagname Length tag key + */ + static sptr make(bool check=false, const std::string& lengthtagname="packet_len"); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_CRC32_BB_H */ + diff --git a/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h b/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h new file mode 100644 index 0000000000..8915c23c45 --- /dev/null +++ b/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H +#define INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H + +#include <digital/api.h> +#include <gr_tagged_stream_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Create frequency domain OFDM symbols from complex values, add pilots. + * \ingroup ofdm_blk + * + * This block turns a stream of complex, scalar modulation symbols into vectors + * which are the input for an IFFT in an OFDM transmitter. It also supports the + * possibility of placing pilot symbols onto the carriers. + * + * The carriers can be allocated freely, if a carrier is not allocated, it is set + * to zero. This allows doing OFDMA-style carrier allocations. + * + * Input: A tagged stream of complex scalars. The first item must have a tag + * containing the number of complex symbols in this frame. + * Output: A tagged stream of complex vectors of length fft_len. This can directly + * be connected to an FFT block. Make sure to set this block to 'reverse' + * for the IFFT and to deactivate FFT shifting. + * + * Carrier indexes are always such that index 0 is the DC carrier (note: you should + * not allocate this carrier). The carriers below the DC carrier are either indexed + * with negative numbers, or with indexes larger than fft_len/2. Index -1 and index + * fft_len-1 both identify the carrier below the DC carrier. + * + */ + class DIGITAL_API ofdm_carrier_allocator_cvc : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<ofdm_carrier_allocator_cvc> sptr; + + virtual std::string len_tag_key() = 0; + virtual const int fft_len() = 0; + virtual std::vector<std::vector<int> > occupied_carriers() = 0; + + /* + * \param occupied_carriers A vector of vectors of indexes. Example: if + * occupied_carriers = ((1, 2, 3), (1, 2, 4)), the first + * three input symbols will be mapped to carriers 1, 2 + * and 3. After that, a new OFDM symbol is started. The next + * three input symbols will be placed onto carriers 1, 2 + * and 4 of the second OFDM symbol. The allocation then + * starts from the beginning. + * Order matters! The first input symbol is always mapped + * onto occupied_carriers[0][0]. + * \param pilot_carriers The position of the pilot symbols. Same as occupied_carriers, + * but the actual symbols are taken from pilot_symbols instead + * of the input stream. + * \param pilot_symbols The pilot symbols which are placed onto the pilot carriers. + * pilot_symbols[0][0] is placed onto the first OFDM symbol, on + * carrier index pilot_carriers[0][0] etc. + * \param len_tag_key The key of the tag identifying the length of the input packet. + */ + static sptr make( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + const std::string &len_tag_key = "packet_len"); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H */ + diff --git a/gr-digital/include/digital/ofdm_chanest_vcvc.h b/gr-digital/include/digital/ofdm_chanest_vcvc.h new file mode 100644 index 0000000000..0c29d630da --- /dev/null +++ b/gr-digital/include/digital/ofdm_chanest_vcvc.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H +#define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Estimate channel and coarse frequency offset for OFDM from preambles + * \ingroup ofdm_blk + * \ingroup sync_blk + * + * Input: OFDM symbols (in frequency domain). The first one (or two) symbols are expected + * to be synchronisation symbols, which are used to estimate the coarse freq offset + * and the initial equalizer taps (these symbols are removed from the stream). + * The following \p n_data_symbols are passed through unmodified (the actual equalisation + * must be done elsewhere). + * Output: The data symbols, without the synchronisation symbols. + * The first data symbol passed through has two tags: + * 'ofdm_sync_carr_offset' (integer), the coarse frequency offset as number of carriers, + * and 'ofdm_sync_eq_taps' (complex vector). + * Any tags attached to the synchronisation symbols are attached to the first data + * symbol. All other tags are propagated normally. + * + * This block assumes the frequency offset is even (i.e. an integer multiple of 2). + * + * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM", + * Communications, IEEE Transactions on, 1997. + * [2] K.D. Kammeyer, "Nachrichtenuebertragung," Chapter. 16.3.2. + */ + class DIGITAL_API ofdm_chanest_vcvc : virtual public gr_block + { + public: + typedef boost::shared_ptr<ofdm_chanest_vcvc> sptr; + + /* + * \param sync_symbol1 First synchronisation symbol in the frequency domain. Its length must be + * the FFT length. For Schmidl & Cox synchronisation, every second sub-carrier + * has to be zero. + * \param sync_symbol2 Second synchronisation symbol in the frequency domain. Must be equal to + * the FFT length, or zero length if only one synchronisation symbol is used. + * Using this symbol is how synchronisation is described in [1]. Leaving this + * empty forces us to interpolate the equalizer taps. + * If you are using an unusual sub-carrier configuration (e.g. because of OFDMA), + * this sync symbol is used to identify the active sub-carriers. If you only + * have one synchronisation symbol, set the active sub-carriers to a non-zero + * value in here, and also set \p force_one_sync_symbol parameter to true. + * \param n_data_symbols The number of data symbols following each set of synchronisation symbols. + * Must be at least 1. + * \param eq_noise_red_len If non-zero, noise reduction for the equalizer taps is done according + * to [2]. In this case, it is the channel influence time in number of + * samples. A good value is usually the length of the cyclic prefix. + * \param max_carr_offset Limit the number of sub-carriers the frequency offset can maximally be. + * Leave this zero to try all possibilities. + * \param force_one_sync_symbol See \p sync_symbol2. + */ + static sptr make( + const std::vector<gr_complex> &sync_symbol1, + const std::vector<gr_complex> &sync_symbol2, + int n_data_symbols, + int eq_noise_red_len=0, + int max_carr_offset=-1, + bool force_one_sync_symbol=false + ); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H */ + diff --git a/gr-digital/include/digital/ofdm_cyclic_prefixer.h b/gr-digital/include/digital/ofdm_cyclic_prefixer.h index 551d1ee834..6292d62697 100644 --- a/gr-digital/include/digital/ofdm_cyclic_prefixer.h +++ b/gr-digital/include/digital/ofdm_cyclic_prefixer.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ -/* - * Copyright 2004-2006,2011,2012 Free Software Foundation, Inc. +/* + * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,34 +24,48 @@ #define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H #include <digital/api.h> -#include <gr_sync_interpolator.h> +#include <gr_tagged_stream_block.h> namespace gr { namespace digital { - + /*! - * \brief adds a cyclic prefix vector to an input size long ofdm - * symbol(vector) and converts vector to a stream output_size - * long. + * \brief Adds a cyclic prefix and performs pulse shaping on OFDM symbols. * \ingroup ofdm_blk + * + * Input: OFDM symbols (in the time domain, i.e. after the IFFT). Optionally, + * entire frames can be processed. In this case, \p len_tag_key must be + * specified which holds the key of the tag that denotes how + * many OFDM symbols are in a frame. + * Output: A stream of (scalar) complex symbols, which include the cyclic prefix + * and the pulse shaping. + * Note: If complete frames are processed, and \p rolloff_len is greater + * than zero, the final OFDM symbol is followed by the delay line of + * the pulse shaping. + * + * The pulse shape is a raised cosine in the time domain. */ - class DIGITAL_API ofdm_cyclic_prefixer : virtual public gr_sync_interpolator + class DIGITAL_API ofdm_cyclic_prefixer : virtual public gr_tagged_stream_block { - public: - // gr::digital::ofdm_cyclic_prefixer::sptr + public: typedef boost::shared_ptr<ofdm_cyclic_prefixer> sptr; /*! - * Make an OFDM cyclic prefix adder block. - * - * \param input_size size of the input symbol - * \param output_size output of the symbol - * (CP len = output_size - input_size) + * \param input_size FFT length (i.e. length of the OFDM symbols) + * \param output_size FFT length + cyclic prefix length (in samples) + * \param rolloff_len Length of the rolloff flank in samples + * \param len_tag_key For framed processing the key of the length tag */ - static sptr make(size_t input_size, size_t output_size); + static sptr make( + size_t input_size, + size_t output_size, + int rolloff_len=0, + const std::string &len_tag_key="" + ); }; - } /* namespace digital */ -} /* namespace gr */ + } // namespace digital +} // namespace gr #endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H */ + diff --git a/gr-digital/include/digital/ofdm_equalizer_base.h b/gr-digital/include/digital/ofdm_equalizer_base.h new file mode 100644 index 0000000000..0e23eb381f --- /dev/null +++ b/gr-digital/include/digital/ofdm_equalizer_base.h @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H +#define INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H + +#include <digital/api.h> +#include <gr_tags.h> +#include <gr_complex.h> +#include <boost/enable_shared_from_this.hpp> + +namespace gr { + namespace digital { + + /* \brief Base class for implementation details of frequency-domain OFDM equalizers. + * \ingroup ofdm_blk + * \ingroup eq_blk + */ + class DIGITAL_API ofdm_equalizer_base + : public boost::enable_shared_from_this<ofdm_equalizer_base> + { + protected: + int d_fft_len; + int d_carr_offset; + + public: + typedef boost::shared_ptr<ofdm_equalizer_base> sptr; + + ofdm_equalizer_base(int fft_len); + ~ofdm_equalizer_base(); + + //! Reset the channel information state knowledge + virtual void reset() = 0; + //! Set the carrier offset in integer multiples + void set_carrier_offset(int offset) { d_carr_offset = offset; }; + virtual void equalize( + gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), + const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()) = 0; + //! Return the current channel state + virtual void get_channel_state(std::vector<gr_complex> &taps) = 0; + int fft_len() { return d_fft_len; }; + sptr base() { return shared_from_this(); }; + }; + + + /* \brief Base class for implementation details of 1-dimensional OFDM FDEs which use pilot tones. + * \ingroup digital + * + */ + class DIGITAL_API ofdm_equalizer_1d_pilots : public ofdm_equalizer_base + { + protected: + //! If \p d_occupied_carriers[k][l] is true, symbol k, carrier l is carrying data. + // (this is a different format than occupied_carriers!) + std::vector<bool> d_occupied_carriers; + //! If \p d_pilot_carriers[k][l] is true, symbol k, carrier l is carrying data. + // (this is a different format than pilot_carriers!) + std::vector<std::vector<bool> > d_pilot_carriers; + //! If \p d_pilot_carriers[k][l] is true, d_pilot_symbols[k][l] is its tx'd value. + // (this is a different format than pilot_symbols!) + std::vector<std::vector<gr_complex> > d_pilot_symbols; + //! In case the frame doesn't begin with OFDM symbol 0, this is the index of the first symbol + int d_symbols_skipped; + //! The current position in the set of pilot symbols + int d_pilot_carr_set; + //! Vector of length d_fft_len saving the current channel state (on the occupied carriers) + std::vector<gr_complex> d_channel_state; + + public: + typedef boost::shared_ptr<ofdm_equalizer_1d_pilots> sptr; + + ofdm_equalizer_1d_pilots( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + bool input_is_shifted); + ~ofdm_equalizer_1d_pilots(); + + void reset(); + void get_channel_state(std::vector<gr_complex> &taps); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H */ + diff --git a/gr-digital/include/digital/ofdm_equalizer_simpledfe.h b/gr-digital/include/digital/ofdm_equalizer_simpledfe.h new file mode 100644 index 0000000000..9d286576bc --- /dev/null +++ b/gr-digital/include/digital/ofdm_equalizer_simpledfe.h @@ -0,0 +1,130 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H +#define INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H + +#include <digital/api.h> +#include <digital/constellation.h> +#include <digital/ofdm_equalizer_base.h> + +namespace gr { + namespace digital { + + /* \brief Simple decision feedback equalizer for OFDM. + * \ingroup ofdm_blk + * \ingroup eq_blk + * + * Equalizes an OFDM signal symbol by symbol using knowledge of the + * complex modulations symbols. + * For every symbol, the following steps are performed: + * - On every sub-carrier, decode the modulation symbol + * - Use the difference between the decoded symbol and the received symbol + * to update the channel state on this carrier + * - Whenever a pilot symbol is found, it uses the known pilot symbol to + * update the channel state. + * + * This equalizer makes a lot of assumptions: + * - The initial channel state is good enough to decode the first + * symbol without error (unless the first symbol only consists of pilot + * tones) + * - The channel changes only very slowly, such that the channel state + * from one symbol is enough to decode the next + * - SNR low enough that equalization will always suffice to correctly + * decode a symbol + * If these assumptions are not met, the most common error is that the + * channel state is estimated incorrectly during equalization; after that, + * all subsequent symbols will be completely wrong. + * + * Note that the equalized symbols are *exact points* on the constellation. + * This means soft information of the modulation symbols is lost after the + * equalization, which is suboptimal for channel codes that use soft decision. + * + */ + class DIGITAL_API ofdm_equalizer_simpledfe : public ofdm_equalizer_1d_pilots + { + public: + typedef boost::shared_ptr<ofdm_equalizer_simpledfe> sptr; + + ofdm_equalizer_simpledfe( + int fft_len, + const gr::digital::constellation_sptr &constellation, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped = 0, + float alpha = 0.1, + bool input_is_shifted = true); + + ~ofdm_equalizer_simpledfe(); + + void equalize(gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), + const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); + + /* + * \param fft_len FFT length + * \param constellation The constellation object describing the modulation used + * on the subcarriers (e.g. QPSK). This is used to decode + * the individual symbols. + * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator + * for a description. + * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param alpha Averaging coefficient (in a nutshell, if \f$H_{i,k}\f$ is the channel + * state for carrier i and symbol k, + * \f$H_{i,k+1} = \alpha H_{i,k} + (1 - \alpha) H_{i,k+1}\f$. Make this + * larger if there's more noise, but keep in mind that larger values + * of alpha mean slower response to channel changes). + * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers. + * If the first symbol of the frame was removed (e.g. to decode the + * header), set this make sure the pilot symbols are correctly + * identified. + * \param input_is_shifted Set this to false if the input signal is not shifted, i.e. + * the first input items is on the DC carrier. + * Note that a lot of the OFDM receiver blocks operate on shifted + * signals! + */ + static sptr make( + int fft_len, + const gr::digital::constellation_sptr &constellation, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped=0, + float alpha=0.1, + bool input_is_shifted=true + ); + + private: + gr::digital::constellation_sptr d_constellation; + //! Averaging coefficient + float d_alpha; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H */ + diff --git a/gr-digital/include/digital/ofdm_equalizer_static.h b/gr-digital/include/digital/ofdm_equalizer_static.h new file mode 100644 index 0000000000..67586be6fb --- /dev/null +++ b/gr-digital/include/digital/ofdm_equalizer_static.h @@ -0,0 +1,100 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H +#define INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H + +#include <digital/api.h> +#include <digital/constellation.h> +#include <digital/ofdm_equalizer_base.h> + +namespace gr { + namespace digital { + + /* \brief Very simple static equalizer for OFDM. + * \ingroup ofdm_blk + * \ingroup eq_blk + * + * This is an extremely simple equalizer. It will only work for high-SNR, very, very + * slowly changing channels. + * It simply divides the signal with the currently known channel state. Whenever + * a pilot symbol comes around, it updates the channel state on that particular + * carrier by dividing the received symbol with the known pilot symbol. + */ + class DIGITAL_API ofdm_equalizer_static : public ofdm_equalizer_1d_pilots + { + public: + typedef boost::shared_ptr<ofdm_equalizer_static> sptr; + + ofdm_equalizer_static( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped = 0, + bool input_is_shifted = true + ); + ~ofdm_equalizer_static(); + + /*! \brief Divide the input signal with the current channel state. + * + * Does the following (and nothing else): + * - Divide every OFDM symbol with the current channel state + * - If a pilot symbol is found, re-set the channel state by dividing the received + * symbol with the known pilot symbol + */ + void equalize(gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), + const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); + + /* + * \param fft_len FFT length + * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator + * for a description. + * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers. + * If the first symbol of the frame was removed (e.g. to decode the + * header), set this make sure the pilot symbols are correctly + * identified. + * \param input_is_shifted Set this to false if the input signal is not shifted, i.e. + * the first input items is on the DC carrier. + * Note that a lot of the OFDM receiver blocks operate on shifted + * signals! + */ + static sptr make( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped = 0, + bool input_is_shifted = true + ); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H */ + diff --git a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h index d5d526ddc3..68e8b7ad9f 100644 --- a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h +++ b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h @@ -19,12 +19,11 @@ * Boston, MA 02110-1301, USA. */ - #ifndef INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H #define INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H -#include <digital_ofdm_equalizer_base.h> #include <digital/api.h> +#include <digital/ofdm_equalizer_base.h> #include <gr_tagged_stream_block.h> namespace gr { @@ -50,7 +49,7 @@ namespace gr { * will be added to the first symbol as a tag */ static sptr make( - digital_ofdm_equalizer_base_sptr equalizer, + ofdm_equalizer_base::sptr equalizer, const std::string &len_tag_key = "frame_len", bool propagate_channel_state=false ); diff --git a/gr-digital/include/digital/ofdm_serializer_vcc.h b/gr-digital/include/digital/ofdm_serializer_vcc.h index 3893d6674e..c4dc36ec06 100644 --- a/gr-digital/include/digital/ofdm_serializer_vcc.h +++ b/gr-digital/include/digital/ofdm_serializer_vcc.h @@ -24,7 +24,7 @@ #include <digital/api.h> #include <gr_tagged_stream_block.h> -#include <digital_ofdm_carrier_allocator_cvc.h> +#include <digital/ofdm_carrier_allocator_cvc.h> namespace gr { namespace digital { @@ -77,7 +77,7 @@ namespace gr { * \param input_is_shifted If the input has the DC carrier on index 0 (i.e. it is not FFT shifted), set this to false */ static sptr make( - const digital_ofdm_carrier_allocator_cvc_sptr &allocator, + const gr::digital::ofdm_carrier_allocator_cvc::sptr &allocator, const std::string &packet_len_tag_key="", int symbols_skipped=0, bool input_is_shifted=true diff --git a/gr-digital/include/digital/ofdm_sync_sc_cfb.h b/gr-digital/include/digital/ofdm_sync_sc_cfb.h new file mode 100644 index 0000000000..0c5c46f38d --- /dev/null +++ b/gr-digital/include/digital/ofdm_sync_sc_cfb.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H +#define INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H + +#include <digital/api.h> +#include <gr_hier_block2.h> + +namespace gr { + namespace digital { + + /*! + * \brief Schmidl & Cox synchronisation for OFDM + * \ingroup ofdm_blk + * \ingroup sync_blk + * + * Input: complex samples. + * Output 0: Fine frequency offset, scaled by the OFDM symbol duration. + * This is \f$\hat{\varphi}\f$ in [1]. The normalized frequency + * offset is then 2.0*output0/fft_len. + * Output 1: Beginning of the first OFDM symbol after the first (doubled) OFDM + * symbol. The beginning is marked with a 1 (it's 0 everywhere else). + * + * The evaluation of the coarse frequency offset is *not* done in this block. + * Also, the initial equalizer taps are not calculated here. + * + * Note that we use a different normalization factor in the timing metric than + * the authors do in their original work[1]. If the timing metric (8) is + * \f[ + * M(d) = \frac{|P(d)|^2}{(R(d))^2}, + * \f] + * we calculate the normalization as + * \f[ + * R(d) = \frac{1}{2} \sum_{k=0}^{N-1} |r_{k+d}|^2, + * \f] + * i.e., we estimate the energy from *both* half-symbols. This avoids spurious detects + * at the end of a burst, when the energy level suddenly drops. + * + * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM", + * Communications, IEEE Transactions on, 1997. + */ + class DIGITAL_API ofdm_sync_sc_cfb : virtual public gr_hier_block2 + { + public: + typedef boost::shared_ptr<ofdm_sync_sc_cfb> sptr; + + /*! \param fft_len FFT length + * \param cp_len Length of the guard interval (cyclic prefix) in samples + */ + static sptr make(int fft_len, int cp_len); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H */ + diff --git a/gr-digital/include/digital/scale_tags.h b/gr-digital/include/digital/scale_tags.h index 8a9e3efba4..dfe6f4a823 100644 --- a/gr-digital/include/digital/scale_tags.h +++ b/gr-digital/include/digital/scale_tags.h @@ -23,7 +23,7 @@ #ifndef INCLUDED_DIGITAL_SCALE_TAGS_H #define INCLUDED_DIGITAL_SCALE_TAGS_H -#include <digital_ofdm_equalizer_base.h> // FIXME: Error without this line. No idea why. +//#include <digital_ofdm_equalizer_base.h> // FIXME: Error without this line. No idea why. #include <digital/api.h> #include <gr_sync_block.h> diff --git a/gr-digital/include/digital/tagged_stream_check.h b/gr-digital/include/digital/tagged_stream_check.h index 73b44a5bb9..68509bcae6 100644 --- a/gr-digital/include/digital/tagged_stream_check.h +++ b/gr-digital/include/digital/tagged_stream_check.h @@ -19,15 +19,13 @@ * Boston, MA 02110-1301, USA. */ - #ifndef INCLUDED_DIGITAL_TAGGED_STREAM_CHECK_H #define INCLUDED_DIGITAL_TAGGED_STREAM_CHECK_H -#include <digital_ofdm_equalizer_base.h> // FIXME: Error without this line. No idea why. +//#include <digital_ofdm_equalizer_base.h> // FIXME: Error without this line. No idea why. #include <digital/api.h> #include <gr_sync_block.h> - namespace gr { namespace digital { diff --git a/gr-digital/include/digital/ts_insert_zeros_cc.h b/gr-digital/include/digital/ts_insert_zeros_cc.h index 299062eb50..588eb300ee 100644 --- a/gr-digital/include/digital/ts_insert_zeros_cc.h +++ b/gr-digital/include/digital/ts_insert_zeros_cc.h @@ -19,16 +19,14 @@ * Boston, MA 02110-1301, USA. */ - #ifndef INCLUDED_DIGITAL_TS_INSERT_ZEROS_CC_H #define INCLUDED_DIGITAL_TS_INSERT_ZEROS_CC_H -#include <digital_ofdm_equalizer_base.h> // FIXME: Error without this line. No idea why. +//#include <digital_ofdm_equalizer_base.h> // FIXME: Error without this line. No idea why. #include <digital/api.h> #include <gr_block.h> #include <string> - namespace gr { namespace digital { diff --git a/gr-digital/include/digital_crc32_bb.h b/gr-digital/include/digital_crc32_bb.h deleted file mode 100644 index efbf2d545a..0000000000 --- a/gr-digital/include/digital_crc32_bb.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_DIGITAL_CRC32_BB_H -#define INCLUDED_DIGITAL_CRC32_BB_H - -#include <digital/api.h> -#include <gr_tagged_stream_block.h> - -class digital_crc32_bb; - -typedef boost::shared_ptr<digital_crc32_bb> digital_crc32_bb_sptr; - -DIGITAL_API digital_crc32_bb_sptr digital_make_crc32_bb (bool check=false, const std::string& lengthtagname="packet_len"); - -/*! - * \brief Byte-stream CRC block - * \ingroup digital - * - * Input: stream of bytes, which form a packet. The first byte of the packet - * has a tag with key "length" and the value being the number of bytes in the - * packet. - * - * Output: The same bytes as incoming, but trailing a CRC32 of the packet. - * The tag is re-set to the new length. - */ -class DIGITAL_API digital_crc32_bb : public gr_tagged_stream_block -{ - private: - friend DIGITAL_API digital_crc32_bb_sptr digital_make_crc32_bb (bool check, const std::string& lengthtagname); - - bool d_check; - - digital_crc32_bb(bool check, const std::string& lengthtagname); - - public: - ~digital_crc32_bb(); - - int calculate_output_stream_length(const std::vector<int> &ninput_items); - - int work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DIGITAL_CRC32_BB_H */ - diff --git a/gr-digital/include/digital_ofdm_carrier_allocator_cvc.h b/gr-digital/include/digital_ofdm_carrier_allocator_cvc.h deleted file mode 100644 index 9052299aa9..0000000000 --- a/gr-digital/include/digital_ofdm_carrier_allocator_cvc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H -#define INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H - -#include <digital/api.h> -#include <gr_tagged_stream_block.h> - -class digital_ofdm_carrier_allocator_cvc; -typedef boost::shared_ptr<digital_ofdm_carrier_allocator_cvc> digital_ofdm_carrier_allocator_cvc_sptr; - -/* - * \param occupied_carriers A vector of vectors of indexes. Example: if - * occupied_carriers = ((1, 2, 3), (1, 2, 4)), the first - * three input symbols will be mapped to carriers 1, 2 - * and 3. After that, a new OFDM symbol is started. The next - * three input symbols will be placed onto carriers 1, 2 - * and 4 of the second OFDM symbol. The allocation then - * starts from the beginning. - * Order matters! The first input symbol is always mapped - * onto occupied_carriers[0][0]. - * \param pilot_carriers The position of the pilot symbols. Same as occupied_carriers, - * but the actual symbols are taken from pilot_symbols instead - * of the input stream. - * \param pilot_symbols The pilot symbols which are placed onto the pilot carriers. - * pilot_symbols[0][0] is placed onto the first OFDM symbol, on - * carrier index pilot_carriers[0][0] etc. - * \param len_tag_key The key of the tag identifying the length of the input packet. - */ -DIGITAL_API digital_ofdm_carrier_allocator_cvc_sptr -digital_make_ofdm_carrier_allocator_cvc ( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - const std::string &len_tag_key = "packet_len"); - -/*! - * \brief Create frequency domain OFDM symbols from complex values, add pilots. - * \ingroup ofdm_blk - * - * This block turns a stream of complex, scalar modulation symbols into vectors - * which are the input for an IFFT in an OFDM transmitter. It also supports the - * possibility of placing pilot symbols onto the carriers. - * - * The carriers can be allocated freely, if a carrier is not allocated, it is set - * to zero. This allows doing OFDMA-style carrier allocations. - * - * Input: A tagged stream of complex scalars. The first item must have a tag - * containing the number of complex symbols in this frame. - * Output: A tagged stream of complex vectors of length fft_len. This can directly - * be connected to an FFT block. Make sure to set this block to 'reverse' - * for the IFFT and to deactivate FFT shifting. - * - * Carrier indexes are always such that index 0 is the DC carrier (note: you should - * not allocate this carrier). The carriers below the DC carrier are either indexed - * with negative numbers, or with indexes larger than fft_len/2. Index -1 and index - * fft_len-1 both identify the carrier below the DC carrier. - * - */ -class DIGITAL_API digital_ofdm_carrier_allocator_cvc : public gr_tagged_stream_block -{ - private: - friend DIGITAL_API digital_ofdm_carrier_allocator_cvc_sptr digital_make_ofdm_carrier_allocator_cvc (int fft_len, const std::vector<std::vector<int> > &occupied_carriers, const std::vector<std::vector<int> > &pilot_carriers, const std::vector<std::vector<gr_complex> > &pilot_symbols, const std::string &len_tag_key); - - digital_ofdm_carrier_allocator_cvc(int fft_len, const std::vector<std::vector<int> > &occupied_carriers, const std::vector<std::vector<int> > &pilot_carriers, const std::vector<std::vector<gr_complex> > &pilot_symbols, const std::string &len_tag_key); - - //! FFT length - const int d_fft_len; - //! Which carriers/symbols carry data - std::vector<std::vector<int> > d_occupied_carriers; - //! Which carriers/symbols carry pilots symbols - std::vector<std::vector<int> > d_pilot_carriers; - //! Value of said pilot symbols - const std::vector<std::vector<gr_complex> > d_pilot_symbols; - int d_symbols_per_set; - - protected: - int calculate_output_stream_length(const gr_vector_int &ninput_items); - - public: - ~digital_ofdm_carrier_allocator_cvc(); - - std::string len_tag_key() { return d_length_tag_key_str; }; - - const int fft_len() { return d_fft_len; }; - std::vector<std::vector<int> > occupied_carriers() { return d_occupied_carriers; }; - - int work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H */ - diff --git a/gr-digital/include/digital_ofdm_chanest_vcvc.h b/gr-digital/include/digital_ofdm_chanest_vcvc.h deleted file mode 100644 index da03f96720..0000000000 --- a/gr-digital/include/digital_ofdm_chanest_vcvc.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H -#define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H - -#include <digital/api.h> -#include <gr_block.h> - -class digital_ofdm_chanest_vcvc; - -typedef boost::shared_ptr<digital_ofdm_chanest_vcvc> digital_ofdm_chanest_vcvc_sptr; - -/* - * \param sync_symbol1 First synchronisation symbol in the frequency domain. Its length must be - * the FFT length. For Schmidl & Cox synchronisation, every second sub-carrier - * has to be zero. - * \param sync_symbol2 Second synchronisation symbol in the frequency domain. Must be equal to - * the FFT length, or zero length if only one synchronisation symbol is used. - * Using this symbol is how synchronisation is described in [1]. Leaving this - * empty forces us to interpolate the equalizer taps. - * If you are using an unusual sub-carrier configuration (e.g. because of OFDMA), - * this sync symbol is used to identify the active sub-carriers. If you only - * have one synchronisation symbol, set the active sub-carriers to a non-zero - * value in here, and also set \p force_one_sync_symbol parameter to true. - * \param n_data_symbols The number of data symbols following each set of synchronisation symbols. - * Must be at least 1. - * \param eq_noise_red_len If non-zero, noise reduction for the equalizer taps is done according - * to [2]. In this case, it is the channel influence time in number of - * samples. A good value is usually the length of the cyclic prefix. - * \param max_carr_offset Limit the number of sub-carriers the frequency offset can maximally be. - * Leave this zero to try all possibilities. - * \param force_one_sync_symbol See \p sync_symbol2. - */ -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=0, - int max_carr_offset=-1, - bool force_one_sync_symbol=false); - -/*! - * \brief Estimate channel and coarse frequency offset for OFDM from preambles - * \ingroup ofdm_blk - * \ingroup sync_blk - * - * Input: OFDM symbols (in frequency domain). The first one (or two) symbols are expected - * to be synchronisation symbols, which are used to estimate the coarse freq offset - * and the initial equalizer taps (these symbols are removed from the stream). - * The following \p n_data_symbols are passed through unmodified (the actual equalisation - * must be done elsewhere). - * Output: The data symbols, without the synchronisation symbols. - * The first data symbol passed through has two tags: - * 'ofdm_sync_carr_offset' (integer), the coarse frequency offset as number of carriers, - * and 'ofdm_sync_eq_taps' (complex vector). - * Any tags attached to the synchronisation symbols are attached to the first data - * symbol. All other tags are propagated normally. - * - * This block assumes the frequency offset is even (i.e. an integer multiple of 2). - * - * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM", - * Communications, IEEE Transactions on, 1997. - * [2] K.D. Kammeyer, "Nachrichtenuebertragung," Chapter. 16.3.2. - */ -class DIGITAL_API digital_ofdm_chanest_vcvc : public gr_block -{ - private: - 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); - - int d_fft_len; //! FFT length - int d_n_data_syms; //! Number of data symbols following the sync symbol(s) - int d_n_sync_syms; //! Number of sync symbols (1 or 2) - //! 0 if no noise reduction is done for the initial channel state estimation. Otherwise, the maximum length of the channel delay in samples. - int d_eq_noise_red_len; - //! Is sync_symbol1 if d_n_sync_syms == 1, otherwise sync_symbol2. Used as a reference symbol to estimate the channel. - std::vector<gr_complex> d_ref_sym; - //! If d_n_sync_syms == 2 this is used as a differential correlation vector (called 'v' in [1]). - std::vector<gr_complex> d_corr_v; - //! If d_n_sync_syms == 1 we use this instead of d_corr_v to estimate the coarse freq. offset - std::vector<float> d_known_symbol_diffs; - //! If d_n_sync_syms == 1 we use this instead of d_corr_v to estimate the coarse freq. offset (temp. variable) - std::vector<float> d_new_symbol_diffs; - //! The index of the first carrier with data (index 0 is not DC here, but the lowest frequency) - int d_first_active_carrier; - //! The index of the last carrier with data - int d_last_active_carrier; - //! If true, the channel estimation must be interpolated - bool d_interpolate; - //! Maximum carrier offset (negative value!) - int d_max_neg_carr_offset; - //! Maximum carrier offset (positive value!) - int d_max_pos_carr_offset; - - - 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); - - //! Calculate the coarse frequency offset in number of carriers - int get_carr_offset(const gr_complex *sync_sym1, const gr_complex *sync_sym2); - //! Estimate the channel (phase and amplitude offset per carrier) - void get_chan_taps(const gr_complex *sync_sym1, const gr_complex *sync_sym2, int carr_offset, std::vector<gr_complex> &taps); - - public: - ~digital_ofdm_chanest_vcvc(); - - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H */ - diff --git a/gr-digital/include/digital_ofdm_cyclic_prefixer.h b/gr-digital/include/digital_ofdm_cyclic_prefixer.h deleted file mode 100644 index 563a311fa3..0000000000 --- a/gr-digital/include/digital_ofdm_cyclic_prefixer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004-2006,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H -#define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H - -#include <digital/api.h> -#include <gr_tagged_stream_block.h> - -class digital_ofdm_cyclic_prefixer; -typedef boost::shared_ptr<digital_ofdm_cyclic_prefixer> digital_ofdm_cyclic_prefixer_sptr; - -/*! - * \param input_size FFT length (i.e. length of the OFDM symbols) - * \param output_size FFT length + cyclic prefix length (in samples) - * \param rolloff_len Length of the rolloff flank in samples - * \param len_tag_key For framed processing the key of the length tag - */ -DIGITAL_API digital_ofdm_cyclic_prefixer_sptr -digital_make_ofdm_cyclic_prefixer (size_t input_size, - size_t output_size, - int rolloff_len=0, - const std::string &len_tag_key=""); - - -/*! - * \brief Adds a cyclic prefix and performs pulse shaping on OFDM symbols. - * \ingroup ofdm_blk - * - * Input: OFDM symbols (in the time domain, i.e. after the IFFT). Optionally, - * entire frames can be processed. In this case, \p len_tag_key must be - * specified which holds the key of the tag that denotes how - * many OFDM symbols are in a frame. - * Output: A stream of (scalar) complex symbols, which include the cyclic prefix - * and the pulse shaping. - * Note: If complete frames are processed, and \p rolloff_len is greater - * than zero, the final OFDM symbol is followed by the delay line of - * the pulse shaping. - * - * The pulse shape is a raised cosine in the time domain. - */ -class DIGITAL_API digital_ofdm_cyclic_prefixer : public gr_tagged_stream_block -{ - friend DIGITAL_API digital_ofdm_cyclic_prefixer_sptr - digital_make_ofdm_cyclic_prefixer (size_t input_size, size_t output_size, int rolloff_len, const std::string &len_tag_key); - - - protected: - digital_ofdm_cyclic_prefixer (size_t input_size, size_t output_size, int rolloff_len, const std::string &len_tag_key); - - //! Return the number of complex samples from the number of OFDM symbols (includes rolloff) - int calculate_output_stream_length(const gr_vector_int &ninput_items); - - public: - int work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - private: - size_t d_fft_len; - //! FFT length + CP length in samples - size_t d_output_size; - //! Length of the cyclic prefix in samples - int d_cp_size; - //! Length of pulse rolloff in samples - int d_rolloff_len; - //! Buffers the up-flank (at the beginning of the cyclic prefix) - std::vector<float> d_up_flank; - //! Buffers the down-flank (which trails the symbol) - std::vector<float> d_down_flank; - std::vector<gr_complex> d_delay_line; // We do this explicitly to avoid outputting zeroes (i.e. no history!) -}; - -#endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H */ - diff --git a/gr-digital/include/digital_ofdm_equalizer_base.h b/gr-digital/include/digital_ofdm_equalizer_base.h deleted file mode 100644 index 8665395540..0000000000 --- a/gr-digital/include/digital_ofdm_equalizer_base.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H -#define INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H - -#include <digital/api.h> -#include <gr_tags.h> -#include <gr_complex.h> -#include <boost/enable_shared_from_this.hpp> - -class digital_ofdm_equalizer_base; -typedef boost::shared_ptr<digital_ofdm_equalizer_base> digital_ofdm_equalizer_base_sptr; - -class digital_ofdm_equalizer_1d_pilots; -typedef boost::shared_ptr<digital_ofdm_equalizer_1d_pilots> digital_ofdm_equalizer_1d_pilots_sptr; - -/* \brief Base class for implementation details of frequency-domain OFDM equalizers. - * \ingroup ofdm_blk - * \ingroup eq_blk - * - */ -class DIGITAL_API digital_ofdm_equalizer_base : public boost::enable_shared_from_this<digital_ofdm_equalizer_base> -{ - protected: - int d_fft_len; - int d_carr_offset; - - public: - digital_ofdm_equalizer_base(int fft_len); - ~digital_ofdm_equalizer_base(); - - virtual void reset() = 0; - void set_carrier_offset(int offset) { d_carr_offset = offset; }; - virtual void equalize( - gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), - const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()) = 0; - virtual void get_channel_state(std::vector<gr_complex> &taps) = 0; - int fft_len() { return d_fft_len; }; - digital_ofdm_equalizer_base_sptr base() { return shared_from_this(); }; -}; - - -/* \brief Base class for implementation details of 1-dimensional OFDM FDEs which use pilot tones. - * \ingroup digital - * - */ -class DIGITAL_API digital_ofdm_equalizer_1d_pilots : public digital_ofdm_equalizer_base -{ - protected: - //! If \p d_occupied_carriers[k][l] is true, symbol k, carrier l is carrying data. - // (this is a different format than occupied_carriers!) - std::vector<bool> d_occupied_carriers; - //! If \p d_pilot_carriers[k][l] is true, symbol k, carrier l is carrying data. - // (this is a different format than pilot_carriers!) - std::vector<std::vector<bool> > d_pilot_carriers; - //! If \p d_pilot_carriers[k][l] is true, d_pilot_symbols[k][l] is its tx'd value. - // (this is a different format than pilot_symbols!) - std::vector<std::vector<gr_complex> > d_pilot_symbols; - //! In case the frame doesn't begin with OFDM symbol 0, this is the index of the first symbol - int d_symbols_skipped; - //! The current position in the set of pilot symbols - int d_pilot_carr_set; - //! Vector of length d_fft_len saving the current channel state (on the occupied carriers) - std::vector<gr_complex> d_channel_state; - - public: - digital_ofdm_equalizer_1d_pilots( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - bool input_is_shifted); - ~digital_ofdm_equalizer_1d_pilots(); - - void reset(); - void get_channel_state(std::vector<gr_complex> &taps); -}; - -#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H */ - diff --git a/gr-digital/include/digital_ofdm_equalizer_simpledfe.h b/gr-digital/include/digital_ofdm_equalizer_simpledfe.h deleted file mode 100644 index 89b0b5cd6d..0000000000 --- a/gr-digital/include/digital_ofdm_equalizer_simpledfe.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H -#define INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H - -#include <digital/api.h> -#include <digital/constellation.h> -#include <digital_ofdm_equalizer_base.h> - -class digital_ofdm_equalizer_simpledfe; -typedef boost::shared_ptr<digital_ofdm_equalizer_simpledfe> digital_ofdm_equalizer_simpledfe_sptr; - -/* - * \param fft_len FFT length - * \param constellation The constellation object describing the modulation used - * on the subcarriers (e.g. QPSK). This is used to decode - * the individual symbols. - * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator - * for a description. - * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator - * for a description. - * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator - * for a description. - * \param alpha Averaging coefficient (in a nutshell, if \f$H_{i,k}\f$ is the channel - * state for carrier i and symbol k, - * \f$H_{i,k+1} = \alpha H_{i,k} + (1 - \alpha) H_{i,k+1}\f$. Make this - * larger if there's more noise, but keep in mind that larger values - * of alpha mean slower response to channel changes). - * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers. - * If the first symbol of the frame was removed (e.g. to decode the - * header), set this make sure the pilot symbols are correctly - * identified. - * \param input_is_shifted Set this to false if the input signal is not shifted, i.e. - * the first input items is on the DC carrier. - * Note that a lot of the OFDM receiver blocks operate on shifted - * signals! - */ -DIGITAL_API digital_ofdm_equalizer_simpledfe_sptr -digital_make_ofdm_equalizer_simpledfe( - int fft_len, - const gr::digital::constellation_sptr &constellation, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - float alpha = 0.1, - bool input_is_shifted = true); - -/* \brief Simple decision feedback equalizer for OFDM. - * \ingroup ofdm_blk - * \ingroup eq_blk - * - * Equalizes an OFDM signal symbol by symbol using knowledge of the - * complex modulations symbols. - * For every symbol, the following steps are performed: - * - On every sub-carrier, decode the modulation symbol - * - Use the difference between the decoded symbol and the received symbol - * to update the channel state on this carrier - * - Whenever a pilot symbol is found, it uses the known pilot symbol to - * update the channel state. - * - * This equalizer makes a lot of assumptions: - * - The initial channel state is good enough to decode the first - * symbol without error (unless the first symbol only consists of pilot - * tones) - * - The channel changes only very slowly, such that the channel state - * from one symbol is enough to decode the next - * - SNR low enough that equalization will always suffice to correctly - * decode a symbol - * If these assumptions are not met, the most common error is that the - * channel state is estimated incorrectly during equalization; after that, - * all subsequent symbols will be completely wrong. - * - * Note that the equalized symbols are *exact points* on the constellation. - * This means soft information of the modulation symbols is lost after the - * equalization, which is suboptimal for channel codes that use soft decision. - * - */ -class DIGITAL_API digital_ofdm_equalizer_simpledfe : public digital_ofdm_equalizer_1d_pilots -{ - public: - digital_ofdm_equalizer_simpledfe( - int fft_len, - const gr::digital::constellation_sptr &constellation, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - float alpha = 0.1, - bool input_is_shifted = true); - - ~digital_ofdm_equalizer_simpledfe(); - - void equalize(gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), - const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); - - private: - gr::digital::constellation_sptr d_constellation; - //! Averaging coefficient - float d_alpha; - -}; - -#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H */ - diff --git a/gr-digital/include/digital_ofdm_equalizer_static.h b/gr-digital/include/digital_ofdm_equalizer_static.h deleted file mode 100644 index 4537d329f4..0000000000 --- a/gr-digital/include/digital_ofdm_equalizer_static.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H -#define INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H - -#include <digital/api.h> -#include <digital/constellation.h> -#include <digital_ofdm_equalizer_base.h> - -class digital_ofdm_equalizer_static; -typedef boost::shared_ptr<digital_ofdm_equalizer_static> digital_ofdm_equalizer_static_sptr; - -/* - * \param fft_len FFT length - * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator - * for a description. - * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator - * for a description. - * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator - * for a description. - * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers. - * If the first symbol of the frame was removed (e.g. to decode the - * header), set this make sure the pilot symbols are correctly - * identified. - * \param input_is_shifted Set this to false if the input signal is not shifted, i.e. - * the first input items is on the DC carrier. - * Note that a lot of the OFDM receiver blocks operate on shifted - * signals! - */ -DIGITAL_API digital_ofdm_equalizer_static_sptr -digital_make_ofdm_equalizer_static( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - bool input_is_shifted = true); - -/* \brief Very simple static equalizer for OFDM. - * \ingroup ofdm_blk - * \ingroup eq_blk - * - * This is an extremely simple equalizer. It will only work for high-SNR, very, very - * slowly changing channels. - * It simply divides the signal with the currently known channel state. Whenever - * a pilot symbol comes around, it updates the channel state on that particular - * carrier by dividing the received symbol with the known pilot symbol. - */ -class DIGITAL_API digital_ofdm_equalizer_static : public digital_ofdm_equalizer_1d_pilots -{ - public: - digital_ofdm_equalizer_static( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - bool input_is_shifted = true); - ~digital_ofdm_equalizer_static(); - - /*! \brief Divide the input signal with the current channel state. - * - * Does the following (and nothing else): - * - Divide every OFDM symbol with the current channel state - * - If a pilot symbol is found, re-set the channel state by dividing the received - * symbol with the known pilot symbol - */ - void equalize(gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), - const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); - - private: - -}; - -#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H */ - diff --git a/gr-digital/include/digital_ofdm_sync_sc_cfb.h b/gr-digital/include/digital_ofdm_sync_sc_cfb.h deleted file mode 100644 index cc728814ed..0000000000 --- a/gr-digital/include/digital_ofdm_sync_sc_cfb.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H -#define INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H - -#include <digital/api.h> -#include <gr_hier_block2.h> - -class digital_ofdm_sync_sc_cfb; -typedef boost::shared_ptr<digital_ofdm_sync_sc_cfb> digital_ofdm_sync_sc_cfb_sptr; - -/*! \param fft_len FFT length - * \param cp_len Length of the guard interval (cyclic prefix) in samples - */ -DIGITAL_API digital_ofdm_sync_sc_cfb_sptr -digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); - -/*! - * \brief Schmidl & Cox synchronisation for OFDM - * \ingroup ofdm_blk - * \ingroup sync_blk - * - * Input: complex samples. - * Output 0: Fine frequency offset, scaled by the OFDM symbol duration. - * This is \f$\hat{\varphi}\f$ in [1]. The normalized frequency - * offset is then 2.0*output0/fft_len. - * Output 1: Beginning of the first OFDM symbol after the first (doubled) OFDM - * symbol. The beginning is marked with a 1 (it's 0 everywhere else). - * - * The evaluation of the coarse frequency offset is *not* done in this block. - * Also, the initial equalizer taps are not calculated here. - * - * Note that we use a different normalization factor in the timing metric than - * the authors do in their original work[1]. If the timing metric (8) is - * \f[ - * M(d) = \frac{|P(d)|^2}{(R(d))^2}, - * \f] - * we calculate the normalization as - * \f[ - * R(d) = \frac{1}{2} \sum_{k=0}^{N-1} |r_{k+d}|^2, - * \f] - * i.e., we estimate the energy from *both* half-symbols. This avoids spurious detects - * at the end of a burst, when the energy level suddenly drops. - * - * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM", - * Communications, IEEE Transactions on, 1997. - */ -class DIGITAL_API digital_ofdm_sync_sc_cfb : public gr_hier_block2 -{ - private: - friend DIGITAL_API digital_ofdm_sync_sc_cfb_sptr digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); - digital_ofdm_sync_sc_cfb(int fft_len, int cp_len); - - public: - ~digital_ofdm_sync_sc_cfb(); - -}; - -#endif /* INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H */ - diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt index 5178506049..7e83b86021 100644 --- a/gr-digital/lib/CMakeLists.txt +++ b/gr-digital/lib/CMakeLists.txt @@ -126,18 +126,11 @@ list(APPEND digital_sources costas_loop_cc_impl.cc cpmmod_bc_impl.cc crc32.cc + crc32_bb_impl.cc descrambler_bb_impl.cc diff_decoder_bb_impl.cc diff_encoder_bb_impl.cc diff_phasor_cc_impl.cc - digital_crc32_bb.cc - digital_ofdm_carrier_allocator_cvc.cc - digital_ofdm_chanest_vcvc.cc - digital_ofdm_cyclic_prefixer.cc - digital_ofdm_equalizer_base.cc - digital_ofdm_equalizer_simpledfe.cc - digital_ofdm_equalizer_static.cc - digital_ofdm_sync_sc_cfb.cc fll_band_edge_cc_impl.cc framer_sink_1_impl.cc glfsr.cc @@ -150,7 +143,12 @@ list(APPEND digital_sources mpsk_receiver_cc_impl.cc mpsk_snr_est.cc mpsk_snr_est_cc_impl.cc + ofdm_carrier_allocator_cvc_impl.cc + ofdm_chanest_vcvc_impl.cc ofdm_cyclic_prefixer_impl.cc + ofdm_equalizer_base.cc + ofdm_equalizer_simpledfe.cc + ofdm_equalizer_static.cc ofdm_frame_acquisition_impl.cc ofdm_frame_equalizer_vcvc_impl.cc ofdm_frame_sink_impl.cc @@ -158,6 +156,7 @@ list(APPEND digital_sources ofdm_mapper_bcv_impl.cc ofdm_sampler_impl.cc ofdm_serializer_vcc_impl.cc + ofdm_sync_sc_cfb_impl.cc packet_header_default.cc packet_header_ofdm.cc packet_headergenerator_bb_impl.cc diff --git a/gr-digital/lib/crc32_bb_impl.cc b/gr-digital/lib/crc32_bb_impl.cc new file mode 100644 index 0000000000..608c5758ac --- /dev/null +++ b/gr-digital/lib/crc32_bb_impl.cc @@ -0,0 +1,105 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_io_signature.h> +#include "crc32_bb_impl.h" +#include <digital/crc32.h> + +namespace gr { + namespace digital { + + crc32_bb::sptr + crc32_bb::make(bool check, const std::string& lengthtagname) + { + return gnuradio::get_initial_sptr (new crc32_bb_impl(check, lengthtagname)); + } + + crc32_bb_impl::crc32_bb_impl(bool check, const std::string& lengthtagname) + : gr_tagged_stream_block("crc32_bb", + gr_make_io_signature(1, 1, sizeof (char)), + gr_make_io_signature(1, 1, sizeof (char)), + lengthtagname), + d_check(check) + { + set_tag_propagation_policy(TPP_DONT); + } + + crc32_bb_impl::~crc32_bb_impl() + { + } + + int + crc32_bb_impl::calculate_output_stream_length(const gr_vector_int &ninput_items) + { + if (d_check) { + return ninput_items[0] - 4; + } else { + return ninput_items[0] + 4; + } + } + + int + crc32_bb_impl::work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const unsigned char *in = (const unsigned char *) input_items[0]; + unsigned char *out = (unsigned char *) output_items[0]; + long packet_length = ninput_items[0]; + int packet_size_diff = d_check ? -4 : 4; + unsigned int crc; + + if (d_check) { + crc = gr::digital::crc32(in, packet_length-4); + if (crc != *(unsigned int *)(in+packet_length-4)) { // Drop package + return 0; + } + memcpy((void *) out, (const void *) in, packet_length-4); + } else { + crc = gr::digital::crc32(in, packet_length); + memcpy((void *) out, (const void *) in, packet_length); + memcpy((void *) (out + packet_length), &crc, 4); // FIXME big-endian/little-endian, this might be wrong + } + + std::vector<gr_tag_t> tags; + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+packet_length); + for (unsigned i = 0; i < tags.size(); i++) { + tags[i].offset -= nitems_read(0); + if (d_check && tags[i].offset > packet_length+packet_size_diff) { + tags[i].offset = packet_length-5; + } + add_item_tag(0, nitems_written(0) + tags[i].offset, + tags[i].key, + tags[i].value); + } + + return packet_length + packet_size_diff; + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/swig/digital_ofdm_chanest_vcvc.i b/gr-digital/lib/crc32_bb_impl.h index aa6e79b5c2..7b9dbb6351 100644 --- a/gr-digital/swig/digital_ofdm_chanest_vcvc.i +++ b/gr-digital/lib/crc32_bb_impl.h @@ -1,5 +1,6 @@ /* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. +/* + * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -19,22 +20,32 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(digital, ofdm_chanest_vcvc); +#ifndef INCLUDED_DIGITAL_CRC32_BB_IMPL_H +#define INCLUDED_DIGITAL_CRC32_BB_IMPL_H -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=0, - int max_carr_offset=-1, - bool force_one_sync_symbol=false); +#include <digital/crc32_bb.h> -class digital_ofdm_chanest_vcvc : public gr_block -{ - private: - 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); +namespace gr { + namespace digital { - public: -}; + class crc32_bb_impl : public crc32_bb + { + private: + bool d_check; + + public: + crc32_bb_impl(bool check, const std::string& lengthtagname); + ~crc32_bb_impl(); + + int calculate_output_stream_length(const gr_vector_int &ninput_items); + int work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_CRC32_BB_IMPL_H */ diff --git a/gr-digital/lib/digital_crc32_bb.cc b/gr-digital/lib/digital_crc32_bb.cc deleted file mode 100644 index 40d313ba89..0000000000 --- a/gr-digital/lib/digital_crc32_bb.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_io_signature.h> -#include <digital/crc32.h> -#include <digital_crc32_bb.h> - -digital_crc32_bb_sptr -digital_make_crc32_bb (bool check, const std::string& lengthtagname) -{ - return gnuradio::get_initial_sptr (new digital_crc32_bb(check, lengthtagname)); -} - - -digital_crc32_bb::digital_crc32_bb (bool check, const std::string& lengthtagname) - : gr_tagged_stream_block ("crc32_bb", - gr_make_io_signature(1, 1, sizeof (char)), - gr_make_io_signature(1, 1, sizeof (char)), - lengthtagname), - d_check(check) -{ - set_tag_propagation_policy(TPP_DONT); -} - - -digital_crc32_bb::~digital_crc32_bb() -{ -} - - -int -digital_crc32_bb::calculate_output_stream_length(const std::vector<int> &ninput_items) -{ - if (d_check) { - return ninput_items[0] - 4; - } else { - return ninput_items[0] + 4; - } -} - - -int -digital_crc32_bb::work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const unsigned char *in = (const unsigned char *) input_items[0]; - unsigned char *out = (unsigned char *) output_items[0]; - long packet_length = ninput_items[0]; - int packet_size_diff = d_check ? -4 : 4; - unsigned int crc; - - if (d_check) { - crc = gr::digital::crc32(in, packet_length-4); - if (crc != *(unsigned int *)(in+packet_length-4)) { // Drop package - return 0; - } - memcpy((void *) out, (const void *) in, packet_length-4); - } else { - crc = gr::digital::crc32(in, packet_length); - memcpy((void *) out, (const void *) in, packet_length); - memcpy((void *) (out + packet_length), &crc, 4); // FIXME big-endian/little-endian, this might be wrong - } - - std::vector<gr_tag_t> tags; - get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+packet_length); - for (unsigned i = 0; i < tags.size(); i++) { - tags[i].offset -= nitems_read(0); - if (d_check && tags[i].offset > packet_length+packet_size_diff) { - tags[i].offset = packet_length-5; - } - add_item_tag(0, nitems_written(0) + tags[i].offset, - tags[i].key, - tags[i].value); - } - - return packet_length + packet_size_diff; -} - diff --git a/gr-digital/lib/digital_ofdm_carrier_allocator_cvc.cc b/gr-digital/lib/digital_ofdm_carrier_allocator_cvc.cc deleted file mode 100644 index e5b3013302..0000000000 --- a/gr-digital/lib/digital_ofdm_carrier_allocator_cvc.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_io_signature.h> -#include "digital_ofdm_carrier_allocator_cvc.h" - -digital_ofdm_carrier_allocator_cvc_sptr -digital_make_ofdm_carrier_allocator_cvc ( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - const std::string &len_tag_key) -{ - return gnuradio::get_initial_sptr (new digital_ofdm_carrier_allocator_cvc(fft_len, occupied_carriers, pilot_carriers, pilot_symbols, len_tag_key)); -} - - -digital_ofdm_carrier_allocator_cvc::digital_ofdm_carrier_allocator_cvc ( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - const std::string &len_tag_key) - : gr_tagged_stream_block ("ofdm_carrier_allocator_cvc", - gr_make_io_signature(1, 1, sizeof (gr_complex)), - gr_make_io_signature(1, 1, sizeof (gr_complex) * fft_len), len_tag_key), - d_fft_len(fft_len), - d_occupied_carriers(occupied_carriers), - d_pilot_carriers(pilot_carriers), - d_pilot_symbols(pilot_symbols), - d_symbols_per_set(0) -{ - for (unsigned i = 0; i < d_occupied_carriers.size(); i++) { - for (unsigned j = 0; j < d_occupied_carriers[i].size(); j++) { - if (occupied_carriers[i][j] < 0) { - d_occupied_carriers[i][j] += d_fft_len; - } - if (d_occupied_carriers[i][j] > d_fft_len || d_occupied_carriers[i][j] < 0) { - throw std::invalid_argument("data carrier index out of bounds"); - } - } - } - for (unsigned i = 0; i < d_pilot_carriers.size(); i++) { - if (d_pilot_carriers[i].size() != pilot_symbols[i].size()) { - throw std::invalid_argument("pilot_carriers do not match pilot_symbols"); - } - for (unsigned j = 0; j < d_pilot_carriers[i].size(); j++) { - if (d_pilot_carriers[i][j] < 0) { - d_pilot_carriers[i][j] += d_fft_len; - } - if (d_pilot_carriers[i][j] > d_fft_len || d_pilot_carriers[i][j] < 0) { - throw std::invalid_argument("pilot carrier index out of bounds"); - } - } - } - - for (unsigned i = 0; i < d_occupied_carriers.size(); i++) { - d_symbols_per_set += d_occupied_carriers[i].size(); - } - set_tag_propagation_policy(TPP_DONT); - set_relative_rate((double) d_symbols_per_set / d_occupied_carriers.size()); -} - - -digital_ofdm_carrier_allocator_cvc::~digital_ofdm_carrier_allocator_cvc() -{ -} - - -int -digital_ofdm_carrier_allocator_cvc::calculate_output_stream_length(const gr_vector_int &ninput_items) -{ - int nin = ninput_items[0]; - int nout = (nin / d_symbols_per_set) * d_occupied_carriers.size(); - int k = 0; - for (int i = 0; i < nin % d_symbols_per_set; k++) { - nout++; - i += d_occupied_carriers[k % d_occupied_carriers.size()].size(); - } - return nout; -} - - -int -digital_ofdm_carrier_allocator_cvc::work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - std::vector<gr_tag_t> tags; - - memset((void *) out, 0x00, sizeof(gr_complex) * d_fft_len * noutput_items); - long n_ofdm_symbols = 0; - int curr_set = 0; - int symbols_to_allocate = d_occupied_carriers[0].size(); - int symbols_allocated = 0; - for (int i = 0; i < ninput_items[0]; i++) { - if (symbols_allocated == 0) { - // Copy all tags associated with these input symbols onto this OFDM symbol - get_tags_in_range(tags, 0, - nitems_read(0)+i, - nitems_read(0)+std::min(i+symbols_to_allocate, (int) ninput_items[0]) - ); - for (unsigned t = 0; t < tags.size(); t++) { - add_item_tag(0, nitems_written(0)+n_ofdm_symbols, - tags[t].key, - tags[t].value); - } - n_ofdm_symbols++; - } - out[(n_ofdm_symbols-1) * d_fft_len + d_occupied_carriers[curr_set][symbols_allocated]] = in[i]; - symbols_allocated++; - if (symbols_allocated == symbols_to_allocate) { - curr_set = (curr_set + 1) % d_occupied_carriers.size(); - symbols_to_allocate = d_occupied_carriers[curr_set].size(); - symbols_allocated = 0; - } - } - // 2) Copy pilot symbols - curr_set = 0; - for (int i = 0; i < n_ofdm_symbols; i++) { - for (unsigned k = 0; k < d_pilot_carriers[curr_set].size(); k++) { - out[i * d_fft_len + d_pilot_carriers[curr_set][k]] = d_pilot_symbols[curr_set][k]; - } - curr_set = (curr_set + 1) % d_pilot_carriers.size(); - } - - return n_ofdm_symbols; -} - diff --git a/gr-digital/lib/digital_ofdm_chanest_vcvc.cc b/gr-digital/lib/digital_ofdm_chanest_vcvc.cc deleted file mode 100644 index a484594577..0000000000 --- a/gr-digital/lib/digital_ofdm_chanest_vcvc.cc +++ /dev/null @@ -1,281 +0,0 @@ -/* -*- c++ -*- */ -// vim: set sw=2: -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_io_signature.h> -#include "digital_ofdm_chanest_vcvc.h" - -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) -{ - return gnuradio::get_initial_sptr (new digital_ofdm_chanest_vcvc( - sync_symbol1, sync_symbol2, n_data_symbols, eq_noise_red_len, max_carr_offset, force_one_sync_symbol)); -} - - -digital_ofdm_chanest_vcvc::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) - : gr_block ("ofdm_chanest_vcvc", - gr_make_io_signature(1, 1, sizeof (gr_complex) * sync_symbol1.size()), - gr_make_io_signature(1, 1, sizeof (gr_complex) * sync_symbol1.size())), - d_fft_len(sync_symbol1.size()), - d_n_data_syms(n_data_symbols), - d_n_sync_syms(1), - d_eq_noise_red_len(eq_noise_red_len), - d_ref_sym((sync_symbol2.size() && !force_one_sync_symbol) ? sync_symbol2 : sync_symbol1), - d_corr_v(sync_symbol2), - d_known_symbol_diffs(0, 0), - d_new_symbol_diffs(0, 0), - d_interpolate(false) -{ - // Set index of first and last active carrier - for (int i = 0; i < d_fft_len; i++) { - if (d_ref_sym[i] != gr_complex(0, 0)) { - d_first_active_carrier = i; - break; - } - } - for (int i = d_fft_len-1; i >= 0; i--) { - if (d_ref_sym[i] != gr_complex(0, 0)) { - d_last_active_carrier = i; - break; - } - } - - // Sanity checks - if (sync_symbol2.size()) { - if (sync_symbol1.size() != sync_symbol2.size()) { - throw std::invalid_argument("sync symbols must have equal length."); - } - if (!force_one_sync_symbol) { - d_n_sync_syms = 2; - } - } else { - if (sync_symbol1[d_first_active_carrier+1] == gr_complex(0, 0)) { - d_last_active_carrier++; - d_interpolate = true; - } - } - - // Set up coarse freq estimation info - // Allow all possible values: - d_max_neg_carr_offset = -d_first_active_carrier; - d_max_pos_carr_offset = d_fft_len - d_last_active_carrier - 1; - if (max_carr_offset != -1) { - d_max_neg_carr_offset = std::max(-max_carr_offset, d_max_neg_carr_offset); - d_max_pos_carr_offset = std::min(max_carr_offset, d_max_pos_carr_offset); - } - // Carrier offsets must be even - if (d_max_neg_carr_offset % 2) - d_max_neg_carr_offset++; - if (d_max_pos_carr_offset % 2) - d_max_pos_carr_offset--; - - if (d_n_sync_syms == 2) { - for (int i = 0; i < d_fft_len; i++) { - if (sync_symbol1[i] == gr_complex(0, 0)) { - d_corr_v[i] = gr_complex(0, 0); - } else { - d_corr_v[i] /= sync_symbol1[i]; - } - } - } else { - d_corr_v.resize(0, 0); - d_known_symbol_diffs.resize(d_fft_len, 0); - d_new_symbol_diffs.resize(d_fft_len, 0); - for (int i = d_first_active_carrier; i < d_last_active_carrier-2 && i < d_fft_len-2; i += 2) { - d_known_symbol_diffs[i] = std::norm(sync_symbol1[i] - sync_symbol1[i+2]); - } - } - - set_relative_rate((double) n_data_symbols / (n_data_symbols + d_n_sync_syms)); - set_tag_propagation_policy(TPP_DONT); -} - - -digital_ofdm_chanest_vcvc::~digital_ofdm_chanest_vcvc() -{ -} - -void -digital_ofdm_chanest_vcvc::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - ninput_items_required[0] = (noutput_items/d_n_data_syms) * (d_n_data_syms + d_n_sync_syms); -} - - -int -digital_ofdm_chanest_vcvc::get_carr_offset(const gr_complex *sync_sym1, const gr_complex *sync_sym2) -{ - int carr_offset = 0; - if (d_corr_v.size()) { - // Use Schmidl & Cox method - float Bg_max = 0; - // g here is 2g in the paper - for (int g = d_max_neg_carr_offset; g <= d_max_pos_carr_offset; g += 2) { - gr_complex tmp = gr_complex(0, 0); - for (int k = 0; k < d_fft_len; k++) { - if (d_corr_v[k] != gr_complex(0, 0)) { - tmp += std::conj(sync_sym1[k+g]) * std::conj(d_corr_v[k]) * sync_sym2[k+g]; - } - } - if (std::abs(tmp) > Bg_max) { - Bg_max = std::abs(tmp); - carr_offset = g; - } - } - } else { - // Correlate - std::fill(d_new_symbol_diffs.begin(), d_new_symbol_diffs.end(), 0); - for(int i = 0; i < d_fft_len-2; i++) { - d_new_symbol_diffs[i] = std::norm(sync_sym1[i] - sync_sym1[i+2]); - } - - float sum; - float max = 0; - for (int g = d_max_neg_carr_offset; g <= d_max_pos_carr_offset; g += 2) { - sum = 0; - for (int j = 0; j < d_fft_len; j++) { - if (d_known_symbol_diffs[j]) { - sum += (d_known_symbol_diffs[j] * d_new_symbol_diffs[j + g]); - } - if(sum > max) { - max = sum; - carr_offset = g; - } - } - } - } - return carr_offset; -} - - -void -digital_ofdm_chanest_vcvc::get_chan_taps( - const gr_complex *sync_sym1, - const gr_complex *sync_sym2, - int carr_offset, - std::vector<gr_complex> &taps) -{ - const gr_complex *sym = ((d_n_sync_syms == 2) ? sync_sym2 : sync_sym1); - std::fill(taps.begin(), taps.end(), gr_complex(0, 0)); - int loop_start = 0; - int loop_end = d_fft_len; - if (carr_offset > 0) { - loop_start = carr_offset; - } else if (carr_offset < 0) { - loop_end = d_fft_len + carr_offset; - } - for (int i = loop_start; i < loop_end; i++) { - if ((d_ref_sym[i-carr_offset] != gr_complex(0, 0))) { - taps[i] = sym[i] / d_ref_sym[i-carr_offset]; - } - } - - if (d_interpolate) { - for (int i = d_first_active_carrier + 1; i < d_last_active_carrier; i += 2) { - taps[i] = (taps[i-1] + taps[i+1]) / gr_complex(2.0, 0); - } - taps[d_last_active_carrier] = taps[d_last_active_carrier-1]; - } - - if (d_eq_noise_red_len) { - // TODO - // 1) IFFT - // 2) Set all elements > d_eq_noise_red_len to zero - // 3) FFT - } -} - - -// 1) Go through all the frames available on the input buffer -// 2) Estimate the coarse freq. offset and the eq. taps from the -// input symbol(s) -// 3) Copy the data symbols to the output -// 4) Copy all other tags onto the output. A tag that was on -// a sync symbol is copied onto the first data symbol. -// 5) Add the new tags for carrier offset and eq. taps -int -digital_ofdm_chanest_vcvc::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - int n_frames = noutput_items/d_n_data_syms; - const int framesize = d_n_sync_syms + d_n_data_syms; - - for (int i = 0; i < n_frames; i++) { - int carr_offset = 0; - if (d_max_neg_carr_offset || d_max_pos_carr_offset) - carr_offset = get_carr_offset(in, in+d_fft_len); - std::vector<gr_complex> chan_taps(d_fft_len, 0); - get_chan_taps(in, in+d_fft_len, carr_offset, chan_taps); - - memcpy((void *) out, - (void *) &in[d_n_sync_syms * d_fft_len], - sizeof(gr_complex) * d_fft_len * d_n_data_syms); - in += framesize * d_fft_len; - out += d_n_data_syms * d_fft_len; - - std::vector<gr_tag_t> tags; - this->get_tags_in_range(tags, 0, - this->nitems_read(0)+i*framesize, - this->nitems_read(0)+(i+1)*framesize); - for (unsigned t = 0; t < tags.size(); t++) { - int offset = tags[t].offset - (this->nitems_read(0) + i*framesize); - if (offset < d_n_sync_syms) { - offset = 0; - } else { - offset -= d_n_sync_syms; - } - tags[t].offset = offset + this->nitems_written(0) + i*d_n_data_syms; - this->add_item_tag(0, tags[t]); - } - - this->add_item_tag(0, this->nitems_written(0) + i*d_n_data_syms, - pmt::string_to_symbol("ofdm_sync_carr_offset"), - pmt::from_long(carr_offset)); - this->add_item_tag(0, this->nitems_written(0) + i*d_n_data_syms, - pmt::string_to_symbol("ofdm_sync_chan_taps"), - pmt::init_c32vector(d_fft_len, chan_taps)); - } - - consume_each(n_frames * framesize); - return n_frames * d_n_data_syms; -} - diff --git a/gr-digital/lib/digital_ofdm_cyclic_prefixer.cc b/gr-digital/lib/digital_ofdm_cyclic_prefixer.cc deleted file mode 100644 index ada5742a51..0000000000 --- a/gr-digital/lib/digital_ofdm_cyclic_prefixer.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2010,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <cmath> -#include <digital_ofdm_cyclic_prefixer.h> -#include <gr_io_signature.h> - -digital_ofdm_cyclic_prefixer_sptr -digital_make_ofdm_cyclic_prefixer (size_t input_size, - size_t output_size, - int rolloff_len, - const std::string &len_tag_key) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_cyclic_prefixer (input_size, - output_size, - rolloff_len, - len_tag_key)); -} - -digital_ofdm_cyclic_prefixer::digital_ofdm_cyclic_prefixer (size_t input_size, - size_t output_size, - int rolloff_len, - const std::string &len_tag_key) - : gr_tagged_stream_block ("ofdm_cyclic_prefixer", - gr_make_io_signature (1, 1, input_size*sizeof(gr_complex)), - gr_make_io_signature (1, 1, sizeof(gr_complex)), - len_tag_key), - d_fft_len(input_size), - d_output_size(output_size), - d_cp_size(output_size - input_size), - d_rolloff_len(rolloff_len), - d_up_flank((rolloff_len ? rolloff_len-1 : 0), 0), - d_down_flank((rolloff_len ? rolloff_len-1 : 0), 0), - d_delay_line(0, 0) -{ - set_relative_rate(d_output_size); - - // Flank of length 1 would just be rectangular - if (d_rolloff_len == 1) { - d_rolloff_len = 0; - } - if (d_rolloff_len) { - d_delay_line.resize(d_rolloff_len-1, 0); - if (rolloff_len > d_cp_size) { - throw std::invalid_argument("cyclic prefixer: rolloff len must smaller than the cyclic prefix."); - } - // The actual flanks are one sample shorter than d_rolloff_len, because the - // first sample of the up- and down flank is always zero and one, respectively - for (int i = 1; i < d_rolloff_len; i++) { - d_up_flank[i-1] = 0.5 * (1 + cos(M_PI * i/rolloff_len - M_PI)); - d_down_flank[i-1] = 0.5 * (1 + cos(M_PI * (rolloff_len-i)/rolloff_len - M_PI)); - } - } - - if (len_tag_key.empty()) { - set_output_multiple(d_output_size); - } else { - set_tag_propagation_policy(TPP_DONT); - } -} - -int -digital_ofdm_cyclic_prefixer::calculate_output_stream_length(const gr_vector_int &ninput_items) -{ - int nout = ninput_items[0] * d_output_size + d_delay_line.size(); - return nout; -} - -// Operates in two ways: -// - When there's a length tag name specified, operates in packet mode. -// Here, an entire OFDM frame is processed at once. The final OFDM symbol -// is postfixed with the delay line of the pulse shape. -// We manually propagate tags. -// - Otherwise, we're in freewheeling mode. Process as many OFDM symbols as -// are space for in the output buffer. The delay line is never flushed. -// Tags are propagated by the scheduler. -int -digital_ofdm_cyclic_prefixer::work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex *in = (gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - int symbols_to_read = 0; - - // 1) Figure out if we're in freewheeling or packet mode - if (!d_length_tag_key_str.empty()) { - symbols_to_read = ninput_items[0]; - noutput_items = symbols_to_read * d_output_size + d_delay_line.size(); - } else { - symbols_to_read = std::min(noutput_items / (int) d_output_size, ninput_items[0]); - noutput_items = symbols_to_read * d_output_size; - } - - // 2) Do the cyclic prefixing and, optionally, the pulse shaping - for (int sym_idx = 0; sym_idx < symbols_to_read; sym_idx++) { - memcpy((void *)(out + d_cp_size), (void *) in, d_fft_len * sizeof(gr_complex)); - memcpy((void *) out, (void *) (in + d_fft_len - d_cp_size), d_cp_size * sizeof(gr_complex)); - if (d_rolloff_len) { - for (int i = 0; i < d_rolloff_len-1; i++) { - out[i] = out[i] * d_up_flank[i] + d_delay_line[i]; - d_delay_line[i] = in[i] * d_down_flank[i]; - } - } - in += d_fft_len; - out += d_output_size; - } - - // 3) If we're in packet mode: - // - flush the delay line, if applicable - // - Propagate tags - if (!d_length_tag_key_str.empty()) { - if (d_rolloff_len) { - for (unsigned i = 0; i < d_delay_line.size(); i++) { - *out++ = d_delay_line[i]; - } - d_delay_line.assign(d_delay_line.size(), 0); - } - std::vector<gr_tag_t> tags; - get_tags_in_range( - tags, 0, - nitems_read(0), nitems_read(0)+symbols_to_read - ); - for (unsigned i = 0; i < tags.size(); i++) { - tags[i].offset = ((tags[i].offset - nitems_read(0)) * d_output_size) + nitems_written(0); - add_item_tag(0, - tags[i].offset, - tags[i].key, - tags[i].value - ); - } - } else { - consume_each(symbols_to_read); - } - - return noutput_items; -} - diff --git a/gr-digital/lib/digital_ofdm_equalizer_base.cc b/gr-digital/lib/digital_ofdm_equalizer_base.cc deleted file mode 100644 index b4fa5df87e..0000000000 --- a/gr-digital/lib/digital_ofdm_equalizer_base.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "digital_ofdm_equalizer_base.h" - -// *** Base class **************************************************** -digital_ofdm_equalizer_base::digital_ofdm_equalizer_base(int fft_len) : - d_fft_len(fft_len), - d_carr_offset(0) -{ -} - - -digital_ofdm_equalizer_base::~digital_ofdm_equalizer_base() -{ -} - - -// *** Sub-Base class for 1D equalizers using pilot tones ************* -digital_ofdm_equalizer_1d_pilots::digital_ofdm_equalizer_1d_pilots( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - bool input_is_shifted) - : digital_ofdm_equalizer_base(fft_len), - d_occupied_carriers(fft_len, false), - d_pilot_carriers(pilot_carriers.size(), std::vector<bool>(fft_len, false)), - d_pilot_symbols(pilot_symbols.size(), std::vector<gr_complex>(fft_len, gr_complex(0, 0))), - d_symbols_skipped(symbols_skipped), - d_pilot_carr_set(symbols_skipped), - d_channel_state(fft_len, gr_complex(1, 0)) -{ - int fft_shift_width = 0; - if (input_is_shifted) { - fft_shift_width = fft_len/2; - } - if (!occupied_carriers.size()) { - std::fill(d_occupied_carriers.begin(), d_occupied_carriers.end(), true); - } else { - for (unsigned i = 0; i < occupied_carriers.size(); i++) { - for (unsigned k = 0; k < occupied_carriers[i].size(); k++) { - int carr_index = occupied_carriers[i][k]; - if (occupied_carriers[i][k] < 0) { - carr_index += fft_len; - } - if (carr_index >= fft_len || carr_index < 0) { - throw std::invalid_argument("data carrier index out of bounds."); - } - d_occupied_carriers[(carr_index + fft_shift_width) % fft_len] = true; - } - } - } - if (pilot_carriers.size()) { - for (unsigned i = 0; i < pilot_carriers.size(); i++) { - if (pilot_carriers[i].size() != pilot_symbols[i].size()) { - throw std::invalid_argument("pilot carriers and -symbols do not match."); - } - for (unsigned k = 0; k < pilot_carriers[i].size(); k++) { - int carr_index = pilot_carriers[i][k]; - if (pilot_carriers[i][k] < 0) { - carr_index += fft_len; - } - if (carr_index >= fft_len || carr_index < 0) { - throw std::invalid_argument("pilot carrier index out of bounds."); - } - d_pilot_carriers[i][(carr_index + fft_shift_width) % fft_len] = true; - d_pilot_symbols[i][(carr_index + fft_shift_width) % fft_len] = pilot_symbols[i][k]; - } - } - } -} - - -digital_ofdm_equalizer_1d_pilots::~digital_ofdm_equalizer_1d_pilots() -{ -} - - -void -digital_ofdm_equalizer_1d_pilots::reset() -{ - std::fill(d_channel_state.begin(), d_channel_state.end(), gr_complex(1, 0)); - d_pilot_carr_set = d_symbols_skipped; -} - - -void digital_ofdm_equalizer_1d_pilots::get_channel_state(std::vector<gr_complex> &taps) -{ - taps = d_channel_state; -} - - diff --git a/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc b/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc deleted file mode 100644 index c6a05b9da8..0000000000 --- a/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "digital_ofdm_equalizer_simpledfe.h" - -digital_ofdm_equalizer_simpledfe_sptr -digital_make_ofdm_equalizer_simpledfe( - int fft_len, - const gr::digital::constellation_sptr &constellation, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - float alpha, - bool input_is_shifted) -{ - return digital_ofdm_equalizer_simpledfe_sptr(new digital_ofdm_equalizer_simpledfe( - fft_len, - constellation, - occupied_carriers, - pilot_carriers, - pilot_symbols, - symbols_skipped, - alpha, - input_is_shifted)); -} - -digital_ofdm_equalizer_simpledfe::digital_ofdm_equalizer_simpledfe( - int fft_len, - const gr::digital::constellation_sptr &constellation, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - float alpha, - bool input_is_shifted) - : digital_ofdm_equalizer_1d_pilots(fft_len, occupied_carriers, pilot_carriers, pilot_symbols, symbols_skipped, input_is_shifted), - d_constellation(constellation), - d_alpha(alpha) -{ -} - - -digital_ofdm_equalizer_simpledfe::~digital_ofdm_equalizer_simpledfe() -{ -} - - -void -digital_ofdm_equalizer_simpledfe::equalize(gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps, - const std::vector<gr_tag_t> &tags) -{ - if (!initial_taps.empty()) { - d_channel_state = initial_taps; - } - gr_complex sym_eq, sym_est; - - for (int i = 0; i < n_sym; i++) { - for (int k = 0; k < d_fft_len; k++) { - if (!d_occupied_carriers[k]) { - continue; - } - if (d_pilot_carriers.size() && d_pilot_carriers[d_pilot_carr_set][k-d_carr_offset]) { - d_channel_state[k] = d_alpha * d_channel_state[k] - + (1-d_alpha) * frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; - frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; - } else { - sym_eq = frame[i*d_fft_len+k] / d_channel_state[k]; - d_constellation->map_to_points(d_constellation->decision_maker(&sym_eq), &sym_est); - d_channel_state[k] = d_alpha * d_channel_state[k] + frame[i*d_fft_len+k] / sym_est; - frame[i*d_fft_len+k] = sym_est; - } - } - d_pilot_carr_set = (d_pilot_carr_set + 1) % d_pilot_carriers.size(); - } -} - diff --git a/gr-digital/lib/digital_ofdm_equalizer_static.cc b/gr-digital/lib/digital_ofdm_equalizer_static.cc deleted file mode 100644 index 66903fa90a..0000000000 --- a/gr-digital/lib/digital_ofdm_equalizer_static.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "digital_ofdm_equalizer_static.h" - -#include <iostream> - -digital_ofdm_equalizer_static_sptr -digital_make_ofdm_equalizer_static( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - bool input_is_shifted) -{ - return digital_ofdm_equalizer_static_sptr(new digital_ofdm_equalizer_static( - fft_len, - occupied_carriers, - pilot_carriers, - pilot_symbols, - symbols_skipped, - input_is_shifted)); -} - -digital_ofdm_equalizer_static::digital_ofdm_equalizer_static( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - bool input_is_shifted) - : digital_ofdm_equalizer_1d_pilots(fft_len, occupied_carriers, pilot_carriers, pilot_symbols, symbols_skipped, input_is_shifted) -{ -} - - -digital_ofdm_equalizer_static::~digital_ofdm_equalizer_static() -{ -} - - -void -digital_ofdm_equalizer_static::equalize(gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps, - const std::vector<gr_tag_t> &tags) -{ - d_channel_state = initial_taps; - - for (int i = 0; i < n_sym; i++) { - for (int k = 0; k < d_fft_len; k++) { - if (!d_occupied_carriers[k]) { - continue; - } - if (d_pilot_carriers.size() && d_pilot_carriers[d_pilot_carr_set][k-d_carr_offset]) { - d_channel_state[k] = frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; - frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; - } else { - frame[i*d_fft_len+k] /= d_channel_state[k]; - } - } - if (!d_pilot_carriers.empty()) { - d_pilot_carr_set = (d_pilot_carr_set + 1) % d_pilot_carriers.size(); - } - } -} - diff --git a/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc b/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc deleted file mode 100644 index dbb8571c28..0000000000 --- a/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_io_signature.h> -#include "digital_ofdm_sync_sc_cfb.h" - -#include <analog/plateau_detector_fb.h> -#include <blocks/complex_to_arg.h> -#include <blocks/complex_to_mag_squared.h> -#include <blocks/conjugate_cc.h> -#include <blocks/delay.h> -#include <blocks/divide_ff.h> -#include <blocks/multiply_cc.h> -#include <blocks/multiply_ff.h> -#include <blocks/sample_and_hold_ff.h> -#include <filter/fir_filter_ccf.h> -#include <filter/fir_filter_fff.h> - -// Define this to add a third output for debugging -//#define SYNC_ADD_DEBUG_OUTPUT - -digital_ofdm_sync_sc_cfb_sptr -digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len) -{ - return gnuradio::get_initial_sptr (new digital_ofdm_sync_sc_cfb(fft_len, cp_len)); -} - - -digital_ofdm_sync_sc_cfb::digital_ofdm_sync_sc_cfb (int fft_len, int cp_len) - : gr_hier_block2 ("ofdm_sync_sc_cfb", - gr_make_io_signature(1, 1, sizeof (gr_complex)), -#ifndef SYNC_ADD_DEBUG_OUTPUT - gr_make_io_signature2(2, 2, sizeof (float), sizeof (unsigned char))) -#else - gr_make_io_signature3(3, 3, sizeof (float), sizeof (unsigned char), sizeof (float))) -#endif -{ - std::vector<float> ma_taps(fft_len/2, 1.0); - gr::blocks::delay::sptr delay(gr::blocks::delay::make(sizeof(gr_complex), fft_len/2)); - gr::blocks::conjugate_cc::sptr delay_conjugate(gr::blocks::conjugate_cc::make()); - gr::blocks::multiply_cc::sptr delay_corr(gr::blocks::multiply_cc::make()); - gr::filter::fir_filter_ccf::sptr delay_ma(gr::filter::fir_filter_ccf::make(1, std::vector<float>(fft_len/2, 1.0))); - gr::blocks::complex_to_mag_squared::sptr delay_magsquare(gr::blocks::complex_to_mag_squared::make()); - gr::blocks::divide_ff::sptr delay_normalize(gr::blocks::divide_ff::make()); - - gr::blocks::complex_to_mag_squared::sptr normalizer_magsquare(gr::blocks::complex_to_mag_squared::make()); - gr::filter::fir_filter_fff::sptr normalizer_ma(gr::filter::fir_filter_fff::make(1, std::vector<float>(fft_len, 0.5))); - gr::blocks::multiply_ff::sptr normalizer_square(gr::blocks::multiply_ff::make()); - - gr::blocks::complex_to_arg::sptr peak_to_angle(gr::blocks::complex_to_arg::make()); - gr::blocks::sample_and_hold_ff::sptr sample_and_hold(gr::blocks::sample_and_hold_ff::make()); - - gr::analog::plateau_detector_fb::sptr plateau_detector(gr::analog::plateau_detector_fb::make(cp_len)); - - // Delay Path - connect(self(), 0, delay, 0); - connect(delay, 0, delay_conjugate, 0); - connect(delay_conjugate, 0, delay_corr, 1); - connect(self(), 0, delay_corr, 0); - connect(delay_corr, 0, delay_ma, 0); - connect(delay_ma, 0, delay_magsquare, 0); - connect(delay_magsquare, 0, delay_normalize, 0); - // Energy Path - connect(self(), 0, normalizer_magsquare, 0); - connect(normalizer_magsquare, 0, normalizer_ma, 0); - connect(normalizer_ma, 0, normalizer_square, 0); - connect(normalizer_ma, 0, normalizer_square, 1); - connect(normalizer_square, 0, delay_normalize, 1); - // Fine frequency estimate (output 0) - connect(delay_ma, 0, peak_to_angle, 0); - connect(peak_to_angle, 0, sample_and_hold, 0); - connect(sample_and_hold, 0, self(), 0); - // Peak detect (output 1) - connect(delay_normalize, 0, plateau_detector, 0); - connect(plateau_detector, 0, sample_and_hold, 1); - connect(plateau_detector, 0, self(), 1); -#ifdef SYNC_ADD_DEBUG_OUTPUT - // Debugging: timing metric (output 2) - connect(delay_normalize, 0, self(), 2); -#endif -} - - -digital_ofdm_sync_sc_cfb::~digital_ofdm_sync_sc_cfb() -{ -} - diff --git a/gr-digital/lib/ofdm_carrier_allocator_cvc_impl.cc b/gr-digital/lib/ofdm_carrier_allocator_cvc_impl.cc new file mode 100644 index 0000000000..d7159547b4 --- /dev/null +++ b/gr-digital/lib/ofdm_carrier_allocator_cvc_impl.cc @@ -0,0 +1,162 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_io_signature.h> +#include "ofdm_carrier_allocator_cvc_impl.h" + +namespace gr { + namespace digital { + + ofdm_carrier_allocator_cvc::sptr + ofdm_carrier_allocator_cvc::make( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + const std::string &len_tag_key) + { + return gnuradio::get_initial_sptr( + new ofdm_carrier_allocator_cvc_impl( + fft_len, + occupied_carriers, + pilot_carriers, + pilot_symbols, + len_tag_key + ) + ); + } + + ofdm_carrier_allocator_cvc_impl::ofdm_carrier_allocator_cvc_impl(int fft_len, const std::vector<std::vector<int> > &occupied_carriers, const std::vector<std::vector<int> > &pilot_carriers, const std::vector<std::vector<gr_complex> > &pilot_symbols, const std::string &len_tag_key) + : gr_tagged_stream_block("ofdm_carrier_allocator_cvc", + gr_make_io_signature(1, 1, sizeof (gr_complex)), + gr_make_io_signature(1, 1, sizeof (gr_complex) * fft_len), len_tag_key), + d_fft_len(fft_len), + d_occupied_carriers(occupied_carriers), + d_pilot_carriers(pilot_carriers), + d_pilot_symbols(pilot_symbols), + d_symbols_per_set(0) + { + for (unsigned i = 0; i < d_occupied_carriers.size(); i++) { + for (unsigned j = 0; j < d_occupied_carriers[i].size(); j++) { + if (occupied_carriers[i][j] < 0) { + d_occupied_carriers[i][j] += d_fft_len; + } + if (d_occupied_carriers[i][j] > d_fft_len || d_occupied_carriers[i][j] < 0) { + throw std::invalid_argument("data carrier index out of bounds"); + } + } + } + for (unsigned i = 0; i < d_pilot_carriers.size(); i++) { + if (d_pilot_carriers[i].size() != pilot_symbols[i].size()) { + throw std::invalid_argument("pilot_carriers do not match pilot_symbols"); + } + for (unsigned j = 0; j < d_pilot_carriers[i].size(); j++) { + if (d_pilot_carriers[i][j] < 0) { + d_pilot_carriers[i][j] += d_fft_len; + } + if (d_pilot_carriers[i][j] > d_fft_len || d_pilot_carriers[i][j] < 0) { + throw std::invalid_argument("pilot carrier index out of bounds"); + } + } + } + + for (unsigned i = 0; i < d_occupied_carriers.size(); i++) { + d_symbols_per_set += d_occupied_carriers[i].size(); + } + set_tag_propagation_policy(TPP_DONT); + set_relative_rate((double) d_symbols_per_set / d_occupied_carriers.size()); + } + + ofdm_carrier_allocator_cvc_impl::~ofdm_carrier_allocator_cvc_impl() + { + } + + int + ofdm_carrier_allocator_cvc_impl::calculate_output_stream_length(const gr_vector_int &ninput_items) + { + int nin = ninput_items[0]; + int nout = (nin / d_symbols_per_set) * d_occupied_carriers.size(); + int k = 0; + for (int i = 0; i < nin % d_symbols_per_set; k++) { + nout++; + i += d_occupied_carriers[k % d_occupied_carriers.size()].size(); + } + return nout; + } + + int + ofdm_carrier_allocator_cvc_impl::work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + std::vector<gr_tag_t> tags; + + memset((void *) out, 0x00, sizeof(gr_complex) * d_fft_len * noutput_items); + long n_ofdm_symbols = 0; + int curr_set = 0; + int symbols_to_allocate = d_occupied_carriers[0].size(); + int symbols_allocated = 0; + for (int i = 0; i < ninput_items[0]; i++) { + if (symbols_allocated == 0) { + // Copy all tags associated with these input symbols onto this OFDM symbol + get_tags_in_range(tags, 0, + nitems_read(0)+i, + nitems_read(0)+std::min(i+symbols_to_allocate, (int) ninput_items[0]) + ); + for (unsigned t = 0; t < tags.size(); t++) { + add_item_tag(0, nitems_written(0)+n_ofdm_symbols, + tags[t].key, + tags[t].value); + } + n_ofdm_symbols++; + } + out[(n_ofdm_symbols-1) * d_fft_len + d_occupied_carriers[curr_set][symbols_allocated]] = in[i]; + symbols_allocated++; + if (symbols_allocated == symbols_to_allocate) { + curr_set = (curr_set + 1) % d_occupied_carriers.size(); + symbols_to_allocate = d_occupied_carriers[curr_set].size(); + symbols_allocated = 0; + } + } + // 2) Copy pilot symbols + curr_set = 0; + for (int i = 0; i < n_ofdm_symbols; i++) { + for (unsigned k = 0; k < d_pilot_carriers[curr_set].size(); k++) { + out[i * d_fft_len + d_pilot_carriers[curr_set][k]] = d_pilot_symbols[curr_set][k]; + } + curr_set = (curr_set + 1) % d_pilot_carriers.size(); + } + + return n_ofdm_symbols; + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/ofdm_carrier_allocator_cvc_impl.h b/gr-digital/lib/ofdm_carrier_allocator_cvc_impl.h new file mode 100644 index 0000000000..5da14332a5 --- /dev/null +++ b/gr-digital/lib/ofdm_carrier_allocator_cvc_impl.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_IMPL_H +#define INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_IMPL_H + +#include <digital/ofdm_carrier_allocator_cvc.h> + +namespace gr { + namespace digital { + + class ofdm_carrier_allocator_cvc_impl : public ofdm_carrier_allocator_cvc + { + private: + //! FFT length + const int d_fft_len; + //! Which carriers/symbols carry data + std::vector<std::vector<int> > d_occupied_carriers; + //! Which carriers/symbols carry pilots symbols + std::vector<std::vector<int> > d_pilot_carriers; + //! Value of said pilot symbols + const std::vector<std::vector<gr_complex> > d_pilot_symbols; + int d_symbols_per_set; + + protected: + int calculate_output_stream_length(const gr_vector_int &ninput_items); + + public: + ofdm_carrier_allocator_cvc_impl(int fft_len, const std::vector<std::vector<int> > &occupied_carriers, const std::vector<std::vector<int> > &pilot_carriers, const std::vector<std::vector<gr_complex> > &pilot_symbols, const std::string &len_tag_key); + ~ofdm_carrier_allocator_cvc_impl(); + + std::string len_tag_key() { return d_length_tag_key_str; }; + + const int fft_len() { return d_fft_len; }; + std::vector<std::vector<int> > occupied_carriers() { return d_occupied_carriers; }; + + int work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_IMPL_H */ + diff --git a/gr-digital/lib/ofdm_chanest_vcvc_impl.cc b/gr-digital/lib/ofdm_chanest_vcvc_impl.cc new file mode 100644 index 0000000000..d0d8faba59 --- /dev/null +++ b/gr-digital/lib/ofdm_chanest_vcvc_impl.cc @@ -0,0 +1,273 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_io_signature.h> +#include "ofdm_chanest_vcvc_impl.h" + +namespace gr { + namespace digital { + + ofdm_chanest_vcvc::sptr + ofdm_chanest_vcvc::make(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) + { + return gnuradio::get_initial_sptr ( + new ofdm_chanest_vcvc_impl( + sync_symbol1, + sync_symbol2, + n_data_symbols, + eq_noise_red_len, + max_carr_offset, + force_one_sync_symbol + ) + ); + } + + ofdm_chanest_vcvc_impl::ofdm_chanest_vcvc_impl(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) + : gr_block("ofdm_chanest_vcvc", + gr_make_io_signature(1, 1, sizeof (gr_complex) * sync_symbol1.size()), + gr_make_io_signature(1, 1, sizeof (gr_complex) * sync_symbol1.size())), + d_fft_len(sync_symbol1.size()), + d_n_data_syms(n_data_symbols), + d_n_sync_syms(1), + d_eq_noise_red_len(eq_noise_red_len), + d_ref_sym((sync_symbol2.size() && !force_one_sync_symbol) ? sync_symbol2 : sync_symbol1), + d_corr_v(sync_symbol2), + d_known_symbol_diffs(0, 0), + d_new_symbol_diffs(0, 0), + d_interpolate(false) + { + // Set index of first and last active carrier + for (int i = 0; i < d_fft_len; i++) { + if (d_ref_sym[i] != gr_complex(0, 0)) { + d_first_active_carrier = i; + break; + } + } + for (int i = d_fft_len-1; i >= 0; i--) { + if (d_ref_sym[i] != gr_complex(0, 0)) { + d_last_active_carrier = i; + break; + } + } + + // Sanity checks + if (sync_symbol2.size()) { + if (sync_symbol1.size() != sync_symbol2.size()) { + throw std::invalid_argument("sync symbols must have equal length."); + } + if (!force_one_sync_symbol) { + d_n_sync_syms = 2; + } + } else { + if (sync_symbol1[d_first_active_carrier+1] == gr_complex(0, 0)) { + d_last_active_carrier++; + d_interpolate = true; + } + } + + // Set up coarse freq estimation info + // Allow all possible values: + d_max_neg_carr_offset = -d_first_active_carrier; + d_max_pos_carr_offset = d_fft_len - d_last_active_carrier - 1; + if (max_carr_offset != -1) { + d_max_neg_carr_offset = std::max(-max_carr_offset, d_max_neg_carr_offset); + d_max_pos_carr_offset = std::min(max_carr_offset, d_max_pos_carr_offset); + } + // Carrier offsets must be even + if (d_max_neg_carr_offset % 2) + d_max_neg_carr_offset++; + if (d_max_pos_carr_offset % 2) + d_max_pos_carr_offset--; + + if (d_n_sync_syms == 2) { + for (int i = 0; i < d_fft_len; i++) { + if (sync_symbol1[i] == gr_complex(0, 0)) { + d_corr_v[i] = gr_complex(0, 0); + } else { + d_corr_v[i] /= sync_symbol1[i]; + } + } + } else { + d_corr_v.resize(0, 0); + d_known_symbol_diffs.resize(d_fft_len, 0); + d_new_symbol_diffs.resize(d_fft_len, 0); + for (int i = d_first_active_carrier; i < d_last_active_carrier-2 && i < d_fft_len-2; i += 2) { + d_known_symbol_diffs[i] = std::norm(sync_symbol1[i] - sync_symbol1[i+2]); + } + } + + set_relative_rate((double) n_data_symbols / (n_data_symbols + d_n_sync_syms)); + set_tag_propagation_policy(TPP_DONT); + } + + ofdm_chanest_vcvc_impl::~ofdm_chanest_vcvc_impl() + { + } + + void + ofdm_chanest_vcvc_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) + { + ninput_items_required[0] = (noutput_items/d_n_data_syms) * (d_n_data_syms + d_n_sync_syms); + } + + int + ofdm_chanest_vcvc_impl::get_carr_offset(const gr_complex *sync_sym1, const gr_complex *sync_sym2) + { + int carr_offset = 0; + if (d_corr_v.size()) { + // Use Schmidl & Cox method + float Bg_max = 0; + // g here is 2g in the paper + for (int g = d_max_neg_carr_offset; g <= d_max_pos_carr_offset; g += 2) { + gr_complex tmp = gr_complex(0, 0); + for (int k = 0; k < d_fft_len; k++) { + if (d_corr_v[k] != gr_complex(0, 0)) { + tmp += std::conj(sync_sym1[k+g]) * std::conj(d_corr_v[k]) * sync_sym2[k+g]; + } + } + if (std::abs(tmp) > Bg_max) { + Bg_max = std::abs(tmp); + carr_offset = g; + } + } + } else { + // Correlate + std::fill(d_new_symbol_diffs.begin(), d_new_symbol_diffs.end(), 0); + for(int i = 0; i < d_fft_len-2; i++) { + d_new_symbol_diffs[i] = std::norm(sync_sym1[i] - sync_sym1[i+2]); + } + + float sum; + float max = 0; + for (int g = d_max_neg_carr_offset; g <= d_max_pos_carr_offset; g += 2) { + sum = 0; + for (int j = 0; j < d_fft_len; j++) { + if (d_known_symbol_diffs[j]) { + sum += (d_known_symbol_diffs[j] * d_new_symbol_diffs[j + g]); + } + if(sum > max) { + max = sum; + carr_offset = g; + } + } + } + } + return carr_offset; + } + + + void + ofdm_chanest_vcvc_impl::get_chan_taps( + const gr_complex *sync_sym1, + const gr_complex *sync_sym2, + int carr_offset, + std::vector<gr_complex> &taps) + { + const gr_complex *sym = ((d_n_sync_syms == 2) ? sync_sym2 : sync_sym1); + std::fill(taps.begin(), taps.end(), gr_complex(0, 0)); + int loop_start = 0; + int loop_end = d_fft_len; + if (carr_offset > 0) { + loop_start = carr_offset; + } else if (carr_offset < 0) { + loop_end = d_fft_len + carr_offset; + } + for (int i = loop_start; i < loop_end; i++) { + if ((d_ref_sym[i-carr_offset] != gr_complex(0, 0))) { + taps[i] = sym[i] / d_ref_sym[i-carr_offset]; + } + } + + if (d_interpolate) { + for (int i = d_first_active_carrier + 1; i < d_last_active_carrier; i += 2) { + taps[i] = (taps[i-1] + taps[i+1]) / gr_complex(2.0, 0); + } + taps[d_last_active_carrier] = taps[d_last_active_carrier-1]; + } + + if (d_eq_noise_red_len) { + // TODO + // 1) IFFT + // 2) Set all elements > d_eq_noise_red_len to zero + // 3) FFT + } + } + + + int + ofdm_chanest_vcvc_impl::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + int n_frames = noutput_items/d_n_data_syms; + const int framesize = d_n_sync_syms + d_n_data_syms; + + for (int i = 0; i < n_frames; i++) { + int carr_offset = 0; + if (d_max_neg_carr_offset || d_max_pos_carr_offset) + carr_offset = get_carr_offset(in, in+d_fft_len); + std::vector<gr_complex> chan_taps(d_fft_len, 0); + get_chan_taps(in, in+d_fft_len, carr_offset, chan_taps); + + memcpy((void *) out, + (void *) &in[d_n_sync_syms * d_fft_len], + sizeof(gr_complex) * d_fft_len * d_n_data_syms); + in += framesize * d_fft_len; + out += d_n_data_syms * d_fft_len; + + std::vector<gr_tag_t> tags; + this->get_tags_in_range(tags, 0, + this->nitems_read(0)+i*framesize, + this->nitems_read(0)+(i+1)*framesize); + for (unsigned t = 0; t < tags.size(); t++) { + int offset = tags[t].offset - (this->nitems_read(0) + i*framesize); + if (offset < d_n_sync_syms) { + offset = 0; + } else { + offset -= d_n_sync_syms; + } + tags[t].offset = offset + this->nitems_written(0) + i*d_n_data_syms; + this->add_item_tag(0, tags[t]); + } + + this->add_item_tag(0, this->nitems_written(0) + i*d_n_data_syms, + pmt::string_to_symbol("ofdm_sync_carr_offset"), + pmt::from_long(carr_offset)); + this->add_item_tag(0, this->nitems_written(0) + i*d_n_data_syms, + pmt::string_to_symbol("ofdm_sync_chan_taps"), + pmt::init_c32vector(d_fft_len, chan_taps)); + } + + consume_each(n_frames * framesize); + return n_frames * d_n_data_syms; + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/ofdm_chanest_vcvc_impl.h b/gr-digital/lib/ofdm_chanest_vcvc_impl.h new file mode 100644 index 0000000000..def8734e64 --- /dev/null +++ b/gr-digital/lib/ofdm_chanest_vcvc_impl.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_IMPL_H +#define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_IMPL_H + +#include <digital/ofdm_chanest_vcvc.h> + +namespace gr { + namespace digital { + + class ofdm_chanest_vcvc_impl : public ofdm_chanest_vcvc + { + private: + int d_fft_len; //! FFT length + int d_n_data_syms; //! Number of data symbols following the sync symbol(s) + int d_n_sync_syms; //! Number of sync symbols (1 or 2) + //! 0 if no noise reduction is done for the initial channel state estimation. Otherwise, the maximum length of the channel delay in samples. + int d_eq_noise_red_len; + //! Is sync_symbol1 if d_n_sync_syms == 1, otherwise sync_symbol2. Used as a reference symbol to estimate the channel. + std::vector<gr_complex> d_ref_sym; + //! If d_n_sync_syms == 2 this is used as a differential correlation vector (called 'v' in [1]). + std::vector<gr_complex> d_corr_v; + //! If d_n_sync_syms == 1 we use this instead of d_corr_v to estimate the coarse freq. offset + std::vector<float> d_known_symbol_diffs; + //! If d_n_sync_syms == 1 we use this instead of d_corr_v to estimate the coarse freq. offset (temp. variable) + std::vector<float> d_new_symbol_diffs; + //! The index of the first carrier with data (index 0 is not DC here, but the lowest frequency) + int d_first_active_carrier; + //! The index of the last carrier with data + int d_last_active_carrier; + //! If true, the channel estimation must be interpolated + bool d_interpolate; + //! Maximum carrier offset (negative value!) + int d_max_neg_carr_offset; + //! Maximum carrier offset (positive value!) + int d_max_pos_carr_offset; + + //! Calculate the coarse frequency offset in number of carriers + int get_carr_offset(const gr_complex *sync_sym1, const gr_complex *sync_sym2); + //! Estimate the channel (phase and amplitude offset per carrier) + void get_chan_taps(const gr_complex *sync_sym1, const gr_complex *sync_sym2, int carr_offset, std::vector<gr_complex> &taps); + + public: + ofdm_chanest_vcvc_impl(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); + ~ofdm_chanest_vcvc_impl(); + + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_IMPL_H */ + diff --git a/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc b/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc index 67cfba615f..d48c5f7e45 100644 --- a/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc +++ b/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ -/* - * Copyright 2004,2006,2010-2012 Free Software Foundation, Inc. +/* + * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,56 +24,142 @@ #include "config.h" #endif -#include "ofdm_cyclic_prefixer_impl.h" #include <gr_io_signature.h> +#include "ofdm_cyclic_prefixer_impl.h" namespace gr { namespace digital { - + ofdm_cyclic_prefixer::sptr - ofdm_cyclic_prefixer::make(size_t input_size, size_t output_size) + ofdm_cyclic_prefixer::make(size_t input_size, size_t output_size, int rolloff_len, const std::string &len_tag_key) { - return gnuradio::get_initial_sptr - (new ofdm_cyclic_prefixer_impl(input_size, output_size)); + return gnuradio::get_initial_sptr (new ofdm_cyclic_prefixer_impl(input_size, output_size, rolloff_len, len_tag_key)); } - ofdm_cyclic_prefixer_impl::ofdm_cyclic_prefixer_impl(size_t input_size, - size_t output_size) - : gr_sync_interpolator("ofdm_cyclic_prefixer", - gr_make_io_signature(1, 1, input_size*sizeof(gr_complex)), - gr_make_io_signature(1, 1, sizeof(gr_complex)), - output_size), - d_input_size(input_size), - d_output_size(output_size) + + ofdm_cyclic_prefixer_impl::ofdm_cyclic_prefixer_impl(size_t input_size, size_t output_size, int rolloff_len, const std::string &len_tag_key) + : gr_tagged_stream_block ("ofdm_cyclic_prefixer", + gr_make_io_signature (1, 1, input_size*sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex)), + len_tag_key), + d_fft_len(input_size), + d_output_size(output_size), + d_cp_size(output_size - input_size), + d_rolloff_len(rolloff_len), + d_up_flank((rolloff_len ? rolloff_len-1 : 0), 0), + d_down_flank((rolloff_len ? rolloff_len-1 : 0), 0), + d_delay_line(0, 0) { + set_relative_rate(d_output_size); + + // Flank of length 1 would just be rectangular + if (d_rolloff_len == 1) { + d_rolloff_len = 0; + } + if (d_rolloff_len) { + d_delay_line.resize(d_rolloff_len-1, 0); + if (rolloff_len > d_cp_size) { + throw std::invalid_argument("cyclic prefixer: rolloff len must smaller than the cyclic prefix."); + } + // The actual flanks are one sample shorter than d_rolloff_len, because the + // first sample of the up- and down flank is always zero and one, respectively + for (int i = 1; i < d_rolloff_len; i++) { + d_up_flank[i-1] = 0.5 * (1 + cos(M_PI * i/rolloff_len - M_PI)); + d_down_flank[i-1] = 0.5 * (1 + cos(M_PI * (rolloff_len-i)/rolloff_len - M_PI)); + } + } + + if (len_tag_key.empty()) { + set_output_multiple(d_output_size); + } else { + set_tag_propagation_policy(TPP_DONT); + } } ofdm_cyclic_prefixer_impl::~ofdm_cyclic_prefixer_impl() { } + int - ofdm_cyclic_prefixer_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + ofdm_cyclic_prefixer_impl::calculate_output_stream_length(const gr_vector_int &ninput_items) { - gr_complex *in = (gr_complex*)input_items[0]; - gr_complex *out = (gr_complex*)output_items[0]; - size_t cp_size = d_output_size - d_input_size; - unsigned int i=0, j=0; - - j = cp_size; - for(i=0; i < d_input_size; i++,j++) { - out[j] = in[i]; + int nout = ninput_items[0] * d_output_size + d_delay_line.size(); + return nout; + } + + + // Operates in two ways: + // - When there's a length tag name specified, operates in packet mode. + // Here, an entire OFDM frame is processed at once. The final OFDM symbol + // is postfixed with the delay line of the pulse shape. + // We manually propagate tags. + // - Otherwise, we're in freewheeling mode. Process as many OFDM symbols as + // are space for in the output buffer. The delay line is never flushed. + // Tags are propagated by the scheduler. + int + ofdm_cyclic_prefixer_impl::work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *in = (gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + int symbols_to_read = 0; + + // 1) Figure out if we're in freewheeling or packet mode + if (!d_length_tag_key_str.empty()) { + symbols_to_read = ninput_items[0]; + noutput_items = symbols_to_read * d_output_size + d_delay_line.size(); + } else { + symbols_to_read = std::min(noutput_items / (int) d_output_size, ninput_items[0]); + noutput_items = symbols_to_read * d_output_size; + } + + // 2) Do the cyclic prefixing and, optionally, the pulse shaping + for (int sym_idx = 0; sym_idx < symbols_to_read; sym_idx++) { + memcpy((void *)(out + d_cp_size), (void *) in, d_fft_len * sizeof(gr_complex)); + memcpy((void *) out, (void *) (in + d_fft_len - d_cp_size), d_cp_size * sizeof(gr_complex)); + if (d_rolloff_len) { + for (int i = 0; i < d_rolloff_len-1; i++) { + out[i] = out[i] * d_up_flank[i] + d_delay_line[i]; + d_delay_line[i] = in[i] * d_down_flank[i]; + } + } + in += d_fft_len; + out += d_output_size; } - j = d_input_size - cp_size; - for(i=0; i < cp_size; i++, j++) { - out[i] = in[j]; + // 3) If we're in packet mode: + // - flush the delay line, if applicable + // - Propagate tags + if (!d_length_tag_key_str.empty()) { + if (d_rolloff_len) { + for (unsigned i = 0; i < d_delay_line.size(); i++) { + *out++ = d_delay_line[i]; + } + d_delay_line.assign(d_delay_line.size(), 0); + } + std::vector<gr_tag_t> tags; + get_tags_in_range( + tags, 0, + nitems_read(0), nitems_read(0)+symbols_to_read + ); + for (unsigned i = 0; i < tags.size(); i++) { + tags[i].offset = ((tags[i].offset - nitems_read(0)) * d_output_size) + nitems_written(0); + add_item_tag(0, + tags[i].offset, + tags[i].key, + tags[i].value + ); + } + } else { + consume_each(symbols_to_read); } - return d_output_size; + return noutput_items; } } /* namespace digital */ } /* namespace gr */ + diff --git a/gr-digital/lib/ofdm_cyclic_prefixer_impl.h b/gr-digital/lib/ofdm_cyclic_prefixer_impl.h index 20f0489d7c..5a5766f131 100644 --- a/gr-digital/lib/ofdm_cyclic_prefixer_impl.h +++ b/gr-digital/lib/ofdm_cyclic_prefixer_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ -/* - * Copyright 2004-2006,2011,2012 Free Software Foundation, Inc. +/* + * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,23 +27,38 @@ namespace gr { namespace digital { - + class ofdm_cyclic_prefixer_impl : public ofdm_cyclic_prefixer { - private: - size_t d_input_size; + private: + size_t d_fft_len; + //! FFT length + CP length in samples size_t d_output_size; + //! Length of the cyclic prefix in samples + int d_cp_size; + //! Length of pulse rolloff in samples + int d_rolloff_len; + //! Buffers the up-flank (at the beginning of the cyclic prefix) + std::vector<float> d_up_flank; + //! Buffers the down-flank (which trails the symbol) + std::vector<float> d_down_flank; + std::vector<gr_complex> d_delay_line; // We do this explicitly to avoid outputting zeroes (i.e. no history!) + + protected: + int calculate_output_stream_length(const gr_vector_int &ninput_items); - public: - ofdm_cyclic_prefixer_impl(size_t input_size, size_t output_size); + public: + ofdm_cyclic_prefixer_impl(size_t input_size, size_t output_size, int rolloff_len, const std::string &len_tag_key); ~ofdm_cyclic_prefixer_impl(); int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; - } /* namespace digital */ -} /* namespace gr */ + } // namespace digital +} // namespace gr #endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_IMPL_H */ + diff --git a/gr-digital/lib/ofdm_equalizer_base.cc b/gr-digital/lib/ofdm_equalizer_base.cc new file mode 100644 index 0000000000..5209b09c29 --- /dev/null +++ b/gr-digital/lib/ofdm_equalizer_base.cc @@ -0,0 +1,121 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <digital/ofdm_equalizer_base.h> + +namespace gr { + namespace digital { + + // *** Base class **************************************************** + ofdm_equalizer_base::ofdm_equalizer_base(int fft_len) : + d_fft_len(fft_len), + d_carr_offset(0) + { + } + + + ofdm_equalizer_base::~ofdm_equalizer_base() + { + } + + + // *** Sub-Base class for 1D equalizers using pilot tones ************* + ofdm_equalizer_1d_pilots::ofdm_equalizer_1d_pilots( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + bool input_is_shifted) + : ofdm_equalizer_base(fft_len), + d_occupied_carriers(fft_len, false), + d_pilot_carriers(pilot_carriers.size(), std::vector<bool>(fft_len, false)), + d_pilot_symbols(pilot_symbols.size(), std::vector<gr_complex>(fft_len, gr_complex(0, 0))), + d_symbols_skipped(symbols_skipped), + d_pilot_carr_set(symbols_skipped), + d_channel_state(fft_len, gr_complex(1, 0)) + { + int fft_shift_width = 0; + if (input_is_shifted) { + fft_shift_width = fft_len/2; + } + if (!occupied_carriers.size()) { + std::fill(d_occupied_carriers.begin(), d_occupied_carriers.end(), true); + } else { + for (unsigned i = 0; i < occupied_carriers.size(); i++) { + for (unsigned k = 0; k < occupied_carriers[i].size(); k++) { + int carr_index = occupied_carriers[i][k]; + if (occupied_carriers[i][k] < 0) { + carr_index += fft_len; + } + if (carr_index >= fft_len || carr_index < 0) { + throw std::invalid_argument("data carrier index out of bounds."); + } + d_occupied_carriers[(carr_index + fft_shift_width) % fft_len] = true; + } + } + } + if (pilot_carriers.size()) { + for (unsigned i = 0; i < pilot_carriers.size(); i++) { + if (pilot_carriers[i].size() != pilot_symbols[i].size()) { + throw std::invalid_argument("pilot carriers and -symbols do not match."); + } + for (unsigned k = 0; k < pilot_carriers[i].size(); k++) { + int carr_index = pilot_carriers[i][k]; + if (pilot_carriers[i][k] < 0) { + carr_index += fft_len; + } + if (carr_index >= fft_len || carr_index < 0) { + throw std::invalid_argument("pilot carrier index out of bounds."); + } + d_pilot_carriers[i][(carr_index + fft_shift_width) % fft_len] = true; + d_pilot_symbols[i][(carr_index + fft_shift_width) % fft_len] = pilot_symbols[i][k]; + } + } + } + } + + + ofdm_equalizer_1d_pilots::~ofdm_equalizer_1d_pilots() + { + } + + + void + ofdm_equalizer_1d_pilots::reset() + { + std::fill(d_channel_state.begin(), d_channel_state.end(), gr_complex(1, 0)); + d_pilot_carr_set = d_symbols_skipped; + } + + + void ofdm_equalizer_1d_pilots::get_channel_state(std::vector<gr_complex> &taps) + { + taps = d_channel_state; + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/ofdm_equalizer_simpledfe.cc b/gr-digital/lib/ofdm_equalizer_simpledfe.cc new file mode 100644 index 0000000000..fcb0e18cbf --- /dev/null +++ b/gr-digital/lib/ofdm_equalizer_simpledfe.cc @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <digital/ofdm_equalizer_simpledfe.h> + +namespace gr { + namespace digital { + + ofdm_equalizer_simpledfe::sptr + ofdm_equalizer_simpledfe::make( + int fft_len, + const gr::digital::constellation_sptr &constellation, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + float alpha, + bool input_is_shifted) + { + return ofdm_equalizer_simpledfe::sptr( + new ofdm_equalizer_simpledfe( + fft_len, + constellation, + occupied_carriers, + pilot_carriers, + pilot_symbols, + symbols_skipped, + alpha, + input_is_shifted + ) + ); + } + + ofdm_equalizer_simpledfe::ofdm_equalizer_simpledfe( + int fft_len, + const gr::digital::constellation_sptr &constellation, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + float alpha, + bool input_is_shifted) + : ofdm_equalizer_1d_pilots(fft_len, occupied_carriers, pilot_carriers, pilot_symbols, symbols_skipped, input_is_shifted), + d_constellation(constellation), + d_alpha(alpha) + { + } + + + ofdm_equalizer_simpledfe::~ofdm_equalizer_simpledfe() + { + } + + + void + ofdm_equalizer_simpledfe::equalize(gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps, + const std::vector<gr_tag_t> &tags) + { + if (!initial_taps.empty()) { + d_channel_state = initial_taps; + } + gr_complex sym_eq, sym_est; + + for (int i = 0; i < n_sym; i++) { + for (int k = 0; k < d_fft_len; k++) { + if (!d_occupied_carriers[k]) { + continue; + } + if (d_pilot_carriers.size() && d_pilot_carriers[d_pilot_carr_set][k-d_carr_offset]) { + d_channel_state[k] = d_alpha * d_channel_state[k] + + (1-d_alpha) * frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; + frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; + } else { + sym_eq = frame[i*d_fft_len+k] / d_channel_state[k]; + d_constellation->map_to_points(d_constellation->decision_maker(&sym_eq), &sym_est); + d_channel_state[k] = d_alpha * d_channel_state[k] + frame[i*d_fft_len+k] / sym_est; + frame[i*d_fft_len+k] = sym_est; + } + } + d_pilot_carr_set = (d_pilot_carr_set + 1) % d_pilot_carriers.size(); + } + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/ofdm_equalizer_static.cc b/gr-digital/lib/ofdm_equalizer_static.cc new file mode 100644 index 0000000000..8601eff430 --- /dev/null +++ b/gr-digital/lib/ofdm_equalizer_static.cc @@ -0,0 +1,97 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <digital/ofdm_equalizer_static.h> + +namespace gr { + namespace digital { + + ofdm_equalizer_static::sptr + ofdm_equalizer_static::make( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + bool input_is_shifted) + { + return ofdm_equalizer_static::sptr( + new ofdm_equalizer_static( + fft_len, + occupied_carriers, + pilot_carriers, + pilot_symbols, + symbols_skipped, + input_is_shifted + ) + ); + } + + ofdm_equalizer_static::ofdm_equalizer_static( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + bool input_is_shifted) + : ofdm_equalizer_1d_pilots(fft_len, occupied_carriers, pilot_carriers, pilot_symbols, symbols_skipped, input_is_shifted) + { + } + + + ofdm_equalizer_static::~ofdm_equalizer_static() + { + } + + + void + ofdm_equalizer_static::equalize(gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps, + const std::vector<gr_tag_t> &tags) + { + d_channel_state = initial_taps; + + for (int i = 0; i < n_sym; i++) { + for (int k = 0; k < d_fft_len; k++) { + if (!d_occupied_carriers[k]) { + continue; + } + if (d_pilot_carriers.size() && d_pilot_carriers[d_pilot_carr_set][k-d_carr_offset]) { + d_channel_state[k] = frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; + frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; + } else { + frame[i*d_fft_len+k] /= d_channel_state[k]; + } + } + if (!d_pilot_carriers.empty()) { + d_pilot_carr_set = (d_pilot_carr_set + 1) % d_pilot_carriers.size(); + } + } + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc index 49235db5bb..594b2df838 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc @@ -30,12 +30,16 @@ namespace gr { namespace digital { ofdm_frame_equalizer_vcvc::sptr - ofdm_frame_equalizer_vcvc::make(digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state) + ofdm_frame_equalizer_vcvc::make(ofdm_equalizer_base::sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state) { - return gnuradio::get_initial_sptr (new ofdm_frame_equalizer_vcvc_impl(equalizer, len_tag_key, propagate_channel_state)); + return gnuradio::get_initial_sptr ( + new ofdm_frame_equalizer_vcvc_impl( + equalizer, len_tag_key, propagate_channel_state + ) + ); } - ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl(digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state) + ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl(ofdm_equalizer_base::sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state) : gr_tagged_stream_block("ofdm_frame_equalizer_vcvc", gr_make_io_signature(1, 1, sizeof (gr_complex) * equalizer->fft_len()), gr_make_io_signature(1, 1, sizeof (gr_complex) * equalizer->fft_len()), diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h index cba2d513ea..803874713f 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h @@ -31,7 +31,7 @@ namespace gr { { private: const int d_fft_len; - digital_ofdm_equalizer_base_sptr d_eq; + ofdm_equalizer_base::sptr d_eq; bool d_propagate_channel_state; std::vector<gr_complex> d_channel_state; @@ -41,7 +41,7 @@ namespace gr { void update_length_tags(int n_produced, int n_ports) {}; public: - ofdm_frame_equalizer_vcvc_impl(digital_ofdm_equalizer_base_sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state); + ofdm_frame_equalizer_vcvc_impl(ofdm_equalizer_base::sptr equalizer, const std::string &len_tag_key, bool propagate_channel_state); ~ofdm_frame_equalizer_vcvc_impl(); int work(int noutput_items, diff --git a/gr-digital/lib/ofdm_serializer_vcc_impl.cc b/gr-digital/lib/ofdm_serializer_vcc_impl.cc index 9c41daae77..09c0039a1c 100644 --- a/gr-digital/lib/ofdm_serializer_vcc_impl.cc +++ b/gr-digital/lib/ofdm_serializer_vcc_impl.cc @@ -50,7 +50,7 @@ namespace gr { ofdm_serializer_vcc::sptr ofdm_serializer_vcc::make( - const digital_ofdm_carrier_allocator_cvc_sptr &allocator, + const gr::digital::ofdm_carrier_allocator_cvc::sptr &allocator, const std::string &packet_len_tag_key, int symbols_skipped, bool input_is_shifted diff --git a/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc b/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc new file mode 100644 index 0000000000..26e791210f --- /dev/null +++ b/gr-digital/lib/ofdm_sync_sc_cfb_impl.cc @@ -0,0 +1,111 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_io_signature.h> +#include "ofdm_sync_sc_cfb_impl.h" + +#include <analog/plateau_detector_fb.h> +#include <blocks/complex_to_arg.h> +#include <blocks/complex_to_mag_squared.h> +#include <blocks/conjugate_cc.h> +#include <blocks/delay.h> +#include <blocks/divide_ff.h> +#include <blocks/multiply_cc.h> +#include <blocks/multiply_ff.h> +#include <blocks/sample_and_hold_ff.h> +#include <filter/fir_filter_ccf.h> +#include <filter/fir_filter_fff.h> + +namespace gr { + namespace digital { + + ofdm_sync_sc_cfb::sptr + ofdm_sync_sc_cfb::make(int fft_len, int cp_len) + { + return gnuradio::get_initial_sptr (new ofdm_sync_sc_cfb_impl(fft_len, cp_len)); + } + + ofdm_sync_sc_cfb_impl::ofdm_sync_sc_cfb_impl(int fft_len, int cp_len) + : gr_hier_block2 ("ofdm_sync_sc_cfb", + gr_make_io_signature(1, 1, sizeof (gr_complex)), +#ifndef SYNC_ADD_DEBUG_OUTPUT + gr_make_io_signature2(2, 2, sizeof (float), sizeof (unsigned char))) +#else + gr_make_io_signature3(3, 3, sizeof (float), sizeof (unsigned char), sizeof (float))) +#endif + { + std::vector<float> ma_taps(fft_len/2, 1.0); + gr::blocks::delay::sptr delay(gr::blocks::delay::make(sizeof(gr_complex), fft_len/2)); + gr::blocks::conjugate_cc::sptr delay_conjugate(gr::blocks::conjugate_cc::make()); + gr::blocks::multiply_cc::sptr delay_corr(gr::blocks::multiply_cc::make()); + gr::filter::fir_filter_ccf::sptr delay_ma(gr::filter::fir_filter_ccf::make(1, std::vector<float>(fft_len/2, 1.0))); + gr::blocks::complex_to_mag_squared::sptr delay_magsquare(gr::blocks::complex_to_mag_squared::make()); + gr::blocks::divide_ff::sptr delay_normalize(gr::blocks::divide_ff::make()); + + gr::blocks::complex_to_mag_squared::sptr normalizer_magsquare(gr::blocks::complex_to_mag_squared::make()); + gr::filter::fir_filter_fff::sptr normalizer_ma(gr::filter::fir_filter_fff::make(1, std::vector<float>(fft_len, 0.5))); + gr::blocks::multiply_ff::sptr normalizer_square(gr::blocks::multiply_ff::make()); + + gr::blocks::complex_to_arg::sptr peak_to_angle(gr::blocks::complex_to_arg::make()); + gr::blocks::sample_and_hold_ff::sptr sample_and_hold(gr::blocks::sample_and_hold_ff::make()); + + gr::analog::plateau_detector_fb::sptr plateau_detector(gr::analog::plateau_detector_fb::make(cp_len)); + + // Delay Path + connect(self(), 0, delay, 0); + connect(delay, 0, delay_conjugate, 0); + connect(delay_conjugate, 0, delay_corr, 1); + connect(self(), 0, delay_corr, 0); + connect(delay_corr, 0, delay_ma, 0); + connect(delay_ma, 0, delay_magsquare, 0); + connect(delay_magsquare, 0, delay_normalize, 0); + // Energy Path + connect(self(), 0, normalizer_magsquare, 0); + connect(normalizer_magsquare, 0, normalizer_ma, 0); + connect(normalizer_ma, 0, normalizer_square, 0); + connect(normalizer_ma, 0, normalizer_square, 1); + connect(normalizer_square, 0, delay_normalize, 1); + // Fine frequency estimate (output 0) + connect(delay_ma, 0, peak_to_angle, 0); + connect(peak_to_angle, 0, sample_and_hold, 0); + connect(sample_and_hold, 0, self(), 0); + // Peak detect (output 1) + connect(delay_normalize, 0, plateau_detector, 0); + connect(plateau_detector, 0, sample_and_hold, 1); + connect(plateau_detector, 0, self(), 1); +#ifdef SYNC_ADD_DEBUG_OUTPUT + // Debugging: timing metric (output 2) + connect(delay_normalize, 0, self(), 2); +#endif + } + + ofdm_sync_sc_cfb_impl::~ofdm_sync_sc_cfb_impl() + { + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/swig/digital_ofdm_cyclic_prefixer.i b/gr-digital/lib/ofdm_sync_sc_cfb_impl.h index 19ffd6a12b..207ea41ae1 100644 --- a/gr-digital/swig/digital_ofdm_cyclic_prefixer.i +++ b/gr-digital/lib/ofdm_sync_sc_cfb_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ -/* - * Copyright 2004-2006,2011 Free Software Foundation, Inc. +/* + * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,16 +20,23 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(digital,ofdm_cyclic_prefixer); +#ifndef INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_IMPL_H +#define INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_IMPL_H -digital_ofdm_cyclic_prefixer_sptr -digital_make_ofdm_cyclic_prefixer (size_t input_size, - size_t output_size, - int rolloff_len=0, - const std::string &len_tag_key=""); +#include <digital/ofdm_sync_sc_cfb.h> +namespace gr { + namespace digital { -class digital_ofdm_cyclic_prefixer : public gr_tagged_stream_block -{ -}; + class ofdm_sync_sc_cfb_impl : public ofdm_sync_sc_cfb + { + public: + ofdm_sync_sc_cfb_impl(int fft_len, int cp_len); + ~ofdm_sync_sc_cfb_impl(); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_IMPL_H */ diff --git a/gr-digital/swig/CMakeLists.txt b/gr-digital/swig/CMakeLists.txt index 0db5140429..cbef8da888 100644 --- a/gr-digital/swig/CMakeLists.txt +++ b/gr-digital/swig/CMakeLists.txt @@ -59,13 +59,7 @@ install( FILES digital_swig.i constellation.i - digital_crc32_bb.i - digital_ofdm_carrier_allocator_cvc.i - digital_ofdm_chanest_vcvc.i - digital_ofdm_equalizer_base.i - digital_ofdm_equalizer_simpledfe.i - digital_ofdm_equalizer_static.i - digital_ofdm_sync_sc_cfb.i + ofdm_equalizer.i packet_header.i ${CMAKE_CURRENT_BINARY_DIR}/digital_swig_doc.i DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig diff --git a/gr-digital/swig/digital_crc32_bb.i b/gr-digital/swig/digital_crc32_bb.i deleted file mode 100644 index 45b240793d..0000000000 --- a/gr-digital/swig/digital_crc32_bb.i +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -GR_SWIG_BLOCK_MAGIC(digital, crc32_bb) - -digital_crc32_bb_sptr -digital_make_crc32_bb (bool check=false, const std::string& lengthtagname="packet_len"); - -class digital_crc32_bb : public gr_block -{ - private: - digital_crc32_bb(bool check, const std::string& lengthtagname); -}; - diff --git a/gr-digital/swig/digital_ofdm_carrier_allocator_cvc.i b/gr-digital/swig/digital_ofdm_carrier_allocator_cvc.i deleted file mode 100644 index 1663a4de3d..0000000000 --- a/gr-digital/swig/digital_ofdm_carrier_allocator_cvc.i +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -GR_SWIG_BLOCK_MAGIC(digital, ofdm_carrier_allocator_cvc); - -digital_ofdm_carrier_allocator_cvc_sptr -digital_make_ofdm_carrier_allocator_cvc ( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - const std::string &len_tag_key = "packet_len"); - -class digital_ofdm_carrier_allocator_cvc : public gr_tagged_stream_block -{ - private: - digital_ofdm_carrier_allocator_cvc(int fft_len, const std::vector<std::vector<int> > &occupied_carriers, const std::vector<std::vector<int> > &pilot_carriers, const std::vector<std::vector<gr_complex> > &pilot_symbols, const std::string &len_tag_key); -}; - diff --git a/gr-digital/swig/digital_ofdm_equalizer_base.i b/gr-digital/swig/digital_ofdm_equalizer_base.i deleted file mode 100644 index c862fed09d..0000000000 --- a/gr-digital/swig/digital_ofdm_equalizer_base.i +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - - -class digital_ofdm_equalizer_base; -typedef boost::shared_ptr<digital_ofdm_equalizer_base> digital_ofdm_equalizer_base_sptr; -%template(digital_ofdm_equalizer_base_sptr) boost::shared_ptr<digital_ofdm_equalizer_base>; -%ignore digital_ofdm_equalizer_base; - -class digital_ofdm_equalizer_1d_pilots; -typedef boost::shared_ptr<digital_ofdm_equalizer_1d_pilots> digital_ofdm_equalizer_1d_pilots_sptr; -%template(digital_ofdm_equalizer_1d_pilots_sptr) boost::shared_ptr<digital_ofdm_equalizer_1d_pilots>; -%ignore digital_ofdm_equalizer_1d_pilots; - -class digital_ofdm_equalizer_base -{ - public: - digital_ofdm_equalizer_base(int fft_len); - - virtual void reset() = 0; - void set_carrier_offset(int offset) { d_carr_offset = offset; }; - virtual void equalize( - gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), - const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()) = 0; - virtual void get_channel_state(std::vector<gr_complex> &taps) = 0; - digital_ofdm_equalizer_base_sptr base(); -}; - - -class digital_ofdm_equalizer_1d_pilots : public digital_ofdm_equalizer_base -{ - public: - digital_ofdm_equalizer_1d_pilots( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers, - const std::vector<std::vector<int> > &pilot_carriers, - const std::vector<std::vector<gr_complex> > &pilot_symbols, - int symbols_skipped, - bool input_is_shifted); - - void reset(); -}; - diff --git a/gr-digital/swig/digital_ofdm_equalizer_simpledfe.i b/gr-digital/swig/digital_ofdm_equalizer_simpledfe.i deleted file mode 100644 index 1ca31c1edd..0000000000 --- a/gr-digital/swig/digital_ofdm_equalizer_simpledfe.i +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -class digital_ofdm_equalizer_simpledfe; -typedef boost::shared_ptr<digital_ofdm_equalizer_simpledfe> digital_ofdm_equalizer_simpledfe_sptr; -%template(digital_ofdm_equalizer_simpledfe_sptr) boost::shared_ptr<digital_ofdm_equalizer_simpledfe>; -%rename(ofdm_equalizer_simpledfe) digital_make_ofdm_equalizer_simpledfe; -digital_ofdm_equalizer_simpledfe_sptr -digital_make_ofdm_equalizer_simpledfe( - int fft_len, - const gr::digital::constellation_sptr &constellation, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - float alpha = 0.1, - bool input_is_shifted = true); -%ignore digital_ofdm_equalizer_simpledfe; - -class digital_ofdm_equalizer_simpledfe : public digital_ofdm_equalizer_1d_pilots -{ - public: - digital_ofdm_equalizer_simpledfe( - int fft_len, - const digital_constellation_sptr &constellation, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - float alpha = 0.1, - bool input_is_shifted = true); - - void equalize(gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), - const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); - void get_channel_state(std::vector<gr_complex> &taps); -}; - diff --git a/gr-digital/swig/digital_ofdm_equalizer_static.i b/gr-digital/swig/digital_ofdm_equalizer_static.i deleted file mode 100644 index 3e99403ff7..0000000000 --- a/gr-digital/swig/digital_ofdm_equalizer_static.i +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- */ -/* Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -class digital_ofdm_equalizer_static; -typedef boost::shared_ptr<digital_ofdm_equalizer_static> digital_ofdm_equalizer_static_sptr; -%template(digital_ofdm_equalizer_static_sptr) boost::shared_ptr<digital_ofdm_equalizer_static>; -%rename(ofdm_equalizer_static) digital_make_ofdm_equalizer_static; -digital_ofdm_equalizer_static_sptr -digital_make_ofdm_equalizer_static( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - bool input_is_shifted = true); -%ignore digital_ofdm_equalizer_static; - -class digital_ofdm_equalizer_static : public digital_ofdm_equalizer_1d_pilots -{ - public: - digital_ofdm_equalizer_static( - int fft_len, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - bool input_is_shifted = true); - ~digital_ofdm_equalizer_static(); - - void equalize(gr_complex *frame, - int n_sym, - const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), - const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); - void get_channel_state(std::vector<gr_complex> &taps); -}; - diff --git a/gr-digital/swig/digital_ofdm_sync_sc_cfb.i b/gr-digital/swig/digital_ofdm_sync_sc_cfb.i deleted file mode 100644 index 6a863ca3f9..0000000000 --- a/gr-digital/swig/digital_ofdm_sync_sc_cfb.i +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -GR_SWIG_BLOCK_MAGIC(digital, ofdm_sync_sc_cfb) - -digital_ofdm_sync_sc_cfb_sptr -digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); - -class digital_ofdm_sync_sc_cfb : public gr_hier_block2 -{ - private: - digital_ofdm_sync_sc_cfb(int fft_len, int cp_len); -}; - diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i index 94e186d7bf..4b41b251a1 100644 --- a/gr-digital/swig/digital_swig.i +++ b/gr-digital/swig/digital_swig.i @@ -57,6 +57,7 @@ #include "digital/costas_loop_cc.h" #include "digital/cpmmod_bc.h" #include "digital/crc32.h" +#include "digital/crc32_bb.h" #include "digital/descrambler_bb.h" #include "digital/diff_decoder_bb.h" #include "digital/diff_encoder_bb.h" @@ -74,6 +75,12 @@ #include "digital/mpsk_receiver_cc.h" #include "digital/mpsk_snr_est.h" #include "digital/mpsk_snr_est_cc.h" +#include "digital/ofdm_carrier_allocator_cvc.h" +#include "digital/ofdm_chanest_vcvc.h" +#include "digital/ofdm_cyclic_prefixer.h" +#include "digital/ofdm_equalizer_base.h" +#include "digital/ofdm_equalizer_simpledfe.h" +#include "digital/ofdm_equalizer_static.h" #include "digital/ofdm_frame_acquisition.h" #include "digital/ofdm_frame_equalizer_vcvc.h" #include "digital/ofdm_frame_sink.h" @@ -81,6 +88,7 @@ #include "digital/ofdm_mapper_bcv.h" #include "digital/ofdm_sampler.h" #include "digital/ofdm_serializer_vcc.h" +#include "digital/ofdm_sync_sc_cfb.h" #include "digital/packet_header_default.h" #include "digital/packet_header_ofdm.h" #include "digital/packet_headergenerator_bb.h" @@ -118,6 +126,7 @@ %include "digital/costas_loop_cc.h" %include "digital/cpmmod_bc.h" %include "digital/crc32.h" +%include "digital/crc32_bb.h" %include "digital/descrambler_bb.h" %include "digital/diff_decoder_bb.h" %include "digital/diff_encoder_bb.h" @@ -135,7 +144,12 @@ %include "digital/mpsk_receiver_cc.h" %include "digital/mpsk_snr_est.h" %include "digital/mpsk_snr_est_cc.h" -//%include "digital/ofdm_cyclic_prefixer.h" +%include "digital/ofdm_carrier_allocator_cvc.h" +%include "digital/ofdm_chanest_vcvc.h" +%include "digital/ofdm_cyclic_prefixer.h" +%include "digital/ofdm_equalizer_base.h" +%include "digital/ofdm_equalizer_simpledfe.h" +%include "digital/ofdm_equalizer_static.h" %include "digital/ofdm_frame_acquisition.h" %include "digital/ofdm_frame_equalizer_vcvc.h" %include "digital/ofdm_frame_sink.h" @@ -143,6 +157,7 @@ %include "digital/ofdm_mapper_bcv.h" %include "digital/ofdm_sampler.h" %include "digital/ofdm_serializer_vcc.h" +%include "digital/ofdm_sync_sc_cfb.h" %include "digital/packet_header_default.h" %include "digital/packet_header_ofdm.h" %include "digital/packet_headergenerator_bb.h" @@ -176,7 +191,7 @@ GR_SWIG_BLOCK_MAGIC2(digital, constellation_receiver_cb); GR_SWIG_BLOCK_MAGIC2(digital, correlate_access_code_bb); GR_SWIG_BLOCK_MAGIC2(digital, correlate_access_code_tag_bb); GR_SWIG_BLOCK_MAGIC2(digital, costas_loop_cc); -//GR_SWIG_BLOCK_MAGIC2(digital, ofdm_cyclic_prefixer); +GR_SWIG_BLOCK_MAGIC2(digital, crc32_bb); GR_SWIG_BLOCK_MAGIC2(digital, cpmmod_bc); GR_SWIG_BLOCK_MAGIC2(digital, descrambler_bb); GR_SWIG_BLOCK_MAGIC2(digital, diff_decoder_bb); @@ -192,6 +207,9 @@ GR_SWIG_BLOCK_MAGIC2(digital, lms_dd_equalizer_cc); GR_SWIG_BLOCK_MAGIC2(digital, map_bb); GR_SWIG_BLOCK_MAGIC2(digital, mpsk_receiver_cc); GR_SWIG_BLOCK_MAGIC2(digital, mpsk_snr_est_cc); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_carrier_allocator_cvc); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_chanest_vcvc); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_cyclic_prefixer); GR_SWIG_BLOCK_MAGIC2(digital, ofdm_frame_acquisition); GR_SWIG_BLOCK_MAGIC2(digital, ofdm_frame_equalizer_vcvc); GR_SWIG_BLOCK_MAGIC2(digital, ofdm_frame_sink); @@ -199,6 +217,7 @@ GR_SWIG_BLOCK_MAGIC2(digital, ofdm_insert_preamble); GR_SWIG_BLOCK_MAGIC2(digital, ofdm_mapper_bcv); GR_SWIG_BLOCK_MAGIC2(digital, ofdm_sampler); GR_SWIG_BLOCK_MAGIC2(digital, ofdm_serializer_vcc); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_sync_sc_cfb); GR_SWIG_BLOCK_MAGIC2(digital, packet_headergenerator_bb); GR_SWIG_BLOCK_MAGIC2(digital, packet_headerparser_b); GR_SWIG_BLOCK_MAGIC2(digital, packet_sink); @@ -216,29 +235,8 @@ GR_SWIG_BLOCK_MAGIC2(digital, ts_insert_zeros_cc); GR_SWIG_BLOCK_MAGIC_FACTORY(digital, cpmmod_bc, gmskmod_bc); -// Properly package up constellation objects +// Properly package up non-block objects %include "constellation.i" - %include "packet_header.i" +%include "ofdm_equalizer.i" -// Old-style blocks to be converted to 3.7 -%{ -#include <digital_crc32_bb.h> -#include <digital_ofdm_carrier_allocator_cvc.h> -#include <digital_ofdm_cyclic_prefixer.h> -#include <digital_ofdm_chanest_vcvc.h> -#include <digital_ofdm_cyclic_prefixer.h> -#include <digital_ofdm_equalizer_base.h> -#include <digital_ofdm_equalizer_simpledfe.h> -#include <digital_ofdm_equalizer_static.h> -#include <digital_ofdm_sync_sc_cfb.h> -%} - -%include "digital_crc32_bb.i" -%include "digital_ofdm_carrier_allocator_cvc.i" -%include "digital_ofdm_chanest_vcvc.i" -%include "digital_ofdm_cyclic_prefixer.i" -%include "digital_ofdm_equalizer_base.i" -%include "digital_ofdm_equalizer_simpledfe.i" -%include "digital_ofdm_equalizer_static.i" -%include "digital_ofdm_sync_sc_cfb.i" diff --git a/gr-digital/swig/ofdm_equalizer.i b/gr-digital/swig/ofdm_equalizer.i new file mode 100644 index 0000000000..bd97b5bc06 --- /dev/null +++ b/gr-digital/swig/ofdm_equalizer.i @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +%template(ofdm_equalizer_base_sptr) boost::shared_ptr<gr::digital::ofdm_equalizer_base>; +%template(ofdm_equalizer_1d_pilots_sptr) boost::shared_ptr<gr::digital::ofdm_equalizer_1d_pilots>; +%pythoncode %{ +ofdm_equalizer_1d_pilots_sptr.__repr__ = lambda self: "<OFDM equalizer 1D base class>" +%} + +%template(ofdm_equalizer_simpledfe_sptr) boost::shared_ptr<gr::digital::ofdm_equalizer_simpledfe>; +%pythoncode %{ +ofdm_equalizer_simpledfe_sptr.__repr__ = lambda self: "<OFDM equalizer simpledfe>" +ofdm_equalizer_simpledfe = ofdm_equalizer_simpledfe.make; +%} +//%rename(ofdm_equalizer_simpledfe) make_ofdm_equalizer_simpledfe; +//%ignore ofdm_equalizer_simpledfe; + +%template(ofdm_equalizer_static_sptr) boost::shared_ptr<gr::digital::ofdm_equalizer_static>; +%pythoncode %{ +ofdm_equalizer_static_sptr.__repr__ = lambda self: "<OFDM equalizer static>" +ofdm_equalizer_static = ofdm_equalizer_static.make; +%} +//%rename(ofdm_equalizer_static) make_ofdm_equalizer_static; +//%ignore ofdm_equalizer_static; + |