Houston, we have a trunk.
[debian/gnuradio] / gr-atsc / src / lib / qa_atsci_reed_solomon.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 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <cppunit/TestAssert.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <atsci_reed_solomon.h>
31 #include <qa_atsci_reed_solomon.h>
32
33
34 static const int NROOTS      =   20;
35 static const int NTRIALS     =  100;
36 static const int NN          = ATSC_MPEG_RS_ENCODED_LENGTH;
37
38 void
39 qa_atsci_reed_solomon::t0_reed_solomon ()
40 {
41   atsc_mpeg_packet_no_sync      in;
42   atsc_mpeg_packet_rs_encoded   enc;
43   atsc_mpeg_packet_no_sync      out;
44   int                     derrors;
45   int                     errlocs[NN];
46   int                     errval;
47   int                     errloc;
48   int                     decoder_errors = 0;
49
50   for (int nt = 0; nt < NTRIALS; nt++){
51
52     // test up to the error correction capacity of the code
53     for (int errors = 0; errors <= NROOTS*2; errors++){
54
55       // load block with random data and encode
56
57       for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
58         in.data[i] = random () & 0xff;
59
60       rs.encode (enc, in);
61
62       memset (errlocs, 0, sizeof (errlocs));
63
64       for (int i = 0; i < errors; i++){
65
66         do {
67           errval = random () & 0xff;
68         } while (errval == 0);  // error value must be non-zero
69
70         do {
71           errloc = random () % NN;
72         } while (errlocs[errloc] != 0);         // must not choose the same location twice
73
74         errlocs[errloc] = 1;
75
76         enc.data[errloc] ^= errval;             // cause the error
77       }
78
79       // decode the errored block
80       derrors = rs.decode (out, enc);
81
82       if (errors <= NROOTS/2) {
83         // We should have handled all these errors and corrected them.
84         if (derrors != errors){
85           fprintf (stderr, "  decoder says %d errors, true number is %d\n", derrors, errors);
86           decoder_errors++;
87         }
88
89         if (in != out){
90           fprintf (stderr, "  uncorrected errors!\n");
91           decoder_errors++;
92         }
93       } else {
94         // We have been given more errors than we could cope with.  Make
95         // sure that we detect these errors.  Complain if we get incorrect
96         // block but don't say it's incorrect.
97         bool differs = (in != out);
98
99         if (differs && (derrors < 0)) {
100           // Reported uncorrectable error accurately
101         } else if (differs) {
102           fprintf (stderr,
103                    "  decoder found %d of %d errors, but incorrect block\n",
104                    derrors, errors);
105         } else {
106           fprintf (stderr, "  decoder corrected %d of %d errors unexpectedly\n",
107                    derrors, errors);
108         }
109       }
110     }
111   }
112
113   CPPUNIT_ASSERT (decoder_errors == 0);
114 }