From f968b36d4ed2b194111585605f9a1b5367638fb3 Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@kit.edu>
Date: Fri, 15 Mar 2013 02:12:20 -0700
Subject: Squash/rebased martin/ofdm-master onto trial merge branch

Conflicts:
	gr-blocks/include/blocks/CMakeLists.txt
---
 gr-digital/include/CMakeLists.txt                  |   7 ++
 gr-digital/include/digital/CMakeLists.txt          |  43 +++++++
 gr-digital/include/digital/api.h                   |  33 +++++
 gr-digital/include/digital/header_payload_demux.h  |  90 ++++++++++++++
 .../include/digital/ofdm_frame_equalizer_vcvc.h    |  63 ++++++++++
 gr-digital/include/digital/ofdm_serializer_vcc.h   |  91 ++++++++++++++
 gr-digital/include/digital/packet_header_default.h | 101 ++++++++++++++++
 gr-digital/include/digital/packet_header_ofdm.h    |  83 +++++++++++++
 .../include/digital/packet_headergenerator_bb.h    |  57 +++++++++
 gr-digital/include/digital/packet_headerparser_b.h |  65 ++++++++++
 gr-digital/include/digital/scale_tags.h            |  58 +++++++++
 gr-digital/include/digital/tagged_stream_check.h   |  55 +++++++++
 gr-digital/include/digital/ts_insert_zeros_cc.h    |  55 +++++++++
 gr-digital/include/digital_crc32_bb.h              |  67 +++++++++++
 .../include/digital_ofdm_carrier_allocator_cvc.h   | 116 ++++++++++++++++++
 gr-digital/include/digital_ofdm_chanest_vcvc.h     | 133 +++++++++++++++++++++
 gr-digital/include/digital_ofdm_cyclic_prefixer.h  |  62 ++++++++--
 gr-digital/include/digital_ofdm_equalizer_base.h   | 102 ++++++++++++++++
 .../include/digital_ofdm_equalizer_simpledfe.h     | 126 +++++++++++++++++++
 gr-digital/include/digital_ofdm_equalizer_static.h |  97 +++++++++++++++
 gr-digital/include/digital_ofdm_sync_sc_cfb.h      |  79 ++++++++++++
 21 files changed, 1570 insertions(+), 13 deletions(-)
 create mode 100644 gr-digital/include/digital/CMakeLists.txt
 create mode 100644 gr-digital/include/digital/api.h
 create mode 100644 gr-digital/include/digital/header_payload_demux.h
 create mode 100644 gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h
 create mode 100644 gr-digital/include/digital/ofdm_serializer_vcc.h
 create mode 100644 gr-digital/include/digital/packet_header_default.h
 create mode 100644 gr-digital/include/digital/packet_header_ofdm.h
 create mode 100644 gr-digital/include/digital/packet_headergenerator_bb.h
 create mode 100644 gr-digital/include/digital/packet_headerparser_b.h
 create mode 100644 gr-digital/include/digital/scale_tags.h
 create mode 100644 gr-digital/include/digital/tagged_stream_check.h
 create mode 100644 gr-digital/include/digital/ts_insert_zeros_cc.h
 create mode 100644 gr-digital/include/digital_crc32_bb.h
 create mode 100644 gr-digital/include/digital_ofdm_carrier_allocator_cvc.h
 create mode 100644 gr-digital/include/digital_ofdm_chanest_vcvc.h
 create mode 100644 gr-digital/include/digital_ofdm_equalizer_base.h
 create mode 100644 gr-digital/include/digital_ofdm_equalizer_simpledfe.h
 create mode 100644 gr-digital/include/digital_ofdm_equalizer_static.h
 create mode 100644 gr-digital/include/digital_ofdm_sync_sc_cfb.h

(limited to 'gr-digital/include')

diff --git a/gr-digital/include/CMakeLists.txt b/gr-digital/include/CMakeLists.txt
index ad5baec87e..06300cc27b 100644
--- a/gr-digital/include/CMakeLists.txt
+++ b/gr-digital/include/CMakeLists.txt
@@ -123,6 +123,13 @@ install(FILES
     digital_scrambler_bb.h
     digital_simple_framer.h
     digital_simple_framer_sync.h
+    digital_ofdm_sync_sc_cfb.h
+    digital_ofdm_chanest_vcvc.h
+    digital_crc32_bb.h
+    digital_ofdm_carrier_allocator_cvc.h
+    digital_ofdm_equalizer_base.h
+    digital_ofdm_equalizer_static.h
+    digital_ofdm_equalizer_simpledfe.h
     digital_simple_correlator.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
new file mode 100644
index 0000000000..7926ae3234
--- /dev/null
+++ b/gr-digital/include/digital/CMakeLists.txt
@@ -0,0 +1,43 @@
+# 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.
+
+########################################################################
+# generate helper scripts to expand templated files
+########################################################################
+include(GrPython)
+
+########################################################################
+# Install header files
+########################################################################
+install(FILES
+    api.h
+    ofdm_frame_equalizer_vcvc.h
+    ofdm_serializer_vcc.h
+    packet_header_default.h
+    packet_header_ofdm.h
+    packet_headergenerator_bb.h
+    scale_tags.h
+    tagged_stream_check.h
+    ts_insert_zeros_cc.h
+    packet_headerparser_b.h
+    header_payload_demux.h
+    DESTINATION ${GR_INCLUDE_DIR}/gnuradio/digital
+    COMPONENT "digital_devel"
+)
+
diff --git a/gr-digital/include/digital/api.h b/gr-digital/include/digital/api.h
new file mode 100644
index 0000000000..0912f7e0d4
--- /dev/null
+++ b/gr-digital/include/digital/api.h
@@ -0,0 +1,33 @@
+/*
+ * 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_API_H
+#define INCLUDED_DIGITAL_API_H
+
+#include <gruel/attributes.h>
+
+#ifdef gnuradio_digital_EXPORTS
+#  define DIGITAL_API __GR_ATTR_EXPORT
+#else
+#  define DIGITAL_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_DIGITAL_API_H */
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..1f4771e861
--- /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..c1efcead22
--- /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..74454a63b2
--- /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
index 1b9682bb35..e6c36b4c14 100644
--- a/gr-digital/include/digital_ofdm_cyclic_prefixer.h
+++ b/gr-digital/include/digital_ofdm_cyclic_prefixer.h
@@ -24,36 +24,72 @@
 #define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H
 
 #include <digital_api.h>
-#include <gr_sync_interpolator.h>
-#include <stdio.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;
 
-DIGITAL_API digital_ofdm_cyclic_prefixer_sptr 
-digital_make_ofdm_cyclic_prefixer (size_t input_size, size_t output_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
+ */
+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 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 digital_ofdm_cyclic_prefixer : public gr_sync_interpolator
+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);
+    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);
+  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_const_void_star &input_items,
-	    gr_vector_void_star &output_items);
+  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_input_size;
+  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..178806a886
--- /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..9fd6395904
--- /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 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 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:
+  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..21f76fbc6a
--- /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..36ea1b22fd
--- /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 */
+
-- 
cgit v1.2.3