summaryrefslogtreecommitdiff
path: root/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc')
-rw-r--r--gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc1954
1 files changed, 962 insertions, 992 deletions
diff --git a/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
index bdf1574104..9b4e92b309 100644
--- a/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_reference_signals_impl.cc
@@ -1,17 +1,17 @@
/* -*- c++ -*- */
-/*
+/*
* Copyright 2015,2016,2018,2019 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,
@@ -30,573 +30,537 @@
#include <algorithm>
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
+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
+// 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
};
-
- // 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) {
+// 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) {
+ } 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 {
+ } 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;
- }
+ }
- d_freq_offset = 0;
- d_carrier_freq_correction = 0.0;
- d_sampling_freq_correction = 0.0;
+ d_freq_offset = 0;
+ d_carrier_freq_correction = 0.0;
+ d_sampling_freq_correction = 0.0;
- //allocate PRBS buffer
- d_wk = new char[d_Kmax - d_Kmin + 1];
- if (d_wk == NULL) {
+ // allocate PRBS buffer
+ d_wk = new char[d_Kmax - d_Kmin + 1];
+ if (d_wk == NULL) {
std::cerr << "Reference Signals, cannot allocate memory for d_wk." << std::endl;
throw std::bad_alloc();
- }
- // Generate wk sequence
- generate_prbs();
-
- // allocate buffer for scattered pilots
- d_spilot_carriers_val = new (std::nothrow) gr_complex[d_Kmax - d_Kmin + 1];
- if (d_spilot_carriers_val == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_spilot_carriers_val." << std::endl;
- delete [] d_wk;
+ }
+ // Generate wk sequence
+ generate_prbs();
+
+ // allocate buffer for scattered pilots
+ d_spilot_carriers_val = new (std::nothrow) gr_complex[d_Kmax - d_Kmin + 1];
+ if (d_spilot_carriers_val == NULL) {
+ std::cerr
+ << "Reference Signals, cannot allocate memory for d_spilot_carriers_val."
+ << std::endl;
+ delete[] d_wk;
throw std::bad_alloc();
- }
-
- // allocate buffer for channel gains (for each useful carrier)
- d_channel_gain = new (std::nothrow) gr_complex[d_Kmax - d_Kmin + 1];
- if (d_channel_gain == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_channel_gain." << std::endl;
- delete [] d_spilot_carriers_val;
- delete [] d_wk;
+ }
+
+ // allocate buffer for channel gains (for each useful carrier)
+ d_channel_gain = new (std::nothrow) gr_complex[d_Kmax - d_Kmin + 1];
+ if (d_channel_gain == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_channel_gain."
+ << std::endl;
+ delete[] d_spilot_carriers_val;
+ delete[] d_wk;
throw std::bad_alloc();
- }
-
- // Allocate buffer for continual pilots phase diffs
- d_known_phase_diff = new (std::nothrow) float[d_cpilot_carriers_size - 1];
- if (d_known_phase_diff == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_known_phase_diff." << std::endl;
- delete [] d_channel_gain;
- delete [] d_spilot_carriers_val;
- delete [] d_wk;
+ }
+
+ // Allocate buffer for continual pilots phase diffs
+ d_known_phase_diff = new (std::nothrow) float[d_cpilot_carriers_size - 1];
+ if (d_known_phase_diff == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_known_phase_diff."
+ << std::endl;
+ delete[] d_channel_gain;
+ delete[] d_spilot_carriers_val;
+ delete[] d_wk;
throw std::bad_alloc();
- }
-
- // 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 (std::nothrow) float[d_cpilot_carriers_size - 1];
- if (d_cpilot_phase_diff == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_cpilot_phase_diff." << std::endl;
- delete [] d_known_phase_diff;
- delete [] d_channel_gain;
- delete [] d_spilot_carriers_val;
- delete [] d_wk;
+ }
+
+ // 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 (std::nothrow) float[d_cpilot_carriers_size - 1];
+ if (d_cpilot_phase_diff == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_cpilot_phase_diff."
+ << std::endl;
+ delete[] d_known_phase_diff;
+ delete[] d_channel_gain;
+ delete[] d_spilot_carriers_val;
+ delete[] d_wk;
throw std::bad_alloc();
- }
-
- // Allocate buffer for derotated input symbol
- d_derot_in = new (std::nothrow) gr_complex[d_fft_length];
- if (d_derot_in == NULL) {
- std::cerr << "Reference Signals, 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;
+ }
+
+ // Allocate buffer for derotated input symbol
+ d_derot_in = new (std::nothrow) gr_complex[d_fft_length];
+ if (d_derot_in == NULL) {
+ std::cerr << "Reference Signals, 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;
throw std::bad_alloc();
- }
-
- // allocate buffer for first tps symbol constellation
- d_tps_carriers_val = new (std::nothrow) gr_complex[d_tps_carriers_size];
- if (d_tps_carriers_val == NULL) {
- std::cerr << "Reference Signals, 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;
+ }
+
+ // allocate buffer for first tps symbol constellation
+ d_tps_carriers_val = new (std::nothrow) gr_complex[d_tps_carriers_size];
+ if (d_tps_carriers_val == NULL) {
+ std::cerr << "Reference Signals, 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;
throw std::bad_alloc();
- }
-
- // allocate tps data buffer
- d_tps_data = new (std::nothrow) unsigned char[d_symbols_per_frame];
- if (d_tps_data == NULL) {
- std::cerr << "Reference Signals, 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;
+ }
+
+ // allocate tps data buffer
+ d_tps_data = new (std::nothrow) unsigned char[d_symbols_per_frame];
+ if (d_tps_data == NULL) {
+ std::cerr << "Reference Signals, 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;
throw std::bad_alloc();
- }
-
- d_prev_tps_symbol = new (std::nothrow) gr_complex[d_tps_carriers_size];
- if (d_prev_tps_symbol == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_prev_tps_symbol." << 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;
+ }
+
+ d_prev_tps_symbol = new (std::nothrow) gr_complex[d_tps_carriers_size];
+ if (d_prev_tps_symbol == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_prev_tps_symbol."
+ << 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;
throw std::bad_alloc();
- }
- std::fill_n(d_prev_tps_symbol, d_tps_carriers_size, 0);
-
- d_tps_symbol = new (std::nothrow) gr_complex[d_tps_carriers_size];
- if (d_tps_symbol == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_tps_symbol." << 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;
+ }
+ std::fill_n(d_prev_tps_symbol, d_tps_carriers_size, 0);
+
+ d_tps_symbol = new (std::nothrow) gr_complex[d_tps_carriers_size];
+ if (d_tps_symbol == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_tps_symbol."
+ << 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;
throw std::bad_alloc();
- }
- std::fill_n(d_tps_symbol, d_tps_carriers_size, 0);
+ }
+ std::fill_n(d_tps_symbol, d_tps_carriers_size, 0);
- // Init receive TPS data vector
- for (int i = 0; i < d_symbols_per_frame; i++) {
+ // 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++) {
+ // 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 (std::nothrow) int[d_Kmax - d_Kmin + 1];
- if (d_chanestim_carriers == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_chanestim_carriers." << 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;
- throw std::bad_alloc();
- }
-
- // Allocate buffer for payload carriers
- d_payload_carriers = new (std::nothrow) int[d_Kmax - d_Kmin + 1];
- if (d_payload_carriers == NULL) {
- std::cerr << "Reference Signals, cannot allocate memory for d_payload_carriers." << 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;
- throw std::bad_alloc();
- }
+ }
- // Reset the pilot generator
- reset_pilot_generator();
- // Format TPS data with current values
- format_tps_data();
+ // Allocate buffer for channel estimation carriers
+ d_chanestim_carriers = new (std::nothrow) int[d_Kmax - d_Kmin + 1];
+ if (d_chanestim_carriers == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_chanestim_carriers."
+ << 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;
+ throw std::bad_alloc();
}
- /*
- * 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;
+ // Allocate buffer for payload carriers
+ d_payload_carriers = new (std::nothrow) int[d_Kmax - d_Kmin + 1];
+ if (d_payload_carriers == NULL) {
+ std::cerr << "Reference Signals, cannot allocate memory for d_payload_carriers."
+ << 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;
+ throw std::bad_alloc();
}
- /*
- * 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++) {
+ // 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++) {
+/*
+ * 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 = 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++) {
+ 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;
+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
+ // 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];
+ //(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++) {
+ // 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++) {
+ // 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 = 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;
+ reg_bch = reg_bch ^ (feedback << 12) ^ (feedback << 11) ^ (feedback << 9) ^
+ (feedback << 8) ^ (feedback << 7) ^ (feedback << 5) ^ (feedback << 4);
}
- void
- dvbt_pilot_gen::set_tps_data()
- {
+ for (int i = 0; i < 14; i++) {
+ if ((unsigned int)data[i + 54] != (0x1 & (reg_bch >> i))) {
+ ret = -1;
+ break;
+ }
}
- void
- dvbt_pilot_gen::get_tps_data()
- {
- }
+ return ret;
+}
- /*
- * 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;
- }
+void dvbt_pilot_gen::set_symbol_index(int sindex) { d_symbol_index = sindex; }
- /*
- * 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);
- }
+int dvbt_pilot_gen::get_symbol_index() { return d_symbol_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_tps_data() {}
- 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;
+void dvbt_pilot_gen::get_tps_data() {}
- if (sindex == 0) {
+/*
+ * 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;
+ // TODO - fix this - what value should we use?
+ ++d_spilot_index;
+ d_spilot_index = d_spilot_index % size;
+}
- return (d_Kmin + 3 * (d_symbol_index % 4));
- }
+int dvbt_pilot_gen::get_first_spilot()
+{
+ d_spilot_index = 0;
- int
- dvbt_pilot_gen::get_last_spilot() const
- {
- int size = d_spilot_carriers_size - 1;
+ return (d_Kmin + 3 * (d_symbol_index % 4));
+}
- if (d_symbol_index == 0) {
- size = d_spilot_carriers_size;
- }
+int dvbt_pilot_gen::get_last_spilot() const
+{
+ int size = d_spilot_carriers_size - 1;
- return (d_Kmin + 3 * (d_symbol_index % 4) + 12 * size);
+ if (d_symbol_index == 0) {
+ size = d_spilot_carriers_size;
}
- int
- dvbt_pilot_gen::get_next_spilot()
- {
- int pilot = (d_Kmin + 3 * (d_symbol_index % 4) + 12 * (++d_spilot_index));
+ return (d_Kmin + 3 * (d_symbol_index % 4) + 12 * size);
+}
- if (pilot > d_Kmax) {
- pilot = d_Kmax;
- }
+int dvbt_pilot_gen::get_next_spilot()
+{
+ int pilot = (d_Kmin + 3 * (d_symbol_index % 4) + 12 * (++d_spilot_index));
- return pilot;
+ if (pilot > d_Kmax) {
+ pilot = d_Kmax;
}
- 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;
+ 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();
- }
+ // 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);
@@ -604,44 +568,46 @@ namespace gr {
// 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]]);
+ 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;
+ 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
- /*************************************************************/
+ /*************************************************************/
+ // 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;
+ d_spilot_index = 0;
+ d_cpilot_index = 0;
+ d_chanestim_index = 0;
- for (int k = 0; k < (d_Kmax - d_Kmin + 1); k++) {
+ 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();
+ 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();
+ 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++) {
+ // 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];
@@ -649,642 +615,646 @@ namespace gr {
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);
+ 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;
+ 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);
- }
+ // Signal that equalizer is ready
+ d_equalizer_ready = 1;
- void
- dvbt_pilot_gen::advance_cpilot()
- {
- ++d_cpilot_index;
- d_cpilot_index = d_cpilot_index % d_cpilot_carriers_size;
- }
+ int diff_sindex = (d_mod_symbol_index - d_prev_mod_symbol_index + 4) % 4;
- 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
+ d_prev_mod_symbol_index = d_mod_symbol_index;
- float max = 0; float sum = 0;
- int start = 0;
- float phase;
+ return diff_sindex;
+}
- for (int i = d_zeros_on_left - d_freq_offset_max; i < d_zeros_on_left + d_freq_offset_max; i++) {
+/*
+ * 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;
+ 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;
+ 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;
+ d_freq_offset = start - d_zeros_on_left;
+}
- // TODO init this in constructor
- float carrier_coeff = 1.0 / (2 * GR_M_PI * (1 + float (d_cp_length) / float (d_fft_length)) * 2);
- float sampling_coeff = 1.0 / (2 * GR_M_PI * ((1 + float (d_cp_length) / float (d_fft_length)) * ((float)d_cpilot_carriers_size / 2.0)));
+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;
- float left_angle, right_angle;
+ // TODO init this in constructor
+ float carrier_coeff =
+ 1.0 / (2 * GR_M_PI * (1 + float(d_cp_length) / float(d_fft_length)) * 2);
+ float sampling_coeff = 1.0 / (2 * GR_M_PI *
+ ((1 + float(d_cp_length) / float(d_fft_length)) *
+ ((float)d_cpilot_carriers_size / 2.0)));
- // 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.
+ float left_angle, right_angle;
- 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]]);
- }
+ // 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 = 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);
+ 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]]);
+ }
- d_carrier_freq_correction = (right_angle + left_angle) * carrier_coeff;
- d_sampling_freq_correction = (right_angle - left_angle) * sampling_coeff;
+ 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]]);
}
- 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;
+ left_angle = std::arg(left_corr_sum);
+ right_angle = std::arg(right_corr_sum);
- for (int k = 0; k < d_fft_length; k++) {
+ 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 * GR_M_PI * correction * \
- (d_fft_length + d_cp_length) / d_fft_length * symbol_count);
+ gr_complex c = gr_expj(-2 * GR_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];
- }
+ return (out);
+}
- gr_complex
- dvbt_pilot_gen::get_tpilot_value(int tpilot)
- {
- //TODO - it can be calculated at the beginnning
- if (d_symbol_index == 0) {
+/*
+ * 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 {
+ } 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);
+ 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;
- }
+ 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--) {
+/*
+ * 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) {
+}
+
+/*
+ * 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 {
+ } else {
set_tps_bits(16, 1, 0x35ee);
- }
- //Clause 4.6.2.3
- if (config.d_include_cell_id) {
+ }
+ // Clause 4.6.2.3
+ if (config.d_include_cell_id) {
set_tps_bits(22, 17, 0x1f);
- }
- else {
+ } 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
- if (d_frame_index % 2) {
+ }
+ // 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
+ if (d_frame_index % 2) {
set_tps_bits(47, 40, config.d_cell_id & 0xff);
- }
- else {
+ } else {
set_tps_bits(47, 40, (config.d_cell_id >> 8) & 0xff);
- }
- //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++) {
+ // 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]];
+ 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--;
- }
+ 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.
+ // 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++) {
+ 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) {
+ 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);
- }
- 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())) {
+ // 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_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;
+ 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;
+ 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())) {
+ } 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_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;
+ 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;
+ 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;
- }
+ return end_frame;
+}
- void
- dvbt_pilot_gen::advance_chanestim()
- {
- d_chanestim_index++;
- }
+void dvbt_pilot_gen::set_chanestim_carrier(int k)
+{
+ d_chanestim_carriers[d_chanestim_index] = k;
+}
- int
- dvbt_pilot_gen::get_current_payload()
- {
- return d_payload_carriers[d_payload_index];
- }
+void dvbt_pilot_gen::advance_chanestim() { d_chanestim_index++; }
- void
- dvbt_pilot_gen::set_payload_carrier(int k)
- {
- d_payload_carriers[d_payload_index] = k;
- }
+int dvbt_pilot_gen::get_current_payload() { return d_payload_carriers[d_payload_index]; }
- void
- dvbt_pilot_gen::advance_payload()
- {
- d_payload_index++;
- }
+void dvbt_pilot_gen::set_payload_carrier(int k)
+{
+ d_payload_carriers[d_payload_index] = k;
+}
- 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;
+void dvbt_pilot_gen::advance_payload() { d_payload_index++; }
- //process one block - one symbol
- for (int k = 0; k < (d_Kmax - d_Kmin + 1); k++) {
+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;
+ 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;
+ advance_cpilot();
+ is_payload = 0;
}
if (k == get_current_tpilot()) {
- advance_tpilot();
- is_payload = 0;
+ advance_tpilot();
+ is_payload = 0;
}
// Keep payload carrier number
// This depends on the symbol index
if (is_payload) {
- set_payload_carrier(k);
- advance_payload();
+ set_payload_carrier(k);
+ advance_payload();
}
- }
+ }
- if (d_equalizer_ready) {
+ 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]];
+ out[i] = in[d_zeros_on_left + d_payload_carriers[i]] *
+ d_channel_gain[d_payload_carriers[i]];
}
- }
- else {
+ } else {
// If equ not ready, return 0
for (int i = 0; i < d_payload_length; i++) {
- out[0] = gr_complex(0.0, 0.0);
+ 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;
+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();
+ // 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;
+ // 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++) {
+ 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)) {
+ // 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()) {
+ 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()) {
+ if (k == get_current_tpilot()) {
out[d_zeros_on_left + k] = get_tpilot_value(k);
advance_tpilot();
is_payload = 0;
- }
+ }
- if (is_payload == 1) {
+ if (is_payload == 1) {
out[d_zeros_on_left + k] = in[payload_count++];
- }
- }
+ }
+ }
- // update indexes
- if (++d_symbol_index == d_symbols_per_frame) {
+ // 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++;
+ d_frame_index = 0;
+ d_superframe_index++;
}
- }
+ }
- for (int i = (d_fft_length - d_zeros_on_right); i < d_fft_length; i++) {
+ 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 acquisition 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) {
+}
+
+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 acquisition 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++) {
+ // 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 */
+ // 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 */