GNU Radio Manual and C++ API Reference  3.10.9.1
The Free & Open Software Radio Ecosystem
symbol_sync_cc.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright (C) 2017 Free Software Foundation, Inc.
4  * Copyright (C) 2023 Daniel Estevez <daniel@destevez.net>
5  *
6  * This file is part of GNU Radio
7  *
8  * SPDX-License-Identifier: GPL-3.0-or-later
9  *
10  */
11 
12 #ifndef INCLUDED_DIGITAL_SYMBOL_SYNC_CC_H
13 #define INCLUDED_DIGITAL_SYMBOL_SYNC_CC_H
14 
15 #include <gnuradio/block.h>
16 #include <gnuradio/digital/api.h>
20 
21 namespace gr {
22 namespace digital {
23 
24 /*!
25  * \brief Symbol Synchronizer block with complex input, complex output.
26  * \ingroup synchronizers_blk
27  *
28  * \details
29  * This implements a discrete-time error-tracking synchronizer.
30  *
31  * For this block to work properly, the input stream must meet the
32  * following requirements:
33  *
34  * 1. if not using the PFB Matched Filter interpolator, and using
35  * a non-CPM timing error detector, the input pulses must have peaks
36  * (not flat), which usually can be implemented by using a matched
37  * filter before this block.
38  *
39  * 2. for decision directed timing error detectors, the input pulses
40  * should nominally match the normalized slicer constellation, which
41  * is normalized to an average symbol magnitude of 1.0 over the entire
42  * constellation.
43  */
44 class DIGITAL_API symbol_sync_cc : virtual public block
45 {
46 public:
47  // gr::digital::symbol_sync_cc::sptr
48  typedef std::shared_ptr<symbol_sync_cc> sptr;
49 
50  /*!
51  * Make a Symbol Synchronizer block.
52  *
53  * \details
54  * This implements a discrete-time error-tracking synchronizer.
55  *
56  * For this block to work properly, the input stream must meet the
57  * following requirements:
58  *
59  * 1. if not using the PFB Matched Filter interpolator, and using
60  * a non-CPM timing error detector, the input pulses must have peaks
61  * (not flat), which usually can be implemented by using a matched
62  * filter before this block.
63  *
64  * 2. for decision directed timing error detectors, the input pulses
65  * should nominally match the normalized slicer constellation, which
66  * is normalized to an average symbol magnitude of 1.0 over the entire
67  * constellation.
68  *
69  * \param detector_type
70  * The enumerated type of timing error detector to use.
71  * See enum ted_type for a list of possible types.
72  *
73  * \param sps
74  * User specified nominal clock period in samples per symbol.
75  *
76  * \param loop_bw
77  * Approximate normalized loop bandwidth of the symbol clock tracking
78  * loop. It should nominally be close to 0, but greater than 0. If
79  * unsure, start with a number around 2*pi*0.040, and experiment to find
80  * the value that works best for your situation.
81  *
82  * \param damping_factor
83  * Damping factor of the symbol clock tracking loop.
84  * Damping < 1.0f is an under-damped loop.
85  * Damping = 1.0f/sqrt(2.0f) is a maximally flat loop response.
86  * Damping = 1.0f is a critically-damped loop.
87  * Damping > 1.0f is an over-damped loop.
88  *
89  * \param ted_gain
90  * Expected gain of the timing error detector, given the TED in use
91  * and the anticipated input amplitude, pulse shape, and Es/No.
92  * This value is the slope of the TED's S-curve at timing offset tau = 0.
93  * This value is normally computed by the user analytically or by
94  * simulation in a tool outside of GNURadio.
95  * This value must be correct for the loop filter gains to be computed
96  * properly from the desired input loop bandwidth and damping factor.
97  *
98  * \param max_deviation
99  * Maximum absolute deviation of the average clock period estimate
100  * from the user specified nominal clock period in samples per symbol.
101  *
102  * \param osps
103  * The number of output samples per symbol (default=1).
104  *
105  * \param slicer
106  * A constellation obj shared pointer that will be used by
107  * decision directed timing error detectors to make decisions.
108  * I.e. the timing error detector will use this constellation
109  * as a slicer, if the particular algorithm needs sliced
110  * symbols.
111  *
112  * \param interp_type
113  * The enumerated type of interpolating resampler to use.
114  * See the interpolating resampler type enum for a list of possible types.
115  *
116  * \param n_filters
117  * The number of arms in the polyphase filterbank of the interpolating
118  * resampler, if using an interpolating resampler that uses a PFB.
119  *
120  * \param taps
121  * The prototype filter for the polyphase filterbank of the interpolating
122  * resampler, if using an interpolating resampler that uses a PFB.
123  */
124  static sptr make(enum ted_type detector_type,
125  float sps,
126  float loop_bw,
127  float damping_factor = 1.0f,
128  float ted_gain = 1.0f,
129  float max_deviation = 1.5f,
130  int osps = 1,
131  constellation_sptr slicer = constellation_sptr(),
132  ir_type interp_type = IR_MMSE_8TAP,
133  int n_filters = 128,
134  const std::vector<float>& taps = std::vector<float>());
135 
136  /*!
137  * \brief Returns the normalized approximate loop bandwidth.
138  *
139  * \details
140  * See the documentation for set_loop_bandwidth() for more details.
141  *
142  * Note that if set_alpha() or set_beta() were called to directly
143  * set gains, the value returned by this method will be inaccurate/stale.
144  */
145  virtual float loop_bandwidth() const = 0;
146 
147  /*!
148  * \brief Returns the loop damping factor.
149  *
150  * \details
151  * See the documentation for set_damping_factor() for more details.
152  *
153  * Note that if set_alpha() or set_beta() were called to directly
154  * set gains, the value returned by this method will be inaccurate/stale.
155  */
156  virtual float damping_factor() const = 0;
157 
158  /*!
159  * \brief Returns the user provided expected gain of the Timing Error
160  * Detector.
161  *
162  * \details
163  * See the documentation for set_ted_gain() for more details.
164  */
165  virtual float ted_gain() const = 0;
166 
167  /*!
168  * \brief Returns the PI filter proportional gain, alpha.
169  *
170  * \details
171  * See the documentation for set_alpha() for more details.
172  */
173  virtual float alpha() const = 0;
174 
175  /*!
176  * \brief Returns the PI filter integral gain, beta.
177  *
178  * \details
179  * See the documentation for set_beta() for more details.
180  */
181  virtual float beta() const = 0;
182 
183  /*!
184  * \brief Returns the nominal clock period in samples per symbol.
185  *
186  * \details
187  * See the doecumentation for set_sps() for more details.
188  */
189  virtual float sps() const = 0;
190 
191  /*!
192  * \brief Set the normalized approximate loop bandwidth.
193  *
194  * \details
195  * Set the normalized approximate loop bandwidth.
196  * Useful values are usually close to 0.0, e.g. 2*pi*0.045.
197  *
198  * It should be a small positive number, corresponding to the normalized
199  * natural radian frequency of the loop as digital low-pass filter that is
200  * filtering the clock phase/timing error.
201  *
202  * Technically this parameter corresponds to the natural radian frequency
203  * of the 2nd order loop transfer function (scaled by Fs),
204  * which is the radius of the pole locations in the s-plane of an
205  * underdamped analog 2nd order system.
206  *
207  * The input parameter corresponds to omega_n_norm in the following
208  * relation:
209  *
210  * omega_n_norm = omega_n*T = 2*pi*f_n*T = 2*pi*f_n_norm
211  *
212  * where T is the period of the clock being estimated by this
213  * clock tracking loop, and omega_n is the natural radian frequency
214  * of the 2nd order loop transfer function.
215  *
216  * When a new loop bandwidth is set, the gains, alpha and beta,
217  * of the loop are automatically recalculated.
218  *
219  * \param omega_n_norm normalized approximate loop bandwidth
220  */
221  virtual void set_loop_bandwidth(float omega_n_norm) = 0;
222 
223  /*!
224  * \brief Set the loop damping factor.
225  *
226  * \details
227  * Set the damping factor of the loop.
228  * Damping in the range (0.0, 1.0) yields an under-damped loop.
229  * Damping in the range (1.0, Inf) yields an over-damped loop.
230  * Damping equal to 1.0 yields a crtically-damped loop.
231  * Damping equal to 1.0/sqrt(2.0) yields a maximally flat
232  * loop filter response.
233  *
234  * Damping factor of the 2nd order loop transfer function.
235  * When a new damping factor is set, the gains, alpha and beta,
236  * of the loop are automatically recalculated.
237  *
238  * \param zeta loop damping factor
239  */
240  virtual void set_damping_factor(float zeta) = 0;
241 
242  /*!
243  * \brief Set the expected gain of the Timing Error Detector.
244  *
245  * \details
246  * Sets the expected gain of the timing error detector, given the TED in
247  * use and the anticipated input amplitude, pulse shape, and Es/No.
248  * This value is the slope of the TED's S-curve at timing offset tau = 0.
249  * This value is normally computed by the user analytically or by
250  * simulation in a tool outside of GNURadio.
251  * This value must be correct for the loop filter gains to be computed
252  * properly from the desired input loop bandwidth and damping factor.
253  *
254  * When a new ted_gain is set, the gains, alpha and beta,
255  * of the loop are automatically recalculated.
256  *
257  * \param ted_gain expected gain of the timing error detector
258  */
259  virtual void set_ted_gain(float ted_gain) = 0;
260 
261  /*!
262  * \brief Set the PI filter proportional gain, alpha.
263  *
264  * \details
265  * Sets the PI filter proportional gain, alpha.
266  * This gain directly multiplies the clock phase/timing error
267  * term in the PI filter when advancing the loop.
268  * It most directly affects the instantaneous clock period estimate,
269  * T_inst, and instantaneous clock phase estimate, tau.
270  *
271  * This value would normally be adjusted by setting the loop
272  * bandwidth and damping factor. However,
273  * it can be set here directly if desired.
274  *
275  * Setting this parameter directly is probably only feasible if
276  * the user is directly observing the estimates of average clock
277  * period and instantaneous clock period over time in response to
278  * an impulsive change in the input stream (i.e. watching the loop
279  * transient behavior at the start of a data burst).
280  *
281  * \param alpha PI filter proportional gain
282  */
283  virtual void set_alpha(float alpha) = 0;
284 
285  /*!
286  * \brief Set the PI filter integral gain, beta.
287  *
288  * \details
289  * Sets the PI filter integral gain, beta.
290  * This gain is used when integrating the clock phase/timing error
291  * term in the PI filter when advancing the loop.
292  * It most directly affects the average clock period estimate,
293  * T_avg.
294  *
295  * This value would normally be adjusted by setting the loop
296  * bandwidth and damping factor. However,
297  * it can be set here directly if desired.
298  *
299  * Setting this parameter directly is probably only feasible if
300  * the user is directly observing the estimates of average clock
301  * period and instantaneous clock period over time in response to
302  * an impulsive change in the input stream (i.e. watching the loop
303  * transient behavior at the start of a data burst).
304  *
305  * \param beta PI filter integral gain
306  */
307  virtual void set_beta(float beta) = 0;
308 
309  /*!
310  * \brief Set the nominal clock period in samples per symbol.
311  *
312  * \details
313  * Sets the nominal clock period, resetting some of the tracking
314  * loop variables to adjust to the new clock period.
315  *
316  * \param sps User specified nominal clock period in samples per symbol.
317  */
318  virtual void set_sps(float sps) = 0;
319 };
320 
321 } /* namespace digital */
322 } /* namespace gr */
323 
324 #endif /* INCLUDED_DIGITAL_SYMBOL_SYNC_CC_H */
The abstract base class for all 'terminal' processing blocks.
Definition: gnuradio-runtime/include/gnuradio/block.h:63
Symbol Synchronizer block with complex input, complex output.
Definition: symbol_sync_cc.h:45
static sptr make(enum ted_type detector_type, float sps, float loop_bw, float damping_factor=1.0f, float ted_gain=1.0f, float max_deviation=1.5f, int osps=1, constellation_sptr slicer=constellation_sptr(), ir_type interp_type=IR_MMSE_8TAP, int n_filters=128, const std::vector< float > &taps=std::vector< float >())
virtual void set_damping_factor(float zeta)=0
Set the loop damping factor.
virtual float loop_bandwidth() const =0
Returns the normalized approximate loop bandwidth.
virtual void set_alpha(float alpha)=0
Set the PI filter proportional gain, alpha.
virtual float damping_factor() const =0
Returns the loop damping factor.
virtual void set_ted_gain(float ted_gain)=0
Set the expected gain of the Timing Error Detector.
virtual float beta() const =0
Returns the PI filter integral gain, beta.
std::shared_ptr< symbol_sync_cc > sptr
Definition: symbol_sync_cc.h:48
virtual void set_beta(float beta)=0
Set the PI filter integral gain, beta.
virtual void set_loop_bandwidth(float omega_n_norm)=0
Set the normalized approximate loop bandwidth.
virtual void set_sps(float sps)=0
Set the nominal clock period in samples per symbol.
virtual float alpha() const =0
Returns the PI filter proportional gain, alpha.
virtual float ted_gain() const =0
Returns the user provided expected gain of the Timing Error Detector.
virtual float sps() const =0
Returns the nominal clock period in samples per symbol.
#define DIGITAL_API
Definition: gr-digital/include/gnuradio/digital/api.h:18
static constexpr float taps[NSTEPS+1][NTAPS]
Definition: interpolator_taps.h:9
ted_type
Definition: timing_error_detector_type.h:18
ir_type
Definition: interpolating_resampler_type.h:18
@ IR_MMSE_8TAP
Definition: interpolating_resampler_type.h:20
GNU Radio logging wrapper.
Definition: basic_block.h:29