xref: /aosp_15_r20/external/fec/vtest27.c (revision 638691a093b4f9473cd6ee8f3e0139deef159a86)
1*638691a0SAndroid Build Coastguard Worker /* Test viterbi decoder speeds */
2*638691a0SAndroid Build Coastguard Worker #include "config.h"
3*638691a0SAndroid Build Coastguard Worker #include <stdio.h>
4*638691a0SAndroid Build Coastguard Worker #include <stdlib.h>
5*638691a0SAndroid Build Coastguard Worker #include <unistd.h>
6*638691a0SAndroid Build Coastguard Worker #include <time.h>
7*638691a0SAndroid Build Coastguard Worker #include <math.h>
8*638691a0SAndroid Build Coastguard Worker #include <memory.h>
9*638691a0SAndroid Build Coastguard Worker #include <sys/time.h>
10*638691a0SAndroid Build Coastguard Worker #include <sys/resource.h>
11*638691a0SAndroid Build Coastguard Worker #ifdef HAVE_GETOPT_H
12*638691a0SAndroid Build Coastguard Worker #include <getopt.h>
13*638691a0SAndroid Build Coastguard Worker #endif
14*638691a0SAndroid Build Coastguard Worker #include "fec.h"
15*638691a0SAndroid Build Coastguard Worker 
16*638691a0SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG
17*638691a0SAndroid Build Coastguard Worker struct option Options[] = {
18*638691a0SAndroid Build Coastguard Worker   {"frame-length",1,NULL,'l'},
19*638691a0SAndroid Build Coastguard Worker   {"frame-count",1,NULL,'n'},
20*638691a0SAndroid Build Coastguard Worker   {"ebn0",1,NULL,'e'},
21*638691a0SAndroid Build Coastguard Worker   {"gain",1,NULL,'g'},
22*638691a0SAndroid Build Coastguard Worker   {"verbose",0,NULL,'v'},
23*638691a0SAndroid Build Coastguard Worker   {"force-altivec",0,NULL,'a'},
24*638691a0SAndroid Build Coastguard Worker   {"force-port",0,NULL,'p'},
25*638691a0SAndroid Build Coastguard Worker   {"force-mmx",0,NULL,'m'},
26*638691a0SAndroid Build Coastguard Worker   {"force-sse",0,NULL,'s'},
27*638691a0SAndroid Build Coastguard Worker   {"force-sse2",0,NULL,'t'},
28*638691a0SAndroid Build Coastguard Worker   {NULL},
29*638691a0SAndroid Build Coastguard Worker };
30*638691a0SAndroid Build Coastguard Worker #endif
31*638691a0SAndroid Build Coastguard Worker 
32*638691a0SAndroid Build Coastguard Worker #define RATE (1./2.)
33*638691a0SAndroid Build Coastguard Worker #define MAXBYTES 10000
34*638691a0SAndroid Build Coastguard Worker 
35*638691a0SAndroid Build Coastguard Worker double Gain = 32.0;
36*638691a0SAndroid Build Coastguard Worker int Verbose = 0;
37*638691a0SAndroid Build Coastguard Worker 
main(int argc,char * argv[])38*638691a0SAndroid Build Coastguard Worker int main(int argc,char *argv[]){
39*638691a0SAndroid Build Coastguard Worker   int i,d,tr;
40*638691a0SAndroid Build Coastguard Worker   int sr=0,trials = 10000,errcnt,framebits=2048;
41*638691a0SAndroid Build Coastguard Worker   long long int tot_errs=0;
42*638691a0SAndroid Build Coastguard Worker   unsigned char bits[MAXBYTES];
43*638691a0SAndroid Build Coastguard Worker   unsigned char data[MAXBYTES];
44*638691a0SAndroid Build Coastguard Worker   unsigned char xordata[MAXBYTES];
45*638691a0SAndroid Build Coastguard Worker   unsigned char symbols[8*2*(MAXBYTES+6)];
46*638691a0SAndroid Build Coastguard Worker   void *vp;
47*638691a0SAndroid Build Coastguard Worker   extern char *optarg;
48*638691a0SAndroid Build Coastguard Worker   struct rusage start,finish;
49*638691a0SAndroid Build Coastguard Worker   double extime;
50*638691a0SAndroid Build Coastguard Worker   double gain,esn0,ebn0;
51*638691a0SAndroid Build Coastguard Worker   time_t t;
52*638691a0SAndroid Build Coastguard Worker   int badframes=0;
53*638691a0SAndroid Build Coastguard Worker 
54*638691a0SAndroid Build Coastguard Worker   time(&t);
55*638691a0SAndroid Build Coastguard Worker   srandom(t);
56*638691a0SAndroid Build Coastguard Worker   ebn0 = -100;
57*638691a0SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG
58*638691a0SAndroid Build Coastguard Worker   while((d = getopt_long(argc,argv,"l:n:te:g:vapmst",Options,NULL)) != EOF){
59*638691a0SAndroid Build Coastguard Worker #else
60*638691a0SAndroid Build Coastguard Worker   while((d = getopt(argc,argv,"l:n:te:g:vapmst")) != EOF){
61*638691a0SAndroid Build Coastguard Worker #endif
62*638691a0SAndroid Build Coastguard Worker     switch(d){
63*638691a0SAndroid Build Coastguard Worker     case 'a':
64*638691a0SAndroid Build Coastguard Worker       Cpu_mode = ALTIVEC;
65*638691a0SAndroid Build Coastguard Worker       break;
66*638691a0SAndroid Build Coastguard Worker     case 'p':
67*638691a0SAndroid Build Coastguard Worker       Cpu_mode = PORT;
68*638691a0SAndroid Build Coastguard Worker       break;
69*638691a0SAndroid Build Coastguard Worker     case 'm':
70*638691a0SAndroid Build Coastguard Worker       Cpu_mode = MMX;
71*638691a0SAndroid Build Coastguard Worker       break;
72*638691a0SAndroid Build Coastguard Worker     case 's':
73*638691a0SAndroid Build Coastguard Worker       Cpu_mode = SSE;
74*638691a0SAndroid Build Coastguard Worker       break;
75*638691a0SAndroid Build Coastguard Worker     case 't':
76*638691a0SAndroid Build Coastguard Worker       Cpu_mode = SSE2;
77*638691a0SAndroid Build Coastguard Worker       break;
78*638691a0SAndroid Build Coastguard Worker     case 'l':
79*638691a0SAndroid Build Coastguard Worker       framebits = atoi(optarg);
80*638691a0SAndroid Build Coastguard Worker       break;
81*638691a0SAndroid Build Coastguard Worker     case 'n':
82*638691a0SAndroid Build Coastguard Worker       trials = atoi(optarg);
83*638691a0SAndroid Build Coastguard Worker       break;
84*638691a0SAndroid Build Coastguard Worker     case 'e':
85*638691a0SAndroid Build Coastguard Worker       ebn0 = atof(optarg);
86*638691a0SAndroid Build Coastguard Worker       break;
87*638691a0SAndroid Build Coastguard Worker     case 'g':
88*638691a0SAndroid Build Coastguard Worker       Gain = atof(optarg);
89*638691a0SAndroid Build Coastguard Worker       break;
90*638691a0SAndroid Build Coastguard Worker     case 'v':
91*638691a0SAndroid Build Coastguard Worker       Verbose++;
92*638691a0SAndroid Build Coastguard Worker       break;
93*638691a0SAndroid Build Coastguard Worker     }
94*638691a0SAndroid Build Coastguard Worker   }
95*638691a0SAndroid Build Coastguard Worker   if(framebits > 8*MAXBYTES){
96*638691a0SAndroid Build Coastguard Worker     fprintf(stderr,"Frame limited to %d bits\n",MAXBYTES*8);
97*638691a0SAndroid Build Coastguard Worker     framebits = MAXBYTES*8;
98*638691a0SAndroid Build Coastguard Worker   }
99*638691a0SAndroid Build Coastguard Worker   if((vp = create_viterbi27(framebits)) == NULL){
100*638691a0SAndroid Build Coastguard Worker     printf("create_viterbi27 failed\n");
101*638691a0SAndroid Build Coastguard Worker     exit(1);
102*638691a0SAndroid Build Coastguard Worker   }
103*638691a0SAndroid Build Coastguard Worker   if(ebn0 != -100){
104*638691a0SAndroid Build Coastguard Worker     esn0 = ebn0 + 10*log10((double)RATE); /* Es/No in dB */
105*638691a0SAndroid Build Coastguard Worker     /* Compute noise voltage. The 0.5 factor accounts for BPSK seeing
106*638691a0SAndroid Build Coastguard Worker      * only half the noise power, and the sqrt() converts power to
107*638691a0SAndroid Build Coastguard Worker      * voltage.
108*638691a0SAndroid Build Coastguard Worker      */
109*638691a0SAndroid Build Coastguard Worker     gain = 1./sqrt(0.5/pow(10.,esn0/10.));
110*638691a0SAndroid Build Coastguard Worker 
111*638691a0SAndroid Build Coastguard Worker     printf("nframes = %d framesize = %d ebn0 = %.2f dB gain = %g\n",trials,framebits,ebn0,Gain);
112*638691a0SAndroid Build Coastguard Worker 
113*638691a0SAndroid Build Coastguard Worker     for(tr=0;tr<trials;tr++){
114*638691a0SAndroid Build Coastguard Worker       /* Encode a frame of random data */
115*638691a0SAndroid Build Coastguard Worker       for(i=0;i<framebits+6;i++){
116*638691a0SAndroid Build Coastguard Worker 	int bit = (i < framebits) ? (random() & 1) : 0;
117*638691a0SAndroid Build Coastguard Worker 
118*638691a0SAndroid Build Coastguard Worker 	sr = (sr << 1) | bit;
119*638691a0SAndroid Build Coastguard Worker 	bits[i/8] = sr & 0xff;
120*638691a0SAndroid Build Coastguard Worker 	symbols[2*i+0] = addnoise(parity(sr & V27POLYA),gain,Gain,127.5,255);
121*638691a0SAndroid Build Coastguard Worker 	symbols[2*i+1] = addnoise(parity(sr & V27POLYB),gain,Gain,127.5,255);
122*638691a0SAndroid Build Coastguard Worker       }
123*638691a0SAndroid Build Coastguard Worker       /* Decode it and make sure we get the right answer */
124*638691a0SAndroid Build Coastguard Worker       /* Initialize Viterbi decoder */
125*638691a0SAndroid Build Coastguard Worker       init_viterbi27(vp,0);
126*638691a0SAndroid Build Coastguard Worker 
127*638691a0SAndroid Build Coastguard Worker       /* Decode block */
128*638691a0SAndroid Build Coastguard Worker       update_viterbi27_blk(vp,symbols,framebits+6);
129*638691a0SAndroid Build Coastguard Worker 
130*638691a0SAndroid Build Coastguard Worker       /* Do Viterbi chainback */
131*638691a0SAndroid Build Coastguard Worker       chainback_viterbi27(vp,data,framebits,0);
132*638691a0SAndroid Build Coastguard Worker       errcnt = 0;
133*638691a0SAndroid Build Coastguard Worker       for(i=0;i<framebits/8;i++){
134*638691a0SAndroid Build Coastguard Worker 	int e = Bitcnt[xordata[i] = data[i] ^ bits[i]];
135*638691a0SAndroid Build Coastguard Worker 	errcnt += e;
136*638691a0SAndroid Build Coastguard Worker 	tot_errs += e;
137*638691a0SAndroid Build Coastguard Worker       }
138*638691a0SAndroid Build Coastguard Worker       if(errcnt != 0)
139*638691a0SAndroid Build Coastguard Worker 	badframes++;
140*638691a0SAndroid Build Coastguard Worker       if(Verbose > 1 && errcnt != 0){
141*638691a0SAndroid Build Coastguard Worker 	printf("frame %d, %d errors: ",tr,errcnt);
142*638691a0SAndroid Build Coastguard Worker 	for(i=0;i<framebits/8;i++){
143*638691a0SAndroid Build Coastguard Worker 	  printf("%02x",xordata[i]);
144*638691a0SAndroid Build Coastguard Worker 	}
145*638691a0SAndroid Build Coastguard Worker 	printf("\n");
146*638691a0SAndroid Build Coastguard Worker       }
147*638691a0SAndroid Build Coastguard Worker       if(Verbose)
148*638691a0SAndroid Build Coastguard Worker 	printf("BER %lld/%lld (%10.3g) FER %d/%d (%10.3g)\r",
149*638691a0SAndroid Build Coastguard Worker 	       tot_errs,(long long)framebits*(tr+1),tot_errs/((double)framebits*(tr+1)),
150*638691a0SAndroid Build Coastguard Worker 	       badframes,tr+1,(double)badframes/(tr+1));
151*638691a0SAndroid Build Coastguard Worker       fflush(stdout);
152*638691a0SAndroid Build Coastguard Worker     }
153*638691a0SAndroid Build Coastguard Worker     if(Verbose > 1)
154*638691a0SAndroid Build Coastguard Worker       printf("nframes = %d framesize = %d ebn0 = %.2f dB gain = %g\n",trials,framebits,ebn0,Gain);
155*638691a0SAndroid Build Coastguard Worker     else if(Verbose == 0)
156*638691a0SAndroid Build Coastguard Worker       printf("BER %lld/%lld (%.3g) FER %d/%d (%.3g)\n",
157*638691a0SAndroid Build Coastguard Worker 	     tot_errs,(long long)framebits*trials,tot_errs/((double)framebits*trials),
158*638691a0SAndroid Build Coastguard Worker 	     badframes,tr+1,(double)badframes/(tr+1));
159*638691a0SAndroid Build Coastguard Worker     else
160*638691a0SAndroid Build Coastguard Worker       printf("\n");
161*638691a0SAndroid Build Coastguard Worker 
162*638691a0SAndroid Build Coastguard Worker   } else {
163*638691a0SAndroid Build Coastguard Worker     /* Do time trials */
164*638691a0SAndroid Build Coastguard Worker     memset(symbols,127,sizeof(symbols));
165*638691a0SAndroid Build Coastguard Worker     printf("Starting time trials\n");
166*638691a0SAndroid Build Coastguard Worker     getrusage(RUSAGE_SELF,&start);
167*638691a0SAndroid Build Coastguard Worker     for(tr=0;tr < trials;tr++){
168*638691a0SAndroid Build Coastguard Worker       /* Initialize Viterbi decoder */
169*638691a0SAndroid Build Coastguard Worker       init_viterbi27(vp,0);
170*638691a0SAndroid Build Coastguard Worker 
171*638691a0SAndroid Build Coastguard Worker       /* Decode block */
172*638691a0SAndroid Build Coastguard Worker       update_viterbi27_blk(vp,symbols,framebits);
173*638691a0SAndroid Build Coastguard Worker 
174*638691a0SAndroid Build Coastguard Worker       /* Do Viterbi chainback */
175*638691a0SAndroid Build Coastguard Worker       chainback_viterbi27(vp,data,framebits,0);
176*638691a0SAndroid Build Coastguard Worker     }
177*638691a0SAndroid Build Coastguard Worker     getrusage(RUSAGE_SELF,&finish);
178*638691a0SAndroid Build Coastguard Worker     extime = finish.ru_utime.tv_sec - start.ru_utime.tv_sec + 1e-6*(finish.ru_utime.tv_usec - start.ru_utime.tv_usec);
179*638691a0SAndroid Build Coastguard Worker     printf("Execution time for %d %d-bit frames: %.2f sec\n",trials,
180*638691a0SAndroid Build Coastguard Worker 	   framebits,extime);
181*638691a0SAndroid Build Coastguard Worker     printf("decoder speed: %g bits/s\n",trials*framebits/extime);
182*638691a0SAndroid Build Coastguard Worker   }
183*638691a0SAndroid Build Coastguard Worker   exit(0);
184*638691a0SAndroid Build Coastguard Worker }
185