1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
/* -*- c++ -*- */
/*
* Copyright 2015,2020 Free Software Foundation, Inc.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_DTV_DVBT_REFERENCE_SIGNALS_IMPL_H
#define INCLUDED_DTV_DVBT_REFERENCE_SIGNALS_IMPL_H
#include "dvbt_configure.h"
#include <gnuradio/dtv/dvbt_reference_signals.h>
#include <gnuradio/fft/fft.h>
#include <gnuradio/logger.h>
#include <deque>
#include <vector>
// This should eventually go into a const file
constexpr int SYMBOLS_PER_FRAME = 68;
constexpr int FRAMES_PER_SUPERFRAME = 4;
constexpr int SCATTERED_PILOT_SIZE_2k = 142;
constexpr int CONTINUAL_PILOT_SIZE_2k = 45;
constexpr int TPS_PILOT_SIZE_2k = 17;
constexpr int SCATTERED_PILOT_SIZE_8k = 568;
constexpr int CONTINUAL_PILOT_SIZE_8k = 177;
constexpr 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 methods
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:
gr::logger_ptr d_logger;
gr::logger_ptr d_debug_logger;
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 correction, 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;
fft::fft_complex ofdm_fft;
int ofdm_fft_size;
float normalization;
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 */
|