Houston, we have a trunk.
[debian/gnuradio] / gr-atsc / src / lib / qa_atsci_data_interleaver.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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <cppunit/TestAssert.h>
24 #include <qa_atsci_data_interleaver.h>
25
26
27 /*!
28  * write an easy to identify pattern into the packet
29  */
30 void
31 qa_atsci_data_interleaver::init_test_packet (int counter,
32                                             atsc_mpeg_packet_rs_encoded &out)
33 {
34   out.data[0] = 0xf0;
35   out.data[1] = 0xff;
36   out.data[2] = (counter >> 8) & 0xff;
37   out.data[3] = counter & 0xff;
38
39   for (int i = 4; i < 205; i++)
40     out.data[i] = i;
41
42   out.data[205] = 0xa0;
43   out.data[206] = 0xaf;
44 }
45
46 void
47 qa_atsci_data_interleaver::print_packet (FILE *fp,
48                                         int frame_number,
49                                         int field_number,
50                                         int segment_number,
51                                         const atsc_mpeg_packet_rs_encoded &in)
52 {
53   fprintf (fp, "%04d:%d:%03d  ", frame_number, field_number, segment_number);
54
55   const unsigned char *p = &in.data[0];
56   for (int i = 0; i < 8; i++)
57     fprintf (fp, "%02X", p[i]);
58
59   fprintf (fp, "  ");
60   p = &in.data[8];
61   for (int i = 0; i < 8; i++)
62     fprintf (fp, "%02X", p[i]);
63
64   
65   fprintf (fp, "  ...  ");
66   p = &in.data[191];
67   for (int i = 0; i < 8; i++)
68     fprintf (fp, "%02X", p[i]);
69
70   fprintf (fp, "  ");
71   p = &in.data[199];
72   for (int i = 0; i < 8; i++)
73     fprintf (fp, "%02X", p[i]);
74
75   fprintf (fp, "\n");
76 }
77
78 void
79 qa_atsci_data_interleaver::chk_assert (const atsc_mpeg_packet_rs_encoded &expected,
80                                       const atsc_mpeg_packet_rs_encoded &actual)
81 {
82   if (expected == actual)
83     return;
84
85   FILE *fp = stderr;
86
87   fprintf (fp, "Expected: ");
88   print_packet (fp, 0, 0, 0, expected);
89
90   fprintf (fp, "Actual:   ");
91   print_packet (fp, 0, 0, 0, actual);
92
93   CPPUNIT_ASSERT (expected == actual);
94 }
95
96 void
97 qa_atsci_data_interleaver::t0 ()
98 {
99   int   counter = 0;
100   atsc_mpeg_packet_rs_encoded   in, enc, out;
101   atsc_mpeg_packet_rs_encoded   zero;
102
103   memset (&zero, 0, sizeof (zero));
104   
105   for (int frame = 0; frame < 4; frame++){
106     for (int field = 0; field < 2; field++){
107       for (int segment = 0; segment < 312; segment++, counter++){
108
109         // build test packet
110         init_test_packet (counter, in);
111         in.pli.set_regular_seg (field == 1, segment);
112
113         // interleave it
114         outbound.interleave (enc, in);
115
116         // deinterleave it
117         inbound.deinterleave (out, enc);
118
119         if (counter < 52)
120           // CPPUNIT_ASSERT (zero == out);
121           chk_assert (zero, out);
122
123         else if (counter >= 52){
124           atsc_mpeg_packet_rs_encoded expected;
125           init_test_packet (counter - 52, expected);
126           // CPPUNIT_ASSERT (expected == out);
127           chk_assert (expected, out);
128         }
129       }
130     }
131   }
132 }
133
134 //
135 // Note, this assumes that the interleaver and deinterleaver
136 // have the state left by t0.
137 //
138 // This test pushes crap into the interleaver, and then confirms that
139 // the deinterleaver recovers.  This would be part of what you'd see
140 // on a channel change.
141 //
142
143 void
144 qa_atsci_data_interleaver::t1 ()
145 {
146   int   counter = 0;
147   atsc_mpeg_packet_rs_encoded   in, enc, out;
148   atsc_mpeg_packet_rs_encoded   zero;
149
150   memset (&zero, 0, sizeof (zero));
151   
152   static const int NCRAP = 13;
153   
154   // push NCRAP segments of crap into the interleaver,
155   // but don't change the deinterleaver state
156
157   for (int i = 0; i < NCRAP; i++){
158     init_test_packet (i + 2758, in);
159     in.pli.set_regular_seg (false, i + 5);
160
161     outbound.interleave (enc, in);
162   }
163
164   // now run the normal test.
165   // we should get good segments after NCRAP + 52
166   
167   int starting_counter = 3141;
168   counter = starting_counter;
169
170   for (int frame = 0; frame < 4; frame++){
171     for (int field = 0; field < 2; field++){
172       for (int segment = 0; segment < 312; segment++, counter++){
173
174         // build test packet
175         init_test_packet (counter, in);
176         in.pli.set_regular_seg (field == 1, segment);
177
178         // interleave it
179         outbound.interleave (enc, in);
180
181         // deinterleave it
182         inbound.deinterleave (out, enc);
183
184         if (counter < starting_counter + 52 + NCRAP){
185           // don't care...
186         }
187         else if (counter >= starting_counter + 52 + NCRAP){
188           atsc_mpeg_packet_rs_encoded expected;
189           init_test_packet (counter - 52, expected);
190           // CPPUNIT_ASSERT (expected == out);
191           chk_assert (expected, out);
192         }
193       }
194     }
195   }
196 }