[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 01/03: gr-dtv: Add DVB-T transmitter.
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 01/03: gr-dtv: Add DVB-T transmitter. |
Date: |
Wed, 27 May 2015 17:25:37 +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 68a224931f8c15c8f718b0c095bdd2ceb4d7476d
Author: Bogdan Diaconescu <address@hidden>
Date: Thu May 14 03:21:28 2015 -0700
gr-dtv: Add DVB-T transmitter.
---
gr-dtv/examples/dvbt_tx_2k.grc | 2076 ++++++++++++++++++++
gr-dtv/examples/dvbt_tx_8k.grc | 2076 ++++++++++++++++++++
gr-dtv/grc/dtv_dvbt_bit_inner_interleaver.xml | 89 +
gr-dtv/grc/dtv_dvbt_convolutional_interleaver.xml | 43 +
gr-dtv/grc/dtv_dvbt_energy_dispersal.xml | 29 +
gr-dtv/grc/dtv_dvbt_inner_coder.xml | 112 ++
gr-dtv/grc/dtv_dvbt_map.xml | 90 +
gr-dtv/grc/dtv_dvbt_reed_solomon_enc.xml | 70 +
gr-dtv/grc/dtv_dvbt_reference_signals.xml | 222 +++
gr-dtv/grc/dtv_dvbt_symbol_inner_interleaver.xml | 56 +
.../gnuradio/dtv/dvbt_bit_inner_interleaver.h | 67 +
gr-dtv/include/gnuradio/dtv/dvbt_config.h | 45 +
.../gnuradio/dtv/dvbt_convolutional_interleaver.h | 58 +
.../include/gnuradio/dtv/dvbt_energy_dispersal.h | 58 +
gr-dtv/include/gnuradio/dtv/dvbt_inner_coder.h | 69 +
gr-dtv/include/gnuradio/dtv/dvbt_map.h | 65 +
.../include/gnuradio/dtv/dvbt_reed_solomon_enc.h | 61 +
.../include/gnuradio/dtv/dvbt_reference_signals.h | 71 +
.../gnuradio/dtv/dvbt_symbol_inner_interleaver.h | 66 +
gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc | 191 ++
gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.h | 65 +
gr-dtv/lib/dvbt/dvbt_configure.cc | 274 +++
gr-dtv/lib/dvbt/dvbt_configure.h | 103 +
.../dvbt/dvbt_convolutional_interleaver_impl.cc | 89 +
.../lib/dvbt/dvbt_convolutional_interleaver_impl.h | 52 +
gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc | 150 ++
gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.h | 65 +
gr-dtv/lib/dvbt/dvbt_inner_coder_impl.cc | 257 +++
gr-dtv/lib/dvbt/dvbt_inner_coder_impl.h | 78 +
gr-dtv/lib/dvbt/dvbt_map_impl.cc | 163 ++
gr-dtv/lib/dvbt/dvbt_map_impl.h | 72 +
gr-dtv/lib/dvbt/dvbt_reed_solomon.cc | 475 +++++
gr-dtv/lib/dvbt/dvbt_reed_solomon.h | 70 +
gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc | 103 +
gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h | 62 +
gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc | 1280 ++++++++++++
gr-dtv/lib/dvbt/dvbt_reference_signals_impl.h | 258 +++
.../lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc | 225 +++
.../lib/dvbt/dvbt_symbol_inner_interleaver_impl.h | 70 +
39 files changed, 9525 insertions(+)
diff --git a/gr-dtv/examples/dvbt_tx_2k.grc b/gr-dtv/examples/dvbt_tx_2k.grc
new file mode 100644
index 0000000..3db36ae
--- /dev/null
+++ b/gr-dtv/examples/dvbt_tx_2k.grc
@@ -0,0 +1,2076 @@
+<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.8'?>
+<flow_graph>
+ <timestamp>Thu Jan 16 23:00:58 2014</timestamp>
+ <block>
+ <key>dtv_dvbt_bit_inner_interleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_bit_inner_interleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T2k</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(984, 243)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>(8000000.0 * 8) / 7</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(8, 83)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_symbol_inner_interleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_symbol_inner_interleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T2k</value>
+ </param>
+ <param>
+ <key>direction</key>
+ <value>Interleave</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(664, 243)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_const_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>qtgui_const_sink_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>autoscale</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-2</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>xmin</key>
+ <value>-2</value>
+ </param>
+ <param>
+ <key>xmax</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>legend</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(360, 555)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_vector_to_stream</key>
+ <param>
+ <key>id</key>
+ <value>blocks_vector_to_stream_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>num_items</key>
+ <value>2048</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(120, 563)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_energy_dispersal</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_energy_dispersal_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>nsize</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(328, 96)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_reed_solomon_enc</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_reed_solomon_enc_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>p</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>m</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>gfpoly</key>
+ <value>0x11d</value>
+ </param>
+ <param>
+ <key>n</key>
+ <value>255</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>239</value>
+ </param>
+ <param>
+ <key>t</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>s</key>
+ <value>51</value>
+ </param>
+ <param>
+ <key>blocks</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(512, 43)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_convolutional_interleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_convolutional_interleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>blocks</key>
+ <value>136</value>
+ </param>
+ <param>
+ <key>I</key>
+ <value>12</value>
+ </param>
+ <param>
+ <key>M</key>
+ <value>17</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(736, 75)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_inner_coder</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_inner_coder_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>ninput</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>noutput</key>
+ <value>1512</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>code_rate</key>
+ <value>C2_3</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1000, 67)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_map</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_map_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T2k</value>
+ </param>
+ <param>
+ <key>gain</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(344, 227)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>fft_vxx</key>
+ <param>
+ <key>id</key>
+ <value>fft_vxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>2048</value>
+ </param>
+ <param>
+ <key>forward</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>window</key>
+ <value>window.rectangular(2048)</value>
+ </param>
+ <param>
+ <key>shift</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>nthreads</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(64, 403)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_source</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>/run/shm/advtest.ts</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(112, 83)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>uhd_usrp_sink</key>
+ <param>
+ <key>id</key>
+ <value>uhd_usrp_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>fc32</value>
+ </param>
+ <param>
+ <key>otw</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_args</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_chans</key>
+ <value>[]</value>
+ </param>
+ <param>
+ <key>dev_addr</key>
+ <value>"send_frame_size=65536,num_send_frames=128,master_clock_rate=" +
str(samp_rate*4)</value>
+ </param>
+ <param>
+ <key>dev_args</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>sync</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_rate</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>num_mboards</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>clock_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>nchan</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>center_freq0</key>
+ <value>429000000</value>
+ </param>
+ <param>
+ <key>gain0</key>
+ <value>50</value>
+ </param>
+ <param>
+ <key>norm_gain0</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw0</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain1</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain2</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain3</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain4</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain5</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain6</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain7</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain8</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain9</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain10</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain11</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant11</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain12</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant12</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain13</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant13</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain14</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant14</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain15</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant15</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain16</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant16</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain17</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant17</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain18</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant18</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain19</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant19</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain20</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant20</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain21</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant21</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain22</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant22</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain23</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant23</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain24</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant24</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain25</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant25</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain26</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant26</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain27</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant27</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain28</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant28</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain29</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant29</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain30</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant30</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain31</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant31</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>len_tag_name</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(984, 387)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>digital_ofdm_cyclic_prefixer</key>
+ <param>
+ <key>id</key>
+ <value>digital_ofdm_cyclic_prefixer_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>input_size</key>
+ <value>2048</value>
+ </param>
+ <param>
+ <key>cp_len</key>
+ <value>64</value>
+ </param>
+ <param>
+ <key>rolloff</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tagname</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(392, 419)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_multiply_const_vxx</key>
+ <param>
+ <key>id</key>
+ <value>blocks_multiply_const_vxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>const</key>
+ <value>0.0022097087</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(664, 435)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>dvbt_tx_demo</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>thread_safe_setters</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(8, 11)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_reference_signals</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_reference_signals_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>code_rate_hp</key>
+ <value>C2_3</value>
+ </param>
+ <param>
+ <key>code_rate_lp</key>
+ <value>C2_3</value>
+ </param>
+ <param>
+ <key>guard_interval</key>
+ <value>GI_1_32</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T2k</value>
+ </param>
+ <param>
+ <key>include_cell_id</key>
+ <value>cell_ide_no</value>
+ </param>
+ <param>
+ <key>cell_id</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(40, 187)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>digital_ofdm_cyclic_prefixer_0</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fft_vxx_0</source_block_id>
+ <sink_block_id>digital_ofdm_cyclic_prefixer_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
+ <sink_block_id>uhd_usrp_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_file_source_0</source_block_id>
+ <sink_block_id>dtv_dvbt_energy_dispersal_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_energy_dispersal_0</source_block_id>
+ <sink_block_id>dtv_dvbt_reed_solomon_enc_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_convolutional_interleaver_0</source_block_id>
+ <sink_block_id>dtv_dvbt_inner_coder_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_inner_coder_0</source_block_id>
+ <sink_block_id>dtv_dvbt_bit_inner_interleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_bit_inner_interleaver_0</source_block_id>
+ <sink_block_id>dtv_dvbt_symbol_inner_interleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_symbol_inner_interleaver_0</source_block_id>
+ <sink_block_id>dtv_dvbt_map_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_map_0</source_block_id>
+ <sink_block_id>dtv_dvbt_reference_signals_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_reference_signals_0</source_block_id>
+ <sink_block_id>fft_vxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_reference_signals_0</source_block_id>
+ <sink_block_id>blocks_vector_to_stream_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_vector_to_stream_0</source_block_id>
+ <sink_block_id>qtgui_const_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_reed_solomon_enc_0</source_block_id>
+ <sink_block_id>dtv_dvbt_convolutional_interleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-dtv/examples/dvbt_tx_8k.grc b/gr-dtv/examples/dvbt_tx_8k.grc
new file mode 100644
index 0000000..4cad688
--- /dev/null
+++ b/gr-dtv/examples/dvbt_tx_8k.grc
@@ -0,0 +1,2076 @@
+<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.8'?>
+<flow_graph>
+ <timestamp>Thu Jan 16 23:00:58 2014</timestamp>
+ <block>
+ <key>qtgui_const_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>qtgui_const_sink_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>autoscale</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-2</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>xmin</key>
+ <value>-2</value>
+ </param>
+ <param>
+ <key>xmax</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_FREE</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>legend</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(360, 555)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>(8000000.0 * 8) / 7</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(8, 83)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_energy_dispersal</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_energy_dispersal_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>nsize</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(328, 96)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_reed_solomon_enc</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_reed_solomon_enc_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>p</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>m</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>gfpoly</key>
+ <value>0x11d</value>
+ </param>
+ <param>
+ <key>n</key>
+ <value>255</value>
+ </param>
+ <param>
+ <key>k</key>
+ <value>239</value>
+ </param>
+ <param>
+ <key>t</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>s</key>
+ <value>51</value>
+ </param>
+ <param>
+ <key>blocks</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(512, 43)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_convolutional_interleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_convolutional_interleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>blocks</key>
+ <value>136</value>
+ </param>
+ <param>
+ <key>I</key>
+ <value>12</value>
+ </param>
+ <param>
+ <key>M</key>
+ <value>17</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(736, 75)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_source</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>/run/shm/advtest.ts</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(112, 83)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>uhd_usrp_sink</key>
+ <param>
+ <key>id</key>
+ <value>uhd_usrp_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>fc32</value>
+ </param>
+ <param>
+ <key>otw</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_args</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_chans</key>
+ <value>[]</value>
+ </param>
+ <param>
+ <key>dev_addr</key>
+ <value>"send_frame_size=65536,num_send_frames=128,master_clock_rate=" +
str(samp_rate*4)</value>
+ </param>
+ <param>
+ <key>dev_args</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>sync</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_rate</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>num_mboards</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>clock_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>nchan</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>center_freq0</key>
+ <value>429000000</value>
+ </param>
+ <param>
+ <key>gain0</key>
+ <value>50</value>
+ </param>
+ <param>
+ <key>norm_gain0</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw0</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain1</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain2</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain3</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain4</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain5</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain6</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain7</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain8</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain9</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain10</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain11</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant11</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain12</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant12</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain13</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant13</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain14</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant14</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain15</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant15</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain16</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant16</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain17</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant17</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain18</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant18</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain19</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant19</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain20</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant20</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain21</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant21</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain22</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant22</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain23</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant23</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain24</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant24</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain25</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant25</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain26</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant26</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain27</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant27</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain28</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant28</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain29</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant29</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain30</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant30</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>norm_gain31</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ant31</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>len_tag_name</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(984, 387)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_multiply_const_vxx</key>
+ <param>
+ <key>id</key>
+ <value>blocks_multiply_const_vxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>const</key>
+ <value>0.0022097087</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(664, 435)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>dvbt_tx_demo</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>thread_safe_setters</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(8, 11)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_bit_inner_interleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_bit_inner_interleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T8k</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(984, 243)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_symbol_inner_interleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_symbol_inner_interleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T8k</value>
+ </param>
+ <param>
+ <key>direction</key>
+ <value>Interleave</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(664, 243)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_map</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_map_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T8k</value>
+ </param>
+ <param>
+ <key>gain</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(344, 227)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_reference_signals</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_reference_signals_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>code_rate_hp</key>
+ <value>C2_3</value>
+ </param>
+ <param>
+ <key>code_rate_lp</key>
+ <value>C2_3</value>
+ </param>
+ <param>
+ <key>guard_interval</key>
+ <value>GI_1_32</value>
+ </param>
+ <param>
+ <key>transmission_mode</key>
+ <value>T8k</value>
+ </param>
+ <param>
+ <key>include_cell_id</key>
+ <value>cell_ide_no</value>
+ </param>
+ <param>
+ <key>cell_id</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(40, 187)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>fft_vxx</key>
+ <param>
+ <key>id</key>
+ <value>fft_vxx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>8192</value>
+ </param>
+ <param>
+ <key>forward</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>window</key>
+ <value>window.rectangular(8192)</value>
+ </param>
+ <param>
+ <key>shift</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>nthreads</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(64, 403)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_vector_to_stream</key>
+ <param>
+ <key>id</key>
+ <value>blocks_vector_to_stream_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>num_items</key>
+ <value>8192</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(120, 563)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>digital_ofdm_cyclic_prefixer</key>
+ <param>
+ <key>id</key>
+ <value>digital_ofdm_cyclic_prefixer_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>input_size</key>
+ <value>8192</value>
+ </param>
+ <param>
+ <key>cp_len</key>
+ <value>256</value>
+ </param>
+ <param>
+ <key>rolloff</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tagname</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(392, 419)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_dvbt_inner_coder</key>
+ <param>
+ <key>id</key>
+ <value>dtv_dvbt_inner_coder_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>ninput</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>noutput</key>
+ <value>6048</value>
+ </param>
+ <param>
+ <key>constellation</key>
+ <value>64qam</value>
+ </param>
+ <param>
+ <key>hierarchy</key>
+ <value>nh</value>
+ </param>
+ <param>
+ <key>code_rate</key>
+ <value>C2_3</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>comment</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1000, 67)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>digital_ofdm_cyclic_prefixer_0</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fft_vxx_0</source_block_id>
+ <sink_block_id>digital_ofdm_cyclic_prefixer_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
+ <sink_block_id>uhd_usrp_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_file_source_0</source_block_id>
+ <sink_block_id>dtv_dvbt_energy_dispersal_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_energy_dispersal_0</source_block_id>
+ <sink_block_id>dtv_dvbt_reed_solomon_enc_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_convolutional_interleaver_0</source_block_id>
+ <sink_block_id>dtv_dvbt_inner_coder_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_inner_coder_0</source_block_id>
+ <sink_block_id>dtv_dvbt_bit_inner_interleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_bit_inner_interleaver_0</source_block_id>
+ <sink_block_id>dtv_dvbt_symbol_inner_interleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_symbol_inner_interleaver_0</source_block_id>
+ <sink_block_id>dtv_dvbt_map_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_map_0</source_block_id>
+ <sink_block_id>dtv_dvbt_reference_signals_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_reference_signals_0</source_block_id>
+ <sink_block_id>fft_vxx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_reference_signals_0</source_block_id>
+ <sink_block_id>blocks_vector_to_stream_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_vector_to_stream_0</source_block_id>
+ <sink_block_id>qtgui_const_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_dvbt_reed_solomon_enc_0</source_block_id>
+ <sink_block_id>dtv_dvbt_convolutional_interleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-dtv/grc/dtv_dvbt_bit_inner_interleaver.xml
b/gr-dtv/grc/dtv_dvbt_bit_inner_interleaver.xml
new file mode 100644
index 0000000..31f1c2c
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_bit_inner_interleaver.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Bit Inner Interleaver
+###################################################
+ -->
+<block>
+ <name>Bit Inner Interleaver</name>
+ <key>dtv_dvbt_bit_inner_interleaver</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_bit_inner_interleaver($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>
+ <nports>$hierarchy.num_streams</nports>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>$transmission_mode.payload_length</vlen>
+ </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_convolutional_interleaver.xml
b/gr-dtv/grc/dtv_dvbt_convolutional_interleaver.xml
new file mode 100644
index 0000000..04518dd
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_convolutional_interleaver.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Convolutional Interleaver
+###################################################
+ -->
+<block>
+ <name>Convolutional Interleaver</name>
+ <key>dtv_dvbt_convolutional_interleaver</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_convolutional_interleaver($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 > 0</check>
+ <check>$I > 0</check>
+ <check>$M > 0</check>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>$blocks*$I</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>1</vlen>
+ </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_energy_dispersal.xml
b/gr-dtv/grc/dtv_dvbt_energy_dispersal.xml
new file mode 100644
index 0000000..50746c8
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_energy_dispersal.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Energy Dispersal
+###################################################
+ -->
+<block>
+ <name>Energy Dispersal</name>
+ <key>dtv_dvbt_energy_dispersal</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_energy_dispersal($nsize)</make>
+ <param>
+ <name>Blocks(1504 Bytes)</name>
+ <key>nsize</key>
+ <value>8</value>
+ <type>int</type>
+ </param>
+ <check>$nsize > 0</check>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>1</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>1504*$nsize</vlen>
+ </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_inner_coder.xml
b/gr-dtv/grc/dtv_dvbt_inner_coder.xml
new file mode 100644
index 0000000..4751065
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_inner_coder.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Inner Coder
+###################################################
+ -->
+<block>
+ <name>Inner Coder</name>
+ <key>dtv_dvbt_inner_coder</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_inner_coder($ninput, $noutput, $constellation.val,
$hierarchy.val, $code_rate.val)</make>
+ <param>
+ <name>Input length</name>
+ <key>ninput</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Output length</name>
+ <key>noutput</key>
+ <value>1512</value>
+ <type>int</type>
+ </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</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>
+ <check>$ninput > 0</check>
+ <check>$noutput > 0</check>
+ <check>$noutput >= $ninput</check>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>$ninput</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>$noutput</vlen>
+ </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_map.xml b/gr-dtv/grc/dtv_dvbt_map.xml
new file mode 100644
index 0000000..705a508
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_map.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Map
+###################################################
+ -->
+<block>
+ <name>DVB-T Map</name>
+ <key>dtv_dvbt_map</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_map($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>byte</type>
+ <vlen>$transmission_mode.payload_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_reed_solomon_enc.xml
b/gr-dtv/grc/dtv_dvbt_reed_solomon_enc.xml
new file mode 100644
index 0000000..3dd57a7
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_reed_solomon_enc.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Reed Solomon Encoder
+###################################################
+ -->
+<block>
+ <name>Reed-Solomon Encoder</name>
+ <key>dtv_dvbt_reed_solomon_enc</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_reed_solomon_enc($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*($k-$s)</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>$blocks*($n-$s)</vlen>
+ </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_reference_signals.xml
b/gr-dtv/grc/dtv_dvbt_reference_signals.xml
new file mode 100644
index 0000000..9be5763
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_reference_signals.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Reference Signals
+###################################################
+ -->
+<block>
+ <name>Reference Signals</name>
+ <key>dtv_dvbt_reference_signals</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_reference_signals($type.size,
$transmission_mode.payload_length, $transmission_mode.fft_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_ide_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.payload_length</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ <vlen>$transmission_mode.fft_length</vlen>
+ </source>
+</block>
diff --git a/gr-dtv/grc/dtv_dvbt_symbol_inner_interleaver.xml
b/gr-dtv/grc/dtv_dvbt_symbol_inner_interleaver.xml
new file mode 100644
index 0000000..f440769
--- /dev/null
+++ b/gr-dtv/grc/dtv_dvbt_symbol_inner_interleaver.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DVB-T Symbol Inner Interleaver
+###################################################
+ -->
+<block>
+ <name>Symbol Inner Interleaver</name>
+ <key>dtv_dvbt_symbol_inner_interleaver</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.dvbt_symbol_inner_interleaver($transmission_mode.payload_length,
$transmission_mode.val, $direction.val)</make>
+ <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>Direction</name>
+ <key>direction</key>
+ <type>enum</type>
+ <option>
+ <name>Interleave</name>
+ <key>Interleave</key>
+ <opt>val:1</opt>
+ </option>
+ <option>
+ <name>Deinterleave</name>
+ <key>Deinterleave</key>
+ <opt>val:0</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>
+ </source>
+</block>
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_bit_inner_interleaver.h
b/gr-dtv/include/gnuradio/dtv/dvbt_bit_inner_interleaver.h
new file mode 100644
index 0000000..d74763e
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_bit_inner_interleaver.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_INTERLEAVER_H
+#define INCLUDED_DTV_DVBT_BIT_INNER_INTERLEAVER_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 interleaver.
+ * \ingroup dtv
+ *
+ * ETSI EN 300 744 Clause 4.3.4.1 \n
+ * Data Input format: \n
+ * 000000X0X1 - QPSK. \n
+ * 0000X0X1X2X3 - 16QAM. \n
+ * 00X0X1X2X3X4X5 - 64QAM. \n
+ * Data Output format: \n
+ * 000000B0B1 - QPSK. \n
+ * 0000B0B1B2B3 - 16QAM. \n
+ * 00B0B1B2B3B4B5 - 64QAM. \n
+ * bit interleaver block size is 126.
+ */
+ class DTV_API dvbt_bit_inner_interleaver : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_bit_inner_interleaver> sptr;
+
+ /*!
+ * \brief Create a Bit Inner interleaver
+ *
+ * \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_INTERLEAVER_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_config.h
b/gr-dtv/include/gnuradio/dtv/dvbt_config.h
new file mode 100644
index 0000000..c6bfa1a
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_config.h
@@ -0,0 +1,45 @@
+/* -*- 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_CONFIG_H
+#define INCLUDED_DTV_DVBT_CONFIG_H
+
+namespace gr {
+ namespace dtv {
+ enum dvbt_hierarchy_t {
+ NH = 0,
+ ALPHA1,
+ ALPHA2,
+ ALPHA4,
+ };
+
+ enum dvbt_transmission_mode_t {
+ T2k = 0,
+ T8k = 1,
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+typedef gr::dtv::dvbt_hierarchy_t dvbt_hierarchy_t;
+typedef gr::dtv::dvbt_transmission_mode_t dvbt_transmission_mode_t;
+
+#endif /* INCLUDED_DTV_DVBT_CONFIG_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_convolutional_interleaver.h
b/gr-dtv/include/gnuradio/dtv/dvbt_convolutional_interleaver.h
new file mode 100644
index 0000000..a4c9577
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_convolutional_interleaver.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_INTERLEAVER_H
+#define INCLUDED_DTV_DVBT_CONVOLUTIONAL_INTERLEAVER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_interpolator.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief Convolutional interleaver.
+ * \ingroup dtv
+ *
+ * ETSI EN 300 744 Clause 4.3.1 \n
+ * Forney (Ramsey type III) convolutional interleaver. \n
+ * Input: Blocks of I bytes size. \n
+ * Output: Stream of 1 byte elements.
+ */
+ class DTV_API dvbt_convolutional_interleaver : virtual public
sync_interpolator
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_convolutional_interleaver> sptr;
+
+ /*!
+ * \brief Create a DVB-T convolutional interleaver.
+ *
+ * \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_INTERLEAVER_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_energy_dispersal.h
b/gr-dtv/include/gnuradio/dtv/dvbt_energy_dispersal.h
new file mode 100644
index 0000000..b5258bb
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_energy_dispersal.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_DISPERSAL_H
+#define INCLUDED_DTV_DVBT_ENERGY_DISPERSAL_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief Energy dispersal.
+ * \ingroup dtv
+ *
+ * ETSI EN 300 744 - Clause 4.3.1 \n
+ * Input - MPEG-2 transport packets (including sync - 0x47). \n
+ * Output - Randomized MPEG-2 transport packets. \n
+ * If first byte is not a SYNC then look for it. \n
+ * First sync in a row of 8 packets is reversed - 0xB8. \n
+ * Block size is 188 bytes.
+ */
+ class DTV_API dvbt_energy_dispersal : virtual public gr::block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_energy_dispersal> sptr;
+
+ /*!
+ * \brief Create DVB-T energy dispersal.
+ *
+ * \param nsize number of blocks.
+ */
+ static sptr make(int nsize);
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_ENERGY_DISPERSAL_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_inner_coder.h
b/gr-dtv/include/gnuradio/dtv/dvbt_inner_coder.h
new file mode 100644
index 0000000..e88596e
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_inner_coder.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_INNER_CODER_H
+#define INCLUDED_DTV_DVBT_INNER_CODER_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 Inner coder with Puncturing.
+ * \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: Packed bytes (each bit is data). \n
+ * MSB - first, LSB last. \n
+ * Data Output format: \n
+ * 000000X0X1 - QPSK. \n
+ * 0000X0X1X2X3 - 16QAM. \n
+ * 00X0X1X2X3X4X5 - 64QAM.
+ */
+ class DTV_API dvbt_inner_coder : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_inner_coder> sptr;
+
+ /*!
+ * \brief Create an Inner coder with Puncturing.
+ *
+ * \param ninput length of input. \n
+ * \param noutput lenght of output. \n
+ * \param constellation type of constellation. \n
+ * \param hierarchy type of hierarchy used. \n
+ * \param coderate coderate used.
+ */
+ static sptr make(int ninput, int noutput, dvb_constellation_t
constellation, dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate);
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_INNER_CODER_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_map.h
b/gr-dtv/include/gnuradio/dtv/dvbt_map.h
new file mode 100644
index 0000000..d9b7976
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_map.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_DVBT_DVBT_MAP_H
+#define INCLUDED_DVBT_DVBT_MAP_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief DVB-T mapper.
+ * \ingroup dtv
+ *
+ * ETSI EN 300 744 Clause 4.3.5. \n
+ * Data input format: \n
+ * 000000Y0Y1 - QPSK. \n
+ * 0000Y0Y1Y2Y3 - 16QAM. \n
+ * 00Y0Y1Y2Y3Y4Y5 - 64QAM. \n
+ * Data output format: \n
+ * complex(real(float), imag(float)).
+ */
+ class DTV_API dvbt_map : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_map> sptr;
+
+ /*!
+ * \brief Create a DVB-T mapper.
+ *
+ * \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 output 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_MAP_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_reed_solomon_enc.h
b/gr-dtv/include/gnuradio/dtv/dvbt_reed_solomon_enc.h
new file mode 100644
index 0000000..08c7c57
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_reed_solomon_enc.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_ENC_H
+#define INCLUDED_DTV_DVBT_REED_SOLOMON_ENC_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief Reed Solomon encoder
+ * \ingroup dtv
+ *
+ * ETSI EN 300 744 Clause 4.3.2 \n
+ * RS(N=204,K=239,T=8).
+ */
+ class DTV_API dvbt_reed_solomon_enc : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_reed_solomon_enc> sptr;
+
+ /*!
+ * \brief Create a Reed Solomon encoder.
+ *
+ * \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 encoder.
+ * \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_ENC_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_reference_signals.h
b/gr-dtv/include/gnuradio/dtv/dvbt_reference_signals.h
new file mode 100644
index 0000000..d41b949
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_reference_signals.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_REFERENCE_SIGNALS_H
+#define INCLUDED_DTV_DVBT_REFERENCE_SIGNALS_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief Reference signals generator.
+ * \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_reference_signals : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_reference_signals> sptr;
+
+ /*!
+ * \brief Create Reference signals generator.
+ *
+ * \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_REFERENCE_SIGNALS_H */
+
diff --git a/gr-dtv/include/gnuradio/dtv/dvbt_symbol_inner_interleaver.h
b/gr-dtv/include/gnuradio/dtv/dvbt_symbol_inner_interleaver.h
new file mode 100644
index 0000000..ae02c91
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/dvbt_symbol_inner_interleaver.h
@@ -0,0 +1,66 @@
+/* -*- 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_SYMBOL_INNER_INTERLEAVER_H
+#define INCLUDED_DTV_DVBT_SYMBOL_INNER_INTERLEAVER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/dtv/dvbt_config.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief Symbol interleaver.
+ * \ingroup dtv
+ *
+ * ETSI EN 300 744 Clause 4.3.4.2 \n
+ * One block is 12 groups x 126 datawords = 1512 datawords.
+ *
+ * Data Input format: \n
+ * 000000I0I1 - QPSK. \n
+ * 0000I0I1I2I3 - 16QAM. \n
+ * 00I0I1I2I3I4I5 - 64QAM. \n
+ * Data Output format: \n
+ * 000000Y0Y1 - QPSK. \n
+ * 0000Y0Y1Y2Y3 - 16QAM. \n
+ * 00Y0Y1Y2Y3Y4Y5 - 64QAM.
+ */
+ class DTV_API dvbt_symbol_inner_interleaver : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<dvbt_symbol_inner_interleaver> sptr;
+
+ /*!
+ * \brief Create a Symbol interleaver.
+ *
+ * \param ninput length of input stream. \n
+ * \param transmission transmission mode used \n
+ * \param direction interleave or deinterleave. \n
+ */
+ static sptr make(int ninput, dvbt_transmission_mode_t transmission, int
direction);
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_SYMBOL_INNER_INTERLEAVER_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc
b/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc
new file mode 100644
index 0000000..0ab3003
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_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_interleaver_impl.h"
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ const int dvbt_bit_inner_interleaver_impl::d_bsize = 126;
+
+ int
+ dvbt_bit_inner_interleaver_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_interleaver::sptr
+ dvbt_bit_inner_interleaver::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_interleaver_impl(nsize, constellation, hierarchy,
transmission));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvbt_bit_inner_interleaver_impl::dvbt_bit_inner_interleaver_impl(int
nsize, dvb_constellation_t constellation, \
+ dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission)
+ : block("dvbt_bit_inner_interleaver",
+ io_signature::make(1, 2, sizeof(unsigned char) * 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_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_interleaver_impl::~dvbt_bit_inner_interleaver_impl()
+ {
+ delete [] d_perm;
+ }
+
+ void
+ dvbt_bit_inner_interleaver_impl::forecast (int noutput_items,
gr_vector_int &ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items;
+ ninput_items_required[1] = noutput_items;
+ }
+
+ int
+ dvbt_bit_inner_interleaver_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 *inh = (const unsigned char *) input_items[0];
+ const unsigned char *inl = (const unsigned char *) input_items[1];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ 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 the Bit interleaver
+ unsigned char d_b[d_v][d_bsize];
+
+ for (int bcount = 0; bcount < bmax; bcount++) {
+ for (int i = 0; i < d_bsize; i++) {
+ if (d_hierarchy == NH) {
+ int c = inh[bcount * d_bsize + i];
+
+ // Create the demultiplexer
+ for (int k = 0; k < d_v; k++) {
+ d_b[d_perm[(d_v * i) + k]][i] = (c >> (d_v - k - 1)) & 1;
+ }
+ }
+ else {
+ int ch = inh[(bcount * d_bsize) + i];
+ int cl = inl[(bcount * d_bsize) + i];
+
+ // High priority input - first 2 streams
+ for (int k = 0; k < 2; k++) {
+ d_b[(d_v * i + k) % 2][(d_v * i + k) / 2] = (ch >> (1 - k)) & 1;
+ }
+
+ // Low priority input - (v - 2) streams
+ for (int k = 2; k < (d_v - 2); k++) {
+ d_b[d_perm[d_v * i + k]][(d_v * i + k) / (d_v - 2)] = (cl >>
(d_v - k - 1)) & 1;
+ }
+ }
+ }
+
+ // Take one bit from each interleaver
+ // and format the output
+
+ for (int w = 0; w < d_bsize; w++) {
+ int val = 0;
+
+ for (int e = 0; e < d_v; e++) {
+ val = (val << 1) | d_b[e][H(e, w)];
+ }
+
+ out[(bcount * d_bsize) + w] = val;
+ }
+ }
+
+ // 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_interleaver_impl.h
b/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.h
new file mode 100644
index 0000000..c5fcbe2
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_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_INTERLEAVER_IMPL_H
+#define INCLUDED_DTV_DVBT_BIT_INNER_INTERLEAVER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_bit_inner_interleaver.h>
+#include "dvbt_configure.h"
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_bit_inner_interleaver_impl : public dvbt_bit_inner_interleaver
+ {
+ 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_interleaver_impl(int nsize, dvb_constellation_t
constellation, dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t
transmission);
+ ~dvbt_bit_inner_interleaver_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_INTERLEAVER_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_configure.cc
b/gr-dtv/lib/dvbt/dvbt_configure.cc
new file mode 100644
index 0000000..1cd1b83
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_configure.cc
@@ -0,0 +1,274 @@
+/* -*- 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_configure.h"
+#include <iostream>
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ void
+ dvbt_configure::set_frame_number(int fn)
+ {
+ d_frame_index = fn;
+ }
+ int
+ dvbt_configure::get_frame_mumber()
+ {
+ return (d_frame_index);
+ }
+ void
+ dvbt_configure::set_constellation(dvb_constellation_t constellation)
+ {
+ d_constellation = constellation;
+ }
+ dvb_constellation_t
+ dvbt_configure::get_constellation()
+ {
+ return (d_constellation);
+ }
+ void
+ dvbt_configure::set_hierarchical(dvbt_hierarchy_t hierarchy)
+ {
+ d_hierarchy = hierarchy;
+ }
+ dvbt_hierarchy_t
+ dvbt_configure::get_hierarchical()
+ {
+ return d_hierarchy;
+ }
+ void
+ dvbt_configure::set_code_rate_HP(dvb_code_rate_t code_rate)
+ {
+ d_code_rate_HP = code_rate;
+ }
+ void
+ dvbt_configure::set_code_rate_LP(dvb_code_rate_t code_rate)
+ {
+ d_code_rate_LP = code_rate;
+ }
+ dvb_code_rate_t
+ dvbt_configure::get_code_rate_HP()
+ {
+ return d_code_rate_HP;
+ }
+ dvb_code_rate_t
+ dvbt_configure::get_code_rate_LP()
+ {
+ return d_code_rate_LP;
+ }
+ void
+ dvbt_configure::set_transmission_mode(dvbt_transmission_mode_t
transmission_mode)
+ {
+ d_transmission_mode = transmission_mode;
+ }
+ dvbt_transmission_mode_t
+ dvbt_configure::get_transmission_mode()
+ {
+ return d_transmission_mode;
+ }
+
+ dvbt_configure::dvbt_configure(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) :
+ d_constellation(constellation), d_hierarchy(hierarchy),
d_code_rate_HP(code_rate_HP),
+ d_code_rate_LP(code_rate_LP), d_guard_interval(guard_interval),
d_transmission_mode(transmission_mode),
+ d_include_cell_id(include_cell_id), d_cell_id(cell_id)
+ {
+ d_symbols_per_frame = 68;
+ d_frames_per_superframe = 4;
+
+ switch (d_transmission_mode) {
+ case T2k:
+ d_Kmin = 0; d_Kmax = 1704;
+ d_fft_length = 2048;
+ d_payload_length = 1512;
+ break;
+ case T8k:
+ d_Kmin = 0; d_Kmax = 6816;
+ d_fft_length = 8192;
+ d_payload_length = 6048;
+ break;
+ default:
+ d_Kmin = 0; d_Kmax = 1704;
+ d_fft_length = 2048;
+ d_payload_length = 1512;
+ break;
+ }
+ d_zeros_on_left = int(ceil((d_fft_length - (d_Kmax - d_Kmin + 1)) /
2.0));
+ d_zeros_on_right = d_fft_length - d_zeros_on_left - (d_Kmax - d_Kmin +
1);
+
+ switch (d_constellation) {
+ case MOD_QPSK:
+ d_constellation_size = 4;
+ d_step = 2;
+ d_m = 2;
+ break;
+ case MOD_16QAM:
+ d_constellation_size = 16;
+ d_step = 2;
+ d_m = 4;
+ break;
+ case MOD_64QAM:
+ d_constellation_size = 64;
+ d_step = 2;
+ d_m = 6;
+ break;
+ default:
+ d_constellation_size = 16;
+ d_step = 2;
+ d_m = 4;
+ break;
+ }
+
+ switch (d_code_rate_HP) {
+ case C1_2:
+ d_cr_k = 1; d_cr_n = 2; d_cr_p = 1;
+ break;
+ case C2_3:
+ d_cr_k = 2; d_cr_n = 3; d_cr_p = 2;
+ break;
+ case C3_4:
+ d_cr_k = 3; d_cr_n = 4; d_cr_p = 3;
+ break;
+ case C5_6:
+ d_cr_k = 5; d_cr_k = 6; d_cr_p = 5;
+ break;
+ case C7_8:
+ d_cr_k = 7; d_cr_n = 8; d_cr_p = 7;
+ break;
+ default:
+ d_cr_k = 1; d_cr_n = 2; d_cr_p = 1;
+ break;
+ }
+
+ switch (d_code_rate_LP) {
+ case C1_2:
+ d_cr_k = 1; d_cr_n = 2;
+ break;
+ case C2_3:
+ d_cr_k = 2; d_cr_n = 3;
+ break;
+ case C3_4:
+ d_cr_k = 3; d_cr_n = 4;
+ break;
+ case C5_6:
+ d_cr_k = 5; d_cr_n = 6;
+ break;
+ case C7_8:
+ d_cr_k = 7; d_cr_n = 8;
+ break;
+ default:
+ d_cr_k = 1; d_cr_n = 2;
+ break;
+ }
+
+ switch (guard_interval) {
+ case GI_1_32:
+ d_cp_length = d_fft_length / 32;
+ break;
+ case GI_1_16:
+ d_cp_length = d_fft_length / 16;
+ break;
+ case GI_1_8:
+ d_cp_length = d_fft_length / 8;
+ break;
+ case GI_1_4:
+ d_cp_length = d_fft_length / 4;
+ break;
+ default:
+ d_cp_length = d_fft_length / 32;
+ break;
+ }
+
+ switch (d_hierarchy) {
+ case NH:
+ d_alpha = 1;
+ break;
+ case ALPHA1:
+ d_alpha = 1;
+ break;
+ case ALPHA2:
+ d_alpha = 2;
+ break;
+ case ALPHA4:
+ d_alpha = 4;
+ break;
+ default:
+ d_alpha = 1;
+ break;
+ }
+
+ // ETSI EN 400 744 Clause 4.4
+ // Normalization factor
+ switch (d_m) {
+ case 2:
+ d_norm = 1.0 / sqrt(2);
+ break;
+ case 4:
+ if (d_alpha == 1) {
+ d_norm = 1.0 / sqrt(10);
+ }
+ if (d_alpha == 2) {
+ d_norm = 1.0 / sqrt(20);
+ }
+ if (d_alpha == 4) {
+ d_norm = 1.0 / sqrt(52);
+ }
+ break;
+ case 6:
+ if (d_alpha == 1) {
+ d_norm = 1.0 / sqrt(42);
+ }
+ if (d_alpha == 2) {
+ d_norm = 1.0 / sqrt(60);
+ }
+ if (d_alpha == 4) {
+ d_norm = 1.0 / sqrt(108);
+ }
+ break;
+ default:
+ if (d_alpha == 1) {
+ d_norm = 1.0 / sqrt(10);
+ }
+ if (d_alpha == 2) {
+ d_norm = 1.0 / sqrt(20);
+ }
+ if (d_alpha == 4) {
+ d_norm = 1.0 / sqrt(52);
+ }
+ break;
+ }
+ }
+
+ dvbt_configure::~dvbt_configure()
+ {
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_configure.h b/gr-dtv/lib/dvbt/dvbt_configure.h
new file mode 100644
index 0000000..5e87410
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_configure.h
@@ -0,0 +1,103 @@
+/* -*- 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_CONFIGURE_H
+#define INCLUDED_DTV_DVBT_CONFIGURE_H
+
+#include <gnuradio/dtv/dvb_config.h>
+#include <gnuradio/dtv/dvbt_config.h>
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_configure
+ {
+ public:
+ int d_symbols_per_frame;
+ int d_frames_per_superframe;
+
+ int d_symbol_index;
+ int d_frame_index;
+ int d_superframe_index;
+
+ //Constelaltion parameters
+ dvb_constellation_t d_constellation;
+ int d_constellation_size;
+ int d_step;
+ int d_m;
+ float d_norm;
+
+ //Hierarchy information
+ dvbt_hierarchy_t d_hierarchy;
+ int d_alpha;
+
+ //Inner Coding parameters
+ dvb_code_rate_t d_code_rate_HP;
+ dvb_code_rate_t d_code_rate_LP;
+
+ // Guard interval length
+ dvb_guardinterval_t d_guard_interval;
+
+ //Transmission type parameters
+ dvbt_transmission_mode_t d_transmission_mode;
+
+ //Include cell id + cell id parameters
+ int d_include_cell_id;
+ int d_cell_id;
+
+ // Puncturer parameters
+ int d_cr_k;
+ int d_cr_n;
+ int d_cr_p;
+
+ //Other DVB-T parameters
+ int d_Kmin;
+ int d_Kmax;
+ int d_fft_length;
+ int d_payload_length;
+ int d_zeros_on_left;
+ int d_zeros_on_right;
+ int d_cp_length;
+
+ void set_frame_number(int fn);
+ int get_frame_mumber();
+ void set_constellation(dvb_constellation_t constellation);
+ dvb_constellation_t get_constellation();
+ void set_hierarchical(dvbt_hierarchy_t hierarchy);
+ dvbt_hierarchy_t get_hierarchical();
+ void set_code_rate_HP(dvb_code_rate_t coderate);
+ dvb_code_rate_t get_code_rate_HP();
+ void set_code_rate_LP(dvb_code_rate_t coderate);
+ dvb_code_rate_t get_code_rate_LP();
+ void set_transmission_mode(dvbt_transmission_mode_t transmission_mode);
+ dvbt_transmission_mode_t get_transmission_mode();
+
+ dvbt_configure(dvb_constellation_t constellation = gr::dtv::MOD_16QAM, \
+ dvbt_hierarchy_t hierarchy = gr::dtv::NH, dvb_code_rate_t
code_rate_HP = gr::dtv::C1_2, \
+ dvb_code_rate_t code_rate_LP = gr::dtv::C1_2, dvb_guardinterval_t
guard_interval = gr::dtv::GI_1_32, \
+ dvbt_transmission_mode_t transmission_mode = gr::dtv::T2k, int
include_cell_id = 0, int cell_id = 0);
+ ~dvbt_configure();
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_CONFIGURE_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_convolutional_interleaver_impl.cc
b/gr-dtv/lib/dvbt/dvbt_convolutional_interleaver_impl.cc
new file mode 100644
index 0000000..e29ec8c
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_convolutional_interleaver_impl.cc
@@ -0,0 +1,89 @@
+/* -*- 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_interleaver_impl.h"
+#include <deque>
+
+namespace gr {
+ namespace dtv {
+
+ dvbt_convolutional_interleaver::sptr
+ dvbt_convolutional_interleaver::make(int nsize, int I, int M)
+ {
+ return gnuradio::get_initial_sptr
+ (new dvbt_convolutional_interleaver_impl(nsize, I, M));
+ }
+
+ /*
+ * The private constructor
+ */
+
dvbt_convolutional_interleaver_impl::dvbt_convolutional_interleaver_impl(int
blocks, int I, int M)
+ : sync_interpolator("dvbt_convolutional_interleaver",
+ io_signature::make(1, 1, sizeof (unsigned char) * I * blocks),
+ io_signature::make(1, 1, sizeof (unsigned char)), I * blocks),
+ d_blocks(blocks), d_I(I), d_M(M)
+ {
+ //Positions are shift registers (FIFOs)
+ //of length i*M
+ for (int i = 0; i < d_I; i++) {
+ d_shift.push_back(new std::deque<unsigned char>(d_M * i, 0));
+ }
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_convolutional_interleaver_impl::~dvbt_convolutional_interleaver_impl()
+ {
+ for (unsigned int i = 0; i < d_shift.size(); i++) {
+ delete d_shift.back();
+ d_shift.pop_back();
+ }
+ }
+
+ int
+ dvbt_convolutional_interleaver_impl::work (int noutput_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];
+
+ for (int i = 0; i < (noutput_items / d_I); i++) {
+ //Process one block of I symbols
+ for (unsigned int j = 0; j < d_shift.size(); j++) {
+ d_shift[j]->push_front(in[(d_I * i) + j]);
+ out[(d_I * i) + j] = d_shift[j]->back();
+ d_shift[j]->pop_back();
+ }
+ }
+
+ // Tell runtime system how many output items we produced.
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_convolutional_interleaver_impl.h
b/gr-dtv/lib/dvbt/dvbt_convolutional_interleaver_impl.h
new file mode 100644
index 0000000..2de1fab
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_convolutional_interleaver_impl.h
@@ -0,0 +1,52 @@
+/* -*- 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_INTERLEAVER_IMPL_H
+#define INCLUDED_DTV_DVBT_CONVOLUTIONAL_INTERLEAVER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_convolutional_interleaver.h>
+#include <vector>
+#include <deque>
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_convolutional_interleaver_impl : public
dvbt_convolutional_interleaver
+ {
+ private:
+ int d_blocks;
+ int d_I;
+ int d_M;
+ std::vector< std::deque<unsigned char> * > d_shift;
+
+ public:
+ dvbt_convolutional_interleaver_impl(int nsize, int I, int M);
+ ~dvbt_convolutional_interleaver_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_CONVOLUTIONAL_INTERLEAVER_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc
b/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc
new file mode 100644
index 0000000..9b49719
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.cc
@@ -0,0 +1,150 @@
+/* -*- 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_dispersal_impl.h"
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ const int dvbt_energy_dispersal_impl::d_npacks = 8;
+ const int dvbt_energy_dispersal_impl::d_psize = 188;
+ const int dvbt_energy_dispersal_impl::d_SYNC = 0x47;
+ const int dvbt_energy_dispersal_impl::d_NSYNC = 0xB8;
+
+ void
+ dvbt_energy_dispersal_impl::init_prbs()
+ {
+ d_reg = 0xa9;
+ }
+
+ int
+ dvbt_energy_dispersal_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_dispersal::sptr
+ dvbt_energy_dispersal::make(int nblocks)
+ {
+ return gnuradio::get_initial_sptr
+ (new dvbt_energy_dispersal_impl(nblocks));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvbt_energy_dispersal_impl::dvbt_energy_dispersal_impl(int nblocks)
+ : gr::block("dvbt_energy_dispersal",
+ gr::io_signature::make(1, 1, sizeof(unsigned char)),
+ gr::io_signature::make(1, 1, sizeof(unsigned char) * nblocks *
d_npacks * d_psize)),
+ d_nblocks(nblocks)
+ {
+ set_relative_rate(1.0/(double) (d_nblocks * d_npacks * d_psize));
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_energy_dispersal_impl::~dvbt_energy_dispersal_impl()
+ {
+ }
+
+ void
+ dvbt_energy_dispersal_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
+ {
+ // Add one block size for SYNC search
+ ninput_items_required[0] = d_npacks * (d_psize + 1) * d_nblocks *
noutput_items;
+ }
+
+ int
+ dvbt_energy_dispersal_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 index = 0;
+ int count = 0;
+ int ret = 0;
+ int is_sync = 0;
+
+ // Search for SYNC byte
+ while (is_sync == 0 && index < d_psize) {
+ if (in[index] == d_SYNC) {
+ is_sync = 1;
+ }
+ else {
+ index++;
+ }
+ }
+
+ // If we found a SYNC byte
+ if (is_sync) {
+ for (int i = 0; i < (d_nblocks * noutput_items); i++) {
+ init_prbs();
+
+ int sync = d_NSYNC;
+
+ for (int j = 0; j < d_npacks; j++) {
+ if (in[index + count] != d_SYNC) {
+ printf("error: Malformed MPEG-TS!\n");
+ }
+
+ out[count++] = sync;
+
+ for (int k = 1; k < d_psize; k++) {
+ out[count] = in[index + count] ^ clock_prbs(d_npacks);
+ count++;
+ }
+
+ sync = d_SYNC;
+ clock_prbs(d_npacks);
+ }
+ }
+ consume_each(index + d_npacks * d_psize * d_nblocks * noutput_items);
+ ret = noutput_items;
+ }
+ else {
+ consume_each(index);
+ ret = 0;
+ }
+
+ // Tell runtime system how many output items we produced.
+ return ret;
+ }
+ } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.h
b/gr-dtv/lib/dvbt/dvbt_energy_dispersal_impl.h
new file mode 100644
index 0000000..e1cfe4e
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_energy_dispersal_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_DISPERSAL_IMPL_H
+#define INCLUDED_DTV_DVBT_ENERGY_DISPERSAL_IMPL_H
+
+#include <gnuradio/dtv/dvbt_energy_dispersal.h>
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_energy_dispersal_impl : public dvbt_energy_dispersal
+ {
+ private:
+ // Packet size
+ static const int d_psize;
+ // Number of packets after which PRBS is reset
+ static const int d_npacks;
+ // Number of blocks
+ int d_nblocks;
+ // SYNC value
+ static const int d_SYNC;
+ // Negative SYNC value
+ static const int d_NSYNC;
+
+ // Register for PRBS
+ int d_reg;
+
+ void init_prbs();
+ int clock_prbs(int clocks);
+
+ public:
+ dvbt_energy_dispersal_impl(int nsize);
+ ~dvbt_energy_dispersal_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_DISPERSAL_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_inner_coder_impl.cc
b/gr-dtv/lib/dvbt/dvbt_inner_coder_impl.cc
new file mode 100644
index 0000000..4f24f02
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_inner_coder_impl.cc
@@ -0,0 +1,257 @@
+/* -*- 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_inner_coder_impl.h"
+#include <stdio.h>
+#include <assert.h>
+
+namespace gr {
+ namespace dtv {
+
+ void
+ dvbt_inner_coder_impl::generate_codeword(unsigned char in, int &x, int &y)
+ {
+ //insert input bit
+ d_reg |= ((in & 0x1) << 7);
+
+ d_reg = d_reg >> 1;
+
+ // TODO - do this with polynoms and bitcnt
+ //generate output G1=171(OCT)
+ x = ((d_reg >> 6) ^ (d_reg >> 5) ^ (d_reg >> 4) ^ \
+ (d_reg >> 3) ^ d_reg) & 0x1;
+ //generate output G2=133(OCT)
+ y = ((d_reg >> 6) ^ (d_reg >> 4) ^ (d_reg >> 3) ^ \
+ (d_reg >> 1) ^ d_reg) & 0x1;
+ }
+
+ //TODO - do this based on puncturing matrix
+ /*
+ * Input e.g rate 2/3:
+ * 000000x0x1
+ * Output e.g. rate 2/3
+ * 00000c0c1c2
+ */
+
+ void
+ dvbt_inner_coder_impl::generate_punctured_code(dvb_code_rate_t coderate,
unsigned char * in, unsigned char * out)
+ {
+ int x, y;
+
+ switch(coderate) {
+ //X1Y1
+ case C1_2:
+ generate_codeword(in[0], x, y);
+ out[0] = x; out[1] = y;
+ break;
+ //X1Y1Y2
+ case C2_3:
+ generate_codeword(in[0], x, y);
+ out[0] = x; out[1] = y;
+ generate_codeword(in[1], x, y);
+ out[2] = y;
+ break;
+ //X1Y1Y2X3
+ case C3_4:
+ generate_codeword(in[0], x, y);
+ out[0] = x; out[1] = y;
+ generate_codeword(in[1], x, y);
+ out[2] = y;
+ generate_codeword(in[2], x, y);
+ out[3] = x;
+ break;
+ //X1Y1Y2X3Y4X5
+ case C5_6:
+ generate_codeword(in[0], x, y);
+ out[0] = x; out[1] = y;
+ generate_codeword(in[1], x, y);
+ out[2] = y;
+ generate_codeword(in[2], x, y);
+ out[3] = x;
+ generate_codeword(in[3], x, y);
+ out[4] = y;
+ generate_codeword(in[4], x, y);
+ out[5] = x;
+ break;
+ //X1Y1Y2X3Y4X5Y6X7
+ case C7_8:
+ generate_codeword(in[0], x, y);
+ out[0] = x; out[1] = y;
+ generate_codeword(in[1], x, y);
+ out[2] = y;
+ generate_codeword(in[2], x, y);
+ out[3] = y;
+ generate_codeword(in[3], x, y);
+ out[4] = y;
+ generate_codeword(in[4], x, y);
+ out[5] = x;
+ generate_codeword(in[5], x, y);
+ out[6] = y;
+ generate_codeword(in[6], x, y);
+ out[7] = x;
+ break;
+ default:
+ generate_codeword(in[0], x, y);
+ out[0] = x; out[1] = y;
+ break;
+ }
+ }
+
+ dvbt_inner_coder::sptr
+ dvbt_inner_coder::make(int ninput, int noutput, dvb_constellation_t
constellation, \
+ dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate)
+ {
+ return gnuradio::get_initial_sptr
+ (new dvbt_inner_coder_impl(ninput, noutput, constellation, hierarchy,
coderate));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvbt_inner_coder_impl::dvbt_inner_coder_impl(int ninput, int noutput,
dvb_constellation_t constellation, \
+ dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate)
+ : block("dvbt_inner_coder",
+ io_signature::make(1, 1, sizeof (unsigned char)),
+ io_signature::make(1, 1, sizeof (unsigned char) * noutput)),
+ config(constellation, hierarchy, coderate, coderate),
+ d_ninput(ninput), d_noutput(noutput),
+ d_reg(0),
+ d_bitcount(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;
+
+ // In order to accomodate all constalations (m=2,4,6)
+ // and rates (1/2, 2/3, 3/4, 5/6, 7/8)
+ // We need the following things to happen:
+ // - output item size multiple of 1512bytes
+ // - noutput_items multiple of 4
+ // - in block size 4*(k*m/8)
+ // - out block size 4*n
+ //
+ // Rate calculation follows:
+ // We process km input bits(km/8 Bytes)
+ // We output nm bits
+ // We output one byte for a symbol of m bits
+ // The out/in rate in bytes is: 8n/km (Bytes)
+
+ assert(d_ninput % 1);
+ assert(d_noutput % 1512);
+
+ // Set output items multiple of 4
+ set_output_multiple(4);
+
+ // Set relative rate out/in
+ assert((d_noutput * d_k * d_m) % (d_ninput * 8 * d_n));
+ set_relative_rate((float)(d_ninput * 8 * d_n) / (float)d_noutput * d_k *
d_m);
+
+ // calculate in and out block sizes
+ d_in_bs = (d_k * d_m) / 2;
+ d_out_bs = 4 * d_n;
+
+ // allocate bit buffers
+ d_in_buff = new unsigned char[8 * d_in_bs];
+ if (d_in_buff == NULL) {
+ std::cout << "Cannot allocate memory for d_in_buff" << std::endl;
+ exit(1);
+ }
+
+ d_out_buff = new unsigned char[8 * d_in_bs * d_n / d_k];
+ if (d_out_buff == NULL) {
+ std::cout << "Cannot allocate memory for d_out_buff" << std::endl;
+ delete [] d_in_buff;
+ exit(1);
+ }
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_inner_coder_impl::~dvbt_inner_coder_impl()
+ {
+ delete [] d_out_buff;
+ delete [] d_in_buff;
+ }
+
+ void
+ dvbt_inner_coder_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
+ {
+ int input_required = noutput_items * d_noutput * d_k * d_m / (d_ninput *
8 * d_n);
+
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = input_required;
+ }
+ }
+
+ int
+ dvbt_inner_coder_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];
+
+ for (int k = 0; k < (noutput_items * d_noutput / d_out_bs); k++) {
+ // Unpack input to bits
+ for (int i = 0; i < d_in_bs; i++) {
+ for (int j = 0; j < 8; j++) {
+ d_in_buff[8*i + j] = (in[k*d_in_bs + i] >> (7 - j)) & 1;
+ }
+ }
+
+ // Encode the data
+ for (int in_bit = 0, out_bit = 0; in_bit < (8 * d_in_bs); in_bit +=
d_k, out_bit += d_n) {
+ generate_punctured_code(config.d_code_rate_HP, &d_in_buff[in_bit],
&d_out_buff[out_bit]);
+ }
+
+ // Pack d_m bit in one output byte
+ for (int i = 0; i < d_out_bs; i++) {
+ unsigned char c = 0;
+
+ for (int j = 0; j < d_m; j++) {
+ c |= d_out_buff[d_m*i + j] << (d_m - 1 - j);
+ }
+
+ out[k*d_out_bs + i] = c;
+ }
+ }
+
+ // Tell runtime system how many input items we consumed on
+ // each input stream.
+ consume_each(noutput_items * d_noutput * d_k * d_m / (d_ninput * 8 *
d_n));
+
+ // Tell runtime system how many output items we produced.
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_inner_coder_impl.h
b/gr-dtv/lib/dvbt/dvbt_inner_coder_impl.h
new file mode 100644
index 0000000..7a46a22
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_inner_coder_impl.h
@@ -0,0 +1,78 @@
+/* -*- 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_INNER_CODER_IMPL_H
+#define INCLUDED_DTV_DVBT_INNER_CODER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_inner_coder.h>
+#include "dvbt_configure.h"
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_inner_coder_impl : public dvbt_inner_coder
+ {
+ private:
+ const dvbt_configure config;
+
+ int d_ninput;
+ int d_noutput;
+
+ int d_reg;
+
+ //counts the bits in the bytes
+ //in input stream
+ int d_bitcount;
+
+ // Code rate k/n
+ int d_k;
+ int d_n;
+ // Constellation with m
+ int d_m;
+
+ // input block size in bytes
+ int d_in_bs;
+ // bit input buffer
+ unsigned char * d_in_buff;
+
+ // output block size in bytes
+ int d_out_bs;
+ // bit output buffer
+ unsigned char * d_out_buff;
+
+ void generate_codeword(unsigned char in, int &x, int &y);
+ void generate_punctured_code(dvb_code_rate_t coderate, unsigned char *
in, unsigned char * out);
+
+ public:
+ dvbt_inner_coder_impl(int ninput, int noutput, dvb_constellation_t
constellation, dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate);
+ ~dvbt_inner_coder_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_INNER_CODER_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_map_impl.cc b/gr-dtv/lib/dvbt/dvbt_map_impl.cc
new file mode 100644
index 0000000..05f6e7f
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_map_impl.cc
@@ -0,0 +1,163 @@
+/* -*- 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 <complex>
+#include "dvbt_map_impl.h"
+#include <stdio.h>
+#include <math.h>
+
+namespace gr {
+ namespace dtv {
+
+ dvbt_map::sptr
+ dvbt_map::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_map_impl(nsize, constellation, hierarchy, transmission,
gain));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvbt_map_impl::dvbt_map_impl(int nsize, dvb_constellation_t constellation,
dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission, float gain)
+ : block("dvbt_map",
+ io_signature::make(1, 1, sizeof (unsigned char) * nsize),
+ io_signature::make(1, 1, sizeof (gr_complex) * 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 = new gr_complex[d_constellation_size];
+ if (d_constellation_points == NULL) {
+ std::cout << "Cannot allocate memory for d_constellation_points" <<
std::endl;
+ exit(1);
+ }
+
+ make_constellation_points(d_constellation_size, d_step, d_alpha);
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_map_impl::~dvbt_map_impl()
+ {
+ delete [] d_constellation_points;
+ }
+
+ unsigned int
+ dvbt_map_impl::bin_to_gray(unsigned int val)
+ {
+ return (val >> 1) ^ val;
+ }
+
+ void
+ dvbt_map_impl::make_constellation_points(int size, int step, int alpha)
+ {
+ // The symmetry of the constellation is used to calculate
+ // 16-QAM from QPSK and 64-QAM form 16-QAM
+
+ 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 correctly calculate 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(QAM64)
+
+ 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);
+ }
+ }
+
+ gr_complex
+ dvbt_map_impl::find_constellation_point(int val)
+ {
+ return d_constellation_points[val];
+ }
+
+ void
+ dvbt_map_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items;
+ }
+
+ int
+ dvbt_map_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];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ for (int i = 0; i < (noutput_items * d_nsize); i++) {
+ out[i] = find_constellation_point(in[i]);
+ }
+
+ // 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_map_impl.h b/gr-dtv/lib/dvbt/dvbt_map_impl.h
new file mode 100644
index 0000000..045a8e0
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_map_impl.h
@@ -0,0 +1,72 @@
+/* -*- 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_MAP_IMPL_H
+#define INCLUDED_DTV_DVBT_MAP_IMPL_H
+
+#include <gnuradio/dtv/dvbt_map.h>
+#include "dvbt_configure.h"
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_map_impl : public dvbt_map
+ {
+ private:
+ const dvbt_configure config;
+
+ int d_nsize;
+
+ //Constellation size
+ unsigned char d_constellation_size;
+ // Keeps 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;
+
+ void make_constellation_points(int size, int step, int alpha);
+ gr_complex find_constellation_point(int val);
+
+ //Return gray representation from natural binary
+ unsigned int bin_to_gray(unsigned int val);
+
+ public:
+ dvbt_map_impl(int nsize, dvb_constellation_t constellation,
dvbt_hierarchy_t hierarchy, dvbt_transmission_mode_t transmission, float gain);
+ ~dvbt_map_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_MAP_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon.cc
b/gr-dtv/lib/dvbt/dvbt_reed_solomon.cc
new file mode 100644
index 0000000..6277350
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon.cc
@@ -0,0 +1,475 @@
+/* -*- 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.h"
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+
+using namespace std;
+
+#define min(a,b) ((a) < (b)) ? (a) : (b)
+
+namespace gr {
+ namespace dtv {
+
+ void
+ dvbt_reed_solomon::gf_init(int p, int m, int gfpoly)
+ {
+ d_p = p; d_m = m;
+
+ //maximum number of elements in the GF(p^m)
+ int q = powl(p, m);
+
+ d_gf_exp = new unsigned char[q];
+ if (d_gf_exp == NULL) {
+ std::cout << "Cannot allocate memory for d_gf_exp" << std::endl;
+ return;
+ }
+
+ d_gf_log = new unsigned char[q];
+ if (d_gf_log == NULL) {
+ std::cout << "Cannot allocate memory for d_gf_log" << std::endl;
+ delete [] d_gf_exp;
+ return;
+ }
+
+ int reg_rs = 1;
+
+ d_gf_exp[q - 1] = 0;
+ d_gf_log[0] = q - 1;
+
+ for (int i = 0; i < (q - 1); i++) {
+ d_gf_exp[i] = reg_rs;
+ d_gf_log[reg_rs] = i;
+
+ //This is equvalent with raise to power
+ reg_rs = reg_rs << 1;
+
+ if (reg_rs & (1 << m)) {
+ reg_rs = reg_rs ^ gfpoly;
+ }
+
+ reg_rs = reg_rs & ((1 << m) - 1);
+ }
+ }
+
+ void
+ dvbt_reed_solomon::gf_uninit()
+ {
+ delete [] d_gf_log;
+ delete [] d_gf_exp;
+ }
+
+ int
+ dvbt_reed_solomon::gf_exp(int a)
+ {
+ return d_gf_exp[a % d_n];
+ }
+
+ int
+ dvbt_reed_solomon::gf_log(int a)
+ {
+ return d_gf_log[a % d_n];
+ }
+
+
+ int
+ dvbt_reed_solomon::gf_add(int a, int b)
+ {
+ return (a ^ b);
+ }
+
+ int
+ dvbt_reed_solomon::gf_mul(int a, int b)
+ {
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+ else {
+ return gf_exp(d_gf_log[a] + d_gf_log[b]);
+ }
+ }
+
+ int
+ dvbt_reed_solomon::gf_div(int a, int b)
+ {
+ if (a == 0 || b == 0) {
+ return (0);
+ }
+
+ return (gf_exp(d_n + d_gf_log[a] - d_gf_log[b]));
+ }
+
+ int
+ dvbt_reed_solomon::gf_pow(int a, int power)
+ {
+ if (a == 0) {
+ return (0);
+ }
+
+ return gf_exp(d_n + d_gf_log[a] + power);
+ }
+
+ int
+ dvbt_reed_solomon::gf_lpow(int power)
+ {
+ return d_l[power % d_n];
+ }
+
+ void
+ dvbt_reed_solomon::rs_init(int lambda, int n, int k, int t)
+ {
+ d_n = n; d_k = k; d_t = t;
+ // 2t = n - k, dmin = 2t + 1 = n -k + 1
+
+ d_l = new unsigned char[d_n + 1];
+ if (d_l == NULL) {
+ std::cout << "Cannot allocate memory for d_l" << std::endl;
+ exit(1);
+ }
+
+ d_g = new unsigned char[2 * d_t + 1];
+ if (d_g == NULL) {
+ std::cout << "Cannot allocate memory for d_g" << std::endl;
+ delete [] d_l;
+ exit(1);
+ }
+
+ //Generate roots of lambda
+ d_l[0] = 1;
+
+ for (int i = 1; i <= d_n; i++) {
+ d_l[i] = gf_mul(d_l[i - 1], lambda);
+ }
+
+ //Init Generator polynomial buffer
+ for (int i = 0; i <= (2*t); i++) {
+ d_g[i] = 0;
+ }
+
+ //Start with x+lambda^0
+ d_g[0] = 1;
+
+ //Create generator polynomial
+ for (int i = 1; i <= (2 * t); i++) {
+ for (int j = i; j > 0; j--) {
+ if (d_g[j] != 0) {
+ d_g[j] = gf_add(d_g[j - 1], gf_mul(d_g[j], d_l[i - 1]));
+ }
+ else {
+ d_g[j] = d_g[j - 1];
+ }
+ }
+
+ d_g[0] = gf_mul(d_g[0], d_l[i - 1]);
+ }
+
+ // Init syndrome array
+ d_syn = new unsigned char[2 * d_t + 1];
+ if (d_syn == NULL) {
+ std::cout << "Cannot allocate memory for d_syn" << std::endl;
+ delete [] d_g;
+ delete [] d_l;
+ exit(1);
+ }
+ }
+
+ void
+ dvbt_reed_solomon::rs_uninit()
+ {
+ if (d_syn) {
+ delete [] d_syn;
+ }
+ if (d_g) {
+ delete [] d_g;
+ }
+ if (d_l) {
+ delete [] d_l;
+ }
+ }
+
+ int
+ dvbt_reed_solomon::rs_encode(unsigned char *data_in, unsigned char *parity)
+ {
+ memset(parity, 0, 2 * d_t);
+
+ for (int i = 0; i < d_k; i++) {
+ int feedback = gf_add(data_in[i], parity[0]);
+
+ if (feedback != 0) {
+ for (int j = 1; j < (2 * d_t); j++) {
+ if (d_g[2 * d_t - j] != 0) {
+ parity[j] = gf_add(parity[j], gf_mul(feedback, d_g[2 * d_t -
j]));
+ }
+ }
+ }
+
+ //Shift the register
+ memmove(&parity[0], &parity[1], (2 * d_t) - 1);
+
+ if (feedback != 0) {
+ parity[2 * d_t - 1] = gf_mul(feedback, d_g[0]);
+ }
+ else {
+ parity[2 * d_t - 1] = 0;
+ }
+ }
+
+ return (0);
+ }
+
+ int
+ dvbt_reed_solomon::rs_decode(unsigned char *data, unsigned char *eras,
const int no_eras)
+ {
+ unsigned char sigma[2 * d_t + 1];
+ unsigned char b[2 * d_t + 1];
+ unsigned char T[2 * d_t + 1];
+ unsigned char reg[2 * d_t + 1];
+ unsigned char root[2 * d_t + 1];
+ unsigned char loc[2 * d_t + 1];
+ unsigned char omega[2 * d_t];
+
+ // Compute erasure locator polynomial
+ memset(sigma, 0, 2 * d_t + 1);
+ sigma[0] = 1;
+
+ if (no_eras > 0) {
+ // In this case we know the locations of errors
+ // Init sigma to be the erasure locator polynomial
+ sigma[1] = gf_exp(d_n-1-eras[0]);
+
+ for (int i = 1; i < no_eras; i++) {
+ int u = d_n-1-eras[i];
+
+ for (int j = i+1; j > 0; j--) {
+ sigma[j] = gf_add(sigma[j], gf_pow(sigma[j - 1], u));
+ }
+ }
+ }
+
+ // Calculate syndrome
+
+ for (int j = 0; j < 2 * d_t; j++) {
+ d_syn[j] = data[0];
+ }
+
+ for (int j = 1; j < d_n; j++) {
+ for (int i = 0; i < 2 * d_t; i++) {
+ d_syn[i] = gf_add(data[j], gf_pow(d_syn[i], i));
+ }
+ }
+
+ int syn_error = 0;
+
+ // Verify all syndromes
+ for (int i = 0; i < 2 * d_t; i++) {
+ syn_error |= d_syn[i];
+ }
+
+ if (!syn_error) {
+ // The syndrome is a codeword
+ // Return data unmodified
+ return (0);
+ }
+
+ // Use Modified (errors+erasures) BMA. Algorithm of Berlekamp-Massey
+ // S(i)=r(lambda^i)=e(lambda^i)
+
+ int r = no_eras;
+ int el = no_eras;
+
+ memcpy(b, sigma, 2 * d_t + 1);
+
+ while (++r <= 2 * d_t) {
+ int d_discr = 0;
+
+ for (int i = 0; i < r; i++) {
+ d_discr = gf_add(d_discr, gf_mul(sigma[i], d_syn[r - i - 1]));
+ }
+
+ if (d_discr == 0) {
+ // b(x) = x * b(x)
+ memmove(&b[1], b, 2 * d_t);
+ b[0] = 0;
+ }
+ else {
+ T[0] = sigma[0];
+
+ // T(x) = sigma(x) + d*x*b(x)
+ for (int i = 0; i < 2 * d_t; i++) {
+ T[i + 1] = gf_add(sigma[i + 1], gf_mul(d_discr, b[i]));
+ }
+
+ if (2 * el <= r + no_eras - 1) {
+ el = r + no_eras - el;
+
+ // b(i) = sigma(i) / discr
+ for (int i = 0; i <= 2 * d_t; i++) {
+ b[i] = gf_div(sigma[i], d_discr);
+ }
+ }
+ else {
+ // b(x) = x*b(x)
+ memmove(&b[1], b, 2 * d_t);
+ b[0] = 0;
+ }
+ memcpy(sigma, T, 2 * d_t + 1);
+ }
+ }
+
+ // Compute degree(sigma)
+ int deg_sigma = 0;
+
+ for (int i = 0; i < 2 * d_t + 1; i++) {
+ if (sigma[i] != 0) {
+ deg_sigma = i;
+ }
+ }
+
+ // Find the roots of sigma(x) by Chien search
+ // Test sum(1)=1+sigma(1)*(lambda^1)+...+sigma(nu)*lambda(^nu)
+ // Test sum(2)=1+sigma(1)*(lambda^2)+...+sigma(nu)*lambda(^nu*2)
+ // ...
+ // Test sum(l)=1+sigma(1)*(lambda^l)+...+sigma(nu)*lambda(^nu*l)
+ // in order to see if lambda^(-1) is a root
+ // where nu is degree(sigma)
+
+ int no_roots = 0;
+
+ memcpy(®[1], &sigma[1], 2 * d_t);
+
+ for (int i = 1; i <= d_n; i++) {
+ int q = 1;
+
+ for (int j = deg_sigma; j > 0; j--) {
+ reg[j] = gf_pow(reg[j], j);
+ q = gf_add(q, reg[j]);
+ }
+
+ if (q != 0) {
+ continue;
+ }
+
+ // We are here when we found roots of the sigma(x)
+ // Keep roots in index form
+ root[no_roots] = i;
+ loc[no_roots] = i - 1;
+
+ if (++no_roots == deg_sigma) {
+ break;
+ }
+ }
+
+ if (no_roots != deg_sigma) {
+ // Uncorrectable error detected
+ if (eras) {
+ for (int i = 0; i < no_roots; i++)
+ eras[i] = loc[i];
+ }
+
+ return (-1);
+ }
+
+ // Compute erros+erasures evaluator polynomial
+ // omega(x)=sigma(x)S(x) mod (x ^ 2 * t)
+ int deg_omega = 0;
+
+ for (int i = 0; i < 2 * d_t; i++) {
+ int tmp = 0;
+ int j = (deg_sigma < i) ? deg_sigma : i;
+
+ for(;j >= 0; j--) {
+ tmp = gf_add(tmp, gf_mul(d_syn[i - j], sigma[j]));
+ }
+
+ if(tmp != 0) {
+ deg_omega = i;
+ }
+
+ omega[i] = tmp;
+ }
+ omega[2 * d_t] = 0;
+
+ // Compute error values using Forney formula (poly form)
+ // e(j(l))) = (lambda(j(l)) ^ 2) * omega(lambda ^ (-j(l))) /
sigma_pr(lambda ^ (-j(l)))
+ // where sigma_pr is the formal derivative of sigma
+
+ for (int j = no_roots - 1; j >= 0; j--) {
+ int num1 = 0;
+
+ // roots[] are in index form
+ for (int i = deg_omega; i >= 0; i--) {
+ num1 = gf_add(num1, gf_pow(omega[i], i * root[j]));
+ }
+
+ // root[] is in index form
+ int num2 = gf_exp(root[j] * (-1) + d_n);
+
+ int den = 0;
+
+ // sigma[i+1] for i even is the formal derivative lambda_pr of sigma[i]
+ int deg_max = min(deg_sigma, 2 * d_t - 1);
+
+ for (int i = 1; i <= deg_max; i += 2) {
+ if (sigma[i] != 0)
+ den = gf_add(den, gf_exp(d_gf_log[sigma[i]] + (i - 1) * root[j]));
+ }
+
+ if (den == 0) {
+ if (eras) {
+ for (int i = 0; i < no_roots; i++) {
+ eras[i] = loc[i];
+ }
+ }
+ return (-1);
+ }
+
+ int err = gf_div(gf_mul(num1, num2), den);
+
+ data[loc[j]] = gf_add(data[loc[j]], err);
+ }
+
+ return(no_roots);
+ }
+
+
+ dvbt_reed_solomon::dvbt_reed_solomon(int p, int m, int gfpoly, int n, int
k, int t, int s, int blocks):
+ d_p(p), d_m(m), d_gfpoly(gfpoly), d_n(n), d_k(k), d_t(t), d_s(s),
d_blocks(blocks)
+ {
+ gf_init(d_p, d_m, d_gfpoly);
+ rs_init(d_p, d_n, d_k, d_t);
+ }
+
+ dvbt_reed_solomon::~dvbt_reed_solomon()
+ {
+ rs_uninit();
+ gf_uninit();
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon.h
b/gr-dtv/lib/dvbt/dvbt_reed_solomon.h
new file mode 100644
index 0000000..b9286d0
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon.h
@@ -0,0 +1,70 @@
+/* -*- 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_H
+#define INCLUDED_DTV_DVBT_REED_SOLOMON_H
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_reed_solomon
+ {
+ 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_gf_exp;
+ unsigned char *d_gf_log;
+ unsigned char *d_l;
+ unsigned char *d_g;
+
+ unsigned char *d_syn;
+
+ int gf_add(int a, int b);
+ int gf_mul(int a, int b);
+ int gf_div(int a, int b);
+ int gf_exp(int a);
+ int gf_log(int a);
+ int gf_pow(int a, int power);
+ int gf_lpow(int power);
+
+ void gf_init(int p, int m, int gfpoly);
+ void gf_uninit();
+ void rs_init(int lambda, int n, int k, int t);
+ void rs_uninit();
+
+ public:
+ int rs_encode(unsigned char *data, unsigned char *parity);
+ int rs_decode(unsigned char *data, unsigned char *eras, const int
no_eras);
+
+ dvbt_reed_solomon(int p, int m, int gfpoly, int n, int k, int t, int s,
int blocks);
+ ~dvbt_reed_solomon();
+ };
+
+ } // namespace dtv
+} // namespace gr
+
+#endif /* INCLUDED_DTV_DVBT_REED_SOLOMON_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc
new file mode 100644
index 0000000..561ea08
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc
@@ -0,0 +1,103 @@
+/* -*- 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_enc_impl.h"
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ dvbt_reed_solomon_enc::sptr
+ dvbt_reed_solomon_enc::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_enc_impl(p, m, gfpoly, n, k, t, s, blocks));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvbt_reed_solomon_enc_impl::dvbt_reed_solomon_enc_impl(int p, int m, int
gfpoly, int n, int k, int t, int s, int blocks)
+ : block("dvbt_reed_solomon",
+ io_signature::make(1, 1, sizeof(unsigned char) * blocks * (k - s)),
+ io_signature::make(1, 1, sizeof(unsigned char) * blocks * (n - 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;
+ return;
+ }
+ memset(&d_in[0], 0, d_n);
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_reed_solomon_enc_impl::~dvbt_reed_solomon_enc_impl()
+ {
+ delete [] d_in;
+ }
+
+ void
+ dvbt_reed_solomon_enc_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items;
+ }
+
+ int
+ dvbt_reed_solomon_enc_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 in_bsize = d_k - d_s;
+ int out_bsize = d_n - d_s;
+
+ // We get a superblock of d_blocks blocks
+ for (int i = 0; i < (d_blocks * noutput_items); i++) {
+ //TODO - zero copy between in/out ?
+ memcpy(&d_in[d_s], &in[i * in_bsize], in_bsize);
+
+ d_rs.rs_encode(&d_in[0], &d_in[d_k]);
+
+ 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_enc_impl.h
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h
new file mode 100644
index 0000000..669ee27
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_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_ENC_IMPL_H
+#define INCLUDED_DTV_DVBT_REED_SOLOMON_ENC_IMPL_H
+
+#include <gnuradio/dtv/dvbt_reed_solomon_enc.h>
+#include "dvbt_reed_solomon.h"
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_reed_solomon_enc_impl : public dvbt_reed_solomon_enc
+ {
+ 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_enc_impl(int p, int m, int gfpoly, int n, int k, int
t, int s, int blocks);
+ ~dvbt_reed_solomon_enc_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_ENC_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
new file mode 100644
index 0000000..d64b403
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
@@ -0,0 +1,1280 @@
+/* -*- 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_reference_signals_impl.h"
+#include <complex>
+#include <stdio.h>
+#include <gnuradio/expj.h>
+#include <gnuradio/math.h>
+
+namespace gr {
+ namespace dtv {
+
+ //Number of symbols in a frame
+ const int dvbt_pilot_gen::d_symbols_per_frame = SYMBOLS_PER_FRAME;
+ //Number of frames in a superframe
+ const int dvbt_pilot_gen::d_frames_per_superframe = FRAMES_PER_SUPERFRAME;
+
+ // 2k mode
+ // Scattered pilots # of carriers
+ const int dvbt_pilot_gen::d_spilot_carriers_size_2k =
SCATTERED_PILOT_SIZE_2k;
+ // Continual pilots # of carriers and positions
+ const int dvbt_pilot_gen::d_cpilot_carriers_size_2k =
CONTINUAL_PILOT_SIZE_2k;
+ const int
dvbt_pilot_gen::d_cpilot_carriers_2k[dvbt_pilot_gen::d_cpilot_carriers_size_2k]
= {
+ 0, 48, 54, 87, 141, 156, 192, \
+ 201, 255, 279, 282, 333, 432, 450, \
+ 483, 525, 531, 618, 636, 714, 759, \
+ 765, 780, 804, 873, 888, 918, 939, \
+ 942, 969, 984, 1050, 1101, 1107, 1110, \
+ 1137, 1140, 1146, 1206, 1269, 1323, 1377, \
+ 1491, 1683, 1704
+ };
+ // TPS pilots # of carriers and positions
+ const int dvbt_pilot_gen::d_tps_carriers_size_2k = TPS_PILOT_SIZE_2k;
+ const int
dvbt_pilot_gen::d_tps_carriers_2k[dvbt_pilot_gen::d_tps_carriers_size_2k] = {
+ 34, 50, 209, 346, 413, \
+ 569, 595, 688, 790, 901, \
+ 1073, 1219, 1262, 1286, 1469, \
+ 1594, 1687
+ };
+
+ // 8k mode
+ // Scattered pilots # of carriers
+ const int dvbt_pilot_gen::d_spilot_carriers_size_8k =
SCATTERED_PILOT_SIZE_8k;
+ // Continual pilots # of carriers and positions
+ const int dvbt_pilot_gen::d_cpilot_carriers_size_8k =
CONTINUAL_PILOT_SIZE_8k;
+ const int
dvbt_pilot_gen::d_cpilot_carriers_8k[dvbt_pilot_gen::d_cpilot_carriers_size_8k]
= {
+ 0, 48, 54, 87, 141, 156, 192,
+ 201, 255, 279, 282, 333, 432, 450,
+ 483, 525, 531, 618, 636, 714, 759,
+ 765, 780, 804, 873, 888, 918, 939,
+ 942, 969, 984, 1050, 1101, 1107, 1110,
+ 1137, 1140, 1146, 1206, 1269, 1323, 1377,
+ 1491, 1683, 1704, 1752, 1758, 1791, 1845,
+ 1860, 1896, 1905, 1959, 1983, 1986, 2037,
+ 2136, 2154, 2187, 2229, 2235, 2322, 2340,
+ 2418, 2463, 2469, 2484, 2508, 2577, 2592,
+ 2622, 2643, 2646, 2673, 2688, 2754, 2805,
+ 2811, 2814, 2841, 2844, 2850, 2910, 2973,
+ 3027, 3081, 3195, 3387, 3408, 3456, 3462,
+ 3495, 3549, 3564, 3600, 3609, 3663, 3687,
+ 3690, 3741, 3840, 3858, 3891, 3933, 3939,
+ 4026, 4044, 4122, 4167, 4173, 4188, 4212,
+ 4281, 4296, 4326, 4347, 4350, 4377, 4392,
+ 4458, 4509, 4515, 4518, 4545, 4548, 4554,
+ 4614, 4677, 4731, 4785, 4899, 5091, 5112,
+ 5160, 5166, 5199, 5253, 5268, 5304, 5313,
+ 5367, 5391, 5394, 5445, 5544, 5562, 5595,
+ 5637, 5643, 5730, 5748, 5826, 5871, 5877,
+ 5892, 5916, 5985, 6000, 6030, 6051, 6054,
+ 6081, 6096, 6162, 6213, 6219, 6222, 6249,
+ 6252, 6258, 6318, 6381, 6435, 6489, 6603,
+ 6795, 6816
+ };
+ // TPS pilots # of carriers and positions
+ const int dvbt_pilot_gen::d_tps_carriers_size_8k = TPS_PILOT_SIZE_8k;
+ const int
dvbt_pilot_gen::d_tps_carriers_8k[dvbt_pilot_gen::d_tps_carriers_size_8k] = {
+ 34, 50, 209, 346, 413, 569, 595, 688, \
+ 790, 901, 1073, 1219, 1262, 1286, 1469, 1594, \
+ 1687, 1738, 1754, 1913, 2050, 2117, 2273, 2299, \
+ 2392, 2494, 2605, 2777, 2923, 2966, 2990, 3173, \
+ 3298, 3391, 3442, 3458, 3617, 3754, 3821, 3977, \
+ 4003, 4096, 4198, 4309, 4481, 4627, 4670, 4694, \
+ 4877, 5002, 5095, 5146, 5162, 5321, 5458, 5525, \
+ 5681, 5707, 5800, 5902, 6013, 6185, 6331, 6374, \
+ 6398, 6581, 6706, 6799
+ };
+
+ // TPS sync sequence for odd and even frames
+ const int dvbt_pilot_gen::d_tps_sync_size = 16; // TODO
+ const int dvbt_pilot_gen::d_tps_sync_even[d_tps_sync_size] = {
+ 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0
+ };
+ const int dvbt_pilot_gen::d_tps_sync_odd[d_tps_sync_size] = {
+ 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1
+ };
+
+ /*
+ * Constructor of class
+ */
+ dvbt_pilot_gen::dvbt_pilot_gen(const dvbt_configure &c) : config(c),
+ d_spilot_index(0),
+ d_cpilot_index(0),
+ d_tpilot_index(0),
+ d_symbol_index(0),
+ d_symbol_index_known(0),
+ d_frame_index(0),
+ d_superframe_index(0),
+ d_freq_offset_max(8),
+ d_trigger_index(0),
+ d_payload_index(0),
+ d_chanestim_index(0),
+ d_prev_mod_symbol_index(0),
+ d_mod_symbol_index(0)
+ {
+ //Determine parameters from config file
+ d_Kmin = config.d_Kmin;
+ d_Kmax = config.d_Kmax;
+ d_fft_length = config.d_fft_length;
+ d_payload_length = config.d_payload_length;
+ d_zeros_on_left = config.d_zeros_on_left;
+ d_zeros_on_right = config.d_zeros_on_right;
+ d_cp_length = config.d_cp_length;
+
+ //Set-up pilot data depending on transmission mode
+ if (config.d_transmission_mode == T2k) {
+ d_spilot_carriers_size = d_spilot_carriers_size_2k;
+ d_cpilot_carriers_size = d_cpilot_carriers_size_2k;
+ d_cpilot_carriers = d_cpilot_carriers_2k;
+ d_tps_carriers_size = d_tps_carriers_size_2k;
+ d_tps_carriers = d_tps_carriers_2k;
+ }
+ else if (config.d_transmission_mode == T8k) {
+ d_spilot_carriers_size = d_spilot_carriers_size_8k;
+ d_cpilot_carriers_size = d_cpilot_carriers_size_8k;
+ d_cpilot_carriers = d_cpilot_carriers_8k;
+ d_tps_carriers_size = d_tps_carriers_size_8k;
+ d_tps_carriers = d_tps_carriers_8k;
+ }
+ else {
+ d_spilot_carriers_size = d_spilot_carriers_size_2k;
+ d_cpilot_carriers_size = d_cpilot_carriers_size_2k;
+ d_cpilot_carriers = d_cpilot_carriers_2k;
+ d_tps_carriers_size = d_tps_carriers_size_2k;
+ d_tps_carriers = d_tps_carriers_2k;
+ }
+
+ //allocate PRBS buffer
+ d_wk = new char[d_Kmax - d_Kmin + 1];
+ if (d_wk == NULL) {
+ std::cout << "Cannot allocate memory for d_wk" << std::endl;
+ exit(1);
+ }
+ // Generate wk sequence
+ generate_prbs();
+
+ // allocate buffer for scattered pilots
+ d_spilot_carriers_val = new gr_complex[d_Kmax - d_Kmin + 1];
+ if (d_spilot_carriers_val == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_carriers_val" <<
std::endl;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // allocate buffer for channel gains (for each useful carrier)
+ d_channel_gain = new gr_complex[d_Kmax - d_Kmin + 1];
+ if (d_channel_gain == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_carriers_val" <<
std::endl;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // Allocate buffer for continual pilots phase diffs
+ d_known_phase_diff = new float[d_cpilot_carriers_size - 1];
+ if (d_known_phase_diff == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_carriers_val" <<
std::endl;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // Obtain phase diff for all continual pilots
+ for (int i = 0; i < (d_cpilot_carriers_size - 1); i++) {
+ d_known_phase_diff[i] = \
+ norm(get_cpilot_value(d_cpilot_carriers[i + 1]) -
get_cpilot_value(d_cpilot_carriers[i]));
+ }
+
+ d_cpilot_phase_diff = new float[d_cpilot_carriers_size - 1];
+ if (d_cpilot_phase_diff == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_carriers_val" <<
std::endl;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // Allocate buffer for derotated input symbol
+ d_derot_in = new gr_complex[d_fft_length];
+ if (d_derot_in == NULL) {
+ std::cout << "Cannot allocate memory for d_derot_in" << std::endl;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // allocate buffer for first tps symbol constellation
+ d_tps_carriers_val = new gr_complex[d_tps_carriers_size];
+ if (d_tps_carriers_val == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_carriers_val" <<
std::endl;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // allocate tps data buffer
+ d_tps_data = new unsigned char[d_symbols_per_frame];
+ if (d_tps_data == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_data" << std::endl;
+ delete [] d_tps_carriers_val;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ d_prev_tps_symbol = new gr_complex[d_tps_carriers_size];
+ if (d_prev_tps_symbol == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_data" << std::endl;
+ delete [] d_tps_data;
+ delete [] d_tps_carriers_val;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+ memset(d_prev_tps_symbol, 0, d_tps_carriers_size * sizeof(gr_complex));
+
+ d_tps_symbol = new gr_complex[d_tps_carriers_size];
+ if (d_tps_symbol == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_data" << std::endl;
+ delete [] d_prev_tps_symbol;
+ delete [] d_tps_data;
+ delete [] d_tps_carriers_val;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+ memset(d_tps_symbol, 0, d_tps_carriers_size * sizeof(gr_complex));
+
+ // Init receive TPS data vector
+ for (int i = 0; i < d_symbols_per_frame; i++) {
+ d_rcv_tps_data.push_back(0);
+ }
+
+ // Init TPS sync sequence
+ for (int i = 0; i < d_tps_sync_size; i++) {
+ d_tps_sync_evenv.push_back(d_tps_sync_even[i]);
+ d_tps_sync_oddv.push_back(d_tps_sync_odd[i]);
+ }
+
+ // Allocate buffer for channel estimation carriers
+ d_chanestim_carriers = new int[d_Kmax - d_Kmin + 1];
+ if (d_chanestim_carriers == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_data" << std::endl;
+ delete [] d_tps_symbol;
+ delete [] d_prev_tps_symbol;
+ delete [] d_tps_data;
+ delete [] d_tps_carriers_val;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // Allocate buffer for payload carriers
+ d_payload_carriers = new int[d_Kmax - d_Kmin + 1];
+ if (d_payload_carriers == NULL) {
+ std::cout << "Cannot allocate memory for d_tps_data" << std::endl;
+ delete [] d_chanestim_carriers;
+ delete [] d_tps_symbol;
+ delete [] d_prev_tps_symbol;
+ delete [] d_tps_data;
+ delete [] d_tps_carriers_val;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ exit(1);
+ }
+
+ // Reset the pilot generator
+ reset_pilot_generator();
+ // Format TPS data with current values
+ format_tps_data();
+ }
+
+ /*
+ * Destructor of class
+ */
+ dvbt_pilot_gen::~dvbt_pilot_gen()
+ {
+ delete [] d_payload_carriers;
+ delete [] d_chanestim_carriers;
+ delete [] d_tps_symbol;
+ delete [] d_prev_tps_symbol;
+ delete [] d_tps_data;
+ delete [] d_tps_carriers_val;
+ delete [] d_derot_in;
+ delete [] d_cpilot_phase_diff;
+ delete [] d_known_phase_diff;
+ delete [] d_channel_gain;
+ delete [] d_spilot_carriers_val;
+ delete [] d_wk;
+ }
+
+ /*
+ * Generate PRBS sequence
+ * X^11 + X^2 + 1
+ * en 300 744 - section 4.5.2
+ */
+ void
+ dvbt_pilot_gen::generate_prbs()
+ {
+ // init PRBS register with 1s
+ unsigned int reg_prbs = (1 << 11) - 1;
+
+ for (int k = 0; k < (d_Kmax - d_Kmin + 1); k++) {
+ d_wk[k] = (char)(reg_prbs & 0x01);
+ int new_bit = ((reg_prbs >> 2) ^ (reg_prbs >> 0)) & 0x01;
+ reg_prbs = (reg_prbs >> 1) | (new_bit << 10);
+ }
+ }
+
+ /*
+ * Generate shortened BCH(67, 53) codes from TPS data
+ * Extend the code with 60 bits and use BCH(127, 113)
+ */
+ void
+ dvbt_pilot_gen::generate_bch_code()
+ {
+ //TODO
+ //DO other way: if (feedback == 1) reg = reg ^ polymomial
+ //else nothing
+
+ //(n, k) = (127, 113) = (60+67, 60+53)
+ unsigned int reg_bch = 0;
+ unsigned char data_in[113];
+
+ //fill in 60 zeros
+ memset(&data_in[0], 0, 60);
+ //fill in TPS data - start bit not included
+ memcpy(&data_in[60], &d_tps_data[1], 53);
+
+ //X^14+X^9+X^8+X^6+X^5+X^4+X^2+X+1
+ for (int i = 0; i < 113; i++) {
+ int feedback = 0x1 & (data_in[i] ^ reg_bch);
+ reg_bch = reg_bch >> 1;
+ reg_bch |= feedback << 13;
+ reg_bch = reg_bch \
+ ^ (feedback << 12) ^ (feedback << 11) \
+ ^ (feedback << 9) ^ (feedback << 8) \
+ ^ (feedback << 7) ^ (feedback << 5) \
+ ^ (feedback << 4);
+ }
+
+ for (int i = 0; i < 14; i++) {
+ d_tps_data[i + 54] = 0x1 & (reg_bch >> i);
+ }
+ }
+
+ int
+ dvbt_pilot_gen::verify_bch_code(std::deque<char> data)
+ {
+ int ret = 0;
+
+ //TODO
+ //DO other way: if (feedback == 1) reg = reg ^ polymomial
+ //else nothing
+
+ //(n, k) = (127, 113) = (60+67, 60+53)
+ unsigned int reg_bch = 0;
+ unsigned char data_in[113];
+
+ //fill in 60 zeros
+ memset(&data_in[0], 0, 60);
+ //fill in TPS data - start bit not included
+ //memcpy(&data_in[60], &data[1], 53);
+ for (int i = 0; i < 53; i++)
+ data_in[60 + i] = data[1 + i];
+
+ //X^14+X^9+X^8+X^6+X^5+X^4+X^2+X+1
+ for (int i = 0; i < 113; i++) {
+ int feedback = 0x1 & (data_in[i] ^ reg_bch);
+ reg_bch = reg_bch >> 1;
+ reg_bch |= feedback << 13;
+ reg_bch = reg_bch \
+ ^ (feedback << 12) ^ (feedback << 11) \
+ ^ (feedback << 9) ^ (feedback << 8) \
+ ^ (feedback << 7) ^ (feedback << 5) \
+ ^ (feedback << 4);
+ }
+
+ for (int i = 0; i < 14; i++) {
+ if ((unsigned int)data[i + 54] != (0x1 & (reg_bch >> i))) {
+ ret = -1;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+ void
+ dvbt_pilot_gen::set_symbol_index(int sindex)
+ {
+ d_symbol_index = sindex;
+ }
+
+ int
+ dvbt_pilot_gen::get_symbol_index()
+ {
+ return d_symbol_index;
+ }
+
+ void
+ dvbt_pilot_gen::set_tps_data()
+ {
+ }
+
+ void
+ dvbt_pilot_gen::get_tps_data()
+ {
+ }
+
+ /*
+ * Reset pilot generator
+ */
+ void
+ dvbt_pilot_gen::reset_pilot_generator()
+ {
+ d_spilot_index = 0; d_cpilot_index = 0; d_tpilot_index = 0;
+ d_payload_index = 0; d_chanestim_index = 0;
+ d_symbol_index = 0; d_frame_index = 0; d_superframe_index = 0;
+ d_symbol_index_known = 0;
+ d_equalizer_ready = 0;
+ }
+
+ /*
+ * Init scattered pilot generator
+ */
+ int
+ dvbt_pilot_gen::get_current_spilot(int sindex) const
+ {
+ //TODO - can be optimized for same symbol_index
+ return (d_Kmin + 3 * (sindex % 4) + 12 * d_spilot_index);
+ }
+
+ gr_complex
+ dvbt_pilot_gen::get_spilot_value(int spilot)
+ {
+ // TODO - can be calculated at the beginning
+ return gr_complex(4 * 2 * (0.5 - d_wk[spilot]) / 3, 0);
+ }
+
+ void
+ dvbt_pilot_gen::set_spilot_value(int spilot, gr_complex val)
+ {
+ d_spilot_carriers_val[spilot] = val;
+ }
+
+ void
+ dvbt_pilot_gen::set_channel_gain(int spilot, gr_complex val)
+ {
+ // Gain gval=rxval/txval
+ d_channel_gain[spilot] = gr_complex((4 * 2 * (0.5 - d_wk[spilot]) / 3),
0) / val;
+ }
+ void
+ dvbt_pilot_gen::advance_spilot(int sindex)
+ {
+ //TODO - do in a simpler way?
+ int size = d_spilot_carriers_size;
+
+ if (sindex == 0) {
+ size = d_spilot_carriers_size + 1;
+ }
+
+ // TODO - fix this - what value should we use?
+ ++d_spilot_index;
+ d_spilot_index = d_spilot_index % size;
+ }
+
+ int
+ dvbt_pilot_gen::get_first_spilot()
+ {
+ d_spilot_index = 0;
+
+ return (d_Kmin + 3 * (d_symbol_index % 4));
+ }
+
+ int
+ dvbt_pilot_gen::get_last_spilot() const
+ {
+ int size = d_spilot_carriers_size - 1;
+
+ if (d_symbol_index == 0) {
+ size = d_spilot_carriers_size;
+ }
+
+ return (d_Kmin + 3 * (d_symbol_index % 4) + 12 * size);
+ }
+
+ int
+ dvbt_pilot_gen::get_next_spilot()
+ {
+ int pilot = (d_Kmin + 3 * (d_symbol_index % 4) + 12 *
(++d_spilot_index));
+
+ if (pilot > d_Kmax) {
+ pilot = d_Kmax;
+ }
+
+ return pilot;
+ }
+
+ int
+ dvbt_pilot_gen::process_spilot_data(const gr_complex * in)
+ {
+ // This is channel estimator
+ // Interpolate the gain between carriers to obtain
+ // gain for non pilot carriers - we use linear interpolation
+
+ /*************************************************************/
+ // Find out the OFDM symbol index (value 0 to 3) sent
+ // in current block by correlating scattered symbols with
+ // current block - result is (symbol index % 4)
+ /*************************************************************/
+ float max = 0; float sum = 0;
+
+ for (int scount = 0; scount < 4; scount++) {
+ d_spilot_index = 0; d_cpilot_index = 0;
+ d_chanestim_index = 0;
+
+ for (int k = 0; k < (d_Kmax - d_Kmin + 1); k++) {
+ // Keep data for channel estimation
+ if (k == get_current_spilot(scount)) {
+ set_chanestim_carrier(k);
+ advance_spilot(scount);
+ advance_chanestim();
+ }
+ }
+
+ gr_complex c = gr_complex(0.0, 0.0);
+
+ // This should be of range 0 to d_chanestim_index bit for now we use
just a
+ // small number of spilots to obtain the symbol index
+ for (int j = 0; j < 10; j++) {
+ c += get_spilot_value(d_chanestim_carriers[j]) *
conj(in[d_zeros_on_left + d_chanestim_carriers[j]]);
+ }
+ sum = norm(c);
+
+ if (sum > max) {
+ max = sum;
+ d_mod_symbol_index = scount;
+ }
+ }
+
+ /*************************************************************/
+ // Keep data for channel estimator
+ // This method interpolates scattered measurements across one OFDM symbol
+ // It does not use measurements from the previous OFDM symbols (does not
use history)
+ // as it may have encountered a phase change for the current phase only
+ /*************************************************************/
+
+ d_spilot_index = 0; d_cpilot_index = 0;
+ d_chanestim_index = 0;
+
+ for (int k = 0; k < (d_Kmax - d_Kmin + 1); k++) {
+ // Keep data for channel estimation
+ if (k == get_current_spilot(d_mod_symbol_index)) {
+ set_chanestim_carrier(k);
+ advance_spilot(d_mod_symbol_index);
+ advance_chanestim();
+ }
+
+ // Keep data for channel estimation
+ if (k == get_current_cpilot()) {
+ set_chanestim_carrier(k);
+ advance_cpilot();
+ advance_chanestim();
+ }
+ }
+
+ // We use both scattered pilots and continual pilots
+ for (int i = 0, startk = d_chanestim_carriers[0]; i < d_chanestim_index;
i++) {
+ // Get a carrier from the list of carriers
+ // used for channel estimation
+ int k = d_chanestim_carriers[i];
+
+ set_channel_gain(k, in[k + d_zeros_on_left]);
+
+ // Calculate tg(alpha) due to linear interpolation
+ gr_complex tg_alpha = (d_channel_gain[k] - d_channel_gain[startk]) /
gr_complex(11.0, 0.0);
+
+ // Calculate interpolation for all intermediate values
+ for (int j = 1; j < (k - startk); j++) {
+ gr_complex current = d_channel_gain[startk] + tg_alpha *
gr_complex(j, 0.0);
+ d_channel_gain[startk + j] = current;
+ }
+
+ startk = k;
+ }
+
+ // Signal that equalizer is ready
+ d_equalizer_ready = 1;
+
+ int diff_sindex = (d_mod_symbol_index - d_prev_mod_symbol_index + 4) % 4;
+
+ d_prev_mod_symbol_index = d_mod_symbol_index;
+
+ return diff_sindex;
+ }
+
+ /*
+ * Init continual pilot generator
+ */
+ int
+ dvbt_pilot_gen::get_current_cpilot() const
+ {
+ return d_cpilot_carriers[d_cpilot_index];
+ }
+
+ gr_complex
+ dvbt_pilot_gen::get_cpilot_value(int cpilot)
+ {
+ //TODO - can be calculated at the beginning
+ return gr_complex((float)(4 * 2 * (0.5 - d_wk[cpilot])) / 3, 0);
+ }
+
+ void
+ dvbt_pilot_gen::advance_cpilot()
+ {
+ ++d_cpilot_index;
+ d_cpilot_index = d_cpilot_index % d_cpilot_carriers_size;
+ }
+
+ void
+ dvbt_pilot_gen::process_cpilot_data(const gr_complex * in)
+ {
+ // Look for maximum correlation for cpilots
+ // in order to obtain post FFT integer frequency correction
+
+ float max = 0; float sum = 0;
+ int start = 0;
+ float phase;
+
+ for (int i = d_zeros_on_left - d_freq_offset_max; i < d_zeros_on_left +
d_freq_offset_max; i++) {
+ sum = 0;
+ for (int j = 0; j < (d_cpilot_carriers_size - 1); j++) {
+ phase = norm(in[i + d_cpilot_carriers[j + 1]] - in[i +
d_cpilot_carriers[j]]);
+ sum += d_known_phase_diff[j] * phase;
+ }
+
+ if (sum > max) {
+ max = sum;
+ start = i;
+ }
+ }
+
+ d_freq_offset = start - d_zeros_on_left;
+ }
+
+ void
+ dvbt_pilot_gen::compute_oneshot_csft(const gr_complex * in)
+ {
+ gr_complex left_corr_sum = 0.0; gr_complex right_corr_sum = 0.0;
+ int half_size = (d_cpilot_carriers_size - 1) / 2;
+
+ // TODO init this in constructor
+ float carrier_coeff = 1.0 / (2 * M_PI * (1 + float (d_cp_length) / float
(d_fft_length)) * 2);
+ float sampling_coeff = 1.0 / (2 * M_PI * ((1 + float (d_cp_length) /
float (d_fft_length)) * ((float)d_cpilot_carriers_size / 2.0)));
+
+ float left_angle, right_angle;
+
+ // Compute cpilots correlation between previous symbol and current symbol
+ // in both halves of the cpilots. The cpilots are distributed evenly
+ // on left and right sides of the center frequency.
+
+ for (int j = 0; j < half_size; j++) {
+ left_corr_sum += in[d_freq_offset + d_zeros_on_left +
d_cpilot_carriers[j]] * \
+ std::conj(in[d_freq_offset + d_fft_length +
d_zeros_on_left + d_cpilot_carriers[j]]);
+ }
+
+ for (int j = half_size + 1; j < d_cpilot_carriers_size; j++) {
+ right_corr_sum += in[d_freq_offset + d_zeros_on_left +
d_cpilot_carriers[j]] * \
+ std::conj(in[d_freq_offset + d_fft_length +
d_zeros_on_left + d_cpilot_carriers[j]]);
+ }
+
+ left_angle = std::arg(left_corr_sum);
+ right_angle = std::arg(right_corr_sum);
+
+ d_carrier_freq_correction = (right_angle + left_angle) * carrier_coeff;
+ d_sampling_freq_correction = (right_angle - left_angle) * sampling_coeff;
+ }
+
+ gr_complex *
+ dvbt_pilot_gen::frequency_correction(const gr_complex * in, gr_complex *
out)
+ {
+ // TODO - use PI control loop to calculate tracking corrections
+ int symbol_count = 1;
+
+ for (int k = 0; k < d_fft_length; k++) {
+ // TODO - for 2k mode the continuous pilots are not split evenly
+ // between left/right center frequency. Probably the scattered
+ // pilots needs to be added.
+
+ float correction = (float)d_freq_offset + d_carrier_freq_correction;
+
+ gr_complex c = gr_expj(-2 * M_PI * correction * \
+ (d_fft_length + d_cp_length) / d_fft_length * symbol_count);
+
+ // TODO - vectorize this operation
+ out[k] = c * in[k + d_freq_offset];
+ }
+
+ return (out);
+ }
+
+ /*
+ * Init tps sequence, return values for first position
+ * If first symbol then init tps DBPSK data
+ */
+ int
+ dvbt_pilot_gen::get_current_tpilot() const
+ {
+ return d_tps_carriers[d_tpilot_index];
+ }
+
+ gr_complex
+ dvbt_pilot_gen::get_tpilot_value(int tpilot)
+ {
+ //TODO - it can be calculated at the beginnning
+ if (d_symbol_index == 0) {
+ d_tps_carriers_val[d_tpilot_index] = gr_complex(2 * (0.5 -
d_wk[tpilot]), 0);
+ }
+ else {
+ if (d_tps_data[d_symbol_index] == 1) {
+ d_tps_carriers_val[d_tpilot_index] =
gr_complex(-d_tps_carriers_val[d_tpilot_index].real(), 0);
+ }
+ }
+
+ return d_tps_carriers_val[d_tpilot_index];
+ }
+
+ void
+ dvbt_pilot_gen::advance_tpilot()
+ {
+ ++d_tpilot_index;
+ d_tpilot_index = d_tpilot_index % d_tps_carriers_size;
+ }
+
+ /*
+ * Set a number of bits to a specified value
+ */
+ void
+ dvbt_pilot_gen::set_tps_bits(int start, int stop, unsigned int data)
+ {
+ for (int i = start; i >= stop; i--) {
+ d_tps_data[i] = data & 0x1;
+ data = data >> 1;
+ }
+ }
+
+ /*
+ * Clause 4.6
+ * Format data that will be sent with TPS signals
+ * en 300 744 - section 4.6.2
+ * s0 Initialization
+ * s1-s16 Synchronization word
+ * s17-s22 Length Indicator
+ * s23-s24 Frame Number
+ * S25-s26 Constellation
+ * s27, s28, s29 Hierarchy information
+ * s30, s31, s32 Code rate, HP stream
+ * s33, s34, s35 Code rate, LP stream
+ * s36, s37 Guard interval
+ * s38, s39 Transmission mode
+ * s40, s47 Cell identifier
+ * s48-s53 All set to "0"
+ * s54-s67 Error protection (BCH code)
+ */
+ void
+ dvbt_pilot_gen::format_tps_data()
+ {
+ //Clause 4.6.3
+ set_tps_bits(0, 0, d_wk[0]);
+ //Clause 4.6.2.2
+ if (d_frame_index % 2) {
+ set_tps_bits(16, 1, 0xca11);
+ }
+ else {
+ set_tps_bits(16, 1, 0x35ee);
+ }
+ //Clause 4.6.2.3
+ if (config.d_include_cell_id) {
+ set_tps_bits(22, 17, 0x1f);
+ }
+ else {
+ set_tps_bits(22, 17, 0x17);
+ }
+ //Clause 4.6.2.4
+ set_tps_bits(24, 23, d_frame_index);
+ //Clause 4.6.2.5
+ set_tps_bits(26, 25, config.d_constellation);
+ //Clause 4.6.2.6
+ set_tps_bits(29, 27, config.d_hierarchy);
+ //Clause 4.6.2.7
+ switch (config.d_code_rate_HP) {
+ case C1_2:
+ set_tps_bits(32, 30, 0);
+ break;
+ case C2_3:
+ set_tps_bits(32, 30, 1);
+ break;
+ case C3_4:
+ set_tps_bits(32, 30, 2);
+ break;
+ case C5_6:
+ set_tps_bits(32, 30, 3);
+ break;
+ case C7_8:
+ set_tps_bits(32, 30, 4);
+ break;
+ default:
+ set_tps_bits(32, 30, 0);
+ break;
+ }
+ switch (config.d_code_rate_LP) {
+ case C1_2:
+ set_tps_bits(35, 33, 0);
+ break;
+ case C2_3:
+ set_tps_bits(35, 33, 1);
+ break;
+ case C3_4:
+ set_tps_bits(35, 33, 2);
+ break;
+ case C5_6:
+ set_tps_bits(35, 33, 3);
+ break;
+ case C7_8:
+ set_tps_bits(35, 33, 4);
+ break;
+ default:
+ set_tps_bits(35, 33, 0);
+ break;
+ }
+ //Clause 4.6.2.8
+ set_tps_bits(37, 36, config.d_guard_interval);
+ //Clause 4.6.2.9
+ set_tps_bits(39, 38, config.d_transmission_mode);
+ //Clause 4.6.2.10
+ set_tps_bits(47, 40, config.d_cell_id);
+ //These bits are set to zero
+ set_tps_bits(53, 48, 0);
+ //Clause 4.6.2.11
+ generate_bch_code();
+ }
+
+ int
+ dvbt_pilot_gen::process_tps_data(const gr_complex * in, const int
diff_symbol_index)
+ {
+ int end_frame = 0;
+
+ // Look for TPS data only - demodulate DBPSK
+ // Calculate phase difference between previous symbol
+ // and current one to determine the current bit.
+ // Use majority voting for decision
+ int tps_majority_zero = 0;
+
+ for (int k = 0; k < d_tps_carriers_size; k++) {
+ // Use equalizer to correct data and frequency correction
+ gr_complex val = in[d_zeros_on_left + d_tps_carriers[k]] *
d_channel_gain[d_tps_carriers[k]];
+
+ if (!d_symbol_index_known || (d_symbol_index != 0)) {
+ gr_complex phdiff = val * conj(d_prev_tps_symbol[k]);
+
+ if (phdiff.real() >= 0.0) {
+ tps_majority_zero++;
+ }
+ else {
+ tps_majority_zero--;
+ }
+ }
+
+ d_prev_tps_symbol[k] = val;
+ }
+
+ // Insert obtained TPS bit into FIFO
+ // Insert the same bit into FIFO in the case
+ // diff_symbol_index is more than one. This will happen
+ // in the case of losing 1 to 3 symbols.
+ // This could be corrected by BCH decoder afterwards.
+
+ for (int i = 0; i < diff_symbol_index; i++) {
+ // Take out the front entry first
+ d_rcv_tps_data.pop_front();
+
+ // Add data at tail
+ if (!d_symbol_index_known || (d_symbol_index != 0)) {
+ if (tps_majority_zero >= 0) {
+ d_rcv_tps_data.push_back(0);
+ }
+ else {
+ d_rcv_tps_data.push_back(1);
+ }
+ }
+ else {
+ d_rcv_tps_data.push_back(0);
+ }
+ }
+
+ // Match synchronization signatures
+ if (std::equal(d_rcv_tps_data.begin() + 1, d_rcv_tps_data.begin() +
d_tps_sync_evenv.size(), d_tps_sync_evenv.begin())) {
+ // Verify parity for TPS data
+ if (!verify_bch_code(d_rcv_tps_data)) {
+ d_frame_index = (d_rcv_tps_data[23] << 1) | (d_rcv_tps_data[24]);
+
+ d_symbol_index_known = 1;
+ end_frame = 1;
+ }
+ else {
+ d_symbol_index_known = 0;
+ end_frame = 0;
+ }
+
+ // Clear up FIFO
+ for (int i = 0; i < d_symbols_per_frame; i++) {
+ d_rcv_tps_data[i] = 0;
+ }
+ }
+ else if (std::equal(d_rcv_tps_data.begin() + 1, d_rcv_tps_data.begin() +
d_tps_sync_oddv.size(), d_tps_sync_oddv.begin())) {
+ // Verify parity for TPS data
+ if (!verify_bch_code(d_rcv_tps_data)) {
+ d_frame_index = (d_rcv_tps_data[23] << 1) | (d_rcv_tps_data[24]);
+
+ d_symbol_index_known = 1;
+ end_frame = 1;
+ }
+ else {
+ d_symbol_index_known = 0;
+ end_frame = 0;
+ }
+
+ // Clear up FIFO
+ for (int i = 0; i < d_symbols_per_frame; i++) {
+ d_rcv_tps_data[i] = 0;
+ }
+ }
+
+ return end_frame;
+ }
+
+ void
+ dvbt_pilot_gen::set_chanestim_carrier(int k)
+ {
+ d_chanestim_carriers[d_chanestim_index] = k;
+ }
+
+ void
+ dvbt_pilot_gen::advance_chanestim()
+ {
+ d_chanestim_index++;
+ }
+
+ int
+ dvbt_pilot_gen::get_current_payload()
+ {
+ return d_payload_carriers[d_payload_index];
+ }
+
+ void
+ dvbt_pilot_gen::set_payload_carrier(int k)
+ {
+ d_payload_carriers[d_payload_index] = k;
+ }
+
+ void
+ dvbt_pilot_gen::advance_payload()
+ {
+ d_payload_index++;
+ }
+
+ void
+ dvbt_pilot_gen::process_payload_data(const gr_complex *in, gr_complex *out)
+ {
+ //reset indexes
+ d_spilot_index = 0; d_cpilot_index = 0; d_tpilot_index = 0;
+ d_payload_index = 0;d_chanestim_index = 0;
+ int is_payload = 1;
+
+ //process one block - one symbol
+ for (int k = 0; k < (d_Kmax - d_Kmin + 1); k++) {
+ is_payload = 1;
+
+ // Keep data for channel estimation
+ // This depends on the symbol index
+ if (k == get_current_spilot(d_mod_symbol_index)) {
+ advance_spilot(d_mod_symbol_index);
+ is_payload = 0;
+ }
+
+ // Keep data for frequency correction
+ // and channel estimation
+ if (k == get_current_cpilot()) {
+ advance_cpilot();
+ is_payload = 0;
+ }
+
+ if (k == get_current_tpilot()) {
+ advance_tpilot();
+ is_payload = 0;
+ }
+
+ // Keep payload carrier number
+ // This depends on the symbol index
+ if (is_payload) {
+ set_payload_carrier(k);
+ advance_payload();
+ }
+ }
+
+ if (d_equalizer_ready) {
+ // Equalize payload data according to channel estimator
+ for (int i = 0; i < d_payload_index; i++) {
+ out[i] = in[d_zeros_on_left + d_payload_carriers[i]] *
d_channel_gain[d_payload_carriers[i]];
+ }
+ }
+ else {
+ // If equ not ready, return 0
+ for (int i = 0; i < d_payload_length; i++) {
+ out[0] = gr_complex(0.0, 0.0);
+ }
+ }
+ }
+
+ void
+ dvbt_pilot_gen::update_output(const gr_complex *in, gr_complex *out)
+ {
+ int is_payload = 1;
+ int payload_count = 0;
+
+ //move to the next symbol
+ //re-genereate TPS data
+ format_tps_data();
+
+ //reset indexes
+ payload_count = 0;
+ d_spilot_index = 0; d_cpilot_index = 0; d_tpilot_index = 0;
+
+ for (int i = 0; i < d_zeros_on_left; i++) {
+ out[i] = gr_complex(0.0, 0.0);
+ }
+
+ //process one block - one symbol
+ for (int k = d_Kmin; k < (d_Kmax - d_Kmin + 1); k++) {
+ is_payload = 1;
+ if (k == get_current_spilot(d_symbol_index)) {
+ out[d_zeros_on_left + k] = get_spilot_value(k);
+ advance_spilot(d_symbol_index);
+ is_payload = 0;
+ }
+
+ if (k == get_current_cpilot()) {
+ out[d_zeros_on_left + k] = get_cpilot_value(k);
+ advance_cpilot();
+ is_payload = 0;
+ }
+
+ if (k == get_current_tpilot()) {
+ out[d_zeros_on_left + k] = get_tpilot_value(k);
+ advance_tpilot();
+ is_payload = 0;
+ }
+
+ if (is_payload == 1) {
+ out[d_zeros_on_left + k] = in[payload_count++];
+ }
+ }
+
+ // update indexes
+ if (++d_symbol_index == d_symbols_per_frame) {
+ d_symbol_index = 0;
+ if (++d_frame_index == d_frames_per_superframe) {
+ d_frame_index = 0;
+ d_superframe_index++;
+ }
+ }
+
+ for (int i = (d_fft_length - d_zeros_on_right); i < d_fft_length; i++) {
+ out[i] = gr_complex(0.0, 0.0);
+ }
+ }
+
+ int
+ dvbt_pilot_gen::parse_input(const gr_complex *in, gr_complex *out, int *
symbol_index, int * frame_index)
+ {
+ d_trigger_index++;
+
+ // Obtain frequency correction based on cpilots.
+ // Obtain channel estimation based on both
+ // cpilots and spilots.
+ // We use spilot correlation for finding the symbol index modulo 4
+ // The diff between previous sym index and current index is used
+ // to advance the symbol index inside a frame (0 to 67)
+ // Then based on the TPS data we find out the start of a frame
+
+ // Process cpilot data
+ // This is post FFT integer frequency offset estimation
+ // This is called before all other processing
+ process_cpilot_data(in);
+
+ // Compute one shot Post-FFT Carrier and Sampling Frequency Tracking
+ // Obtain fractional Carrer and Sampling frequency corrections
+ // Before this moment it is assumed to have corrected this:
+ // - symbol timing (pre-FFT)
+ // - symbol frequency correction (pre-FFT)
+ // - integer frequency correction (post-FFT)
+ // TODO - call this just in the aquisition mode
+ compute_oneshot_csft(in);
+
+ // Gather all corrections and obtain a corrected OFDM symbol:
+ // - input symbol shift (post-FFT)
+ // - integer frequency correction (post-FFT)
+ // - fractional frequency (carrier and sampling) corrections (post-FFT)
+ // TODO - use PI to update the corrections
+ frequency_correction(in, d_derot_in);
+
+ // Process spilot data
+ // This is channel estimation function
+ int diff_symbol_index = process_spilot_data(d_derot_in);
+
+ // Correct symbol index so that all subsequent processing
+ // use correct symbol index
+ d_symbol_index = (d_symbol_index + diff_symbol_index) %
d_symbols_per_frame;
+
+ // Symbol index is used in other modules too
+ *symbol_index = d_symbol_index;
+ // Frame index is used in other modules too
+ *frame_index = d_frame_index;
+
+ // Process TPS data
+ // If a frame is recognized then signal end of frame
+ int frame_end = process_tps_data(d_derot_in, diff_symbol_index);
+
+ // We are just at the end of a frame
+ if (frame_end) {
+ d_symbol_index = d_symbols_per_frame - 1;
+ }
+
+ // Process payload data with correct symbol index
+ process_payload_data(d_derot_in, out);
+
+ // noutput_items should be 1 in this case
+ return 1;
+ }
+
+ dvbt_reference_signals::sptr
+ dvbt_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_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_reference_signals_impl::dvbt_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_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_ninput = ninput;
+ d_noutput = noutput;
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_reference_signals_impl::~dvbt_reference_signals_impl()
+ {
+ }
+
+ void
+ dvbt_reference_signals_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items;
+ }
+
+ int
+ dvbt_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];
+
+ for (int i = 0; i < noutput_items; i++) {
+ d_pg.update_output(&in[i * d_ninput], &out[i * d_noutput]);
+ }
+
+ // 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_reference_signals_impl.h
b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.h
new file mode 100644
index 0000000..7d35620
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.h
@@ -0,0 +1,258 @@
+/* -*- 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_REFERENCE_SIGNALS_IMPL_H
+#define INCLUDED_DTV_DVBT_REFERENCE_SIGNALS_IMPL_H
+
+#include <gnuradio/dtv/dvbt_reference_signals.h>
+#include "dvbt_configure.h"
+#include <vector>
+#include <deque>
+
+ // This should eventually go into a const file
+ const int SYMBOLS_PER_FRAME = 68;
+ const int FRAMES_PER_SUPERFRAME = 4;
+
+ const int SCATTERED_PILOT_SIZE_2k = 142;
+ const int CONTINUAL_PILOT_SIZE_2k = 45;
+ const int TPS_PILOT_SIZE_2k = 17;
+
+ const int SCATTERED_PILOT_SIZE_8k = 568;
+ const int CONTINUAL_PILOT_SIZE_8k = 177;
+ const int TPS_PILOT_SIZE_8k = 68;
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_pilot_gen {
+ private:
+ // this should be first in order to be initialized first
+ const dvbt_configure &config;
+
+ int d_Kmin;
+ int d_Kmax;
+ int d_fft_length;
+ int d_payload_length;
+ int d_zeros_on_left;
+ int d_zeros_on_right;
+ int d_cp_length;
+
+ static const int d_symbols_per_frame;
+ static const int d_frames_per_superframe;
+
+ // 2k mode
+ // scattered pilot carriers info
+ static const int d_spilot_carriers_size_2k;
+
+ // continual pilot carriers info
+ static const int d_cpilot_carriers_size_2k;
+ static const int d_cpilot_carriers_2k[];
+
+ // TPS carriers info
+ static const int d_tps_carriers_size_2k;
+ static const int d_tps_carriers_2k[];
+
+ //8k mode
+ // scattered pilot carriers info
+ static const int d_spilot_carriers_size_8k;
+
+ // continual pilot carriers info
+ static const int d_cpilot_carriers_size_8k;
+ static const int d_cpilot_carriers_8k[];
+
+ // TPS carriers info
+ static const int d_tps_carriers_size_8k;
+ static const int d_tps_carriers_8k[];
+
+ // TPS sync data
+ static const int d_tps_sync_size;
+ static const int d_tps_sync_even[];
+ static const int d_tps_sync_odd[];
+
+ // Variables to keep data for 2k, 8k, 4k
+ int d_spilot_carriers_size;
+ gr_complex * d_spilot_carriers_val;
+ gr_complex * d_channel_gain;
+
+ int d_cpilot_carriers_size;
+ const int * d_cpilot_carriers;
+ float * d_known_phase_diff;
+ float * d_cpilot_phase_diff;
+ int d_freq_offset;
+ float d_carrier_freq_correction;
+ float d_sampling_freq_correction;
+
+ // Variable to keep corrected OFDM symbol
+ gr_complex * d_derot_in;
+
+ int d_tps_carriers_size;
+ const int * d_tps_carriers;
+ gr_complex * d_tps_carriers_val;
+
+ // Keeps TPS data
+ unsigned char * d_tps_data;
+ // Keep TPS carriers values from previous symbol
+ gr_complex * d_prev_tps_symbol;
+ // Keep TPS carriers values from current symbol
+ gr_complex * d_tps_symbol;
+ // Keeps the rcv TPS data, is a FIFO
+ std::deque<char> d_rcv_tps_data;
+ // Keeps the TPS sync sequence
+ std::deque<char> d_tps_sync_evenv;
+ std::deque<char> d_tps_sync_oddv;
+
+ // Keeps channel estimation carriers
+ // we use both continual and scattered carriers
+ int * d_chanestim_carriers;
+
+ // Keeps paload carriers
+ int * d_payload_carriers;
+
+ // Indexes for all carriers
+ int d_spilot_index;
+ int d_cpilot_index;
+ int d_tpilot_index;
+ int d_symbol_index;
+ int d_symbol_index_known;
+ int d_frame_index;
+ int d_superframe_index;
+ int d_freq_offset_max;
+ int d_trigger_index;
+ int d_payload_index;
+ int d_chanestim_index;
+ int d_prev_mod_symbol_index;
+ int d_mod_symbol_index;
+ int d_equalizer_ready;
+
+ // PRPS generator data buffer
+ char * d_wk;
+ // Generate PRBS
+ void generate_prbs();
+
+ // TPS private methods
+ void set_tps_bits(int start, int stop, unsigned int data);
+
+ void set_symbol_index(int index);
+ int get_symbol_index();
+ void set_tps_data();
+ void get_tps_data();
+
+ void reset_pilot_generator();
+
+ // Scattered pilot generator methods
+ int get_current_spilot(int spilot) const;
+ gr_complex get_spilot_value(int spilot);
+ void set_spilot_value(int spilot, gr_complex val);
+ void advance_spilot(int sindex);
+ // Methods used to quick iterate through all spilots
+ int get_first_spilot();
+ int get_last_spilot() const;
+ int get_next_spilot();
+ // Scattered pilot data processing method
+ int process_spilot_data(const gr_complex * in);
+
+ // Channel estimation methods
+ void set_channel_gain(int spilot, gr_complex val);
+
+ // Continual pilot generator methods
+ int get_current_cpilot() const;
+ gr_complex get_cpilot_value(int cpilot);
+ void advance_cpilot();
+ // Continual pilot data processing methods
+ void process_cpilot_data(const gr_complex * in);
+ void compute_oneshot_csft(const gr_complex * in);
+ gr_complex * frequency_correction(const gr_complex * in, gr_complex *
out);
+
+ // TPS generator methods
+ int get_current_tpilot() const;
+ gr_complex get_tpilot_value(int tpilot);
+ void advance_tpilot();
+ // TPS data
+ void format_tps_data();
+ // Encode TPS data
+ void generate_bch_code();
+ // Verify parity on TPS data
+ int verify_bch_code(std::deque<char> data);
+ // TPS data processing metods
+ int process_tps_data(const gr_complex * in, const int diff_symbo_index);
+
+ // Channel estimation methods
+ void set_chanestim_carrier(int k);
+
+ // Payload data processing methods
+ int get_current_payload();
+ void advance_chanestim();
+ void set_payload_carrier(int k);
+ void advance_payload();
+ void process_payload_data(const gr_complex *in, gr_complex *out);
+
+ public:
+ dvbt_pilot_gen(const dvbt_configure &config);
+ ~dvbt_pilot_gen();
+
+ /*!
+ * ETSI EN 300 744 Clause 4.5. \n
+ * Update a set of carriers with the pilot signals. \n
+ */
+ void update_output(const gr_complex *in, gr_complex *out);
+
+ /*!
+ * TODO
+ * ETSI EN 300 744 Clause 4.5. \n
+ * Extract data from a set of carriers using pilot signals. \n
+ * This is doing frequency correcton, equalization. \n
+ */
+ int parse_input(const gr_complex *in, gr_complex *out, int *
symbol_index, int * frame_index);
+ };
+
+ class dvbt_reference_signals_impl : public dvbt_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;
+
+ public:
+ dvbt_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_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_REFERENCE_SIGNALS_IMPL_H */
+
diff --git a/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc
b/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc
new file mode 100644
index 0000000..7c2e2f7
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.cc
@@ -0,0 +1,225 @@
+/* -*- 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_symbol_inner_interleaver_impl.h"
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ const char dvbt_symbol_inner_interleaver_impl::d_bit_perm_2k[] = {4, 3, 9,
6, 2, 8, 1, 5, 7, 0};
+ const char dvbt_symbol_inner_interleaver_impl::d_bit_perm_8k[] = {7, 1, 4,
2, 9, 6, 8, 10, 0, 3, 11, 5};
+
+ void
+ dvbt_symbol_inner_interleaver_impl::generate_H()
+ {
+ const int Mmax = d_fft_length;
+ const int Nmax = d_payload_length;
+ const int Nr = int(ceil(log2(d_fft_length)));
+ int q = 0;
+
+ for (int i = 0; i < Mmax; i++) {
+ d_h[q] = ((i % 2) << (Nr - 1)) + calculate_R(i);
+ if (d_h[q] < Nmax) {
+ q++;
+ }
+ }
+ }
+
+ int
+ dvbt_symbol_inner_interleaver_impl::H(int q)
+ {
+ return d_h[q];
+ }
+
+ int
+ dvbt_symbol_inner_interleaver_impl::calculate_R(int i)
+ {
+ const int Nr = int(ceil(log2(d_fft_length)));
+ int reg = 0;
+
+ if (i == 0) {
+ reg = 0;
+ }
+ else if (i == 1) {
+ reg = 0;
+ }
+ else if (reg == 2) {
+ reg = 1;
+ }
+ else {
+ reg = 1;
+ for (int k = 3; k <= i; k++) {
+ char new_bit = 0;
+
+ if (d_transmission_mode == T2k) {
+ new_bit = (reg ^ (reg >> 3)) & 1;
+ }
+ else if (d_transmission_mode == T8k) {
+ new_bit = (reg ^ (reg >> 1) ^ (reg >> 4) ^ (reg >> 6)) & 1;
+ }
+ else {
+ new_bit = (reg ^ (reg >> 3)) & 1;
+ }
+
+ int mask = (1 << Nr) - 1;
+ reg = ((reg >> 1) | (new_bit << (Nr - 2))) & mask;
+ }
+ }
+
+ int newreg = 0;
+
+ for (int k = 0; k < (Nr - 1); k++) {
+ char bit = (reg >> k) & 1;
+ newreg = newreg | (bit << d_bit_perm[k]);
+ }
+
+ return newreg;
+ }
+
+ dvbt_symbol_inner_interleaver::sptr
+ dvbt_symbol_inner_interleaver::make(int nsize, dvbt_transmission_mode_t
transmission, int direction)
+ {
+ return gnuradio::get_initial_sptr
+ (new dvbt_symbol_inner_interleaver_impl(nsize, transmission,
direction));
+ }
+
+ /*
+ * The private constructor
+ */
+ dvbt_symbol_inner_interleaver_impl::dvbt_symbol_inner_interleaver_impl(int
nsize, dvbt_transmission_mode_t transmission, int direction)
+ : block("dvbt_symbol_inner_interleaver",
+ io_signature::make(1, 1, sizeof(unsigned char) *
nsize),
+ io_signature::make(1, 1, sizeof(unsigned char) *
nsize)),
+ config(gr::dtv::MOD_16QAM, gr::dtv::NH, gr::dtv::C1_2, gr::dtv::C1_2,
gr::dtv::GI_1_32, transmission),
+ d_nsize(nsize), d_direction(direction),
+ d_fft_length(0), d_payload_length(0),
+ d_symbol_index(0)
+ {
+ d_symbols_per_frame = config.d_symbols_per_frame;
+ d_transmission_mode = config.d_transmission_mode;
+ d_fft_length = config.d_fft_length;
+ d_payload_length = config.d_payload_length;
+ d_direction = direction;
+
+ // Verify if transmission mode matches with size of block
+ assert(d_payload_length == d_nsize);
+
+ // Allocate memory for h vector
+ d_h = new int[d_fft_length];
+ if (d_h == NULL) {
+ std::cout << "Cannot allocate memory for d_h" << std::endl;
+ exit(1);
+ }
+
+ // Setup bit permutation vectors
+ if (d_transmission_mode == T2k) {
+ d_bit_perm = d_bit_perm_2k;
+ }
+ else if (d_transmission_mode == T8k) {
+ d_bit_perm = d_bit_perm_8k;
+ }
+ else {
+ d_bit_perm = d_bit_perm_2k;
+ }
+
+ // Generate the h function
+ generate_H();
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ dvbt_symbol_inner_interleaver_impl::~dvbt_symbol_inner_interleaver_impl()
+ {
+ delete [] d_h;
+ }
+
+ void
+ dvbt_symbol_inner_interleaver_impl::forecast (int noutput_items,
gr_vector_int &ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items;
+ }
+
+ int
+ dvbt_symbol_inner_interleaver_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 = (unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ // Demod reference signals sends a tag per OFDM frame
+ // containing the symbol index.
+ std::vector<tag_t> tags;
+ const uint64_t nread = this->nitems_read(0); //number of items read on
port 0
+
+ // Read all tags on the input buffer
+ this->get_tags_in_range(tags, 0, nread, nread + noutput_items,
pmt::string_to_symbol("symbol_index"));
+
+ for (int k = 0; k < noutput_items; k++) {
+ int blocks = k * d_nsize;
+
+ if (d_direction) {
+ // Interleave
+ for (int q = 0; q < d_nsize; q++) {
+ if (d_symbol_index % 2) {
+ out[blocks + q] = in[blocks + H(q)];
+ }
+ else {
+ out[blocks + H(q)] = in[blocks + q];
+ }
+ }
+
+ ++d_symbol_index;
+ d_symbol_index = d_symbol_index % d_symbols_per_frame;
+ }
+ else {
+ // Deinterleave
+ d_symbol_index = pmt::to_long(tags[k].value);
+
+ for (int q = 0; q < d_nsize; q++) {
+ if (d_symbol_index % 2) {
+ out[blocks + H(q)] = in[blocks + q];
+ }
+ else {
+ out[blocks + q] = in[blocks + H(q)];
+ }
+ }
+ }
+ }
+
+ // 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_symbol_inner_interleaver_impl.h
b/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.h
new file mode 100644
index 0000000..6a7265d
--- /dev/null
+++ b/gr-dtv/lib/dvbt/dvbt_symbol_inner_interleaver_impl.h
@@ -0,0 +1,70 @@
+/* -*- 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_SYMBOL_INNER_INTERLEAVER_IMPL_H
+#define INCLUDED_DTV_DVBT_SYMBOL_INNER_INTERLEAVER_IMPL_H
+
+#include <gnuradio/dtv/dvbt_symbol_inner_interleaver.h>
+#include "dvbt_configure.h"
+
+namespace gr {
+ namespace dtv {
+
+ class dvbt_symbol_inner_interleaver_impl : public
dvbt_symbol_inner_interleaver
+ {
+ private:
+ const dvbt_configure config;
+
+ int d_symbols_per_frame;
+ dvbt_transmission_mode_t d_transmission_mode;
+ int d_nsize;
+ int d_direction;
+ int d_fft_length;
+ int d_payload_length;
+
+ int * d_h;
+ const char * d_bit_perm;
+ static const char d_bit_perm_2k[];
+ static const char d_bit_perm_8k[];
+
+ //Keeps the symbol index
+ unsigned int d_symbol_index;
+
+ void generate_H();
+ int H(int q);
+ int calculate_R(int i);
+
+ public:
+ dvbt_symbol_inner_interleaver_impl(int nsize, dvbt_transmission_mode_t
transmission, int direction);
+ ~dvbt_symbol_inner_interleaver_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_SYMBOL_INNER_INTERLEAVER_IMPL_H */
+