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