Fix compiler warnings across the tree. Adds --enable-warnings-as-errors configure...
[debian/gnuradio] / gr-atsc / src / lib / atsc_field_sync_demux.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 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 3, 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 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <cmath>
28 #include <atsc_field_sync_demux.h>
29 #include <gr_io_signature.h>
30 #include <atsc_types.h>
31 #include <atsc_consts.h>
32 #include <atsci_syminfo.h>
33 #include <stdio.h>
34 #include <assert.h>
35 #include <iostream>
36
37 using std::cerr;
38 using std::endl;
39
40
41 static const int        DEC = ATSC_DATA_SEGMENT_LENGTH; // nominal decimation factor
42
43
44 atsc_field_sync_demux_sptr
45 atsc_make_field_sync_demux()
46 {
47   return atsc_field_sync_demux_sptr(new atsc_field_sync_demux());
48 }
49
50 atsc_field_sync_demux::atsc_field_sync_demux()
51   : gr_block("atsc_field_sync_demux",
52                   gr_make_io_signature(2, 2, sizeof(float)),
53                   gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment))),
54                   d_locked(false), d_in_field2(true), d_segment_number(0),
55                   d_next_input(0), d_lost_index(0), d_inputs0_index(0), 
56                   d_inputs0_size(0), d_consume(0)
57 {
58   reset();
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 void
68 atsc_field_sync_demux::forecast (int noutput_items, gr_vector_int &ninput_items_required)
69 {
70   unsigned ninputs = ninput_items_required.size();
71   for (unsigned i = 0; i < ninputs; i++) {
72     ninput_items_required[i] = noutput_items * DEC + 2 * DEC ;
73
74   d_inputs0_index = d_next_input;
75   d_inputs0_size = noutput_items * DEC + 2 * DEC ;
76   }
77 }
78
79 int
80 atsc_field_sync_demux::general_work (int noutput_items,
81                                  gr_vector_int &ninput_items,
82                                  gr_vector_const_void_star &input_items,
83                                  gr_vector_void_star &output_items)
84 {
85   int   r = work (noutput_items, input_items, output_items);
86     consume_each (d_consume);
87     // printf("Consumed: %d, produced: %d\n",d_consume,r);
88     // we consume input even if no output is produced
89     // while looking for sync
90   return r;
91 }
92
93
94 int
95 atsc_field_sync_demux::work (int noutput_items,
96                        gr_vector_const_void_star &input_items,
97                        gr_vector_void_star &output_items)
98 {
99   float *in = (float *) input_items[0];
100   atsc::syminfo *input_tags    = (atsc::syminfo *) input_items[1];
101   atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0];
102
103   assert(sizeof(float) == sizeof(atsc::syminfo));
104
105   unsigned int  ii = 0;         // input index
106
107   // Are we in sync?
108   if (!tag_is_seg_sync_or_field_sync (input_tags[0])){      // No ...
109
110     if (d_locked){
111       d_locked = false;
112       d_lost_index = d_inputs0_index + ii;
113       cerr << "atsc_field_sync_demux: lost sync at  "
114            << d_lost_index << endl;
115     }
116
117     // ... search for beginning of a field sync
118
119     // cerr << "atsc_field_sync_demux: searching for sync at "
120     //      << d_inputs0_index + ii << endl;
121
122     for (ii = 1; ii < d_inputs0_size; ii++){
123       if (atsc::tag_is_start_field_sync (input_tags[ii])){
124         // found one
125         d_locked = true;
126
127         const char *str;
128         if (atsc::tag_is_start_field_sync_1 (input_tags[ii]))
129           str = "FIELD-1";
130         else if (atsc::tag_is_start_field_sync_2 (input_tags[ii]))
131           str = "FIELD-2";
132         else
133           str = "SEGMENT";
134
135         cerr << "atsc_field_sync_demux: synced (" << str << ") at "
136              << d_inputs0_index + ii
137              << " [delta = " << d_inputs0_index + ii - d_lost_index
138              << "]\n";
139
140         d_next_input += ii;     // update for forecast
141         d_consume = ii;
142         return 0;               // no work completed so far
143       }
144     }
145     // no non-NORMAL tag found
146     d_next_input += ii;         // update for forecast
147     d_consume = ii;
148     // printf("ii: %d, d_next_input: %d\n",ii,d_next_input);
149     return 0;                   // no work completed so far
150   }
151
152   // We are in sync.  Produce output...
153
154   int  k = 0;          // output index
155
156   while (k < noutput_items){
157
158     if (d_inputs0_size - ii <  static_cast<unsigned int>(ATSC_DATA_SEGMENT_LENGTH)){
159       // We're out of input data.
160       cerr << "atsc_field_sync_demux: ran out of input data\n";
161       d_next_input += ii;       // update for forecast
162       return k;                 // return amount of work completed so far
163     }
164
165     if (!tag_is_seg_sync_or_field_sync (input_tags[ii])){
166       // lost sync...
167       cerr << "atsc_field_sync_demux: lost sync at "
168            << d_inputs0_index + ii << endl;
169
170       d_next_input += ii;       // update for forecast
171       return k;                 // return amount of work completed so far
172     }
173
174     if (atsc::tag_is_start_field_sync_1 (input_tags[ii])){
175       d_in_field2 = false;
176       d_segment_number = 0;
177       ii += ATSC_DATA_SEGMENT_LENGTH;   // skip over field sync
178       continue;
179     }
180
181     if (atsc::tag_is_start_field_sync_2 (input_tags[ii])){
182       d_in_field2 = true;
183       d_segment_number = 0;
184       ii += ATSC_DATA_SEGMENT_LENGTH;   // skip over field sync
185       continue;
186     }
187
188     if (d_segment_number >= ATSC_DSEGS_PER_FIELD){
189       // something's wrong...
190       cerr << "atsc_field_sync_demux: segment number overflow\n";
191       d_segment_number = 0;
192     }
193
194     out[k].pli.set_regular_seg (d_in_field2, d_segment_number++);
195     for (int jj = 0; jj < ATSC_DATA_SEGMENT_LENGTH; jj++)
196       out[k].data[jj] = in[ii + jj];
197     ii += ATSC_DATA_SEGMENT_LENGTH;
198     k++;
199   }
200
201   d_next_input += ii;           // update for forecast
202   d_consume = ii;
203   return k;                     // return amount of work completed
204
205 }
206
207
208
209