diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2013-03-15 09:57:31 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2013-03-15 09:57:31 -0700 |
commit | e965a5bb209ad46a509ccd21f393667fd69d95f9 (patch) | |
tree | 40d683ef8f80980f12eac6cfe7f3423c49b45f87 /gr-digital/include | |
parent | 2bf9c4cb4b0b426690f353fc1662a13e70c0d5e0 (diff) | |
parent | 27990ca9e236931e39a830e48f0a1efe13ec085f (diff) |
Merge branch 'ofdm-master' into ofdm-next
Added fixups for next branch changes
Conflicts:
CMakeLists.txt
gnuradio-core/src/lib/io/gr_message_sink.cc
gnuradio-core/src/lib/io/gr_message_sink.h
gnuradio-core/src/lib/io/gr_message_sink.i
gnuradio-core/src/lib/io/gr_message_source.cc
gnuradio-core/src/lib/io/gr_message_source.h
gnuradio-core/src/lib/io/gr_message_source.i
gr-blocks/CMakeLists.txt
gr-digital/CMakeLists.txt
gr-digital/grc/digital_block_tree.xml
gr-digital/include/digital/CMakeLists.txt
gr-digital/include/digital_ofdm_cyclic_prefixer.h
gr-digital/lib/CMakeLists.txt
gr-digital/lib/digital_ofdm_cyclic_prefixer.cc
gr-digital/lib/ofdm_cyclic_prefixer_impl.h
gr-digital/python/CMakeLists.txt
gr-digital/swig/CMakeLists.txt
gr-digital/swig/digital_swig.i
Diffstat (limited to 'gr-digital/include')
21 files changed, 1589 insertions, 13 deletions
diff --git a/gr-digital/include/CMakeLists.txt b/gr-digital/include/CMakeLists.txt new file mode 100644 index 0000000000..a32f11ed4d --- /dev/null +++ b/gr-digital/include/CMakeLists.txt @@ -0,0 +1,34 @@ +# 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 11cab88337..06438c092b 100644 --- a/gr-digital/include/digital/CMakeLists.txt +++ b/gr-digital/include/digital/CMakeLists.txt @@ -75,54 +75,63 @@ add_custom_target(digital_generated_includes DEPENDS ######################################################################## install(FILES ${generated_includes} - api.h - constellation.h - crc32.h - lfsr.h - glfsr.h - mpsk_snr_est.h - simple_framer_sync.h additive_scrambler_bb.h + api.h binary_slicer_fb.h clock_recovery_mm_cc.h clock_recovery_mm_ff.h cma_equalizer_cc.h - cpmmod_bc.h - constellation_receiver_cb.h + constellation.h constellation_decoder_cb.h + constellation_receiver_cb.h correlate_access_code_bb.h correlate_access_code_tag_bb.h costas_loop_cc.h + cpmmod_bc.h + crc32.h descrambler_bb.h diff_decoder_bb.h diff_encoder_bb.h diff_phasor_cc.h - framer_sink_1.h fll_band_edge_cc.h + framer_sink_1.h + glfsr.h glfsr_source_b.h glfsr_source_f.h + header_payload_demux.h kurtotic_equalizer_cc.h + lfsr.h lms_dd_equalizer_cc.h map_bb.h metric_type.h mpsk_receiver_cc.h + mpsk_snr_est.h mpsk_snr_est_cc.h ofdm_cyclic_prefixer.h ofdm_frame_acquisition.h + ofdm_frame_equalizer_vcvc.h ofdm_frame_sink.h ofdm_insert_preamble.h ofdm_mapper_bcv.h ofdm_sampler.h + ofdm_serializer_vcc.h + packet_header_default.h + packet_header_ofdm.h + packet_headergenerator_bb.h + packet_headerparser_b.h packet_sink.h pfb_clock_sync_ccf.h pfb_clock_sync_fff.h pn_correlator_cc.h probe_density_b.h probe_mpsk_snr_est_c.h + scale_tags.h scrambler_bb.h - simple_framer.h simple_correlator.h + simple_framer.h + simple_framer_sync.h + tagged_stream_check.h + ts_insert_zeros_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/digital COMPONENT "digital_devel" ) - diff --git a/gr-digital/include/digital/constellation.h b/gr-digital/include/digital/constellation.h index ee7a704eb6..a7a2ec2023 100644 --- a/gr-digital/include/digital/constellation.h +++ b/gr-digital/include/digital/constellation.h @@ -82,7 +82,7 @@ namespace gr { //! Calculates metrics for all points in the constellation. //! For use with the viterbi algorithm. - virtual void calc_metric(const gr_complex *sample, float *metric, trellis_metric_type_t type); + virtual void calc_metric(const gr_complex *sample, float *metric, gr::digital::trellis_metric_type_t type); virtual void calc_euclidean_metric(const gr_complex *sample, float *metric); virtual void calc_hard_symbol_metric(const gr_complex *sample, float *metric); diff --git a/gr-digital/include/digital/header_payload_demux.h b/gr-digital/include/digital/header_payload_demux.h new file mode 100644 index 0000000000..014e0304a2 --- /dev/null +++ b/gr-digital/include/digital/header_payload_demux.h @@ -0,0 +1,90 @@ +/* -*- 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_HEADER_PAYLOAD_DEMUX_H +#define INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Header/Payload demuxer. + * \ingroup digital + * + * This block is designed to handle packets from a bursty transmission. + * Input 0 takes a continuous transmission of samples. + * If used, input 1 is a trigger signal. In this case, a 1 on input 1 + * is a trigger. Otherwise, a tag with the key specified in \p trigger_tag_key + * is used as a trigger (its value is irrelevant). + * + * Until a trigger signal is detected, all samples are dropped onto the floor. + * Once a trigger is detected, a total of \p header_len items are copied to output 0. + * The block then stalls until it receives a message on the message port + * \p header_data. The message must be a PMT dictionary; all key/value pairs are + * copied as tags to the first item of the payload (which is assumed to be the + * first item after the header). + * The value corresponding to the key specified in \p length_tag_key is read + * and taken as the payload length. The payload, together with the header data + * as tags, is then copied to output 1. + * + * If specified, \p guard_interval items are discarded before every symbol. + * This is useful for demuxing bursts of OFDM signals. + * + * Any tags on the input stream are copied to the corresponding output *if* they're + * on an item that is propagated. Note that a tag on the header items is copied to the + * header stream; that means the header-parsing block must handle these tags if they + * should go on the payload. + * A special case are tags on items that make up the guard interval. These are copied + * to the first item of the following symbol. + */ + class DIGITAL_API header_payload_demux : virtual public gr_block + { + public: + typedef boost::shared_ptr<header_payload_demux> sptr; + + /*! + * \param header_len Number of symbols per header + * \param items_per_symbol Number of items per symbol + * \param guard_interval Number of items between two consecutive symbols + * \param length_tag_key Key of the frame length tag + * \param trigger_tag_key Key of the trigger tag + * \param output_symbols Output symbols (true) or items (false)? + * \param itemsize Item size (bytes per item) + */ + static sptr make( + int header_len, + int items_per_symbol, + int guard_interval=0, + const std::string &length_tag_key="frame_len", + const std::string &trigger_tag_key="", + bool output_symbols=false, + size_t itemsize=sizeof(gr_complex) + ); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H */ + diff --git a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h new file mode 100644 index 0000000000..d5d526ddc3 --- /dev/null +++ b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h @@ -0,0 +1,63 @@ +/* -*- 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_OFDM_FRAME_EQUALIZER_VCVC_H +#define INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H + +#include <digital_ofdm_equalizer_base.h> +#include <digital/api.h> +#include <gr_tagged_stream_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief OFDM frame equalizer + * \ingroup ofdm + * + * Performs equalization in one or two dimensions on a tagged OFDM frame. + * Input: a tagged series of OFDM symbols. + * Output: The same as the input, but equalized. + */ + class DIGITAL_API ofdm_frame_equalizer_vcvc : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<ofdm_frame_equalizer_vcvc> sptr; + + /* + * \param equalizer The equalizer object that will do the actual work + * \param len_tag_key Length tag key + * \param propagate_channel_state If true, the channel state after the last symbol + * will be added to the first symbol as a tag + */ + static sptr make( + digital_ofdm_equalizer_base_sptr equalizer, + const std::string &len_tag_key = "frame_len", + bool propagate_channel_state=false + ); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H */ + diff --git a/gr-digital/include/digital/ofdm_serializer_vcc.h b/gr-digital/include/digital/ofdm_serializer_vcc.h new file mode 100644 index 0000000000..3893d6674e --- /dev/null +++ b/gr-digital/include/digital/ofdm_serializer_vcc.h @@ -0,0 +1,91 @@ +/* -*- 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_SERIALIZER_VCC_H +#define INCLUDED_DIGITAL_OFDM_SERIALIZER_VCC_H + +#include <digital/api.h> +#include <gr_tagged_stream_block.h> +#include <digital_ofdm_carrier_allocator_cvc.h> + +namespace gr { + namespace digital { + + /*! + * \brief Serializes complex modulations symbols from OFDM sub-carriers + * \ingroup ofdm_blk + * + * This is the inverse block to the carrier_allocator_cvc. It outputs the + * complex data symbols as a tagged stream, discarding the pilot symbols. + * + * If given, two different tags are parsed: The first key (\p len_tag_key) + * specifies the number of OFDM symbols in the frame at the input. The + * second key (\p packet_len_tag_key) specifies the number of complex symbols + * that are coded into this frame. If given, this second key is then used + * at the output, otherwise, \p len_tag_key is used. + * If both are given, the packet length specifies the maximum number of + * output items, and the frame length specifies the exact number of + * consumed input items. + * + * Input: Complex vectors of length \p fft_len + * Output: Complex scalars, in the same order as specified in occupied_carriers. + */ + class DIGITAL_API ofdm_serializer_vcc : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<ofdm_serializer_vcc> sptr; + + /*! + * \param fft_len FFT length + * \param occupied_carriers See ofdm_carrier_allocator_cvc. + * \param len_tag_key The key of the tag identifying the length of the input frame in OFDM symbols. + * \param packet_len_tag_key The key of the tag identifying the number of complex symbols in this packet. + * \param symbols_skipped If the first symbol is not allocated as in \p occupied_carriers[0], set this + * \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( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::string &len_tag_key="frame_len", + const std::string &packet_len_tag_key="", + int symbols_skipped=0, + bool input_is_shifted=true + ); + + /*! + * \param allocator The carrier allocator block of which this shall be the inverse + * \param packet_len_tag_key The key of the tag identifying the number of complex symbols in this packet. + * \param symbols_skipped If the first symbol is not allocated as in \p occupied_carriers[0], set this + * \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 std::string &packet_len_tag_key="", + int symbols_skipped=0, + bool input_is_shifted=true + ); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_SERIALIZER_VCC_H */ + diff --git a/gr-digital/include/digital/packet_header_default.h b/gr-digital/include/digital/packet_header_default.h new file mode 100644 index 0000000000..a4158e728c --- /dev/null +++ b/gr-digital/include/digital/packet_header_default.h @@ -0,0 +1,101 @@ +/* -*- 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_PACKET_HEADER_DEFAULT_H +#define INCLUDED_DIGITAL_PACKET_HEADER_DEFAULT_H + +#include <gr_tags.h> +#include <digital/api.h> +#include <boost/enable_shared_from_this.hpp> + +namespace gr { + namespace digital { + + /*! + * \brief <+description of block+> + * \ingroup digital + * + */ + class DIGITAL_API packet_header_default : public boost::enable_shared_from_this<gr::digital::packet_header_default> + { + public: + typedef boost::shared_ptr<packet_header_default> sptr; + + packet_header_default( + long header_len, + const std::string &len_tag_key="packet_len", + const std::string &num_tag_key="packet_num", + int bits_per_byte=1); + ~packet_header_default(); + + sptr base() { return shared_from_this(); }; + sptr formatter() { return shared_from_this(); }; + + void set_header_num(unsigned header_num) { d_header_number = header_num; }; + long header_len() { return d_header_len; }; + pmt::pmt_t len_tag_key() { return d_len_tag_key; }; + + /* \brief Encodes the header information in the given tags into bits and places them into \p out + * + * Uses the following header format: + * Bits 0-11: The packet length (what was stored in the tag with key \p len_tag_key) + * Bits 12-27: The header number (counts up everytime this function is called) + * Bit 28: Even parity bit + * All other bits: Are set to zero + * + * If the header length is smaller than 29, bits are simply left out. For this + * reason, they always start with the LSB. + */ + bool header_formatter( + long packet_len, + unsigned char *out, + const std::vector<gr_tag_t> &tags=std::vector<gr_tag_t>() + ); + + /* \brief Inverse function to header_formatter(). + * + * Reads the bit stream in \in and writes a corresponding tag into \p tags. + * + */ + bool header_parser( + const unsigned char *header, + std::vector<gr_tag_t> &tags); + + static sptr make( + long header_len, + const std::string &len_tag_key="packet_len", + const std::string &num_tag_key="packet_num", + int bits_per_byte=1); + + protected: + long d_header_len; + pmt::pmt_t d_len_tag_key; + pmt::pmt_t d_num_tag_key; + int d_bits_per_byte; + unsigned d_header_number; + unsigned d_mask; + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_PACKET_HEADER_DEFAULT_H */ + diff --git a/gr-digital/include/digital/packet_header_ofdm.h b/gr-digital/include/digital/packet_header_ofdm.h new file mode 100644 index 0000000000..6c3453ed1d --- /dev/null +++ b/gr-digital/include/digital/packet_header_ofdm.h @@ -0,0 +1,83 @@ +/* -*- 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_PACKET_HEADER_OFDM_H +#define INCLUDED_DIGITAL_PACKET_HEADER_OFDM_H + +#include <vector> +#include <digital/api.h> +#include <digital/packet_header_default.h> + +namespace gr { + namespace digital { + + /*! + * \brief Header utility for OFDM signals. + * \ingroup ofdm_blk + * + */ + class DIGITAL_API packet_header_ofdm : public packet_header_default + { + public: + typedef boost::shared_ptr<packet_header_ofdm> sptr; + + packet_header_ofdm( + const std::vector<std::vector<int> > &occupied_carriers, + int n_syms, + const std::string &len_tag_key="packet_len", + const std::string &frame_len_tag_key="frame_len", + const std::string &num_tag_key="packet_num", + int bits_per_sym=1); + ~packet_header_ofdm(); + + /* \brief Inverse function to header_formatter(). + * + * Does the same as packet_header_default::header_parser(), but + * adds another tag that stores the number of OFDM symbols in the + * packet. + * Note that there is usually no linear connection between the number + * of OFDM symbols and the packet length, because, a packet might + * finish mid-OFDM-symbol. + */ + bool header_parser( + const unsigned char *header, + std::vector<gr_tag_t> &tags); + + static sptr make( + const std::vector<std::vector<int> > &occupied_carriers, + int n_syms, + const std::string &len_tag_key="packet_len", + const std::string &frame_len_tag_key="frame_len", + const std::string &num_tag_key="packet_num", + int bits_per_sym=1); + + + protected: + pmt::pmt_t d_frame_len_tag_key; + const std::vector<std::vector<int> > d_occupied_carriers; //! Which carriers/symbols carry data + int d_syms_per_set; //! Helper variable: Total number of elements in d_occupied_carriers + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_PACKET_HEADER_OFDM_H */ + diff --git a/gr-digital/include/digital/packet_headergenerator_bb.h b/gr-digital/include/digital/packet_headergenerator_bb.h new file mode 100644 index 0000000000..8d92bf84ed --- /dev/null +++ b/gr-digital/include/digital/packet_headergenerator_bb.h @@ -0,0 +1,57 @@ +/* -*- 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_PACKET_HEADERGENERATOR_BB_H +#define INCLUDED_PACKET_HEADERGENERATOR_BB_H + +#include <digital/api.h> +#include <gr_tagged_stream_block.h> +#include <digital/packet_header_default.h> + +namespace gr { + namespace digital { + + /*! + * \brief Generates a header for a tagged, streamed packet. + * \ingroup digital + * + * Input: A tagged stream. The first element must have a tag with the key + * specified in len_tag_key, which hold the exact number of elements + * in the PDU. + * Output: An tagged stream of length header_len. The output is determined + * by a header formatter. + */ + class DIGITAL_API packet_headergenerator_bb : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<packet_headergenerator_bb> sptr; + + static sptr make(const packet_header_default::sptr &header_formatter); + static sptr make( + long header_len, + const std::string &len_tag_key = "packet_len"); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_PACKET_HEADERGENERATOR_BB_H */ + diff --git a/gr-digital/include/digital/packet_headerparser_b.h b/gr-digital/include/digital/packet_headerparser_b.h new file mode 100644 index 0000000000..a3db069cbd --- /dev/null +++ b/gr-digital/include/digital/packet_headerparser_b.h @@ -0,0 +1,65 @@ +/* -*- 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_PACKET_HEADERPARSER_B_H +#define INCLUDED_DIGITAL_PACKET_HEADERPARSER_B_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <digital/packet_header_default.h> + +namespace gr { + namespace digital { + + /*! + * \brief Post header metadata as a PMT + * \ingroup digital + * + * In a sense, this is the inverse block to packet_headergenerator_bb. + * The difference is, the parsed header is not output as a stream, + * but as a message. + * + * If only a header length is given, this block uses the default header + * format. + */ + class DIGITAL_API packet_headerparser_b : virtual public gr_sync_block + { + public: + typedef boost::shared_ptr<packet_headerparser_b> sptr; + + /*! + * \param header_formatter Header object. This should be the same as used for + * packet_headergenerator_bb. + */ + static sptr make(const gr::digital::packet_header_default::sptr &header_formatter); + + /*! + * \param header_len Number of bytes per header + * \param len_tag_key Length Tag Key + */ + static sptr make(long header_len, const std::string &len_tag_key); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_PACKET_HEADERPARSER_B_H */ + diff --git a/gr-digital/include/digital/scale_tags.h b/gr-digital/include/digital/scale_tags.h new file mode 100644 index 0000000000..8a9e3efba4 --- /dev/null +++ b/gr-digital/include/digital/scale_tags.h @@ -0,0 +1,58 @@ +/* -*- 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_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/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief <+description of block+> + * \ingroup block + * + */ + class DIGITAL_API scale_tags : virtual public gr_sync_block + { + public: + typedef boost::shared_ptr<scale_tags> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of digital::scale_tags. + * + * To avoid accidental use of raw pointers, digital::scale_tags's + * constructor is in a private implementation + * class. digital::scale_tags::make is the public interface for + * creating new instances. + */ + static sptr make(size_t itemsize, const std::string&, float scale_factor); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_SCALE_TAGS_H */ + diff --git a/gr-digital/include/digital/tagged_stream_check.h b/gr-digital/include/digital/tagged_stream_check.h new file mode 100644 index 0000000000..73b44a5bb9 --- /dev/null +++ b/gr-digital/include/digital/tagged_stream_check.h @@ -0,0 +1,55 @@ +/* -*- 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_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/api.h> +#include <gr_sync_block.h> + + +namespace gr { + namespace digital { + + /*! + * \brief Checks a tagged stream to make sure it's valid. + * + * \description + * Produces error messages if the tags in a tagged stream aren't where + * they should be. + * + * \ingroup digital + * + */ + class DIGITAL_API tagged_stream_check : virtual public gr_sync_block + { + public: + typedef boost::shared_ptr<tagged_stream_check> sptr; + static sptr make(size_t itemsize, const std::string &lengthtagname); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_TAGGED_STREAM_CHECK_H */ + diff --git a/gr-digital/include/digital/ts_insert_zeros_cc.h b/gr-digital/include/digital/ts_insert_zeros_cc.h new file mode 100644 index 0000000000..299062eb50 --- /dev/null +++ b/gr-digital/include/digital/ts_insert_zeros_cc.h @@ -0,0 +1,55 @@ +/* -*- 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_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/api.h> +#include <gr_block.h> +#include <string> + + +namespace gr { + namespace digital { + + /*! + * \brief Inserts zeros between the packets of a tagged stream. + * + * \description + * Outputs zeros if a packet is not yet ready at the input, otherwise + * passes packets through. + * + * \ingroup digital + * + */ + class DIGITAL_API ts_insert_zeros_cc : virtual public gr_block + { + public: + typedef boost::shared_ptr<ts_insert_zeros_cc> sptr; + static sptr make(const std::string &lengthtagname); + }; + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_TS_INSERT_ZEROS_CC_H */ + diff --git a/gr-digital/include/digital_crc32_bb.h b/gr-digital/include/digital_crc32_bb.h new file mode 100644 index 0000000000..efbf2d545a --- /dev/null +++ b/gr-digital/include/digital_crc32_bb.h @@ -0,0 +1,67 @@ +/* -*- 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 new file mode 100644 index 0000000000..9052299aa9 --- /dev/null +++ b/gr-digital/include/digital_ofdm_carrier_allocator_cvc.h @@ -0,0 +1,116 @@ +/* -*- 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 new file mode 100644 index 0000000000..da03f96720 --- /dev/null +++ b/gr-digital/include/digital_ofdm_chanest_vcvc.h @@ -0,0 +1,133 @@ +/* -*- 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 new file mode 100644 index 0000000000..563a311fa3 --- /dev/null +++ b/gr-digital/include/digital_ofdm_cyclic_prefixer.h @@ -0,0 +1,95 @@ +/* -*- 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 new file mode 100644 index 0000000000..8665395540 --- /dev/null +++ b/gr-digital/include/digital_ofdm_equalizer_base.h @@ -0,0 +1,102 @@ +/* -*- 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 new file mode 100644 index 0000000000..89b0b5cd6d --- /dev/null +++ b/gr-digital/include/digital_ofdm_equalizer_simpledfe.h @@ -0,0 +1,126 @@ +/* -*- 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 new file mode 100644 index 0000000000..4537d329f4 --- /dev/null +++ b/gr-digital/include/digital_ofdm_equalizer_static.h @@ -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. + */ + +#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 new file mode 100644 index 0000000000..cc728814ed --- /dev/null +++ b/gr-digital/include/digital_ofdm_sync_sc_cfb.h @@ -0,0 +1,79 @@ +/* -*- 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 */ + |