Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / lib / reed-solomon / exercise.c
1 /* Exercise an RS codec a specified number of times using random
2  * data and error patterns
3  *
4  * Copyright 2002 Phil Karn, KA9Q
5  * May be used under the terms of the GNU General Public License (GPL)
6  */
7 #define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <strings.h>
17
18 #ifdef FIXED
19 #include "fixed.h"
20 #define EXERCISE exercise_8
21 #elif defined(CCSDS)
22 #include "fixed.h"
23 #include "ccsds.h"
24 #define EXERCISE exercise_ccsds
25 #elif defined(BIGSYM)
26 #include "int.h"
27 #define EXERCISE exercise_int
28 #else
29 #include "char.h"
30 #define EXERCISE exercise_char
31 #endif
32
33 #ifdef FIXED
34 #define PRINTPARM printf("(255,223):");
35 #elif defined(CCSDS)
36 #define PRINTPARM printf("CCSDS (255,223):");
37 #else
38 #define PRINTPARM printf("(%d,%d):",rs->nn,rs->nn-rs->nroots);
39 #endif
40
41 /* Exercise the RS codec passed as an argument */
42 int EXERCISE(
43 #if !defined(CCSDS) && !defined(FIXED)
44 void *p,
45 #endif
46 int trials){
47 #if !defined(CCSDS) && !defined(FIXED)
48   struct rs *rs = (struct rs *)p;
49 #endif
50   DTYPE block[NN],tblock[NN];
51   int i;
52   int errors;
53   int errlocs[NN];
54   int derrlocs[NROOTS];
55   int derrors;
56   int errval,errloc;
57   int erasures;
58   int decoder_errors = 0;
59
60   while(trials-- != 0){
61     /* Test up to the error correction capacity of the code */
62     for(errors=0;errors <= NROOTS/2;errors++){
63
64       /* Load block with random data and encode */
65       for(i=0;i<NN-NROOTS;i++)
66         block[i] = random() & NN;
67       
68 #if defined(CCSDS) || defined(FIXED)
69       ENCODE_RS(&block[0],&block[NN-NROOTS]);
70 #else
71       ENCODE_RS(rs,&block[0],&block[NN-NROOTS]);
72 #endif
73
74       /* Make temp copy, seed with errors */
75       memcpy(tblock,block,sizeof(tblock));
76       memset(errlocs,0,sizeof(errlocs));
77       memset(derrlocs,0,sizeof(derrlocs));
78       erasures=0;
79       for(i=0;i<errors;i++){
80         do {
81           errval = random() & NN;
82         } while(errval == 0); /* Error value must be nonzero */
83
84         do {
85           errloc = random() % NN;
86         } while(errlocs[errloc] != 0); /* Must not choose the same location twice */
87
88         errlocs[errloc] = 1;
89
90 #if FLAG_ERASURE
91         if(random() & 1) /* 50-50 chance */
92           derrlocs[erasures++] = errloc;
93 #endif
94         tblock[errloc] ^= errval;
95       }
96
97       /* Decode the errored block */
98 #if defined(CCSDS) || defined(FIXED)
99       derrors = DECODE_RS(tblock,derrlocs,erasures);
100 #else
101       derrors = DECODE_RS(rs,tblock,derrlocs,erasures);
102 #endif
103
104       if(derrors != errors){
105         PRINTPARM
106         printf(" decoder says %d errors, true number is %d\n",derrors,errors);
107         decoder_errors++;
108       }
109       for(i=0;i<derrors;i++){
110         if(errlocs[derrlocs[i]] == 0){
111           PRINTPARM
112           printf(" decoder indicates error in location %d without error\n",i);
113           decoder_errors++;
114         }
115       }
116       if(memcmp(tblock,block,sizeof(tblock)) != 0){
117         PRINTPARM
118         printf(" uncorrected errors! output ^ input:");
119         decoder_errors++;
120         for(i=0;i<NN;i++)
121           printf(" %02x",tblock[i] ^ block[i]);
122         printf("\n");
123       }
124     }
125   }
126   return decoder_errors;
127 }