Merge branch 'upstream' into dfsg-orig
[debian/gnuradio] / gr-atsc / src / lib / qa_atsci_viterbi_decoder.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 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <cppunit/TestAssert.h>
28 #include <qa_atsci_viterbi_decoder.h>
29 #include <qa_atsci_trellis_encoder.h>
30 #include <cstdio>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <time.h>
34
35 #define NELEM(x) (sizeof (x) / sizeof (x[0]))
36
37
38 static const int NCODERS = atsci_viterbi_decoder::NCODERS;
39
40 #if 0
41 static void
42 map_to_soft_symbols (atsc_soft_data_segment &out,
43                      const atsc_data_segment &in)
44 {
45   for (unsigned int i = 0; i < NELEM (in.data); i++){
46     out.data[i] = in.data[i] * 2 - 7;
47   }
48 }
49 #endif
50
51 static void
52 pad_decoder_input (atsc_soft_data_segment out[NCODERS])
53 {
54   memset (out,  0, sizeof (out));
55
56   // add data segment sync
57   for (int i = 0; i < NCODERS; i++){
58     out[i].data[0] =  5;
59     out[i].data[1] = -5;
60     out[i].data[2] = -5;
61     out[i].data[3] =  5;
62     out[i].pli.set_regular_seg (false, i);
63   }
64 }
65
66 void
67 qa_atsci_viterbi_decoder::t0 ()
68 {
69 #if 0
70   atsci_trellis_encoder         enc;
71   atsc_mpeg_packet_rs_encoded   encoder_in[NCODERS];
72   atsc_data_segment             encoder_out[NCODERS];
73   atsc_soft_data_segment        decoder_in[NCODERS];
74   atsc_soft_data_segment        decoder_in_pad[NCODERS];
75   atsc_mpeg_packet_rs_encoded   decoder_out[NCODERS];
76   atsc_mpeg_packet_rs_encoded   decoder_out_pad[NCODERS];
77
78   
79   memset (encoder_in,      0, sizeof (encoder_in));
80   memset (encoder_out,     0, sizeof (encoder_out));
81   memset (decoder_out_pad, 0, sizeof (decoder_out_pad));
82
83   srandom (1);
84
85   for (int i = 0; i < NCODERS; i++){
86     for (unsigned int j = 0; j < NELEM (encoder_in[i].data); j++){
87       int t = (random () >> 8) & 0xff;  // 8 random bits
88       encoder_in[i].data[j] = t;
89     }
90   }
91   
92   fflush (stdout);
93   printf ("@@@ ENCODER INPUT @@@\n");
94   for (int i = 0; i < NCODERS; i++){
95     for (unsigned int j = 0; j < NELEM (encoder_in[i].data); j++){
96        printf ("%d\n", encoder_in[i].data[j]);
97     }
98   }
99
100   enc.reset ();
101   enc.encode (encoder_out, encoder_in);
102
103   printf ("@@@ ENCODER OUTPUT @@@\n");
104   for (int i = 0; i < NCODERS; i++){
105     for (unsigned int j = 0; j < NELEM (encoder_out[i].data); j++){
106        printf ("%d\n", encoder_out[i].data[j]);
107     }
108   }
109
110   for (int i = 0; i < NCODERS; i++)
111     map_to_soft_symbols (decoder_in[i], encoder_out[i]);
112
113   viterbi.reset ();
114
115   // this has only the previous (non-existant) output
116   viterbi.decode (decoder_out_pad, decoder_in); 
117
118   // now we'll see the real output
119   pad_decoder_input (decoder_in_pad);
120   viterbi.decode (decoder_out, decoder_in_pad);
121
122   printf ("@@@ DECODER OUTPUT @@@\n");
123   for (int i = 0; i < NCODERS; i++){
124     for (unsigned int j = 0; j < NELEM (decoder_out[i].data); j++){
125        printf ("%d\n", decoder_out[i].data[j]);
126     }
127   }
128   fflush (stdout);
129 #endif
130 }
131
132 void
133 qa_atsci_viterbi_decoder::t1 ()
134 {
135   atsc_soft_data_segment        decoder_in[NCODERS];
136   atsc_soft_data_segment        decoder_in_pad[NCODERS];
137   atsc_mpeg_packet_rs_encoded   decoder_out[NCODERS];
138   atsc_mpeg_packet_rs_encoded   decoder_out_pad[NCODERS];
139   atsc_mpeg_packet_rs_encoded   expected_out[NCODERS];
140   static const float            raw_input[NCODERS * NELEM (decoder_in[0].data)] = {
141 #include "qa_atsci_viterbi_decoder_t1_input.dat"
142   };
143   static const unsigned char    raw_output[NCODERS * NELEM (expected_out[0].data)] = {
144 #include "qa_atsci_viterbi_decoder_t1_output.dat"
145   };
146
147
148   // load up input
149   const float *ri = &raw_input[0];
150   for (int i = 0; i < NCODERS; i++){
151     for (unsigned int j = 0; j < NELEM (decoder_in[i].data); j++){
152       decoder_in[i].data[j] = *ri++;
153     }
154     decoder_in[i].pli.set_regular_seg (false, i);
155   }
156
157   // load up expected output
158   const unsigned char *ro = &raw_output[0];
159   for (int i = 0; i < NCODERS; i++){
160     for (unsigned int j = 0; j < NELEM (expected_out[i].data); j++){
161       expected_out[i].data[j] = *ro++;
162     }
163     expected_out[i].pli.set_regular_seg (false, i);
164   }
165
166   viterbi.reset ();
167
168   // this has only the previous (non-existant) output
169   viterbi.decode (decoder_out_pad, decoder_in); 
170
171   // now we'll see the real output
172   pad_decoder_input (decoder_in_pad);
173   viterbi.decode (decoder_out, decoder_in_pad);
174
175   for (int i = 0; i < NCODERS; i++){                    // check the result
176     CPPUNIT_ASSERT (expected_out[i] == decoder_out[i]);
177   }
178 }