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
|
/* -*- c++ -*- */
/*
* Copyright (C) 2017 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio 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.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_DIGITAL_SYMBOL_SYNC_FF_IMPL_H
#define INCLUDED_DIGITAL_SYMBOL_SYNC_FF_IMPL_H
#include <gnuradio/digital/symbol_sync_ff.h>
#include "clock_tracking_loop.h"
#include "timing_error_detector.h"
#include "interpolating_resampler.h"
namespace gr {
namespace digital {
class symbol_sync_ff_impl : public symbol_sync_ff
{
public:
symbol_sync_ff_impl(enum ted_type detector_type,
float sps,
float loop_bw,
float damping_factor,
float max_deviation,
int osps,
constellation_sptr slicer,
ir_type interp_type,
int n_filters,
const std::vector<float> &taps);
~symbol_sync_ff_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);
// Symbol Clock Tracking and Estimation
float loop_bandwidth() const { return d_clock->get_loop_bandwidth(); }
float damping_factor() const { return d_clock->get_damping_factor(); }
float alpha() const { return d_clock->get_alpha(); }
float beta() const { return d_clock->get_beta(); }
void set_loop_bandwidth (float omega_n_norm) {
d_clock->set_loop_bandwidth(omega_n_norm);
}
void set_damping_factor (float zeta) {
d_clock->set_damping_factor(zeta);
}
void set_alpha (float alpha) { d_clock->set_alpha(alpha); }
void set_beta (float beta) { d_clock->set_beta(beta); }
private:
// Timing Error Detector
timing_error_detector *d_ted;
// Symbol Clock Tracking and Estimation
clock_tracking_loop *d_clock;
// Interpolator and Interpolator Positioning and Alignment
interpolating_resampler_fff *d_interp;
// Block Internal Clocks
// 4 clocks that run synchronously, aligned to the Symbol Clock:
// Interpolator Clock (always highest rate)
// Timing Error Detector Input Clock
// Output Sample Clock
// Symbol Clock (always lowest rate)
int d_interp_clock;
float d_inst_interp_period;
float d_interps_per_ted_input;
int d_interps_per_ted_input_n;
bool d_ted_input_clock;
int d_interps_per_output_sample_n;
bool d_output_sample_clock;
float d_inst_output_period;
float d_interps_per_symbol;
int d_interps_per_symbol_n;
bool d_symbol_clock;
float d_inst_clock_period;
float d_avg_clock_period;
// Block output
float d_osps;
int d_osps_n;
// Tag Propagation and Symbol Clock Tracking Reset/Resync
uint64_t d_filter_delay; // interpolator filter delay
std::vector<tag_t> d_tags;
std::vector<tag_t> d_new_tags;
pmt::pmt_t d_time_est_key;
pmt::pmt_t d_clock_est_key;
// Optional Diagnostic Outputs
int d_noutputs;
float *d_out_error;
float *d_out_instantaneous_clock_period;
float *d_out_average_clock_period;
// Block Internal Clocks
void update_internal_clock_outputs();
void advance_internal_clocks();
void revert_internal_clocks();
void sync_reset_internal_clocks();
bool ted_input_clock() { return d_ted_input_clock; }
bool output_sample_clock() { return d_output_sample_clock; }
bool symbol_clock() { return d_symbol_clock; }
// Tag Propagation and Clock Tracking Reset/Resync
void collect_tags(uint64_t nitems_rd, int count);
bool find_sync_tag(uint64_t nitems_rd, int iidx,
int distance,
uint64_t &tag_offset,
float &timing_offset,
float &clock_period);
void propagate_tags(uint64_t nitems_rd, int iidx,
float iidx_fraction,
float inst_output_period,
uint64_t nitems_wr, int oidx);
void save_expiring_tags(uint64_t nitems_rd, int consumed);
// Optional Diagnostic Outputs
void setup_optional_outputs(gr_vector_void_star &output_items);
void emit_optional_output(int oidx,
float error,
float inst_clock_period,
float avg_clock_period);
};
} /* namespace digital */
} /* namespace gr */
#endif /* INCLUDED_DIGITAL_SYMBOL_SYNC_FF_IMPL_H */
|