1 // This code tests our NORM FEC encoder/decoder implementations
2 
3 
4 #include "protoTime.h"  // for ProtoTime
5 
6 #include "normEncoderRS8.h"
7 #include "normEncoderRS16.h"
8 
9 #include <string.h> // for memcpy(), etc
10 #include <stdlib.h> // for rand()
11 #include <stdio.h>
12 
13 const unsigned int NUM_PARITY   = 100;
14 const unsigned int NUM_DATA     = 400;
15 const unsigned int SHORT_DATA   = 400;
16 const unsigned int SEG_SIZE     = 64;
17 
18 const unsigned int B_SIZE = (SHORT_DATA + NUM_PARITY);
19 
20 #define NORM_ENCODER NormEncoderRS16
21 #define NORM_DECODER NormDecoderRS16
22 
main(int argc,char * argv[])23 int main(int argc, char* argv[])
24 {
25     // Uncomment to seed random generator
26     ProtoTime currentTime;
27     currentTime.GetCurrentTime();
28     int seed = (unsigned int)currentTime.usec();
29     fprintf(stderr, "fect: seed = %u\n", seed);
30     srand(seed);
31 
32     NORM_ENCODER encoder;
33     encoder.Init(NUM_DATA, NUM_PARITY, SEG_SIZE);
34     NORM_DECODER decoder;
35     decoder.Init(NUM_DATA, NUM_PARITY, SEG_SIZE);
36 
37     for (int trial = 0; trial < 2; trial++)
38     {
39 
40         // 1) Create some "printable" source data
41         char txData[B_SIZE][SEG_SIZE];
42         char* txDataPtr[B_SIZE];
43         for (unsigned int i = 0 ; i < SHORT_DATA; i++)
44         {
45             txDataPtr[i] = txData[i];
46             memset(txDataPtr[i], 'a' + (i%26), SEG_SIZE - 1);
47             txDataPtr[i][SEG_SIZE - 1] = '\0';
48         }
49 
50         // 2) Zero-init the parity vectors of our txData
51         for (unsigned int i = SHORT_DATA; i < B_SIZE; i++)
52         {
53             txDataPtr[i] = txData[i];
54             memset(txDataPtr[i], 0, SEG_SIZE);
55         }
56 
57         // 3) Run our encoder (and record CPU time)
58         ProtoTime startTime, stopTime;
59         startTime.GetCurrentTime();
60         for (unsigned int i = 0; i < SHORT_DATA; i++)
61         {
62             encoder.Encode(txDataPtr[i], txDataPtr + SHORT_DATA);
63         }
64         stopTime.GetCurrentTime();
65         double encodeTime = ProtoTime::Delta(stopTime, startTime);
66 
67         // 4) Copy "txData" to our "rxData"
68         char rxData[B_SIZE][SEG_SIZE];
69         char* rxDataPtr[B_SIZE];
70         for (unsigned int i = 0; i < B_SIZE; i++)
71         {
72             rxDataPtr[i] = rxData[i];
73             memcpy(rxDataPtr[i], txDataPtr[i], SEG_SIZE);
74         }
75 
76         // 5) Randomly pick some number of erasures and their locations
77         unsigned int erasureCount = 2;//rand() % NUM_PARITY;
78         unsigned int erasureLocs[B_SIZE];
79         for (unsigned int i = 0; i < B_SIZE; i++)
80             erasureLocs[i] = i;
81         for (unsigned int i = 0; i < erasureCount; i++)
82         {
83             // We do a little random shuffle here to generate
84             // "erasureCount" unique erasure locations
85             unsigned int loc = i + (rand() % (B_SIZE - i));
86             unsigned int tmp = erasureLocs[i];
87             erasureLocs[i] = erasureLocs[loc];
88             erasureLocs[loc] = tmp;
89         }
90         // Sort the "erasureLocs" into order (important!)
91         for (unsigned int i = 0; i < erasureCount; i++)
92         {
93             for (unsigned int j = i+1; j < erasureCount; j++)
94             {
95                 if (erasureLocs[j] < erasureLocs[i])
96                 {
97                     unsigned int tmp = erasureLocs[i];
98                     erasureLocs[i] = erasureLocs[j];
99                     erasureLocs[j] = tmp;
100                 }
101             }
102         }
103         fprintf(stderr, "erasureCount: %u erasureLocs: ", erasureCount);
104         for (unsigned int i = 0; i < erasureCount; i++)
105             fprintf(stderr, "%u ", erasureLocs[i]);
106         fprintf(stderr, "\n");
107 
108         // 6) Clear our erasure locs
109         for (unsigned int i = 0; i < erasureCount; i++)
110             memset(rxDataPtr[erasureLocs[i]], 0, SEG_SIZE);
111 
112         // 7) Decode the rxData
113 
114 
115         startTime.GetCurrentTime();
116         decoder.Decode(rxDataPtr, SHORT_DATA, erasureCount, erasureLocs);
117         stopTime.GetCurrentTime();
118         double decodeTime = ProtoTime::Delta(stopTime, startTime);
119 
120         // 8) check decoding
121         for (unsigned int i = 0; i < SHORT_DATA; i++)
122         {
123             if (0 != memcmp(rxDataPtr[i], txDataPtr[i], SEG_SIZE))
124             {
125                 fprintf(stderr, "fect: segment:%d rxData decode error!\n", i);
126                 fprintf(stderr, "  txData: %.32s ...\n", txDataPtr[i]);
127                 fprintf(stderr, "  rxData: %.32s ...\n", rxDataPtr[i]);
128             }
129         }
130 
131 
132         // 9) Print results
133         fprintf(stderr, "fect: encodeTime:%lf usec decodeTime:%lf usec\n", 1.0e+06*encodeTime, 1.0e+06*decodeTime);
134     }
135 }  // end main()
136