diff options
author | Bogdan Diaconescu <b_diaconescu@yahoo.com> | 2015-05-14 03:21:28 -0700 |
---|---|---|
committer | Ron Economos <w6rz@comcast.net> | 2015-05-14 03:21:28 -0700 |
commit | 68a224931f8c15c8f718b0c095bdd2ceb4d7476d (patch) | |
tree | 3ba9ecfcf29abc5846a7aa768e2519065019624e | |
parent | 1425e4828ab61d0579d39e8e6b6f362cba1017d8 (diff) |
gr-dtv: Add DVB-T transmitter.
39 files changed, 9525 insertions, 0 deletions
diff --git a/gr-dtv/examples/dvbt_tx_2k.grc b/gr-dtv/examples/dvbt_tx_2k.grc new file mode 100644 index 0000000000..3db36aedcf --- /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 0000000000..4cad688e29 --- /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 0000000000..31f1c2cfa5 --- /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 0000000000..04518dd622 --- /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 0000000000..50746c8e4d --- /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 0000000000..4751065dd1 --- /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 0000000000..705a508033 --- /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 0000000000..3dd57a7df0 --- /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 0000000000..9be57630e5 --- /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 0000000000..f440769a46 --- /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 0000000000..d74763e5eb --- /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 0000000000..c6bfa1a7e5 --- /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 0000000000..a4c9577b54 --- /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 0000000000..b5258bbe1d --- /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 0000000000..e88596e09b --- /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 0000000000..d9b7976b31 --- /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 0000000000..08c7c571fd --- /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 0000000000..d41b949528 --- /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 0000000000..ae02c9192f --- /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 0000000000..0ab3003d50 --- /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 0000000000..c5fcbe2d82 --- /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 0000000000..1cd1b833c4 --- /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 0000000000..5e87410c90 --- /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 0000000000..e29ec8cfe2 --- /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 0000000000..2de1fab282 --- /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 0000000000..9b497195ee --- /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 0000000000..e1cfe4e925 --- /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 0000000000..4f24f0258f --- /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 0000000000..7a46a2222c --- /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 0000000000..05f6e7f69b --- /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 0000000000..045a8e0e6d --- /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 0000000000..6277350b42 --- /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 0000000000..b9286d0ffd --- /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 0000000000..561ea08ded --- /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 0000000000..669ee2761a --- /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 0000000000..d64b403915 --- /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 0000000000..7d356203cb --- /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 0000000000..7c2e2f7e1a --- /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 0000000000..6a7265d7e1 --- /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 */ + |