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 3, 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 <atsci_equalizer.h>
26 #include <atsc_types.h>
33 // total number of symbols (including field sync) / field
34 static const int SYMBOLS_PER_FIELD =
35 (ATSC_DSEGS_PER_FIELD + 1) * ATSC_DATA_SEGMENT_LENGTH;
38 atsci_equalizer::atsci_equalizer ()
41 d_offset_from_last_field_sync = 0;
45 atsci_equalizer::~atsci_equalizer ()
50 atsci_equalizer::reset ()
53 d_offset_from_last_field_sync = 0;
58 * Errrr.... Define to 1 if compiler handles tail recursion without pushing
59 * unnecessary stack frames, else define to 0 for lame compilers.
61 #define WINNING_COMPILER 0
65 * divide and conquer...
67 * Note that this could be refactored to take advantage of the
68 * symbol_num that is contained in the input_tags. Then we wouldn't
69 * have to be counting here.
71 * Today's strategy: get it working.
75 atsci_equalizer::filter (const float *input_samples,
76 const atsc::syminfo *input_tags,
77 float *output_samples,
84 // look for a field sync
87 for (i = 0; i < nsamples; i++){
88 if (atsc::tag_is_start_field_sync (input_tags[i]))
92 // whether we found one or not, everything up to it should
93 // be run through the normal path
96 filter_normal (input_samples, output_samples, i);
98 if (i == nsamples) // no field sync found, still not locked.
101 // OK, we've just transitioned to the locked state.
104 d_offset_from_last_field_sync = 0;
106 // handle locked case recursively
108 if (WINNING_COMPILER)
109 filter (&input_samples[i], &input_tags[i],
110 &output_samples[i], nsamples - i);
116 goto lame_compiler_kludge;
122 // We're in the locked state.
124 // Figure out where we are with respect to a data segment boundary
125 // and do the right thing. Note that in the interested of performance,
126 // we don't scan all the tags looking for trouble. We only check
127 // them where we expect them to be non-NORMAL. Worst case, it'll take
128 // us a field to notice that something went wrong...
130 if (d_offset_from_last_field_sync % SYMBOLS_PER_FIELD == 0){ // we should be looking
132 if (atsc::tag_is_start_field_sync_1 (input_tags[0]))
135 else if (atsc::tag_is_start_field_sync_2 (input_tags[0]))
138 else { // we're lost... no field sync where we expected it
140 cerr << "!!! atsci_equalizer: expected field sync, didn't find one\n";
143 d_offset_from_last_field_sync = 0;
145 if (WINNING_COMPILER)
146 filter (input_samples, input_tags, output_samples, nsamples);
148 goto lame_compiler_kludge;
153 // OK, everything's cool. We're looking at a field sync.
155 int n = min (ATSC_DATA_SEGMENT_LENGTH, nsamples);
157 filter_field_sync (input_samples, output_samples, n, 0, d_current_field);
159 d_offset_from_last_field_sync = n;
163 if (WINNING_COMPILER)
164 filter (&input_samples[n], &input_tags[n],
165 &output_samples[n], nsamples);
170 goto lame_compiler_kludge;
176 if (d_offset_from_last_field_sync < ATSC_DATA_SEGMENT_LENGTH){ // we're in the middle of a field sync
177 int n = min (ATSC_DATA_SEGMENT_LENGTH - d_offset_from_last_field_sync, nsamples);
179 filter_field_sync (input_samples, output_samples, n,
180 d_offset_from_last_field_sync, d_current_field);
182 d_offset_from_last_field_sync += n;
186 if (WINNING_COMPILER)
187 filter (&input_samples[n], &input_tags[n],
188 &output_samples[n], nsamples);
193 goto lame_compiler_kludge;
199 // OK, we're not in a field sync. We're either in a data segment sync or in the clear...
201 int seg_offset = d_offset_from_last_field_sync % ATSC_DATA_SEGMENT_LENGTH;
203 assert (seg_offset >= 0);
205 if (seg_offset < 4){ // somewhere in a data seg sync.
206 int n = min (4 - seg_offset, nsamples);
208 filter_data_seg_sync (input_samples, output_samples, n, seg_offset);
210 d_offset_from_last_field_sync += n;
214 if (WINNING_COMPILER)
215 filter (&input_samples[n], &input_tags[n],
216 &output_samples[n], nsamples);
221 goto lame_compiler_kludge;
227 // otherwise... we're in the normal zone
229 int n = min (ATSC_DATA_SEGMENT_LENGTH - seg_offset, nsamples);
231 filter_normal (input_samples, output_samples, n);
233 d_offset_from_last_field_sync += n;
239 if (WINNING_COMPILER)
240 filter (&input_samples[n], &input_tags[n],
241 &output_samples[n], nsamples);
246 goto lame_compiler_kludge;