Updated FSF address in all files. Fixes ticket:51
[debian/gnuradio] / gr-atsc / src / lib / GrAtscFieldSyncDemux.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
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)
10  * any later version.
11  * 
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.
16  * 
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.
21  */
22
23 #include <cmath>
24 #include <GrAtscFieldSyncDemux.h>
25 #include <atsc_consts.h>
26 #include <atsc_types.h>
27 #include <atsci_syminfo.h>
28 #include <stdio.h>
29 #include <assert.h>
30
31 using std::abs;
32
33 static const int        DEC = ATSC_DATA_SEGMENT_LENGTH; // nominal decimation factor
34
35 GrAtscFieldSyncDemux::GrAtscFieldSyncDemux ()
36   : VrDecimatingSigProc<float,atsc_soft_data_segment> (1, DEC),
37     d_locked (false), d_in_field2(true), d_segment_number(0), d_next_input(0),
38     d_lost_index (0)
39 {
40   history = 2 * ATSC_DATA_SEGMENT_LENGTH;  // spare input samples in case we need them.
41 }
42
43 GrAtscFieldSyncDemux::~GrAtscFieldSyncDemux ()
44 {
45 }
46
47 int
48 GrAtscFieldSyncDemux::forecast (VrSampleRange output,
49                                 VrSampleRange inputs[]) {
50   /* dec:1 ratio with history */
51
52   assert (numberInputs == 2);
53   
54   for (unsigned int i = 0; i < numberInputs; i++) {
55     inputs[i].index = d_next_input;
56     inputs[i].size = output.size * decimation + history - 1;
57   }
58   return 0;
59 }  
60
61 inline static bool
62 tag_is_seg_sync_or_field_sync (atsc::syminfo tag)
63 {
64   return tag.symbol_num == 0 && tag.valid;
65 }
66
67 int
68 GrAtscFieldSyncDemux::work (VrSampleRange output, void *ao[],
69                             VrSampleRange inputs[], void *ai[])
70 {
71   float         *input_samples = (float *) ai[0];
72   atsc::syminfo *input_tags    = (atsc::syminfo *) ai[1];
73   atsc_soft_data_segment  *out = ((atsc_soft_data_segment **)ao)[0];
74
75   sync (output.index);
76
77   unsigned int  ii = 0;         // input index
78
79   // Are we in sync?
80   if (!tag_is_seg_sync_or_field_sync (input_tags[0])){      // No ...
81
82     if (d_locked){
83       d_locked = false;
84       d_lost_index = inputs[0].index + ii;
85       cerr << "GrAtscFieldSyncDemux: lost sync at  "
86            << d_lost_index << endl;
87     }
88
89     // ... search for beginning of a field sync
90
91     // cerr << "GrAtscFieldSyncDemux: searching for sync at "
92     //      << inputs[0].index + ii << endl;
93
94     for (ii = 1; ii < inputs[0].size; ii++){
95       if (atsc::tag_is_start_field_sync (input_tags[ii])){
96         // found one
97         d_locked = true;
98
99         const char *str;
100         if (atsc::tag_is_start_field_sync_1 (input_tags[ii]))
101           str = "FIELD-1";
102         else if (atsc::tag_is_start_field_sync_2 (input_tags[ii]))
103           str = "FIELD-2";
104         else
105           str = "SEGMENT";
106         
107         cerr << "GrAtscFieldSyncDemux: synced (" << str << ") at "
108              << inputs[0].index + ii
109              << " [delta = " << inputs[0].index + ii - d_lost_index
110              << "]\n";
111         
112         d_next_input += ii;     // update for forecast
113         return 0;               // no work completed so far
114       }
115     }
116     // no non-NORMAL tag found
117     d_next_input += ii;         // update for forecast
118     return 0;                   // no work completed so far
119   }
120     
121   // We are in sync.  Produce output...
122
123   unsigned int  k = 0;          // output index
124
125   while (k < output.size){
126
127     if (inputs[0].size - ii < (unsigned) ATSC_DATA_SEGMENT_LENGTH){
128       // We're out of input data.
129       cerr << "GrAtscFieldSyncDemux: ran out of input data\n";
130       d_next_input += ii;       // update for forecast
131       return k;                 // return amount of work completed so far
132     }
133
134     if (!tag_is_seg_sync_or_field_sync (input_tags[ii])){
135       // lost sync...
136       // cerr << "GrAtscFieldSyncDemux: lost sync at "
137       //    << inputs[0].index + ii << endl;
138       
139       d_next_input += ii;       // update for forecast
140       return k;                 // return amount of work completed so far
141     }
142
143     if (atsc::tag_is_start_field_sync_1 (input_tags[ii])){
144       d_in_field2 = false;
145       d_segment_number = 0;
146       ii += ATSC_DATA_SEGMENT_LENGTH;   // skip over field sync
147       continue;
148     }
149     
150     if (atsc::tag_is_start_field_sync_2 (input_tags[ii])){
151       d_in_field2 = true;
152       d_segment_number = 0;
153       ii += ATSC_DATA_SEGMENT_LENGTH;   // skip over field sync
154       continue;
155     }
156
157     if (d_segment_number >= ATSC_DSEGS_PER_FIELD){
158       // something's wrong...
159       cerr << "GrAtscFieldSyncDemux: segment number overflow\n";
160       d_segment_number = 0;
161     }
162
163     out[k].pli.set_regular_seg (d_in_field2, d_segment_number++);
164     for (int jj = 0; jj < ATSC_DATA_SEGMENT_LENGTH; jj++)
165       out[k].data[jj] = input_samples[ii + jj];
166     ii += ATSC_DATA_SEGMENT_LENGTH;
167     k++;
168   }
169
170   d_next_input += ii;           // update for forecast
171   return k;                     // return amount of work completed
172 }
173