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