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