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 <gr_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
00045
00046 class digital_correlator {
00047 int d_sr;
00048
00049
public:
00050
00051
00052 digital_correlator () {
reset (); }
00053
00054
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);
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
00079 seg_sync_integrator () {
reset (); }
00080
00081
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
00102 quad_filter () {
reset (); }
00103
00104
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
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;
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
atsc_sssr ();
00162
~atsc_sssr ();
00163
00164
00165
00167
void reset ();
00168
00169
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
00196 class atsc_interpolator {
00197 gr_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:
00207
atsc_interpolator (
double nominal_ratio_of_rx_clock_to_symbol_freq);
00208
~atsc_interpolator ();
00209
00210
00211
00213
void reset ();
00214
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