GNU Radio Manual and C++ API Reference  3.7.4
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
sssr_impl.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 /*
24  * --- ATSC Segment and Symbol Sync Recovery ---
25  */
26 
27 #ifndef _ATSC_SSSR_H_
28 #define _ATSC_SSSR_H_
29 
30 #include <gnuradio/atsc/api.h>
31 #include <gnuradio/atsc/consts.h>
34 #include <cstdio>
35 
36 /*
37  * --- support classes for atsci_sssr ---
38  */
39 
40 namespace sssr {
41 
42  typedef float sample_t;
43 
44  // ----------------------------------------------------------------
45  //! digital correlator for 1001 and 0110 patterns
46 
48  int d_sr; // 4 bit shift register
49 
50  public:
51 
52  // Constructor
53  digital_correlator () { reset (); }
54 
55  // Manipulators
56 
57  //! called on channel change
58  void reset () { d_sr = 0; }
59 
60  //! clock bit in and return true if we've seen 1001
61 
62  bool update (int bit) {
63  d_sr = ((bit & 1) << 3) | (d_sr >> 1);
64 
65  return (d_sr == 0x9); // 1001
66  }
67 
68  };
69 
70 
71  // ----------------------------------------------------------------
72  //! segment sync integrator
73 
75  signed char d_integrator[ATSC_DATA_SEGMENT_LENGTH];
76 
77  public:
78 
79  // Constructor
80  seg_sync_integrator () { reset (); }
81 
82  // Manipulators
83 
84  //! called on channel change
85  void reset ();
86 
87  //! update current tap with weight and return integrated correlation value
88  int update (int weight, int index);
89 
90  //! return index of maximum correlation value
91  int find_max (int *value);
92 
93  };
94 
95  // ----------------------------------------------------------------
96  //! quad filter (used to compute timing error)
97 
99  sample_t d_delay[4];
100 
101  public:
102  // Constructor
103  quad_filter () { reset (); }
104 
105  // Manipulators
106 
107  //! called on channel change
108  void reset () { d_delay[0] = d_delay[1] = d_delay[2] = d_delay[3] = 0; }
109 
110  double update (sample_t sample){
111  d_delay[3] = d_delay[2];
112  d_delay[2] = d_delay[1];
113  d_delay[1] = d_delay[0];
114  d_delay[0] = sample;
115 
116  // the coefficients are -1,-1,+1,+1
117  return d_delay[3] + d_delay[2] - d_delay[1] - d_delay[0];
118  }
119  };
120 }
121 
122 // ----------------------------------------------------------------
123 
124 /*!
125  * \brief ATSC Segment and Symbol Sync Recovery
126  *
127  * This class implements data segment sync tracking and symbol timing
128  * using the method described in "ATSC/VSB Tutorial - Receiver Technology"
129  * by Wayne E. Bretl of Zenith, pgs 41-45.
130  */
131 
133  sssr::digital_correlator d_correlator;
134  sssr::seg_sync_integrator d_integrator;
135  sssr::quad_filter d_quad_filter;
136  double d_quad_output[ATSC_DATA_SEGMENT_LENGTH];
137  double d_timing_adjust;
138  int d_counter; // free running mod 832 counter
139  int d_symbol_index;
140  bool d_seg_locked;
141  FILE *d_debug_fp;
142 
143 
144  bool incr_counter () {
145  d_counter++;
146  if (d_counter >= ATSC_DATA_SEGMENT_LENGTH){
147  d_counter = 0;
148  return true;
149  }
150  return false;
151  }
152 
153  void incr_symbol_index () {
154  d_symbol_index++;
155  if (d_symbol_index >= ATSC_DATA_SEGMENT_LENGTH)
156  d_symbol_index = 0;
157  }
158 
159 public:
160 
161  // Constructor
162  atsci_sssr ();
163  ~atsci_sssr ();
164 
165  // Manipulators
166 
167  //! call on channel change
168  void reset ();
169 
170 
171  /*!
172  * \brief process a single sample at the ATSC symbol rate (~10.76 MSPS)
173  *
174  * This block computes an indication of our timing error and keeps
175  * track of where the segment sync's occur. \p timing_adjust is
176  * returned to indicate how the interpolator timing needs to be
177  * adjusted to track the transmitter's symbol timing. If \p seg_locked
178  * is true, then \p symbol_index is the index of this sample in
179  * the current segment. The symbols are numbered from 0 to 831, where
180  * symbols 0, 1, 2 and 3 correspond to the data segment sync pattern,
181  * nominally +5, -5, -5, +5.
182  */
183 
184  void update (sssr::sample_t sample_in, // input
185  bool *seg_locked, // are we seeing segment syncs?
186  int *symbol_index, // 0..831
187  double *timing_adjust); // how much to adjust timing
188 
189 };
190 
191 // ----------------------------------------------------------------
192 
193 /*!
194  * \brief interpolator control for segment and symbol sync recovery
195  */
196 
199  gr::filter::single_pole_iir<float,float,float> d_loop; // ``VCO'' loop filter
200  double d_nominal_ratio_of_rx_clock_to_symbol_freq; // FREQ
201  double d_w; // ratio of PERIOD of Tx to Rx clocks
202  double d_mu; // fractional delay [0,1]
203  int d_incr; // diagnostic only
204  FILE *d_debug_fp; // diagnostic only
205 
206 public:
207  //! \p nominal_ratio_of_rx_clock_to_symbol_freq must be >= 1.8
208  atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq);
209  ~atsci_interpolator ();
210 
211  // Manipulators
212 
213  //! call on channel change
214  void reset ();
215 
216  /*!
217  * \brief produce next sample referenced to Tx clock
218  *
219  * If there aren't enough input_samples left to produce
220  * an output, return false, else true.
221  */
222 
223  bool update (const sssr::sample_t input_samples[], // I: vector of samples
224  int nsamples, // I: total number of samples
225  int *index, // I/O: current input index
226  double timing_adjustment, // I: how much to bump timing
227  sssr::sample_t *output_sample); // O: the output sample
228 
229  // Accessors
230 
231  // how much history we require on our input
232  unsigned ntaps () const { return d_interp.ntaps (); }
233 
234  // diagnostic accessors
235  double mu () const { return d_mu; }
236  double w () const { return d_w; }
237  int incr () const { return d_incr; }
238 
239 };
240 
241 #endif /* _ATSC_SSSR_H_ */
seg_sync_integrator()
Definition: sssr_impl.h:80
static const int ATSC_DATA_SEGMENT_LENGTH
Definition: consts.h:33
quad_filter()
Definition: sssr_impl.h:103
#define ATSC_API
Definition: gr-atsc/include/gnuradio/atsc/api.h:30
quad filter (used to compute timing error)
Definition: sssr_impl.h:98
double w() const
Definition: sssr_impl.h:236
float sample_t
Definition: sssr_impl.h:42
double update(sample_t sample)
Definition: sssr_impl.h:110
int incr() const
Definition: sssr_impl.h:237
ATSC Segment and Symbol Sync Recovery.
Definition: sssr_impl.h:132
void reset()
called on channel change
Definition: sssr_impl.h:108
interpolator control for segment and symbol sync recovery
Definition: sssr_impl.h:197
void reset()
called on channel change
Definition: sssr_impl.h:58
digital_correlator()
Definition: sssr_impl.h:53
segment sync integrator
Definition: sssr_impl.h:74
bool update(int bit)
clock bit in and return true if we've seen 1001
Definition: sssr_impl.h:62
Compute intermediate samples between signal samples x(k*Ts)
Definition: mmse_fir_interpolator_ff.h:50
double mu() const
Definition: sssr_impl.h:235
digital correlator for 1001 and 0110 patterns
Definition: sssr_impl.h:47
unsigned ntaps() const
Definition: sssr_impl.h:232