Merge commit 'v3.3.0' into upstream
[debian/gnuradio] / gr-atsc / src / lib / qa_atsci_equalizer_nop.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 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 #include <qa_atsci_equalizer_nop.h>
24 #include <atsci_equalizer.h>
25 #include <atsci_equalizer_nop.h>
26 #include <atsci_pnXXX.h>
27 #include <atsc_types.h>
28 #include <cppunit/TestAssert.h>
29 #include <assert.h>
30 #include <iostream>
31 #include <string.h>
32
33 using std::cerr;
34 using std::endl;
35
36
37 static const int SYMBOLS_PER_FIELD = (ATSC_DSEGS_PER_FIELD + 1) * ATSC_DATA_SEGMENT_LENGTH;
38 static const int PAD = 500;
39 static const int NFIELDS = 2;
40
41 static const int INPUT_SIZE = PAD + (NFIELDS * SYMBOLS_PER_FIELD);
42
43 static float
44 bin_map (int bit)
45 {
46   return bit ? +5 : -5;
47 }
48
49 static void
50 init_tags (atsc::syminfo *tags, int segnum, int fieldnum)
51 {
52   int   i;
53
54   for (i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++){
55     tags[i].symbol_num = i;
56     tags[i].segment_num = segnum;
57     tags[i].field_num = fieldnum;
58     tags[i].valid = 1;
59   }
60 }
61
62 static void
63 init_data_seg (float *p, atsc::syminfo *tags, int v, int segnum, int fieldnum)
64 {
65   init_tags (tags, segnum, fieldnum);
66
67   int   i = 0;
68
69   p[i++] = bin_map (1);                 // data segment sync pulse
70   p[i++] = bin_map (0);
71   p[i++] = bin_map (0);
72   p[i++] = bin_map (1);
73
74   for (; i < ATSC_DATA_SEGMENT_LENGTH; i++)
75     p[i] = (float) (i + v);
76 }
77
78 static void
79 init_field_sync_tags (atsc::syminfo *tags, int fieldnum)
80 {
81   init_tags (tags, atsc::SI_FIELD_SYNC_SEGMENT_NUM, fieldnum);
82 }
83
84 static void
85 init_field_sync_common (float *p, int mask)
86                         
87 {
88   int  i = 0;
89
90   p[i++] = bin_map (1);                 // data segment sync pulse
91   p[i++] = bin_map (0);
92   p[i++] = bin_map (0);
93   p[i++] = bin_map (1);
94
95   for (int j = 0; j < 511; j++)         // PN511
96     p[i++] = bin_map (atsc_pn511[j]);
97
98   for (int j = 0; j < 63; j++)          // PN63
99     p[i++] = bin_map (atsc_pn63[j]);
100
101   for (int j = 0; j < 63; j++)          // PN63, toggled on field 2
102     p[i++] = bin_map (atsc_pn63[j] ^ mask);
103   
104   for (int j = 0; j < 63; j++)          // PN63
105     p[i++] = bin_map (atsc_pn63[j]);
106
107   p[i++] = bin_map (0);                 // 24 bits of VSB8 mode identifiera
108   p[i++] = bin_map (0);
109   p[i++] = bin_map (0);
110   p[i++] = bin_map (0);
111
112   p[i++] = bin_map (1);
113   p[i++] = bin_map (0);
114   p[i++] = bin_map (1);
115   p[i++] = bin_map (0);
116
117   p[i++] = bin_map (0);
118   p[i++] = bin_map (1);
119   p[i++] = bin_map (0);
120   p[i++] = bin_map (1);
121
122   p[i++] = bin_map (1);
123   p[i++] = bin_map (1);
124   p[i++] = bin_map (1);
125   p[i++] = bin_map (1);
126
127   p[i++] = bin_map (0);
128   p[i++] = bin_map (1);
129   p[i++] = bin_map (0);
130   p[i++] = bin_map (1);
131
132   p[i++] = bin_map (1);
133   p[i++] = bin_map (0);
134   p[i++] = bin_map (1);
135   p[i++] = bin_map (0);
136
137
138   for (int j = 0; j < 92; j++)          // 92 more bits
139     p[i++] = bin_map (atsc_pn63[j % 63]);
140
141   // now copy the last 12 symbols of the previous segment
142   // bogus fill
143
144   for (int j = 0; j < 12; j++)
145     p[i++] = bin_map (j & 1);
146
147   assert (i == ATSC_DATA_SEGMENT_LENGTH);
148 }
149
150 void
151 qa_atsci_equalizer_nop::setUp ()
152 {
153   eq = new atsci_equalizer_nop ();
154 }
155
156 void
157 qa_atsci_equalizer_nop::tearDown ()
158 {
159   delete eq;
160   eq = 0;
161 }
162
163 static void
164 setup_test_data (float *data, atsc::syminfo *tags)
165 {
166   int   mask = 0;
167   int   i = 0;
168
169   for (i = 0; i < PAD; i++){
170     data[i] = (float) i;
171     tags[i].symbol_num = 13 + i;
172     tags[i].segment_num = 17;
173     tags[i].field_num = 0;
174     tags[i].valid = 1;
175   }
176
177   for (int nfields = 0; nfields < NFIELDS; nfields++){
178     init_field_sync_common (&data[i], mask);
179     init_field_sync_tags (&tags[i], mask);
180     i += ATSC_DATA_SEGMENT_LENGTH;
181
182     for (int segnum = 0; segnum < 312; segnum++){
183       init_data_seg (&data[i], &tags[i], i, segnum, mask);
184       i += ATSC_DATA_SEGMENT_LENGTH;
185     }
186     mask ^= 1;
187   }
188   assert (i == INPUT_SIZE);
189 }
190
191 void
192 qa_atsci_equalizer_nop::t0 ()
193 {
194   // these are dynamically allocated because they are bigger
195   // than the default stack limit.
196
197   float         *input_data = new float[INPUT_SIZE];
198   atsc::syminfo *input_tags = new atsc::syminfo[INPUT_SIZE];
199   float         *output_data = new float[INPUT_SIZE];
200
201   try {
202
203     memset (input_data, 0, sizeof (input_data));
204     memset (input_tags, 0, sizeof (input_tags));
205     memset (output_data, 0, sizeof (output_data));
206
207     setup_test_data (input_data, input_tags);
208
209     eq->filter (input_data, input_tags,
210                 output_data, INPUT_SIZE);
211
212
213     // now check that data values got copied correctly
214
215     for (int i = 0; i < INPUT_SIZE; i++){
216
217       if (input_tags[i].segment_num == atsc::SI_FIELD_SYNC_SEGMENT_NUM){
218         // ignore entire field sync data segment
219       }
220       else if (input_tags[i].symbol_num <= 3){
221         // ignore 4 symbols of data segment sync (+5, -5, -5, +5)
222       }
223       else {
224         if (output_data[i] != (float) i){
225           cerr << "output_data[" << i << "] == " << output_data[i] << endl;
226           CPPUNIT_ASSERT_DOUBLES_EQUAL ((float) i, output_data[i], 1e-6);
227         }
228       }
229     }
230
231     delete [] input_data;
232     delete [] input_tags;
233     delete [] output_data;
234   }
235
236   catch ( ... ){
237     delete [] input_data;
238     delete [] input_tags;
239     delete [] output_data;
240   }
241 }
242
243 void
244 qa_atsci_equalizer_nop::t1 ()
245 {
246   // think of another test...
247 }