commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 09/13: Add DVB-T receiver.


From: git
Subject: [Commit-gnuradio] [gnuradio] 09/13: Add DVB-T receiver.
Date: Sun, 6 Sep 2015 01:19:38 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit 0b05c304f420196874f2a13bb21420a7609eb778
Author: Bogdan Diaconescu <address@hidden>
Date:   Sat Sep 5 16:35:12 2015 -0700

    Add DVB-T receiver.
---
 gr-dtv/grc/dtv_dvbt_bit_inner_deinterleaver.xml    |  89 ++++
 .../grc/dtv_dvbt_convolutional_deinterleaver.xml   |  43 ++
 gr-dtv/grc/dtv_dvbt_demap.xml                      |  90 ++++
 gr-dtv/grc/dtv_dvbt_demod_reference_signals.xml    | 222 +++++++++
 gr-dtv/grc/dtv_dvbt_energy_descramble.xml          |  29 ++
 gr-dtv/grc/dtv_dvbt_ofdm_sym_acquisition.xml       |  76 ++++
 gr-dtv/grc/dtv_dvbt_reed_solomon_dec.xml           |  70 +++
 gr-dtv/grc/dtv_dvbt_viterbi_decoder.xml            | 120 +++++
 .../gnuradio/dtv/dvbt_bit_inner_deinterleaver.h    |  67 +++
 .../dtv/dvbt_convolutional_deinterleaver.h         |  58 +++
 gr-dtv/include/gnuradio/dtv/dvbt_demap.h           |  65 +++
 .../gnuradio/dtv/dvbt_demod_reference_signals.h    |  73 +++
 .../include/gnuradio/dtv/dvbt_energy_descramble.h  |  58 +++
 .../gnuradio/dtv/dvbt_ofdm_sym_acquisition.h       |  60 +++
 .../include/gnuradio/dtv/dvbt_reed_solomon_dec.h   |  61 +++
 gr-dtv/include/gnuradio/dtv/dvbt_viterbi_decoder.h |  69 +++
 .../lib/dvbt/dvbt_bit_inner_deinterleaver_impl.cc  | 191 ++++++++
 .../lib/dvbt/dvbt_bit_inner_deinterleaver_impl.h   |  65 +++
 .../dvbt/dvbt_convolutional_deinterleaver_impl.cc  | 137 ++++++
 .../dvbt/dvbt_convolutional_deinterleaver_impl.h   |  57 +++
 gr-dtv/lib/dvbt/dvbt_demap_impl.cc                 | 185 ++++++++
 gr-dtv/lib/dvbt/dvbt_demap_impl.h                  |  71 +++
 .../lib/dvbt/dvbt_demod_reference_signals_impl.cc  | 152 +++++++
 .../lib/dvbt/dvbt_demod_reference_signals_impl.h   |  68 +++
 gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.cc     | 156 +++++++
 gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.h      |  65 +++
 gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.cc  | 417 +++++++++++++++++
 gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.h   | 105 +++++
 gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc      | 106 +++++
 gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h       |  62 +++
 gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc       | 495 +++++++++++++++++++++
 gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.h        | 125 ++++++
 32 files changed, 3707 insertions(+)

