Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

atsc_sssr.h

Go to the documentation of this file.
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2002 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 * Boston, MA 02111-1307, USA. 00021 */ 00022 00023 /* 00024 * --- ATSC Segment and Symbol Sync Recovery --- 00025 */ 00026 00027 #ifndef _ATSC_SSSR_H_ 00028 #define _ATSC_SSSR_H_ 00029 00030 #include <atsc_consts.h> 00031 #include <gr_mmse_fir_interpolator.h> 00032 #include <gr_single_pole_iir.h> 00033 #include <cstdio> 00034 00035 /* 00036 * --- support classes for atsc_sssr --- 00037 */ 00038 00039 namespace sssr { 00040 00041 typedef float sample_t; 00042 00043 // ---------------------------------------------------------------- 00045 00046 class digital_correlator { 00047 int d_sr; // 4 bit shift register 00048 00049 public: 00050 00051 // Constructor 00052 digital_correlator () { reset (); } 00053 00054 // Manipulators 00055 00057 void reset () { d_sr = 0; } 00058 00060 00061 bool update (int bit) { 00062 d_sr = ((bit & 1) << 3) | (d_sr >> 1); 00063 00064 return (d_sr == 0x9); // 1001 00065 } 00066 00067 }; 00068 00069 00070 // ---------------------------------------------------------------- 00072 00073 class seg_sync_integrator { 00074 signed char d_integrator[ATSC_DATA_SEGMENT_LENGTH]; 00075 00076 public: 00077 00078 // Constructor 00079 seg_sync_integrator () { reset (); } 00080 00081 // Manipulators 00082 00084 void reset (); 00085 00087 int update (int weight, int index); 00088 00090 int find_max (int *value); 00091 00092 }; 00093 00094 // ---------------------------------------------------------------- 00096 00097 class quad_filter { 00098 sample_t d_delay[4]; 00099 00100 public: 00101 // Constructor 00102 quad_filter () { reset (); } 00103 00104 // Manipulators 00105 00107 void reset () { d_delay[0] = d_delay[1] = d_delay[2] = d_delay[3] = 0; } 00108 00109 double update (sample_t sample){ 00110 d_delay[3] = d_delay[2]; 00111 d_delay[2] = d_delay[1]; 00112 d_delay[1] = d_delay[0]; 00113 d_delay[0] = sample; 00114 00115 // the coefficients are -1,-1,+1,+1 00116 return d_delay[3] + d_delay[2] - d_delay[1] - d_delay[0]; 00117 } 00118 }; 00119 } 00120 00121 // ---------------------------------------------------------------- 00122 00131 class atsc_sssr { 00132 sssr::digital_correlator d_correlator; 00133 sssr::seg_sync_integrator d_integrator; 00134 sssr::quad_filter d_quad_filter; 00135 double d_quad_output[ATSC_DATA_SEGMENT_LENGTH]; 00136 double d_timing_adjust; 00137 int d_counter; // free running mod 832 counter 00138 int d_symbol_index; 00139 bool d_seg_locked; 00140 FILE *d_debug_fp; 00141 00142 00143 bool incr_counter () { 00144 d_counter++; 00145 if (d_counter >= ATSC_DATA_SEGMENT_LENGTH){ 00146 d_counter = 0; 00147 return true; 00148 } 00149 return false; 00150 } 00151 00152 void incr_symbol_index () { 00153 d_symbol_index++; 00154 if (d_symbol_index >= ATSC_DATA_SEGMENT_LENGTH) 00155 d_symbol_index = 0; 00156 } 00157 00158 public: 00159 00160 // Constructor 00161 atsc_sssr (); 00162 ~atsc_sssr (); 00163 00164 // Manipulators 00165 00167 void reset (); 00168 00169 00183 void update (sssr::sample_t sample_in, // input 00184 bool *seg_locked, // are we seeing segment syncs? 00185 int *symbol_index, // 0..831 00186 double *timing_adjust); // how much to adjust timing 00187 00188 }; 00189 00190 // ---------------------------------------------------------------- 00191 00196 class atsc_interpolator { 00197 gr_mmse_fir_interpolator d_interp; 00198 gr_single_pole_iir<float,float,float> d_loop; // ``VCO'' loop filter 00199 double d_nominal_ratio_of_rx_clock_to_symbol_freq; // FREQ 00200 double d_w; // ratio of PERIOD of Tx to Rx clocks 00201 double d_mu; // fractional delay [0,1] 00202 int d_incr; // diagnostic only 00203 FILE *d_debug_fp; // diagnostic only 00204 00205 public: 00207 atsc_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq); 00208 ~atsc_interpolator (); 00209 00210 // Manipulators 00211 00213 void reset (); 00214 00222 bool update (const sssr::sample_t input_samples[], // I: vector of samples 00223 int nsamples, // I: total number of samples 00224 int *index, // I/O: current input index 00225 double timing_adjustment, // I: how much to bump timing 00226 sssr::sample_t *output_sample); // O: the output sample 00227 00228 // Accessors 00229 00230 // how much history we require on our input 00231 unsigned ntaps () const { return d_interp.ntaps (); } 00232 00233 // diagnostic accessors 00234 double mu () const { return d_mu; } 00235 double w () const { return d_w; } 00236 int incr () const { return d_incr; } 00237 00238 }; 00239 00240 #endif /* _ATSC_SSSR_H_ */

Generated on Wed Aug 4 02:22:03 2004 for GNU Radio by doxygen 1.3.8