3 * Copyright 2002 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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 2, or (at your option)
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.
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.
23 #include <GrAtscBitTimingLoop2.h>
25 #include <atsc_consts.h>
30 static const int DEC = 2; // nominal decimation factor
32 static const unsigned AVG_WINDOW_LEN = 256;
33 static const float TIMING_RATE_CONST = 1e-5; // FIXME document interaction with AGC
36 GrAtscBitTimingLoop2::GrAtscBitTimingLoop2 ()
37 : VrDecimatingSigProc<float,float> (1, DEC),
38 next_input(0), dc (0.0002), mu (0.0), last_right(0), use_right_p (true)
40 history = 100; // spare input samples in case we need them.
42 #ifdef _BT_DIAG_OUTPUT_
43 fp_loop = fopen ("loop.out", "w");
49 fp_ps = fopen ("ps.out", "w");
59 // We are nominally a 2x decimator, but our actual rate varies slightly
60 // depending on the difference between the transmitter and receiver
61 // sampling clocks. Hence, we need to compute our input ranges
65 GrAtscBitTimingLoop2::forecast(VrSampleRange output,
66 VrSampleRange inputs[]) {
67 /* dec:1 ratio with history */
68 for(unsigned int i=0;i<numberInputs;i++) {
69 inputs[i].index=next_input;
70 inputs[i].size=output.size*decimation + history-1;
76 GrAtscBitTimingLoop2::filter_error (float e)
78 return e; // identity function
82 GrAtscBitTimingLoop2::work (VrSampleRange output, void *ao[],
83 VrSampleRange inputs[], void *ai[])
85 iType *in = ((iType **)ai)[0];
86 oType *out = ((oType **)ao)[0];
88 // Force in-order computation of output stream.
89 // This is required because of our slightly variable decimation factor
93 // We are tasked with producing output.size output samples.
94 // We will consume approximately 2 * output.size input samples.
97 unsigned int ii = 0; // input index
98 unsigned int k; // output index
100 // We look at a window of 3 samples that we call left (oldest),
101 // middle, right (newest). Each time through the loop, the previous
102 // right becomes the new left, and the new samples are middle and
105 // The basic game plan is to drive the average difference between
106 // right and left to zero. Given that all transitions are
107 // equiprobable (the data is white) and that the composite matched
108 // filter is symmetric (raised cosine) it turns out that in the
109 // average, if we drive that difference to zero, (implying that the
110 // average slope at the middle point is zero), we'll be sampling
111 // middle at the maximum or minimum point in the pulse.
115 iType right = last_right;
117 for (k = 0; k < output.size; k++){
121 iType middle_raw = produce_sample (in, ii);
122 iType middle_dc = dc.filter (middle_raw);
123 middle = middle_raw - middle_dc;
125 iType right_raw = produce_sample (in, ii);
126 iType right_dc = dc.filter (right_raw);
127 right = right_raw - right_dc;
129 if (use_right_p) // produce our output
135 #ifdef _BT_DIAG_OUTPUT_
144 iodata[7] = 0; // spare
145 if (fwrite (iodata, sizeof (iodata), 1, fp_loop) != 1){
146 perror ("fwrite: loop");
153 next_input += ii; // update next_input so forecast can get us what we need
158 * Produce samples equally spaced in time that are referenced
159 * to the transmitter's sample clock, not ours.
161 * See pp 523-527 of "Digital Communication Receivers", Meyr,
162 * Moeneclaey and Fechtel, Wiley, 1998.
165 GrAtscBitTimingLoop2::iType
166 GrAtscBitTimingLoop2::produce_sample (const iType *in, unsigned int &index)
168 iType n = intr.interpolate (&in[index], mu);