diff --git a/gr-dtv/grc/dtv_dvbt_bit_inner_deinterleaver.xml 
b/gr-dtv/grc/dtv_dvbt_bit_inner_deinterleaver.xml
new file mode 100644
index 0000000..ff338d2
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_bit_inner_deinterleaver.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Bit Inner Deinterleaver
+###################################################
+ -->
+<block>
+  <name>Bit Inner Deinterleaver</name>
+  <key>dtv_dvbt_bit_inner_deinterleaver</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_bit_inner_deinterleaver($transmission_mode.payload_length, 
$constellation.val, $hierarchy.val, $transmission_mode.val)</make>
+  <param>
+    <name>Constellation Type</name>
+    <key>constellation</key>
+    <type>enum</type>
+    <option>
+      <name>QPSK</name>
+      <key>qpsk</key>
+      <opt>val:dtv.MOD_QPSK</opt>
+    </option>
+    <option>
+      <name>16QAM</name>
+      <key>16qam</key>
+      <opt>val:dtv.MOD_16QAM</opt>
+    </option>
+    <option>
+      <name>64QAM</name>
+      <key>64qam</key>
+      <opt>val:dtv.MOD_64QAM</opt>
+    </option>
+  </param>
+  <param>
+    <name>Hierarchy Type</name>
+    <key>hierarchy</key>
+    <type>enum</type>
+    <option>
+      <name>Non Hierarchical</name>
+      <key>nh</key>
+      <opt>val:dtv.NH</opt>
+      <opt>num_streams:1</opt>
+    </option>
+    <option>
+      <name>Alpha 1</name>
+      <key>alpha1</key>
+      <opt>val:dtv.ALPHA1</opt>
+      <opt>num_streams:2</opt>
+    </option>
+    <option>
+      <name>Alpha 2</name>
+      <key>alpha2</key>
+      <opt>val:dtv.ALPHA2</opt>
+      <opt>num_streams:2</opt>
+    </option>
+    <option>
+      <name>Alpha 4</name>
+      <key>alpha4</key>
+      <opt>val:dtv.ALPHA4</opt>
+      <opt>num_streams:2</opt>
+    </option>
+  </param>
+  <param>
+    <name>Transmission Mode</name>
+    <key>transmission_mode</key>
+    <type>enum</type>
+    <option>
+      <name>2K</name>
+      <key>T2k</key>
+      <opt>val:dtv.T2k</opt>
+      <opt>payload_length:1512</opt>
+    </option>
+    <option>
+      <name>8K</name>
+      <key>T8k</key>
+      <opt>val:dtv.T8k</opt>
+      <opt>payload_length:6048</opt>
+    </option>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+    <vlen>$transmission_mode.payload_length</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>byte</type>
+    <vlen>$transmission_mode.payload_length</vlen>
+    <nports>$hierarchy.num_streams</nports>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_convolutional_deinterleaver.xml 
b/gr-dtv/grc/dtv_dvbt_convolutional_deinterleaver.xml
new file mode 100644
index 0000000..315920b
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_convolutional_deinterleaver.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Convolutional Deinterleaver
+###################################################
+ -->
+<block>
+  <name>Convolutional Deinterleaver</name>
+  <key>dtv_dvbt_convolutional_deinterleaver</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_convolutional_deinterleaver($blocks, $I, $M)</make>
+  <param>
+    <name>Blocks (12 Bytes)</name>
+    <key>blocks</key>
+    <value>136</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Number of Shift registers</name>
+    <key>I</key>
+    <value>12</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Depth of shift registers</name>
+    <key>M</key>
+    <value>17</value>
+    <type>int</type>
+  </param>
+  <check>$blocks &gt; 0</check>
+  <check>$I &gt; 0</check>
+  <check>$M &gt; 0</check>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+    <vlen>1</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>byte</type>
+    <vlen>$blocks*$I</vlen>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_demap.xml b/gr-dtv/grc/dtv_dvbt_demap.xml
new file mode 100644
index 0000000..2268ed7
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_demap.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Demap
+###################################################
+ -->
+<block>
+  <name>DVB-T Demap</name>
+  <key>dtv_dvbt_demap</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_demap($transmission_mode.payload_length, $constellation.val, 
$hierarchy.val, $transmission_mode.val, $gain)</make>
+  <param>
+    <name>Constellation Type</name>
+    <key>constellation</key>
+    <type>enum</type>
+    <option>
+      <name>QPSK</name>
+      <key>qpsk</key>
+      <opt>val:dtv.MOD_QPSK</opt>
+    </option>
+    <option>
+      <name>16QAM</name>
+      <key>16qam</key>
+      <opt>val:dtv.MOD_16QAM</opt>
+    </option>
+    <option>
+      <name>64QAM</name>
+      <key>64qam</key>
+      <opt>val:dtv.MOD_64QAM</opt>
+    </option>
+  </param>
+  <param>
+    <name>Hierarchy Type</name>
+    <key>hierarchy</key>
+    <type>enum</type>
+    <option>
+      <name>Non Hierarchical</name>
+      <key>nh</key>
+      <opt>val:dtv.NH</opt>
+    </option>
+    <option>
+      <name>Alpha 1</name>
+      <key>alpha1</key>
+      <opt>val:dtv.ALPHA1</opt>
+    </option>
+    <option>
+      <name>Alpha 2</name>
+      <key>alpha2</key>
+      <opt>val:dtv.ALPHA2</opt>
+    </option>
+    <option>
+      <name>Alpha 4</name>
+      <key>alpha4</key>
+      <opt>val:dtv.ALPHA4</opt>
+    </option>
+  </param>
+  <param>
+    <name>Transmission Mode</name>
+    <key>transmission_mode</key>
+    <type>enum</type>
+    <option>
+      <name>2K</name>
+      <key>T2k</key>
+      <opt>val:dtv.T2k</opt>
+      <opt>payload_length:1512</opt>
+    </option>
+    <option>
+      <name>8K</name>
+      <key>T8k</key>
+      <opt>val:dtv.T8k</opt>
+      <opt>payload_length:6048</opt>
+    </option>
+  </param>
+  <param>
+    <name>Gain</name>
+    <key>gain</key>
+    <value>1</value>
+    <type>complex</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>complex</type>
+    <vlen>$transmission_mode.payload_length</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>byte</type>
+    <vlen>$transmission_mode.payload_length</vlen>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_demod_reference_signals.xml 
b/gr-dtv/grc/dtv_dvbt_demod_reference_signals.xml
new file mode 100644
index 0000000..f92469b
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_demod_reference_signals.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Demod Reference Signals
+###################################################
+ -->
+<block>
+  <name>Demod Reference Signals</name>
+  <key>dtv_dvbt_demod_reference_signals</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_demod_reference_signals($type.size, 
$transmission_mode.fft_length, $transmission_mode.payload_length, 
$constellation.val, $hierarchy.val, $code_rate_hp.val, $code_rate_lp.val, 
$guard_interval.val, $transmission_mode.val, $include_cell_id.val, 
$cell_id)</make>
+  <param>
+    <name>IO Type</name>
+    <key>type</key>
+    <type>enum</type>
+    <option>
+      <name>Complex</name>
+      <key>complex</key>
+      <opt>size:gr.sizeof_gr_complex</opt>
+    </option>
+    <option>
+      <name>Float</name>
+      <key>float</key>
+      <opt>size:gr.sizeof_float</opt>
+    </option>
+    <option>
+      <name>Int</name>
+      <key>int</key>
+      <opt>size:gr.sizeof_int</opt>
+    </option>
+    <option>
+      <name>Short</name>
+      <key>short</key>
+      <opt>size:gr.sizeof_short</opt>
+    </option>
+    <option>
+      <name>Byte</name>
+      <key>byte</key>
+      <opt>size:gr.sizeof_char</opt>
+    </option>
+  </param>
+  <param>
+    <name>Constellation Type</name>
+    <key>constellation</key>
+    <type>enum</type>
+    <option>
+      <name>QPSK</name>
+      <key>qpsk</key>
+      <opt>val:dtv.MOD_QPSK</opt>
+    </option>
+    <option>
+      <name>16QAM</name>
+      <key>16qam</key>
+      <opt>val:dtv.MOD_16QAM</opt>
+    </option>
+    <option>
+      <name>64QAM</name>
+      <key>64qam</key>
+      <opt>val:dtv.MOD_64QAM</opt>
+    </option>
+  </param>
+  <param>
+    <name>Hierarchy Type</name>
+    <key>hierarchy</key>
+    <type>enum</type>
+    <option>
+      <name>Non Hierarchical</name>
+      <key>nh</key>
+      <opt>val:dtv.NH</opt>
+    </option>
+    <option>
+      <name>Alpha 1</name>
+      <key>alpha1</key>
+      <opt>val:dtv.ALPHA1</opt>
+    </option>
+    <option>
+      <name>Alpha 2</name>
+      <key>alpha2</key>
+      <opt>val:dtv.ALPHA2</opt>
+    </option>
+    <option>
+      <name>Alpha 4</name>
+      <key>alpha4</key>
+      <opt>val:dtv.ALPHA4</opt>
+    </option>
+  </param>
+  <param>
+    <name>Code rate HP</name>
+    <key>code_rate_hp</key>
+    <type>enum</type>
+    <option>
+      <name>1/2</name>
+      <key>C1_2</key>
+      <opt>val:dtv.C1_2</opt>
+    </option>
+    <option>
+      <name>2/3</name>
+      <key>C2_3</key>
+      <opt>val:dtv.C2_3</opt>
+    </option>
+    <option>
+      <name>3/4</name>
+      <key>C3_4</key>
+      <opt>val:dtv.C3_4</opt>
+    </option>
+    <option>
+      <name>5/6</name>
+      <key>C5_6</key>
+      <opt>val:dtv.C5_6</opt>
+    </option>
+    <option>
+      <name>7/8</name>
+      <key>C7_8</key>
+      <opt>val:dtv.C7_8</opt>
+    </option>
+  </param>
+  <param>
+    <name>Code rate LP</name>
+    <key>code_rate_lp</key>
+    <type>enum</type>
+    <option>
+      <name>1/2</name>
+      <key>C1_2</key>
+      <opt>val:dtv.C1_2</opt>
+    </option>
+    <option>
+      <name>2/3</name>
+      <key>C2_3</key>
+      <opt>val:dtv.C2_3</opt>
+    </option>
+    <option>
+      <name>3/4</name>
+      <key>C3_4</key>
+      <opt>val:dtv.C3_4</opt>
+    </option>
+    <option>
+      <name>5/6</name>
+      <key>C5_6</key>
+      <opt>val:dtv.C5_6</opt>
+    </option>
+    <option>
+      <name>7/8</name>
+      <key>C7_8</key>
+      <opt>val:dtv.C7_8</opt>
+    </option>
+  </param>
+  <param>
+    <name>Guard Interval</name>
+    <key>guard_interval</key>
+    <type>enum</type>
+    <option>
+      <name>1/32</name>
+      <key>GI_1_32</key>
+      <opt>val:dtv.GI_1_32</opt>
+    </option>
+    <option>
+      <name>1/16</name>
+      <key>GI_1_16</key>
+      <opt>val:dtv.GI_1_16</opt>
+    </option>
+    <option>
+      <name>1/8</name>
+      <key>GI_1_8</key>
+      <opt>val:dtv.GI_1_8</opt>
+    </option>
+    <option>
+      <name>1/4</name>
+      <key>GI_1_4</key>
+      <opt>val:dtv.GI_1_4</opt>
+    </option>
+  </param>
+  <param>
+    <name>Transmission Mode</name>
+    <key>transmission_mode</key>
+    <type>enum</type>
+    <option>
+      <name>2K</name>
+      <key>T2k</key>
+      <opt>val:dtv.T2k</opt>
+      <opt>fft_length:2048</opt>
+      <opt>payload_length:1512</opt>
+    </option>
+    <option>
+      <name>8K</name>
+      <key>T8k</key>
+      <opt>val:dtv.T8k</opt>
+      <opt>fft_length:8192</opt>
+      <opt>payload_length:6048</opt>
+    </option>
+  </param>
+  <param>
+    <name>Include Cell ID</name>
+    <key>include_cell_id</key>
+    <type>enum</type>
+      <option>
+        <name>Yes</name>
+        <key>call_id_yes</key>
+        <opt>val:1</opt>
+      </option>
+      <option>
+        <name>No</name>
+        <key>cell_id_no</key>
+        <opt>val:0</opt>
+      </option>
+  </param>
+  <param>
+    <name>Cell Id</name>
+    <key>cell_id</key>
+    <value>0</value>
+    <type>int</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>complex</type>
+    <vlen>$transmission_mode.fft_length</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>complex</type>
+    <vlen>$transmission_mode.payload_length</vlen>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_energy_descramble.xml 
b/gr-dtv/grc/dtv_dvbt_energy_descramble.xml
new file mode 100644
index 0000000..689f854
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_energy_descramble.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Energy Descramble
+###################################################
+ -->
+<block>
+  <name>Energy Descramble</name>
+  <key>dtv_dvbt_energy_descramble</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_energy_descramble($nsize)</make>
+  <param>
+    <name>Blocks(188 Bytes)</name>
+    <key>nsize</key>
+    <value>8</value>
+    <type>int</type>
+  </param>
+  <check>$nsize &gt; 0</check>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+    <vlen>188*8</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>byte</type>
+    <vlen>1</vlen>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_ofdm_sym_acquisition.xml 
b/gr-dtv/grc/dtv_dvbt_ofdm_sym_acquisition.xml
new file mode 100644
index 0000000..a75dcc0
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_ofdm_sym_acquisition.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## OFDM Symbol Acquisition
+###################################################
+ -->
+<block>
+  <name>OFDM Symbol Acquisition</name>
+  <key>dtv_dvbt_ofdm_sym_acquisition</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_ofdm_sym_acquisition(1, $fft_length, $occupied_tones, 
$cp_length, $snr)</make>
+  <param>
+    <name>Output Type</name>
+    <key>type</key>
+    <value>float</value>
+    <type>enum</type>
+    <option>
+      <name>Complex</name>
+      <key>complex</key>
+      <opt>fcn:c</opt>
+    </option>
+    <option>
+      <name>Float</name>
+      <key>float</key>
+      <opt>fcn:f</opt>
+    </option>
+    <option>
+      <name>Int</name>
+      <key>int</key>
+      <opt>fcn:i</opt>
+    </option>
+    <option>
+      <name>Short</name>
+      <key>short</key>
+      <opt>fcn:s</opt>
+    </option>
+    <option>
+      <name>Byte</name>
+      <key>byte</key>
+      <opt>fcn:b</opt>
+    </option>
+  </param>
+  <param>
+    <name>FFT Length</name>
+    <key>fft_length</key>
+    <value>2048</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Occupied Tones</name>
+    <key>occupied_tones</key>
+    <value>1705</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Cyclic Prefix Length</name>
+    <key>cp_length</key>
+    <value>64</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>SNR</name>
+    <key>snr</key>
+    <value>10</value>
+    <type>real</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>complex</type>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>$type</type>
+    <vlen>$fft_length</vlen>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_reed_solomon_dec.xml 
b/gr-dtv/grc/dtv_dvbt_reed_solomon_dec.xml
new file mode 100644
index 0000000..798a6d4
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_reed_solomon_dec.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Reed Solomon Decoder
+###################################################
+ -->
+<block>
+  <name>Reed-Solomon Decoder</name>
+  <key>dtv_dvbt_reed_solomon_dec</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_reed_solomon_dec($p, $m, $gfpoly, $n, $k, $t, $s, 
$blocks)</make>
+  <param>
+    <name>p</name>
+    <key>p</key>
+    <value>2</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>m</name>
+    <key>m</key>
+    <value>8</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>GF polynomial</name>
+    <key>gfpoly</key>
+    <value>0x11d</value>
+    <type>raw</type>
+  </param>
+  <param>
+    <name>N</name>
+    <key>n</key>
+    <value>255</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>K</name>
+    <key>k</key>
+    <value>239</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>t</name>
+    <key>t</key>
+    <value>8</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Shortening size</name>
+    <key>s</key>
+    <value>51</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Blocks</name>
+    <key>blocks</key>
+    <value>8</value>
+    <type>int</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+    <vlen>$blocks*($n-$s)</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>byte</type>
+    <vlen>$blocks*($k-$s)</vlen>
+  </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_viterbi_decoder.xml 
b/gr-dtv/grc/dtv_dvbt_viterbi_decoder.xml
new file mode 100644
index 0000000..1dde80c
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_viterbi_decoder.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Viterbi Decoder
+###################################################
+ -->
+<block>
+  <name>Viterbi Decoder</name>
+  <key>dtv_dvbt_viterbi_decoder</key>
+  <import>from gnuradio import dtv</import>
+  <make>dtv.dvbt_viterbi_decoder($constellation.val, $hierarchy.val, 
$code_rate.val, $block_size)</make>
+  <param>
+    <name>Constellation Type</name>
+    <key>constellation</key>
+    <type>enum</type>
+    <option>
+      <name>QPSK</name>
+      <key>qpsk</key>
+      <opt>val:dtv.MOD_QPSK</opt>
+    </option>
+    <option>
+      <name>16QAM</name>
+      <key>16qam</key>
+      <opt>val:dtv.MOD_16QAM</opt>
+    </option>
+    <option>
+      <name>64QAM</name>
+      <key>64qam</key>
+      <opt>val:dtv.MOD_64QAM</opt>
+    </option>
+  </param>
+  <param>
+    <name>Hierarchy Type</name>
+    <key>hierarchy</key>
+    <type>enum</type>
+    <option>
+      <name>Non Hierarchical</name>
+      <key>nh</key>
+      <opt>val:dtv.NH</opt>
+    </option>
+    <option>
+      <name>Alpha 1</name>
+      <key>alpha1</key>
+      <opt>val:dtv.ALPHA1</opt>
+    </option>
+    <option>
+      <name>Alpha 2</name>
+      <key>alpha2</key>
+      <opt>val:dtv.ALPHA2</opt>
+    </option>
+    <option>
+      <name>Alpha 4</name>
+      <key>alpha4</key>
+      <opt>val:dtv.ALPHA4</opt>
+    </option>
+  </param>
+  <param>
+    <name>Code rate</name>
+    <key>code_rate</key>
+    <type>enum</type>
+    <option>
+      <name>1/2</name>
+      <key>C1_2</key>
+      <opt>val:dtv.C1_2</opt>
+    </option>
+    <option>
+      <name>2/3</name>
+      <key>C2_3</key>
+      <opt>val:dtv.C2_3</opt>
+    </option>
+    <option>
+      <name>3/4</name>
+      <key>C3_4</key>
+      <opt>val:dtv.C3_4</opt>
+    </option>
+    <option>
+      <name>5/6</name>
+      <key>C5_6</key>
+      <opt>val:dtv.C5_6</opt>
+    </option>
+    <option>
+      <name>7/8</name>
+      <key>C7_8</key>
+      <opt>val:dtv.C7_8</opt>
+    </option>
+  </param>
+  <param>
+    <name>Type</name>
+    <key>type</key>
+    <type>enum</type>
+    <option>
+      <name>Int</name>
+      <key>i</key>
+      <opt>io:int</opt>
+    </option>
+    <option>
+      <name>Short</name>
+      <key>s</key>
+      <opt>io:short</opt>
+    </option>
+    <option>
+      <name>Byte</name>
+      <key>b</key>
+      <opt>io:byte</opt>
+    </option>
+  </param>
+  <param>
+    <name>Block Size</name>
+    <key>block_size</key>
+    <type>int</type>
+  </param>
+  <sink>
+    <name>in</name>
+    <type>byte</type>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>$type.io</type>
+  </source>
+</block>
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_bit_inner_deinterleaver.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_bit_inner_deinterleaver.h
new file mode 100644
index 0000000..1f9aab1
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_bit_inner_deinterleaver.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_BIT_INNER_DEINTERLEVER_H
+#define INCLUDED_DTV_DVBT_BIT_INNER_DEINTERLEVER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief Bit Inner deinterleaver.
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 Clause 4.3.4.1 \n
+     * Data Input format: \n
+     * 000000B0B1 - QPSK. \n
+     * 0000B0B1B2B3 - 16QAM. \n
+     * 00B0B1B2B3B4B5 - 64QAM. \n
+     * Data Output format: \n
+     * 000000X0X1 - QPSK. \n
+     * 0000X0X1X2X3 - 16QAM. \n
+     * 00X0X1X2X3X4X5 - 64QAM. \n
+     * bit deinterleaver block size is 126.
+     */
+    class DTV_API dvbt_bit_inner_deinterleaver : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_bit_inner_deinterleaver> sptr;
+
+      /*!
+       * \brief Create a Bit Inner deinterleaver
+       *
+       * \param nsize length of input stream. \n
+       * \param constellation constellation used. \n
+       * \param hierarchy hierarchy used. \n
+       * \param transmission transmission mode used.
+       */
+      static sptr make(int nsize, dvb_constellation_t constellation, 
dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_BIT_INNER_DEINTERLEVER_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_convolutional_deinterleaver.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_convolutional_deinterleaver.h
new file mode 100644
index 0000000..1a52c41
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_convolutional_deinterleaver.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_CONVOLUTIONAL_DEINTERLEAVER_H
+#define INCLUDED_DTV_DVBT_CONVOLUTIONAL_DEINTERLEAVER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief Convolutional deinterleaver.
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 Clause 4.3.1 \n
+     * Forney (Ramsey type III) convolutional deinterleaver. \n
+     * Data input: Stream of 1 byte elements. \n
+     * Data output: Blocks of I bytes size.
+     */
+    class DTV_API dvbt_convolutional_deinterleaver : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_convolutional_deinterleaver> sptr;
+
+      /*!
+       * \brief Create a DVB-T convolutional deinterleaver.
+       *
+       * \param nsize number of blocks to process. \n
+       * \param I size of a block. \n
+       * \param M depth length for each element in shift registers.
+       */
+      static sptr make(int nsize, int I, int M);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_CONVOLUTIONAL_DEINTERLEAVER_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_demap.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_demap.h
new file mode 100644
index 0000000..1f04bee
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_demap.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_DVBT_DEMAP_H
+#define INCLUDED_DTV_DVBT_DVBT_DEMAP_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief DVB-T demapper.
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 Clause 4.3.5. \n
+     * Data input format: \n
+     * complex(real(float), imag(float)). \n
+     * Data output format: \n
+     * 000000Y0Y1 - QPSK. \n
+     * 0000Y0Y1Y2Y3 - 16QAM. \n
+     * 00Y0Y1Y2Y3Y4Y5 - 64QAM.
+     */
+    class DTV_API dvbt_demap : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_demap> sptr;
+
+      /*!
+       * \brief Create a DVB-T demapper.
+       *
+       * \param nsize length of input stream. \n
+       * \param constellation constellation used. \n
+       * \param hierarchy hierarchy used. \n
+       * \param transmission transmission mode used. \n
+       * \param gain gain of complex input stream.
+       */
+      static sptr make(int nsize, dvb_constellation_t constellation, 
dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission, float gain);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_DVBT_DEMAP_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_demod_reference_signals.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_demod_reference_signals.h
new file mode 100644
index 0000000..3f28dde
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_demod_reference_signals.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_DEMOD_REFERENCE_SIGNALS_H
+#define INCLUDED_DTV_DVBT_DEMOD_REFERENCE_SIGNALS_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief Reference signals demodulator.
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 Clause 4.5 \n
+     * Data input format: \n
+     * complex(real(float), imag(float)). \n
+     * Data output format: \n
+     * complex(real(float), imag(float)).
+     */
+    class DTV_API dvbt_demod_reference_signals : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_demod_reference_signals> sptr;
+
+      /*!
+       * \brief Create Reference signals demodulator.
+       *
+       * \param itemsize size of an in/out item. \n
+       * \param ninput input stream length. \n
+       * \param noutput output stream length. \n
+       * \param constellation constellation used. \n
+       * \param hierarchy hierarchy used. \n
+       * \param code_rate_HP high priority stream code rate. \n
+       * \param code_rate_LP low priority stream code rate. \n
+       * \param guard_interval guard interval used. \n
+       * \param transmission_mode transmission mode used. \n
+       * \param include_cell_id include or not Cell ID. \n
+       * \param cell_id value of the Cell ID.
+       */
+      static sptr make(int itemsize, int ninput, int noutput, \
+        dvb_constellation_t constellation, dvbt_hierarchy_t hierarchy, \
+        dvb_code_rate_t code_rate_HP, dvb_code_rate_t code_rate_LP, \
+        dvb_guardinterval_t guard_interval, dvbt_transmission_mode_t 
transmission_mode, \
+        int include_cell_id, int cell_id);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_DEMOD_REFERENCE_SIGNALS_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_energy_descramble.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_energy_descramble.h
new file mode 100644
index 0000000..6d50da1
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_energy_descramble.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_ENERGY_DESCRAMBLE_H
+#define INCLUDED_DTV_DVBT_ENERGY_DESCRAMBLE_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief Energy descramble
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 - Clause 4.3.1. \n
+     * Input - Randomized MPEG-2 transport packets. \n
+     * Output - MPEG-2 transport packets (including sync - 0x47). \n
+     * We assume the first byte is a NSYNC. \n
+     * First sync in a row of 8 packets is reversed - 0xB8. \n
+     * Block size is 188 bytes
+     */
+    class DTV_API dvbt_energy_descramble : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_energy_descramble> sptr;
+
+      /*!
+       * \brief Create DVB-T Energy descramble.
+       *
+       * \param nblocks number of blocks.
+       */
+      static sptr make(int nblocks);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_ENERGY_DESCRAMBLE_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_ofdm_sym_acquisition.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_ofdm_sym_acquisition.h
new file mode 100644
index 0000000..ced054d
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_ofdm_sym_acquisition.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_OFDM_SYM_ACQUISITION_H
+#define INCLUDED_DTV_DVBT_OFDM_SYM_ACQUISITION_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief OFDM symbol acquisition.
+     * \ingroup dtv
+     *
+     * Data input format: \n
+     * complex(real(float), imag(float)). \n
+     * Data output format: \n
+     * complex(real(float), imag(float)).
+     */
+    class DTV_API dvbt_ofdm_sym_acquisition : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_ofdm_sym_acquisition> sptr;
+
+      /*!
+       * \brief Create OFDM symbol acquisition.
+       *
+       * \param blocks Always equal to 1.\n
+       * \param fft_length FFT size, 2048 or 8192. \n
+       * \param occupied_tones Active OFDM carriers, 1705 or 6817. \n
+       * \param cp_length Length of Cyclic Prefix (FFT size / 32, 16, 8 or 4). 
\n
+       * \param snr Initial Signal to Noise Ratio.
+       */
+      static sptr make(int blocks, int fft_length, int occupied_tones, int 
cp_length, float snr);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_OFDM_SYM_ACQUISITION_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_reed_solomon_dec.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_reed_solomon_dec.h
new file mode 100644
index 0000000..5ef8e04
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_reed_solomon_dec.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_H
+#define INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief Reed Solomon decoder.
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 Clause 4.3.2 \n
+     * RS(N=204,K=239,T=8).
+     */
+    class DTV_API dvbt_reed_solomon_dec : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_reed_solomon_dec> sptr;
+
+      /*!
+       * \brief Create a Reed Solomon decoder.
+       *
+       * \param p characteristic of GF(p^m).
+       * \param m we use GF(p^m).
+       * \param gfpoly Generator Polynomial.
+       * \param n length of codeword of RS coder.
+       * \param k length of information sequence of RS decoder.
+       * \param t number of corrected errors.
+       * \param s shortened length.
+       * \param blocks number of blocks to process at once.
+       */
+      static sptr make(int p, int m, int gfpoly, int n, int k, int t, int s, 
int blocks);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_viterbi_decoder.h 
b/gr-dtv/include/gnuradio/dtv/dvbt_viterbi_decoder.h
new file mode 100644
index 0000000..b44ec4f
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_viterbi_decoder.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_VITERBI_DECODER_H
+#define INCLUDED_DTV_DVBT_VITERBI_DECODER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+
+namespace gr {
+  namespace dtv {
+
+    /*!
+     * \brief DVB-T Viterbi decoder.
+     * \ingroup dtv
+     *
+     * ETSI EN 300 744 Clause 4.3.3 \n
+     * Mother convolutional code with rate 1/2. \n
+     * k=1, n=2, K=6. \n
+     * Generator polynomial G1=171(OCT), G2=133(OCT). \n
+     * Punctured to obtain rates of 2/3, 3/4, 5/6, 7/8. \n
+     * Data Input format: \n
+     * 000000X0X1 - QPSK. \n
+     * 0000X0X1X2X3 - 16QAM. \n
+     * 00X0X1X2X3X4X5 - 64QAM. \n
+     * Data Output format: Packed bytes (each bit is data). \n
+     * MSB - first, LSB last.
+     */
+    class DTV_API dvbt_viterbi_decoder : virtual public block
+    {
+     public:
+      typedef boost::shared_ptr<dvbt_viterbi_decoder> sptr;
+
+      /*!
+       * \brief Create a DVB-T Viterbi decoder.
+       *
+       * \param constellation constellation used. \n
+       * \param hierarchy hierarchy used. \n
+       * \param coderate coderate used. \n
+       * \param bsize block size.
+       */
+      static sptr make(dvb_constellation_t constellation, \
+                  dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate, int 
bsize);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_VITERBI_DECODER_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_bit_inner_deinterleaver_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_bit_inner_deinterleaver_impl.cc
new file mode 100644
index 0000000..bf7613a
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_bit_inner_deinterleaver_impl.cc
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_bit_inner_deinterleaver_impl.h"
+#include <stdio.h>
+
+namespace gr {
+  namespace dtv {
+
+    const int dvbt_bit_inner_deinterleaver_impl::d_bsize = 126;
+
+    int
+    dvbt_bit_inner_deinterleaver_impl::H(int e, int w)
+    {
+      int rez = 0;
+
+      switch (e) {
+        case 0:
+          rez = w;
+          break;
+        case 1:
+          rez = (w + 63) % d_bsize;
+          break;
+        case 2:
+          rez = (w + 105) % d_bsize;
+          break;
+        case 3:
+          rez = (w + 42) % d_bsize;
+          break;
+        case 4:
+          rez = (w + 21) % d_bsize;
+          break;
+        case 5:
+          rez = (w + 84) % d_bsize;
+          break;
+        default:
+          break;
+      }
+
+      return rez;
+    }
+
+    dvbt_bit_inner_deinterleaver::sptr
+    dvbt_bit_inner_deinterleaver::make(int nsize, \
+        dvb_constellation_t constellation, dvbt_hierarchy_t hierarchy, 
dvbt_transmission_mode_t transmission)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_bit_inner_deinterleaver_impl(nsize, constellation, 
hierarchy, transmission));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_bit_inner_deinterleaver_impl::dvbt_bit_inner_deinterleaver_impl(int 
nsize, dvb_constellation_t constellation, \
+        dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission)
+      : block("dvbt_bit_inner_deinterleaver",
+          io_signature::make(1, 1, sizeof (unsigned char) * nsize),
+          io_signature::make(1, 2, sizeof (unsigned char) * nsize)),
+      config(constellation, hierarchy, gr::dtv::C1_2, gr::dtv::C1_2, 
gr::dtv::GI_1_32, transmission),
+      d_nsize(nsize),
+      d_hierarchy(hierarchy)
+    {
+      d_v = config.d_m;
+      d_hierarchy = config.d_hierarchy;
+
+      d_perm = (unsigned char *)new unsigned char[d_v * d_bsize];
+      if (d_perm == NULL) {
+        std::cout << "Cannot allocate memory for d_perm" << std::endl;
+        exit(1);
+      }
+
+      //Init permutation table (used for b[e][do])
+      for (int i = 0; i <  d_bsize * d_v; i++) {
+        if (d_hierarchy == NH) {
+          d_perm[i] = ((i % d_v) / (d_v / 2)) + 2 * (i % (d_v / 2));
+        }
+        else {
+          d_perm[i] = (i % (d_v - 2)) / ((d_v - 2) / 2) + 2 * (i % ((d_v - 2) 
/ 2)) + 2;
+        }
+      }
+
+      if (d_nsize % d_bsize) {
+        std::cout << "Error: Input size must be multiple of block size: " \
+          << "nsize: " << d_nsize << "bsize: " << d_bsize << std::endl;
+      }
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_bit_inner_deinterleaver_impl::~dvbt_bit_inner_deinterleaver_impl()
+    {
+      delete [] d_perm;
+    }
+
+    void
+    dvbt_bit_inner_deinterleaver_impl::forecast (int noutput_items, 
gr_vector_int &ninput_items_required)
+    {
+      ninput_items_required[0] = noutput_items;
+    }
+
+    int
+    dvbt_bit_inner_deinterleaver_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      const unsigned char *in = (const unsigned char *) input_items[0];
+      unsigned char *outh = (unsigned char *) output_items[0];
+      unsigned char *outl = (unsigned char *) output_items[1];
+
+      int bmax = noutput_items * d_nsize / d_bsize;
+
+      // First index of d_b is Bit interleaver number
+      // Second index of d_b is the position inside Bit interleaver
+      unsigned char d_b[d_v][d_bsize];
+
+      for (int bcount = 0; bcount < bmax; bcount++) {
+        for (int w = 0; w < d_bsize; w++) {
+          int c = in[(bcount * d_bsize) + w];
+
+          for (int e = 0; e < d_v; e++) {
+            d_b[e][H(e, w)] = (c >> (d_v - e - 1)) & 1;
+          }
+        }
+
+        for (int i = 0; i < d_bsize; i++) {
+          if (d_hierarchy == NH) {
+            // Create output from demultiplexer
+            int c = 0;
+
+            for (int k = 0; k < d_v; k++) {
+              c = (c << 1) | d_b[d_perm[(d_v * i) + k]][i];
+            }
+
+            outh[(bcount * d_bsize) + i] = c;
+          }
+          else {
+            int c = 0;
+
+            // High priority output - first 2 streams
+            for (int k = 0; k < 2; k++) {
+              c = (c << 1) | d_b[(d_v * i + k) % 2][(d_v * i + k) / 2];
+            }
+
+            outh[(bcount * d_bsize) + i] = c;
+
+            c = 0;
+            // Low priority output - (v - 2) streams
+            for (int k = 2; k < (d_v - 2); k++) {
+              c = (c << 1) | d_b[d_perm[d_v * i + k]][(d_v * i + k) / (d_v - 
2)];
+            }
+
+            outl[(bcount * d_bsize) + i] = c;
+          }
+        }
+      }
+
+      // Tell runtime system how many input items we consumed on
+      // each input stream.
+      consume_each (noutput_items);
+
+      // Tell runtime system how many output items we produced.
+      return noutput_items;
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_bit_inner_deinterleaver_impl.h 
b/gr-dtv/lib/dvbt/dvbt_bit_inner_deinterleaver_impl.h
new file mode 100644
index 0000000..9f38113
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_bit_inner_deinterleaver_impl.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_BIT_INNER_DEINTERLEVER_IMPL_H
+#define INCLUDED_DTV_DVBT_BIT_INNER_DEINTERLEVER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_bit_inner_deinterleaver.h>
+#include "dvbt_configure.h"
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_bit_inner_deinterleaver_impl : public 
dvbt_bit_inner_deinterleaver
+    {
+     private:
+      const dvbt_configure config;
+
+      int d_nsize;
+      dvbt_hierarchy_t d_hierarchy;
+
+      // constellation
+      int d_v;
+      // Bit interleaver block size
+      static const int d_bsize;
+
+      // Table to keep interleaved indices
+      unsigned char * d_perm;
+
+      // Permutation function
+      int H(int e, int w);
+
+     public:
+      dvbt_bit_inner_deinterleaver_impl(int nsize, dvb_constellation_t 
constellation, dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t 
transmission);
+      ~dvbt_bit_inner_deinterleaver_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_BIT_INNER_DEINTERLEVER_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_convolutional_deinterleaver_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_convolutional_deinterleaver_impl.cc
new file mode 100644
index 0000000..0358ada
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_convolutional_deinterleaver_impl.cc
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_convolutional_deinterleaver_impl.h"
+
+namespace gr {
+  namespace dtv {
+
+    const int dvbt_convolutional_deinterleaver_impl::d_SYNC = 0x47;
+    const int dvbt_convolutional_deinterleaver_impl::d_NSYNC = 0xB8;
+    const int dvbt_convolutional_deinterleaver_impl::d_MUX_PKT = 8;
+
+    dvbt_convolutional_deinterleaver::sptr
+    dvbt_convolutional_deinterleaver::make(int nsize, int I, int M)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_convolutional_deinterleaver_impl(nsize, I, M));
+    }
+
+    /*
+     * The private constructor
+     */
+    
dvbt_convolutional_deinterleaver_impl::dvbt_convolutional_deinterleaver_impl(int
 blocks, int I, int M)
+      : block("dvbt_convolutional_deinterleaver",
+          io_signature::make(1, 1, sizeof (unsigned char)),
+          io_signature::make(1, 1, sizeof (unsigned char) * I * blocks)),
+      d_blocks(blocks), d_I(I), d_M(M)
+    {
+      set_relative_rate(1.0 / d_I * d_blocks);
+      set_output_multiple(2);
+      //The positions are shift registers (FIFOs)
+      //of length i*M
+      for (int i = (d_I - 1); i >= 0; i--) {
+        d_shift.push_back(new std::deque<unsigned char>(d_M * i, 0));
+      }
+
+      // There are 8 mux packets
+      assert(d_blocks / d_M == d_MUX_PKT);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    
dvbt_convolutional_deinterleaver_impl::~dvbt_convolutional_deinterleaver_impl()
+    {
+      for (unsigned int i = 0; i < d_shift.size(); i++) {
+        delete d_shift.back();
+        d_shift.pop_back();
+      }
+    }
+
+    void
+    dvbt_convolutional_deinterleaver_impl::forecast (int noutput_items, 
gr_vector_int &ninput_items_required)
+    {
+      int ninputs = ninput_items_required.size ();
+
+      for (int i = 0; i < ninputs; i++) {
+        ninput_items_required[i] = noutput_items * d_I * d_blocks;
+      }
+    }
+
+
+    int
+    dvbt_convolutional_deinterleaver_impl::general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      const unsigned char *in = (const unsigned char *) input_items[0];
+      unsigned char *out = (unsigned char *) output_items[0];
+
+      int to_out = noutput_items;
+
+      /*
+       * Look for a tag that signals superframe_start and consume all input 
items
+       * that are in input buffer so far.
+       * This will actually reset the convolutional deinterleaver
+       */
+      std::vector<tag_t> tags;
+      const uint64_t nread = this->nitems_read(0); //number of items read on 
port 0
+      this->get_tags_in_range(tags, 0, nread, nread + (noutput_items * d_I * 
d_blocks), pmt::string_to_symbol("superframe_start"));
+
+      if (tags.size()) {
+        if (tags[0].offset - nread) {
+          consume_each(tags[0].offset - nread);
+          return (0);
+        }
+      }
+
+      /*
+       * At this moment the first item in input buffer should be NSYNC or SYNC
+       */
+
+      for (int count = 0, i = 0; i < to_out; i++) {
+        for (int mux_pkt = 0; mux_pkt < d_MUX_PKT; mux_pkt++) {
+          // This is actually the deinterleaver
+          for (int k = 0; k < (d_M * d_I); k++) {
+            d_shift[k % d_I]->push_back(in[count]);
+            out[count++] = d_shift[k % d_I]->front();
+            d_shift[k % d_I]->pop_front();
+          }
+        }
+      }
+
+      // Tell runtime system how many input items we consumed on
+      // each input stream.
+      consume_each(d_I * d_blocks * to_out);
+
+      // Tell runtime system how many output items we produced.
+      return (to_out);
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_convolutional_deinterleaver_impl.h 
b/gr-dtv/lib/dvbt/dvbt_convolutional_deinterleaver_impl.h
new file mode 100644
index 0000000..7b3fafe
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_convolutional_deinterleaver_impl.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_CONVOLUTIONAL_DEINTERLEAVER_IMPL_H
+#define INCLUDED_DTV_DVBT_CONVOLUTIONAL_DEINTERLEAVER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_convolutional_deinterleaver.h>
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_convolutional_deinterleaver_impl : public 
dvbt_convolutional_deinterleaver
+    {
+     private:
+      static const int d_SYNC;
+      static const int d_NSYNC;
+      static const int d_MUX_PKT;
+
+      int d_blocks;
+      int d_I;
+      int d_M;
+      std::vector< std::deque<unsigned char> * > d_shift;
+
+     public:
+      dvbt_convolutional_deinterleaver_impl(int nsize, int I, int M);
+      ~dvbt_convolutional_deinterleaver_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_CONVOLUTIONAL_DEINTERLEAVER_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_demap_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_demap_impl.cc
new file mode 100644
index 0000000..4bdec1d
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_demap_impl.cc
@@ -0,0 +1,185 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_demap_impl.h"
+#include <volk/volk.h>
+#include <stdio.h>
+
+namespace gr {
+  namespace dtv {
+
+    dvbt_demap::sptr
+    dvbt_demap::make(int nsize, dvb_constellation_t constellation, 
dvbt_hierarchy_t hierarchy, \
+        dvbt_transmission_mode_t transmission, float gain)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_demap_impl(nsize, constellation, hierarchy, transmission, 
gain));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_demap_impl::dvbt_demap_impl(int nsize, dvb_constellation_t 
constellation, dvbt_hierarchy_t hierarchy, \
+        dvbt_transmission_mode_t transmission, float gain)
+      : block("dvbt_demap",
+          io_signature::make(1, 1, sizeof (gr_complex) * nsize),
+          io_signature::make(1, 1, sizeof (unsigned char) * nsize)),
+      config(constellation, hierarchy, gr::dtv::C1_2, gr::dtv::C1_2, 
gr::dtv::GI_1_32, transmission),
+      d_nsize(nsize),
+      d_constellation_size(0),
+      d_step(0),
+      d_alpha(0),
+      d_gain(0.0)
+    {
+      //Get parameters from config object
+      d_constellation_size = config.d_constellation_size;
+      d_transmission_mode = config.d_transmission_mode;
+      d_step = config.d_step;
+      d_alpha = config.d_alpha;
+      d_gain = gain * config.d_norm;
+
+      d_constellation_points = (gr_complex*) volk_malloc(sizeof(gr_complex) * 
d_constellation_size, volk_get_alignment());
+      if (d_constellation_points == NULL) {
+        std::cout << "cannot allocate memory for d_constellation_points" << 
std::endl;
+        exit(1);
+      }
+
+      d_sq_dist = (float*) volk_malloc(sizeof(float) * d_constellation_size, 
volk_get_alignment());
+      if (d_sq_dist == NULL) {
+        std::cout << "cannot allocate memory for d_sq_dist" << std::endl;
+        volk_free(d_constellation_points);
+        exit(1);
+      }
+
+      make_constellation_points(d_constellation_size, d_step, d_alpha);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_demap_impl::~dvbt_demap_impl()
+    {
+      volk_free(d_sq_dist);
+      volk_free(d_constellation_points);
+    }
+
+    void
+    dvbt_demap_impl::make_constellation_points(int size, int step, int alpha)
+    {
+      // The symmetry of the constellation is used to calculate
+      // 16QAM from QPSK and 64QAM from 16QAM
+
+      int bits_per_axis = log2(size) / 2;
+      int steps_per_axis = sqrt(size) / 2 - 1;
+
+      for (int i = 0; i < size; i++) {
+        // This is the quadrant made of the first two bits starting from MSB
+        int q = i >> (2 * (bits_per_axis - 1)) & 3;
+        // Sign for correct calculation of I and Q in each quadrant
+        int sign0 = (q >> 1) ? -1 : 1; int sign1 = (q & 1) ? -1 : 1;
+
+        int x = (i >> (bits_per_axis - 1)) & ((1 << (bits_per_axis - 1)) - 1);
+        int y = i & ((1 << (bits_per_axis - 1)) - 1);
+
+        int xval = alpha + (steps_per_axis - x) * step;
+        int yval = alpha + (steps_per_axis - y) * step;
+
+        int val = (bin_to_gray(x) << (bits_per_axis - 1)) + bin_to_gray(y);
+
+        // ETSI EN 300 744 Clause 4.3.5
+        // Actually the constellation is gray coded
+        // but the bits on each axis are not taken in consecutive order
+        // So we need to convert from b0b2b4b1b3b5->b0b1b2b3b4b5(64QAM)
+
+        x = 0; y = 0;
+
+        for (int j = 0; j < (bits_per_axis - 1); j++) {
+          x += ((val >> (1 + 2 * j)) & 1) << j;
+          y += ((val >> (2 * j)) & 1) << j;
+        }
+
+        val = (q << 2 * (bits_per_axis - 1)) + (x << (bits_per_axis - 1)) + y;
+
+        // Keep corresponding symbol bits->complex symbol in one vector
+        // Normalize the signal using gain
+        d_constellation_points[val] = d_gain * gr_complex(sign0 * xval, sign1 
* yval);
+      }
+    }
+
+    int
+    dvbt_demap_impl::find_constellation_value(gr_complex val)
+    {
+      float min_dist = std::norm(val - d_constellation_points[0]);
+      int min_index = 0;
+
+      volk_32fc_x2_square_dist_32f(&d_sq_dist[0], &val, 
&d_constellation_points[0], d_constellation_size);
+
+      for (int i = 0; i < d_constellation_size; i++) {
+        if (d_sq_dist[i] < min_dist) {
+          min_dist = d_sq_dist[i];
+          min_index = i;
+        }
+      }
+
+      //return d_constellation_bits[min_index];
+      return min_index;
+    }
+
+    int
+    dvbt_demap_impl::bin_to_gray(int val)
+    {
+      return (val >> 1) ^ val;
+    }
+
+    void
+    dvbt_demap_impl::forecast (int noutput_items, gr_vector_int 
&ninput_items_required)
+    {
+      ninput_items_required[0] = noutput_items;
+    }
+
+    int
+    dvbt_demap_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      const gr_complex *in = (const gr_complex *) input_items[0];
+      unsigned char *out = (unsigned char *) output_items[0];
+
+      // TODO - use DFE (Decision Feedback Equalizer)
+
+      for (int i = 0; i < (noutput_items * d_nsize); i++) {
+        out[i] = find_constellation_value(in[i]);
+      }
+
+      consume_each (noutput_items);
+
+      // Tell runtime system how many output items we produced.
+      return noutput_items;
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_demap_impl.h 
b/gr-dtv/lib/dvbt/dvbt_demap_impl.h
new file mode 100644
index 0000000..020578b
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_demap_impl.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_DVBT_DEMAP_IMPL_H
+#define INCLUDED_DTV_DVBT_DVBT_DEMAP_IMPL_H
+
+#include <gnuradio/dtv/dvbt_demap.h>
+#include "dvbt_configure.h"
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_demap_impl : public dvbt_demap
+    {
+     private:
+      const dvbt_configure config;
+
+      int d_nsize;
+
+      //Constellation size
+      unsigned char d_constellation_size;
+      //Transmission mode
+      dvbt_transmission_mode_t d_transmission_mode;
+      //Step on each axis of the constellation
+      unsigned char d_step;
+      //Keep Alpha internally
+      unsigned char d_alpha;
+      //Gain for the complex values
+      float d_gain;
+
+      gr_complex * d_constellation_points;
+      float * d_sq_dist;
+
+      void make_constellation_points(int size, int step, int alpha);
+      int find_constellation_value(gr_complex val);
+      int bin_to_gray(int val);
+
+     public:
+      dvbt_demap_impl(int nsize, dvb_constellation_t constellation, 
dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission, float gain);
+      ~dvbt_demap_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_DVBT_DEMAP_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.cc
new file mode 100644
index 0000000..e9ee864
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.cc
@@ -0,0 +1,152 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_demod_reference_signals_impl.h"
+
+namespace gr {
+  namespace dtv {
+
+    dvbt_demod_reference_signals::sptr
+    dvbt_demod_reference_signals::make(int itemsize, int ninput, int noutput, \
+        dvb_constellation_t constellation, dvbt_hierarchy_t hierarchy, \
+        dvb_code_rate_t code_rate_HP, dvb_code_rate_t code_rate_LP, \
+        dvb_guardinterval_t guard_interval, dvbt_transmission_mode_t 
transmission_mode, \
+        int include_cell_id, int cell_id)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_demod_reference_signals_impl(itemsize, ninput, \
+            noutput, constellation, hierarchy, code_rate_HP, code_rate_LP, \
+            guard_interval, transmission_mode, include_cell_id, cell_id));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_demod_reference_signals_impl::dvbt_demod_reference_signals_impl(int 
itemsize, int ninput, int noutput, \
+        dvb_constellation_t constellation, dvbt_hierarchy_t hierarchy, 
dvb_code_rate_t code_rate_HP,\
+          dvb_code_rate_t code_rate_LP, dvb_guardinterval_t guard_interval,\
+          dvbt_transmission_mode_t transmission_mode, int include_cell_id, int 
cell_id)
+      : block("dvbt_demod_reference_signals",
+          io_signature::make(1, 1, itemsize * ninput),
+          io_signature::make(1, 1, itemsize * noutput)),
+          config(constellation, hierarchy, code_rate_HP, code_rate_LP, \
+            guard_interval, transmission_mode, include_cell_id, cell_id),
+          d_pg(config),
+          d_init(0),
+          d_fi_start(0)
+    {
+      d_ninput = ninput;
+      d_noutput = noutput;
+
+      // TODO - investigate why this is happening
+      if ((config.d_constellation == MOD_64QAM) && (config.d_transmission_mode 
== T8k))
+        d_fi_start = 2;
+      else
+        d_fi_start = 3;
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_demod_reference_signals_impl::~dvbt_demod_reference_signals_impl()
+    {
+    }
+
+    void
+    dvbt_demod_reference_signals_impl::forecast (int noutput_items, 
gr_vector_int &ninput_items_required)
+    {
+      int ninputs = ninput_items_required.size();
+
+      for (int i = 0; i < ninputs; i++)
+        ninput_items_required[i] =  2 * noutput_items;
+    }
+
+    int
+    dvbt_demod_reference_signals_impl::is_sync_start(int nitems)
+    {
+      std::vector<tag_t> tags;
+      const uint64_t nread = this->nitems_read(0); //number of items read on 
port 0
+      this->get_tags_in_range(tags, 0, nread, nread + nitems, 
pmt::string_to_symbol("sync_start"));
+
+      return tags.size() ? 1 : 0;
+    }
+
+    int
+    dvbt_demod_reference_signals_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      const gr_complex *in = (const gr_complex *) input_items[0];
+      gr_complex *out = (gr_complex *) output_items[0];
+
+      int symbol_index, frame_index;
+      int to_out = 0;
+
+      for (int i = 0; i < noutput_items; i++) {
+        to_out += d_pg.parse_input(&in[i * d_ninput], &out[i * d_noutput], 
&symbol_index, &frame_index);
+      }
+
+      /*
+       * Wait for a sync_start tag from upstream that signals when to start.
+       * Allways consume until to a superframe start.
+       */
+      if (is_sync_start(noutput_items)) {
+        d_init = 0;
+      }
+
+      if (d_init == 0) {
+        // This is super-frame start
+        if (((symbol_index % 68) == 0) && ((frame_index % 4) == d_fi_start)) {
+          d_init = 1;
+
+          const uint64_t offset = this->nitems_written(0);
+          pmt::pmt_t key = pmt::string_to_symbol("superframe_start");
+          pmt::pmt_t value = pmt::from_long(0xaa);
+          this->add_item_tag(0, offset, key, value);
+        }
+        else {
+          consume_each(1);
+          return (0);
+        }
+      }
+
+      // Send a tag for each OFDM symbol informing about
+      // symbol index.
+      const uint64_t offset = this->nitems_written(0);
+      pmt::pmt_t key = pmt::string_to_symbol("symbol_index");
+      pmt::pmt_t value = pmt::from_long(symbol_index);
+      this->add_item_tag(0, offset, key, value);
+
+      // Consume from input stream
+      consume_each (noutput_items);
+
+      // Tell runtime system how many output items we produced.
+      return to_out;
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.h 
b/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.h
new file mode 100644
index 0000000..1c7f5fd
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_demod_reference_signals_impl.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_DEMOD_REFERENCE_SIGNALS_IMPL_H
+#define INCLUDED_DTV_DVBT_DEMOD_REFERENCE_SIGNALS_IMPL_H
+
+#include <gnuradio/dtv/dvbt_demod_reference_signals.h>
+#include "dvbt_reference_signals_impl.h"
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_demod_reference_signals_impl : public 
dvbt_demod_reference_signals
+    {
+      // configuration object for this class
+      const dvbt_configure config;
+
+     private:
+      // Pilot Generator object
+      dvbt_pilot_gen d_pg;
+
+      //In and Out data length
+      int d_ninput;
+      int d_noutput;
+
+      int d_init;
+      int d_fi_start;
+
+      int is_sync_start(int nitems);
+
+     public:
+      dvbt_demod_reference_signals_impl(int itemsize, int ninput, int noutput, 
\
+        dvb_constellation_t constellation, dvbt_hierarchy_t hierarchy, \
+        dvb_code_rate_t code_rate_HP, dvb_code_rate_t code_rate_LP, \
+        dvb_guardinterval_t guard_interval, \
+        dvbt_transmission_mode_t transmission_mode = gr::dtv::T2k, int 
include_cell_id = 0, int cell_id = 0);
+      ~dvbt_demod_reference_signals_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_DEMOD_REFERENCE_SIGNALS_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.cc
new file mode 100644
index 0000000..6b47814
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.cc
@@ -0,0 +1,156 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_energy_descramble_impl.h"
+
+namespace gr {
+  namespace dtv {
+
+    const int dvbt_energy_descramble_impl::d_nblocks = 8;
+    const int dvbt_energy_descramble_impl::d_bsize = 188;
+    const int dvbt_energy_descramble_impl::d_SYNC = 0x47;
+    const int dvbt_energy_descramble_impl::d_NSYNC = 0xB8;
+    const int dvbt_energy_descramble_impl::d_MUX_PKT = 8;
+
+    void
+    dvbt_energy_descramble_impl::init_prbs()
+    {
+      d_reg = 0xa9;
+    }
+
+    int
+    dvbt_energy_descramble_impl::clock_prbs(int clocks)
+    {
+      int res = 0;
+      int feedback = 0;
+
+      for(int i = 0; i < clocks; i++) {
+        feedback = ((d_reg >> (14 - 1)) ^ (d_reg >> (15 - 1))) & 0x1;
+        d_reg = ((d_reg << 1) | feedback) & 0x7fff;
+
+        res = (res << 1) | feedback;
+      }
+
+      return res;
+    }
+
+    dvbt_energy_descramble::sptr
+    dvbt_energy_descramble::make(int nblocks)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_energy_descramble_impl(nblocks));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_energy_descramble_impl::dvbt_energy_descramble_impl(int nblocks)
+      : block("dvbt_energy_descramble",
+          io_signature::make(1, 1, sizeof (unsigned char) * d_nblocks * 
d_bsize),
+          io_signature::make(1, 1, sizeof (unsigned char))),
+      d_reg(0xa9), d_index(0), d_search(0)
+    {
+      set_relative_rate((double) (d_nblocks * d_bsize));
+
+      // Set output multiple of (2 search + 1 data = 3) at least (4 for now)
+      set_output_multiple(4 * d_nblocks * d_bsize);
+
+      // Search interval for NSYNC is 2 * 8 * MUX size
+      d_search = 2 * (d_nblocks * d_bsize);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_energy_descramble_impl::~dvbt_energy_descramble_impl()
+    {
+    }
+
+    void
+    dvbt_energy_descramble_impl::forecast (int noutput_items, gr_vector_int 
&ninput_items_required)
+    {
+      ninput_items_required[0] = 4 * (noutput_items / (d_nblocks * d_bsize));
+    }
+
+    int
+    dvbt_energy_descramble_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      const unsigned char *in = (const unsigned char *) input_items[0];
+      unsigned char *out = (unsigned char *) output_items[0];
+
+      int to_consume, to_out;
+
+      // Search for a NSYNC
+      while ((in[d_index] != d_NSYNC) && (d_index < d_search)) {
+        d_index += d_bsize;
+      }
+
+      /*
+       * If we did not find a NSYNC then just consume
+       * and return 0.
+       */
+      if (d_index >= d_search) {
+        d_index = 0;
+        to_consume = 2;
+        to_out = 0;
+      }
+      else {
+        // We found a NSYNC, descramble the data
+
+        to_consume = (noutput_items / (d_nblocks * d_bsize)) - 2;
+        to_out = noutput_items - 2 * (d_nblocks * d_bsize);
+
+        for (int count = 0, i = 0; i < to_consume; i++) {
+          init_prbs();
+
+          for (int mux_pkt = 0; mux_pkt < d_MUX_PKT; mux_pkt++) {
+            out[count++] = d_SYNC;
+            // PRBS clocking starts right after NSYNC
+
+            for (int k = 1; k < d_bsize; k++) {
+              out[count] = in[d_index + count] ^ clock_prbs(d_nblocks);
+              count++;
+            }
+
+            // For subsequent blocks PRBS is clocked also on SYNC
+            // but its output is not used
+            clock_prbs(d_nblocks);
+          }
+        }
+      }
+
+      // Tell runtime how many input items we consumed
+      consume_each(to_consume);
+
+      // Tell runtime system how many output items we produced.
+      return (to_out);
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.h 
b/gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.h
new file mode 100644
index 0000000..8681732
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_energy_descramble_impl.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_ENERGY_DESCRAMBLE_IMPL_H
+#define INCLUDED_DTV_DVBT_ENERGY_DESCRAMBLE_IMPL_H
+
+#include <gnuradio/dtv/dvbt_energy_descramble.h>
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_energy_descramble_impl : public dvbt_energy_descramble
+    {
+     private:
+      static const int d_nblocks;
+      static const int d_bsize;
+      static const int d_SYNC;
+      static const int d_NSYNC;
+      static const int d_MUX_PKT;
+
+      // Register for PRBS
+      int d_reg;
+
+      // Index
+      int d_index;
+      // Search interval
+      int d_search;
+
+      void init_prbs();
+      int clock_prbs(int clocks);
+
+     public:
+      dvbt_energy_descramble_impl(int nblocks);
+      ~dvbt_energy_descramble_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_ENERGY_DESCRAMBLE_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.cc
new file mode 100644
index 0000000..2383c54
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.cc
@@ -0,0 +1,417 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_ofdm_sym_acquisition_impl.h"
+#include <complex>
+#include <gnuradio/math.h>
+#include <gnuradio/expj.h>
+#include <stdio.h>
+#include <volk/volk.h>
+
+namespace gr {
+  namespace dtv {
+
+    int
+    dvbt_ofdm_sym_acquisition_impl::peak_detect_init(float 
threshold_factor_rise, float threshold_factor_fall, int look_ahead, float alpha)
+    {
+      d_avg_alpha = alpha;
+      d_threshold_factor_rise = threshold_factor_rise;
+      d_threshold_factor_fall = threshold_factor_fall;
+      d_avg = 0;
+
+      return (0);
+    }
+
+    int
+    dvbt_ofdm_sym_acquisition_impl::peak_detect_process(const float * datain, 
const int datain_length, int * peak_pos, int * peak_max)
+    {
+      int state = 0;
+      float peak_val = -(float)INFINITY; int peak_index = 0; int 
peak_pos_length = 0;
+
+      int i = 0;
+
+      while(i < datain_length) {
+        if (state == 0) {
+          if (datain[i] > d_avg * d_threshold_factor_rise) {
+            state = 1;
+          }
+          else {
+            d_avg = d_avg_alpha * datain[i] + (1 - d_avg_alpha) * d_avg;
+            i++;
+          }
+        }
+        else if (state == 1) {
+          if (datain[i] > peak_val) {
+            peak_val = datain[i];
+            peak_index = i;
+            d_avg = d_avg_alpha * datain[i] + (1 - d_avg_alpha) * d_avg;
+            i++;
+          }
+          else if (datain[i] > d_avg * d_threshold_factor_fall) {
+            d_avg = (d_avg_alpha) * datain[i] + (1 - d_avg_alpha) * d_avg;
+            i++;
+          }
+          else {
+            peak_pos[peak_pos_length] = peak_index;
+            peak_pos_length++;
+            state = 0;
+            peak_val = - (float)INFINITY;
+          }
+        }
+      }
+
+      // Find peak of peaks
+      if (peak_pos_length) {
+        float max = datain[peak_pos[0]];
+        int maxi = 0;
+
+        for (int i = 1; i < peak_pos_length; i++) {
+          if (datain[peak_pos[i]] > max) {
+            max = datain[peak_pos[i]];
+            maxi = i;
+          }
+        }
+
+        *peak_max = maxi;
+      }
+
+      return (peak_pos_length);
+    }
+
+    int
+    dvbt_ofdm_sym_acquisition_impl::ml_sync(const gr_complex * in, int 
lookup_start, int lookup_stop, int * cp_pos, gr_complex * derot, int * 
to_consume, int * to_out)
+    {
+      assert(lookup_start >= lookup_stop);
+      assert(lookup_stop >= (d_cp_length + d_fft_length - 1));
+
+      int low, size;
+
+      // Array to store peak positions
+      int peak_pos[d_fft_length];
+      float d_phi[d_fft_length];
+
+      // Calculate norm
+      low = lookup_stop - (d_cp_length + d_fft_length - 1);
+      size = lookup_start - (lookup_stop - (d_cp_length + d_fft_length - 1)) + 
1;
+
+      volk_32fc_magnitude_squared_32f(&d_norm[low], &in[low], size);
+
+      // Calculate gamma on each point
+#ifdef SEGFAULT_FIX
+      low = lookup_stop - d_cp_length + 1;
+      size = lookup_start - (lookup_stop - d_cp_length + 1) + 1;
+#else
+      low = lookup_stop - d_cp_length - 1;
+      size = lookup_start - (lookup_stop - d_cp_length - 1) + 1;
+#endif
+      volk_32fc_x2_multiply_conjugate_32fc(&d_corr[low - d_fft_length], 
&in[low], &in[low - d_fft_length], size);
+
+      // Calculate time delay and frequency correction
+      // This looks like spaghetti code but it is fast
+      for (int i = lookup_start - 1; i >= lookup_stop; i--) {
+        int k = i - lookup_stop;
+
+        d_phi[k] = 0.0;
+        d_gamma[k] = 0.0;
+
+        // Moving sum for calculating gamma and phi
+        for (int j = 0; j < d_cp_length; j++) {
+          // Calculate gamma and store it
+          d_gamma[k] += d_corr[i - j - d_fft_length];
+          // Calculate phi and store it
+          d_phi[k] += d_norm[i - j] + d_norm[i - j - d_fft_length];
+        }
+      }
+
+      // Init lambda with gamma
+      low = 0;
+      size = lookup_start - lookup_stop;
+
+      volk_32fc_magnitude_32f(&d_lambda[low], &d_gamma[low], size);
+
+      // Calculate lambda
+      low = 0;
+      size = lookup_start - lookup_stop;
+
+      volk_32f_s32f_multiply_32f(&d_phi[low], &d_phi[low], d_rho / 2.0, size);
+      volk_32f_x2_subtract_32f(&d_lambda[low], &d_lambda[low], &d_phi[low], 
size);
+
+      int peak_length, peak, peak_max;
+      // Find peaks of lambda
+      // We have found an end of symbol at peak_pos[0] + CP + FFT
+      if ((peak_length = peak_detect_process(&d_lambda[0], (lookup_start - 
lookup_stop), &peak_pos[0], &peak_max))) {
+        peak = peak_pos[peak_max] + lookup_stop;
+        *cp_pos = peak;
+
+        // Calculate frequency correction
+        float peak_epsilon = fast_atan2f(d_gamma[peak_pos[peak_max]]);
+        double sensitivity = (double)(-1) / (double)d_fft_length;
+
+        // Store phases for derotating the signal
+        // We always process CP len + FFT len
+        for (int i = 0; i < (d_cp_length + d_fft_length); i++) {
+          if (i == d_nextpos) {
+            d_phaseinc = d_nextphaseinc;
+          }
+
+          // We are interested only in fft_length
+          d_phase += d_phaseinc;
+
+          while (d_phase > (float)M_PI) {
+            d_phase -= (float)(2.0 * M_PI);
+          }
+          while (d_phase < (float)(-M_PI)) {
+            d_phase += (float)(2.0 * M_PI);
+          }
+
+          derot[i] = gr_expj(d_phase);
+        }
+
+        d_nextphaseinc = sensitivity * peak_epsilon;
+        d_nextpos = peak - (d_cp_length + d_fft_length);
+
+        *to_consume = d_cp_length + d_fft_length;
+        *to_out = 1;
+      }
+      else {
+        for (int i = 0; i < (d_cp_length + d_fft_length); i++) {
+          d_phase += d_phaseinc;
+
+          while (d_phase > (float)M_PI) {
+            d_phase -= (float)(2.0 * M_PI);
+          }
+          while (d_phase < (float)(-M_PI)) {
+            d_phase += (float)(2.0 * M_PI);
+          }
+        }
+
+        // We consume only fft_length
+        *to_consume = d_cp_length + d_fft_length;
+        *to_out = 0;
+      }
+
+      return (peak_length);
+    }
+
+    void
+    dvbt_ofdm_sym_acquisition_impl::send_sync_start()
+    {
+      const uint64_t offset = this->nitems_written(0);
+      pmt::pmt_t key = pmt::string_to_symbol("sync_start");
+      pmt::pmt_t value = pmt::from_long(1);
+      this->add_item_tag(0, offset, key, value);
+    }
+
+    dvbt_ofdm_sym_acquisition::sptr
+    dvbt_ofdm_sym_acquisition::make(int blocks, int fft_length, int 
occupied_tones, int cp_length, float snr)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_ofdm_sym_acquisition_impl(blocks, fft_length, 
occupied_tones, cp_length, snr));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_ofdm_sym_acquisition_impl::dvbt_ofdm_sym_acquisition_impl(int blocks, 
int fft_length, int occupied_tones, int cp_length, float snr)
+      : block("dvbt_ofdm_sym_acquisition",
+          io_signature::make(1, 1, sizeof (gr_complex) * blocks),
+          io_signature::make(1, 1, sizeof (gr_complex) * blocks * fft_length)),
+      d_blocks(blocks), d_fft_length(fft_length), d_cp_length(cp_length), 
d_snr(snr),
+      d_index(0), d_phase(0.0), d_phaseinc(0.0), d_cp_found(0), d_count(0), 
d_nextphaseinc(0), d_nextpos(0), \
+        d_sym_acq_count(0),d_sym_acq_timeout(100), d_initial_acquisition(0), \
+        d_freq_correction_count(0), d_freq_correction_timeout(0)
+    {
+      set_relative_rate(1.0 / (double) (d_cp_length + d_fft_length));
+
+      d_snr = pow(10, d_snr / 10.0);
+      d_rho = d_snr / (d_snr + 1.0);
+
+      d_gamma = (gr_complex*) volk_malloc(sizeof(gr_complex) * d_fft_length, 
volk_get_alignment());
+      if (d_gamma == NULL) {
+        std::cout << "cannot allocate memory for d_gamma" << std::endl;
+        exit(1);
+      }
+
+      d_lambda = (float*) volk_malloc(sizeof(float) * d_fft_length, 
volk_get_alignment());
+      if (d_lambda == NULL) {
+        std::cout << "cannot allocate memory for d_lambda" << std::endl;
+        volk_free(d_gamma);
+        exit(1);
+      }
+
+      d_derot = (gr_complex*) volk_malloc(sizeof(gr_complex) * (d_fft_length + 
d_cp_length), volk_get_alignment());
+      if (d_derot == NULL) {
+        std::cout << "cannot allocate memory for d_derot" << std::endl;
+        volk_free(d_lambda);
+        volk_free(d_gamma);
+        exit(1);
+      }
+
+      d_conj = (gr_complex*) volk_malloc(sizeof(gr_complex) * (2 * 
d_fft_length + d_cp_length), volk_get_alignment());
+      if (d_conj == NULL) {
+        std::cout << "cannot allocate memory for d_conj" << std::endl;
+        volk_free(d_derot);
+        volk_free(d_lambda);
+        volk_free(d_gamma);
+        exit(1);
+      }
+
+      d_norm = (float*) volk_malloc(sizeof(float) * (2 * d_fft_length + 
d_cp_length), volk_get_alignment());
+      if (d_norm == NULL) {
+        std::cout << "cannot allocate memory for d_norm" << std::endl;
+        volk_free(d_conj);
+        volk_free(d_derot);
+        volk_free(d_lambda);
+        volk_free(d_gamma);
+        exit(1);
+      }
+
+      d_corr = (gr_complex*) volk_malloc(sizeof(gr_complex) * (2 * 
d_fft_length + d_cp_length), volk_get_alignment());
+      if (d_corr == NULL) {
+        std::cout << "cannot allocate memory for d_corr" << std::endl;
+        volk_free(d_norm);
+        volk_free(d_conj);
+        volk_free(d_derot);
+        volk_free(d_lambda);
+        volk_free(d_gamma);
+        exit(1);
+      }
+
+      peak_detect_init(0.8, 0.9, 30, 0.9);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_ofdm_sym_acquisition_impl::~dvbt_ofdm_sym_acquisition_impl()
+    {
+      volk_free(d_corr);
+      volk_free(d_norm);
+      volk_free(d_conj);
+      volk_free(d_derot);
+      volk_free(d_lambda);
+      volk_free(d_gamma);
+    }
+
+    void
+    dvbt_ofdm_sym_acquisition_impl::forecast (int noutput_items, gr_vector_int 
&ninput_items_required)
+    {
+      int ninputs = ninput_items_required.size();
+
+      // make sure we receive at least (symbol_length + fft_length)
+      for (int i = 0; i < ninputs; i++) {
+        ninput_items_required[i] = (2 * d_fft_length + d_cp_length) * 
noutput_items;
+      }
+    }
+
+    /*
+     * ML Estimation of Time and Frequency Offset in OFDM systems
+     * Jan-Jaap van de Beek
+     */
+
+    int
+    dvbt_ofdm_sym_acquisition_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+        const gr_complex *in = (const gr_complex *) input_items[0];
+        gr_complex *out = (gr_complex *) output_items[0];
+
+        int low, size;
+
+        // This is initial acquisition of symbol start
+        // TODO - make a FSM
+        if (!d_initial_acquisition) {
+          d_initial_acquisition = ml_sync(in, 2 * d_fft_length + d_cp_length - 
1, d_fft_length + d_cp_length - 1, \
+              &d_cp_start, &d_derot[0], &d_to_consume, &d_to_out);
+
+#ifdef SEGFAULT_FIX
+          d_cp_start_initial = d_cp_start;
+          d_cp_start_slip = 0;
+#endif
+          // Send sync_start downstream
+          send_sync_start();
+        }
+
+        // This is fractional frequency correction (pre FFT)
+        // It is also called coarse frequency correction
+        if (d_initial_acquisition) {
+#ifdef SEGFAULT_FIX
+          d_cp_found = ml_sync(in, d_cp_start + 16, d_cp_start, \
+              &d_cp_start, &d_derot[0], &d_to_consume, &d_to_out);
+#else
+          d_cp_found = ml_sync(in, d_cp_start + 8, d_cp_start - 8, \
+              &d_cp_start, &d_derot[0], &d_to_consume, &d_to_out);
+#endif
+
+          if (d_cp_found) {
+            d_freq_correction_count = 0;
+
+#ifdef SEGFAULT_FIX
+            // detect and ignore false peaks
+            if (d_cp_start != d_cp_start_initial) {
+              d_cp_start_slip++;
+              if (d_cp_start_slip == 2) {
+                d_cp_start_slip = 0;
+              }
+              else {
+                d_cp_start = d_cp_start_initial;
+              }
+            }
+            else {
+              d_cp_start_slip = 0;
+            }
+#endif
+
+            // Derotate the signal and out
+            low = d_cp_start - d_fft_length + 1;
+            size = d_cp_start - (d_cp_start - d_fft_length + 1) + 1;
+
+            volk_32fc_x2_multiply_32fc(&out[0], &d_derot[0], &in[low], size);
+          }
+          else {
+            // If we have a number of consecutive misses then we restart 
acquisition
+            if (++d_freq_correction_count > d_freq_correction_timeout) {
+              d_initial_acquisition = 0;
+              d_freq_correction_count = 0;
+
+              // Restart with a half number so that we'll not endup with the 
same situation
+              // This will prevent peak_detect to not detect anything
+              d_to_consume = d_to_consume / 2;
+            }
+          }
+        }
+
+        // Tell runtime system how many input items we consumed on
+        // each input stream.
+        consume_each(d_to_consume);
+
+        // Tell runtime system how many output items we produced.
+        return (d_to_out);
+    }
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.h 
b/gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.h
new file mode 100644
index 0000000..7190ec5
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_ofdm_sym_acquisition_impl.h
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_OFDM_SYM_ACQUISITION_IMPL_H
+#define INCLUDED_DTV_DVBT_OFDM_SYM_ACQUISITION_IMPL_H
+
+#include <gnuradio/dtv/dvbt_ofdm_sym_acquisition.h>
+
+#undef SEGFAULT_FIX
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_ofdm_sym_acquisition_impl : public dvbt_ofdm_sym_acquisition
+    {
+     private:
+      int d_blocks;
+      int d_fft_length;
+      int d_cp_length;
+      float d_snr;
+      float d_rho;
+
+      int d_index;
+
+      int d_search_max;
+
+      gr_complex * d_conj;
+      float * d_norm;
+      gr_complex * d_corr;
+      gr_complex * d_gamma;
+      float * d_lambda;
+      float * d_arg;
+
+      // For peak detector
+      float d_threshold_factor_rise;
+      float d_threshold_factor_fall;
+      float d_avg_alpha;
+      float d_avg;
+      float d_phase;
+      double d_phaseinc;
+      int d_cp_found;
+      int d_count;
+      double d_nextphaseinc;
+      int d_nextpos;
+
+      int d_sym_acq_count;
+      int d_sym_acq_timeout;
+
+      int d_initial_acquisition;
+
+      int d_freq_correction_count;
+      int d_freq_correction_timeout;
+
+      int d_cp_start;
+
+#ifdef SEGFAULT_FIX
+      int d_cp_start_initial;
+      int d_cp_start_slip;
+#endif
+
+      gr_complex * d_derot;
+      int d_to_consume;
+      int d_to_out;
+
+      int ml_sync(const gr_complex * in, int lookup_start, int lookup_stop, 
int * cp_pos, gr_complex * derot, int * to_consume, int * to_out);
+
+      int peak_detect_init(float threshold_factor_rise, float 
threshold_factor_fall, int look_ahead, float alpha);
+
+      int peak_detect_process(const float * datain, const int datain_length, 
int * peak_pos, int * peak_max);
+
+      void send_sync_start();
+     public:
+      dvbt_ofdm_sym_acquisition_impl(int blocks, int fft_length, int 
occupied_tones, int cp_length, float snr);
+      ~dvbt_ofdm_sym_acquisition_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_OFDM_SYM_ACQUISITION_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc
new file mode 100644
index 0000000..4a5530c
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_reed_solomon_dec_impl.h"
+#include <stdio.h>
+
+namespace gr {
+  namespace dtv {
+
+    dvbt_reed_solomon_dec::sptr
+    dvbt_reed_solomon_dec::make(int p, int m, int gfpoly, int n, int k, int t, 
int s, int blocks)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_reed_solomon_dec_impl(p, m, gfpoly, n, k, t, s, blocks));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_reed_solomon_dec_impl::dvbt_reed_solomon_dec_impl(int p, int m, int 
gfpoly, int n, int k, int t, int s, int blocks)
+      : block("dvbt_reed_solomon_dec",
+          io_signature::make(1, 1, sizeof(unsigned char) * blocks * (n - s)),
+          io_signature::make(1, 1, sizeof(unsigned char) * blocks * (k - s))),
+      d_p(p), d_m(m), d_gfpoly(gfpoly), d_n(n), d_k(k), d_t(t), d_s(s), 
d_blocks(blocks),
+      d_rs(p, m, gfpoly, n, k, t, s, blocks)
+    {
+      d_in = new unsigned char[d_n];
+      if (d_in == NULL) {
+        std::cout << "Cannot allocate memory for d_in" << std::endl;
+        exit(1);
+      }
+      memset(&d_in[0], 0, d_n);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_reed_solomon_dec_impl::~dvbt_reed_solomon_dec_impl()
+    {
+      delete [] d_in;
+    }
+
+    void
+    dvbt_reed_solomon_dec_impl::forecast (int noutput_items, gr_vector_int 
&ninput_items_required)
+    {
+      ninput_items_required[0] = noutput_items;
+    }
+
+    int
+    dvbt_reed_solomon_dec_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      const unsigned char *in = (const unsigned char *) input_items[0];
+      unsigned char *out = (unsigned char *) output_items[0];
+
+      // We receive only nonzero data
+      int in_bsize = d_n - d_s;
+      int out_bsize = d_k - d_s;
+
+      for (int i = 0; i < (d_blocks * noutput_items); i++) {
+        //TODO - zero copy?
+        // Set first d_s symbols to zero
+        memset(&d_in[0], 0, d_s);
+        // Then copy actual data
+        memcpy(&d_in[d_s], &in[i * in_bsize], in_bsize);
+
+        d_rs.rs_decode(d_in, NULL, 0);
+
+        memcpy(&out[i * out_bsize], &d_in[d_s], out_bsize);
+      }
+
+      // Tell runtime system how many input items we consumed on
+      // each input stream.
+      consume_each (noutput_items);
+
+      // Tell runtime system how many output items we produced.
+      return noutput_items;
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h
new file mode 100644
index 0000000..951aa4b
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_IMPL_H
+#define INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_IMPL_H
+
+#include <gnuradio/dtv/dvbt_reed_solomon_dec.h>
+#include "dvbt_reed_solomon.h"
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_reed_solomon_dec_impl : public dvbt_reed_solomon_dec
+    {
+     private:
+      int d_p;
+      int d_m;
+      int d_gfpoly;
+      int d_n;
+      int d_k;
+      int d_t;
+      int d_s;
+      int d_blocks;
+
+      unsigned char * d_in;
+
+      dvbt_reed_solomon d_rs;
+
+     public:
+      dvbt_reed_solomon_dec_impl(int p, int m, int gfpoly, int n, int k, int 
t, int s, int blocks);
+      ~dvbt_reed_solomon_dec_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc
new file mode 100644
index 0000000..4f2362c
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc
@@ -0,0 +1,495 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dvbt_viterbi_decoder_impl.h"
+#include <stdio.h>
+
+namespace gr {
+  namespace dtv {
+
+    const unsigned char dvbt_viterbi_decoder_impl::d_puncture_1_2[2] = {1, 1};
+    const unsigned char dvbt_viterbi_decoder_impl::d_puncture_2_3[4] = {1, 1, 
0, 1};
+    const unsigned char dvbt_viterbi_decoder_impl::d_puncture_3_4[6] = {1, 1, 
0, 1, 1, 0};
+    const unsigned char dvbt_viterbi_decoder_impl::d_puncture_5_6[10] = {1, 1, 
0, 1, 1, 0, 0, 1, 1, 0};
+    const unsigned char dvbt_viterbi_decoder_impl::d_puncture_7_8[14] = {1, 1, 
0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0};
+    /* 8-bit parity lookup table, generated by partab.c */
+    const unsigned char dvbt_viterbi_decoder_impl::d_Partab[] = {
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      0, 1, 1, 0, 1, 0, 0, 1,
+      1, 0, 0, 1, 0, 1, 1, 0,
+    };
+
+    __m128i dvbt_viterbi_decoder_impl::d_metric0[4] __attribute__ 
((aligned(16)));
+    __m128i dvbt_viterbi_decoder_impl::d_metric1[4] __attribute__ 
((aligned(16)));
+    __m128i dvbt_viterbi_decoder_impl::d_path0[4] __attribute__ 
((aligned(16)));
+    __m128i dvbt_viterbi_decoder_impl::d_path1[4] __attribute__ 
((aligned(16)));
+
+    branchtab27 dvbt_viterbi_decoder_impl::Branchtab27_sse2[2] __attribute__ 
((aligned(16)));
+
+    unsigned char dvbt_viterbi_decoder_impl::mmresult[64] 
__attribute__((aligned(16)));
+    unsigned char dvbt_viterbi_decoder_impl::ppresult[TRACEBACK_MAX][64] 
__attribute__((aligned(16)));
+
+    void
+    dvbt_viterbi_decoder_impl::dvbt_viterbi_chunks_init_sse2(__m128i *mm0, 
__m128i *pp0)
+    {
+      // Initialize starting metrics to prefer 0 state
+      int i, j;
+
+      for (i = 0; i < 4; i++) {
+        mm0[i] = _mm_setzero_si128();
+        pp0[i] = _mm_setzero_si128();
+      }
+
+      int polys[2] = { POLYA, POLYB };
+      for (i = 0; i < 32; i++) {
+        Branchtab27_sse2[0].c[i] = (polys[0] < 0) ^ d_Partab[(2*i) & 
abs(polys[0])] ? 1 : 0;
+        Branchtab27_sse2[1].c[i] = (polys[1] < 0) ^ d_Partab[(2*i) & 
abs(polys[1])] ? 1 : 0;
+      }
+
+      for (i = 0; i < 64; i++) {
+        mmresult[i] = 0;
+        for (j = 0; j < TRACEBACK_MAX; j++) {
+          ppresult[j][i] = 0;
+        }
+      }
+    }
+
+    void
+    dvbt_viterbi_decoder_impl::dvbt_viterbi_butterfly2_sse2(unsigned char 
*symbols, __m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1)
+    {
+      int i;
+
+      __m128i *metric0, *metric1;
+      __m128i *path0, *path1;
+
+      metric0 = mm0;
+      path0 = pp0;
+      metric1 = mm1;
+      path1 = pp1;
+
+      // Operate on 4 symbols (2 bits) at a time
+
+      __m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1;
+      __m128i metsv, metsvm;
+      __m128i shift0, shift1;
+      __m128i tmp0, tmp1;
+      __m128i sym0v, sym1v;
+
+      sym0v = _mm_set1_epi8(symbols[0]);
+      sym1v = _mm_set1_epi8(symbols[1]);
+
+      for (i = 0; i < 2; i++) {
+        if (symbols[0] == 2) {
+          metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v);
+          metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
+        }
+        else if (symbols[1] == 2) {
+          metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v);
+          metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
+        }
+        else {
+          metsvm = 
_mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v));
+          metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
+        }
+
+        m0 = _mm_add_epi8(metric0[i], metsv);
+        m1 = _mm_add_epi8(metric0[i+2], metsvm);
+        m2 = _mm_add_epi8(metric0[i], metsvm);
+        m3 = _mm_add_epi8(metric0[i+2], metsv);
+
+        decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
+        decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
+        survivor0 = 
_mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
+        survivor1 = 
_mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
+
+        shift0 = _mm_slli_epi16(path0[i], 1);
+        shift1 = _mm_slli_epi16(path0[2+i], 1);
+        shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
+
+        metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
+        tmp0 = 
_mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
+
+        metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
+        tmp1 = 
_mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
+
+        path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
+        path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
+      }
+
+      metric0 = mm1;
+      path0 = pp1;
+      metric1 = mm0;
+      path1 = pp0;
+
+      sym0v = _mm_set1_epi8(symbols[2]);
+      sym1v = _mm_set1_epi8(symbols[3]);
+
+      for (i = 0; i < 2; i++) {
+        if (symbols[2] == 2) {
+          metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v);
+          metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
+        }
+        else if (symbols[3] == 2) {
+          metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v);
+          metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
+        }
+        else {
+          metsvm = 
_mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v));
+          metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
+        }
+
+        m0 = _mm_add_epi8(metric0[i], metsv);
+        m1 = _mm_add_epi8(metric0[i+2], metsvm);
+        m2 = _mm_add_epi8(metric0[i], metsvm);
+        m3 = _mm_add_epi8(metric0[i+2], metsv);
+
+        decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
+        decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
+        survivor0 = 
_mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
+        survivor1 = 
_mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
+
+        shift0 = _mm_slli_epi16(path0[i], 1);
+        shift1 = _mm_slli_epi16(path0[2+i], 1);
+        shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
+
+        metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
+        tmp0 = 
_mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
+
+        metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
+        tmp1 = 
_mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
+
+        path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
+        path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
+      }
+    }
+
+    unsigned char
+    dvbt_viterbi_decoder_impl::dvbt_viterbi_get_output_sse2(__m128i *mm0, 
__m128i *pp0, int ntraceback, unsigned char *outbuf)
+    {
+      //  Find current best path
+      int i;
+      int bestmetric, minmetric;
+      int beststate = 0;
+      int pos = 0;
+
+      // Implement a circular buffer with the last ntraceback paths
+      store_pos = (store_pos + 1) % ntraceback;
+
+      // TODO - find another way to extract the value
+      for (i = 0; i < 4; i++) {
+        _mm_store_si128((__m128i *) &mmresult[i*16], mm0[i]);
+        _mm_store_si128((__m128i *) &ppresult[store_pos][i*16], pp0[i]);
+      }
+
+      // Find out the best final state
+      bestmetric = mmresult[beststate];
+      minmetric = mmresult[beststate];
+
+      for (i = 1; i < 64; i++) {
+        if (mmresult[i] > bestmetric) {
+          bestmetric = mmresult[i];
+          beststate = i;
+        }
+        if (mmresult[i] < minmetric) {
+          minmetric = mmresult[i];
+        }
+      }
+
+      // Trace back
+      for (i = 0, pos = store_pos; i < (ntraceback - 1); i++) {
+        // Obtain the state from the output bits
+        // by clocking in the output bits in reverse order.
+        // The state has only 6 bits
+        beststate = ppresult[pos][beststate] >> 2;
+        pos = (pos - 1 + ntraceback) % ntraceback;
+      }
+
+      // Store output byte
+      *outbuf = ppresult[pos][beststate];
+
+      // Zero out the path variable
+      // and prevent metric overflow
+      for (i = 0; i < 4; i++) {
+        pp0[i] = _mm_setzero_si128();
+        mm0[i] = _mm_sub_epi8(mm0[i], _mm_set1_epi8(minmetric));
+      }
+
+      return bestmetric;
+    }
+
+    dvbt_viterbi_decoder::sptr
+    dvbt_viterbi_decoder::make(dvb_constellation_t constellation, \
+                dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate, int 
bsize)
+    {
+      return gnuradio::get_initial_sptr
+        (new dvbt_viterbi_decoder_impl(constellation, hierarchy, coderate, 
bsize));
+    }
+
+    /*
+     * The private constructor
+     */
+    dvbt_viterbi_decoder_impl::dvbt_viterbi_decoder_impl(dvb_constellation_t 
constellation, \
+                dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate, int 
bsize)
+      : block("dvbt_viterbi_decoder",
+          io_signature::make(1, 1, sizeof (unsigned char)),
+          io_signature::make(1, 1, sizeof (unsigned char))),
+      config(constellation, hierarchy, coderate, coderate),
+      d_bsize(bsize),
+      d_init(0),
+      store_pos(0)
+    {
+      //Determine k - input of encoder
+      d_k = config.d_cr_k;
+      //Determine n - output of encoder
+      d_n = config.d_cr_n;
+      //Determine m - constellation symbol size
+      d_m = config.d_m;
+      // Determine puncturing vector and traceback
+      if (config.d_code_rate_HP == C1_2) {
+        d_puncture = d_puncture_1_2;
+        d_ntraceback = 5;
+      }
+      else if (config.d_code_rate_HP == C2_3) {
+        d_puncture = d_puncture_2_3;
+        d_ntraceback = 9;
+      }
+      else if (config.d_code_rate_HP == C3_4) {
+        d_puncture = d_puncture_3_4;
+        d_ntraceback = 10;
+      }
+      else if (config.d_code_rate_HP == C5_6) {
+        d_puncture = d_puncture_5_6;
+        d_ntraceback = 15;
+      }
+      else if (config.d_code_rate_HP == C7_8) {
+        d_puncture = d_puncture_7_8;
+        d_ntraceback = 24;
+      }
+      else {
+        d_puncture = d_puncture_1_2;
+        d_ntraceback = 5;
+      }
+
+      /*
+       * We input n bytes, each carrying m bits => nm bits
+       * The result after decoding is km bits, therefore km/8 bytes.
+       *
+       * out/in rate is therefore km/8n in bytes
+       */
+      assert((d_k * d_m) % (8 * d_n));
+      set_relative_rate((d_k * d_m) / (8 * d_n));
+
+      assert ((d_bsize * d_n) % d_m == 0);
+      set_output_multiple (d_bsize * d_k / 8);
+
+      /*
+       * Calculate process variables:
+       * Number of symbols (d_m bits) in all blocks
+       * It is also the number of input bytes since
+       * one byte always contains just one symbol.
+       */
+      d_nsymbols = d_bsize * d_n / d_m;
+      // Number of bits after depuncturing a block (before decoding)
+      d_nbits = 2 * d_k * d_bsize;
+      // Number of output bytes after decoding
+      d_nout = d_nbits / 2 / 8;
+
+      // Allocate the buffer for the bits
+      d_inbits = new unsigned char [d_nbits];
+      if (d_inbits == NULL) {
+        std::cout << "Cannot allocate memory for d_inbits" << std::endl;
+        exit(1);
+      }
+
+      mettab[0][0] = 1;
+      mettab[0][1] = 0;
+      mettab[1][0] = 0;
+      mettab[1][1] = 1;
+
+      dvbt_viterbi_chunks_init_sse2(d_metric0, d_path0);
+    }
+
+    /*
+     * Our virtual destructor.
+     */
+    dvbt_viterbi_decoder_impl::~dvbt_viterbi_decoder_impl()
+    {
+      delete [] d_inbits;
+    }
+
+    void
+    dvbt_viterbi_decoder_impl::forecast (int noutput_items, gr_vector_int 
&ninput_items_required)
+    {
+      int input_required = noutput_items * 8 * d_n / (d_k * d_m);
+
+      unsigned ninputs = ninput_items_required.size();
+      for (unsigned int i = 0; i < ninputs; i++) {
+        ninput_items_required[i] = input_required;
+      }
+    }
+
+    int
+    dvbt_viterbi_decoder_impl::general_work (int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+    {
+      int nstreams = input_items.size();
+      int nblocks = 8 * noutput_items / (d_bsize * d_k);
+      int out_count = 0;
+
+      for (int m = 0; m < nstreams; m++) {
+        const unsigned char *in = (const unsigned char *) input_items[m];
+        unsigned char *out = (unsigned char *) output_items[m];
+
+        /*
+         * Look for a tag that signals superframe_start and consume all input 
items
+         * that are in input buffer so far.
+         * This will actually reset the viterbi decoder.
+         */
+        std::vector<tag_t> tags;
+        const uint64_t nread = this->nitems_read(0); //number of items read on 
port 0
+        this->get_tags_in_range(tags, 0, nread, nread + (nblocks * 
d_nsymbols), pmt::string_to_symbol("superframe_start"));
+
+        if (tags.size()) {
+          d_init = 0;
+          dvbt_viterbi_chunks_init_sse2(d_metric0, d_path0);
+
+          if (tags[0].offset - nread) {
+            consume_each(tags[0].offset - nread);
+            return (0);
+          }
+        }
+
+        // This is actually the Viterbi decoder
+        for (int n = 0; n < nblocks; n++) {
+          /*
+           * Depuncture and unpack a block.
+           * We receive the symbol (d_m bits/byte) in one byte (e.g. for QAM16 
00001111).
+           * Create a buffer of bytes containing just one bit/byte.
+           * Also depuncture according to the puncture vector.
+           * TODO - reduce the number of branches while depuncturing.
+           */
+          for (int count = 0, i = 0; i < d_nsymbols; i++) {
+            for (int j = (d_m - 1); j >= 0; j--) {
+              // Depuncture
+              while (d_puncture[count % (2 * d_k)] == 0) {
+                d_inbits[count++] = 2;
+              }
+
+              // Insert received bits
+              d_inbits[count++] = (in[(n * d_nsymbols) + i] >> j) & 1;
+
+              // Depuncture
+              while (d_puncture[count % (2 * d_k)] == 0) {
+                d_inbits[count++] = 2;
+              }
+            }
+          }
+
+          /*
+           * Decode a block.
+           */
+          for (int in_count = 0; in_count < d_nbits; in_count++) {
+            if ((in_count % 4) == 0) { // 0 or 3
+              dvbt_viterbi_butterfly2_sse2(&d_inbits[in_count & 0xfffffffc], 
d_metric0, d_metric1, d_path0, d_path1);
+
+              if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
+                unsigned char c;
+
+                dvbt_viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, 
&c);
+
+                if (d_init == 0) {
+                  if (out_count >= d_ntraceback) {
+                    out[out_count - d_ntraceback] = c;
+                  }
+                }
+                else {
+                      out[out_count] = c;
+                }
+                out_count++;
+              }
+            }
+          }
+        }
+      }
+
+      int to_out = noutput_items;
+
+      if (d_init == 0) {
+        /*
+         * Send superframe_start to signal this situation
+         * downstream
+         */
+        const uint64_t offset = this->nitems_written(0);
+        pmt::pmt_t key = pmt::string_to_symbol("superframe_start");
+        pmt::pmt_t value = pmt::from_long(1);
+        this->add_item_tag(0, offset, key, value);
+
+        // Take in consideration the traceback length
+        to_out = to_out - d_ntraceback;
+        d_init = 1;
+      }
+
+      // Tell runtime system how many input items we consumed on
+      // each input stream.
+      consume_each (nblocks * d_nsymbols);
+
+      // Tell runtime system how many output items we produced.
+      return (to_out);
+    }
+
+  } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.h 
b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.h
new file mode 100644
index 0000000..8870a79
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.h
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This 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.
+ * 
+ * This software 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 this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_DVBT_VITERBI_DECODER_IMPL_H
+#define INCLUDED_DTV_DVBT_VITERBI_DECODER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_viterbi_decoder.h>
+#include "dvbt_configure.h"
+#include <xmmintrin.h>
+
+/* The two generator polynomials for the NASA Standard K=7 code.
+ * Since these polynomials are known to be optimal for this constraint
+ * length there is not much point in changing them.
+ */
+
+#define POLYA 0x4f
+#define POLYB 0x6d
+// Maximum number of traceback bytes
+#define TRACEBACK_MAX 24
+
+union branchtab27 {
+  unsigned char c[32];
+  __m128i v[2];
+};
+
+namespace gr {
+  namespace dtv {
+
+    class dvbt_viterbi_decoder_impl : public dvbt_viterbi_decoder
+    {
+     private:
+      dvbt_configure config;
+
+      // Puncturing vectors
+      static const unsigned char d_puncture_1_2[];
+      static const unsigned char d_puncture_2_3[];
+      static const unsigned char d_puncture_3_4[];
+      static const unsigned char d_puncture_5_6[];
+      static const unsigned char d_puncture_7_8[];
+      static const unsigned char d_Partab[];
+
+      static __m128i d_metric0[4];
+      static __m128i d_metric1[4];
+      static __m128i d_path0[4];
+      static __m128i d_path1[4];
+
+      static branchtab27 Branchtab27_sse2[2];
+
+      // Metrics for each state
+      static unsigned char mmresult[64];
+      // Paths for each state
+      static unsigned char ppresult[TRACEBACK_MAX][64];
+
+      // Current puncturing vector
+      const unsigned char * d_puncture;
+
+      // Code rate k/n
+      int d_k;
+      int d_n;
+      // Constellation with m
+      int d_m;
+
+      // Block size
+      int d_bsize;
+      // Symbols to consume on decoding from one block
+      int d_nsymbols;
+      // Number of bits after depuncturing a block
+      int d_nbits;
+      // Number of full packed out bytes
+      int d_nout;
+
+      // Traceback (in bytes)
+      int d_ntraceback;
+
+      // Viterbi tables
+      int mettab[2][256];
+
+      // Buffer to keep the input bits
+      unsigned char * d_inbits;
+
+      // This is used to get rid of traceback on the first frame
+      int d_init;
+
+      // Position in circular buffer where the current decoded byte is stored
+      int store_pos;
+
+      void dvbt_viterbi_chunks_init_sse2(__m128i *mm0, __m128i *pp0);
+      void dvbt_viterbi_butterfly2_sse2(unsigned char *symbols, __m128i m0[], 
__m128i m1[], __m128i p0[], __m128i p1[]);
+      unsigned char dvbt_viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0, 
int ntraceback, unsigned char *outbuf);
+
+     public:
+      dvbt_viterbi_decoder_impl(dvb_constellation_t constellation, \
+                  dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate, int 
bsize);
+      ~dvbt_viterbi_decoder_impl();
+
+      void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_VITERBI_DECODER_IMPL_H */
+



reply via email to

[Prev in Thread] Current Thread [Next in Thread]