00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _ATSC_SSSR_H_
00028 #define _ATSC_SSSR_H_
00029
00030 #include <atsc_consts.h>
00031 #include <gri_mmse_fir_interpolator.h>
00032 #include <gr_single_pole_iir.h>
00033 #include <cstdio>
00034
00035
00036
00037
00038
00039 namespace sssr {
00040
00041 typedef float sample_t;
00042
00043
00044
00045
00046 class digital_correlator {
00047 int d_sr;
00048
00049 public:
00050
00051
00052 digital_correlator () { reset (); }
00053
00054
00055
00056
00057 void reset () { d_sr = 0; }
00058
00059
00060
00061 bool update (int bit) {
00062 d_sr = ((bit & 1) << 3) | (d_sr >> 1);
00063
00064 return (d_sr == 0x9);
00065 }
00066
00067 };
00068
00069
00070
00071
00072
00073 class seg_sync_integrator {
00074 signed char d_integrator[ATSC_DATA_SEGMENT_LENGTH];
00075
00076 public:
00077
00078
00079 seg_sync_integrator () { reset (); }
00080
00081
00082
00083
00084 void reset ();
00085
00086
00087 int update (int weight, int index);
00088
00089
00090 int find_max (int *value);
00091
00092 };
00093
00094
00095
00096
00097 class quad_filter {
00098 sample_t d_delay[4];
00099
00100 public:
00101
00102 quad_filter () { reset (); }
00103
00104
00105
00106
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
00116 return d_delay[3] + d_delay[2] - d_delay[1] - d_delay[0];
00117 }
00118 };
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 class atsci_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;
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
00161 atsci_sssr ();
00162 ~atsci_sssr ();
00163
00164
00165
00166
00167 void reset ();
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 void update (sssr::sample_t sample_in,
00184 bool *seg_locked,
00185 int *symbol_index,
00186 double *timing_adjust);
00187
00188 };
00189
00190
00191
00192
00193
00194
00195
00196 class atsci_interpolator {
00197 gri_mmse_fir_interpolator d_interp;
00198 gr_single_pole_iir<float,float,float> d_loop;
00199 double d_nominal_ratio_of_rx_clock_to_symbol_freq;
00200 double d_w;
00201 double d_mu;
00202 int d_incr;
00203 FILE *d_debug_fp;
00204
00205 public:
00206
00207 atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq);
00208 ~atsci_interpolator ();
00209
00210
00211
00212
00213 void reset ();
00214
00215
00216
00217
00218
00219
00220
00221
00222 bool update (const sssr::sample_t input_samples[],
00223 int nsamples,
00224 int *index,
00225 double timing_adjustment,
00226 sssr::sample_t *output_sample);
00227
00228
00229
00230
00231 unsigned ntaps () const { return d_interp.ntaps (); }
00232
00233
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