aboutsummaryrefslogtreecommitdiffstats
path: root/vtest39.c
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2014-01-02 21:55:13 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2014-01-02 21:55:13 +0100
commita31630e0d5b9880c716d9004ef4154396ba41ebc (patch)
treeaebbd3b132e5f2dd31bc34750ccded2378fc687a /vtest39.c
parent9aaac5be9db5e1537badc65242412ef14c5096e3 (diff)
downloadka9q-fec-a31630e0d5b9880c716d9004ef4154396ba41ebc.tar.gz
ka9q-fec-a31630e0d5b9880c716d9004ef4154396ba41ebc.tar.bz2
ka9q-fec-a31630e0d5b9880c716d9004ef4154396ba41ebc.zip
Extract fec-3.0.1
Diffstat (limited to 'vtest39.c')
-rw-r--r--vtest39.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/vtest39.c b/vtest39.c
new file mode 100644
index 0000000..76723b2
--- /dev/null
+++ b/vtest39.c
@@ -0,0 +1,186 @@
+/* Test viterbi decoder speeds */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <math.h>
+#include <memory.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include "fec.h"
+
+#if HAVE_GETOPT_LONG
+struct option Options[] = {
+ {"frame-length",1,NULL,'l'},
+ {"frame-count",1,NULL,'n'},
+ {"ebn0",1,NULL,'e'},
+ {"gain",1,NULL,'g'},
+ {"verbose",0,NULL,'v'},
+ {"force-altivec",0,NULL,'a'},
+ {"force-port",0,NULL,'p'},
+ {"force-mmx",0,NULL,'m'},
+ {"force-sse",0,NULL,'s'},
+ {"force-sse2",0,NULL,'t'},
+ {NULL},
+};
+#endif
+
+#define RATE (1./3.)
+#define MAXBYTES 10000
+
+double Gain = 32.0;
+int Verbose = 0;
+
+int main(int argc,char *argv[]){
+ int i,d,tr;
+ int sr=0,trials = 10000,errcnt,framebits=2048;
+ long long tot_errs=0;
+ unsigned char bits[MAXBYTES];
+ unsigned char data[MAXBYTES];
+ unsigned char xordata[MAXBYTES];
+ unsigned char symbols[8*3*(MAXBYTES+8)];
+ void *vp;
+ extern char *optarg;
+ struct rusage start,finish;
+ double extime;
+ double gain,esn0,ebn0;
+ time_t t;
+ int badframes=0;
+
+ time(&t);
+ srandom(t);
+ ebn0 = -100;
+#if HAVE_GETOPT_LONG
+ while((d = getopt_long(argc,argv,"l:n:te:g:vapmst",Options,NULL)) != EOF){
+#else
+ while((d = getopt(argc,argv,"l:n:te:g:vapmst")) != EOF){
+#endif
+ switch(d){
+ case 'a':
+ Cpu_mode = ALTIVEC;
+ break;
+ case 'p':
+ Cpu_mode = PORT;
+ break;
+ case 'm':
+ Cpu_mode = MMX;
+ break;
+ case 's':
+ Cpu_mode = SSE;
+ break;
+ case 't':
+ Cpu_mode = SSE2;
+ break;
+ case 'l':
+ framebits = atoi(optarg);
+ break;
+ case 'n':
+ trials = atoi(optarg);
+ break;
+ case 'e':
+ ebn0 = atof(optarg);
+ break;
+ case 'g':
+ Gain = atof(optarg);
+ break;
+ case 'v':
+ Verbose++;
+ break;
+ }
+ }
+ if(framebits > 8*MAXBYTES){
+ fprintf(stderr,"Frame limited to %d bits\n",MAXBYTES*8);
+ framebits = MAXBYTES*8;
+ }
+ if((vp = create_viterbi39(framebits)) == NULL){
+ printf("create_viterbi39 failed\n");
+ exit(1);
+ }
+ if(ebn0 != -100){
+ esn0 = ebn0 + 10*log10((double)RATE); /* Es/No in dB */
+ /* Compute noise voltage. The 0.5 factor accounts for BPSK seeing
+ * only half the noise power, and the sqrt() converts power to
+ * voltage.
+ */
+ gain = 1./sqrt(0.5/pow(10.,esn0/10.));
+
+ printf("nframes = %d framesize = %d ebn0 = %.2f dB gain = %g\n",trials,framebits,ebn0,Gain);
+
+ for(tr=0;tr<trials;tr++){
+ /* Encode a frame of random data */
+ for(i=0;i<framebits+8;i++){
+ int bit = (i < framebits) ? (random() & 1) : 0;
+
+ sr = (sr << 1) | bit;
+ bits[i/8] = sr & 0xff;
+ symbols[3*i+0] = addnoise(parity(sr & V39POLYA),gain,Gain,127.5,255);
+ symbols[3*i+1] = addnoise(parity(sr & V39POLYB),gain,Gain,127.5,255);
+ symbols[3*i+2] = addnoise(parity(sr & V39POLYC),gain,Gain,127.5,255);
+ }
+ /* Decode it and make sure we get the right answer */
+ /* Initialize Viterbi decoder */
+ init_viterbi39(vp,0);
+
+ /* Decode block */
+ update_viterbi39_blk(vp,symbols,framebits+8);
+
+ /* Do Viterbi chainback */
+ chainback_viterbi39(vp,data,framebits,0);
+ errcnt = 0;
+ for(i=0;i<framebits/8;i++){
+ int e = Bitcnt[xordata[i] = data[i] ^ bits[i]];
+ errcnt += e;
+ tot_errs += e;
+ }
+ if(errcnt != 0)
+ badframes++;
+ if(Verbose > 1 && errcnt != 0){
+ printf("frame %d, %d errors: ",tr,errcnt);
+ for(i=0;i<framebits/8;i++){
+ printf("%02x",xordata[i]);
+ }
+ printf("\n");
+ }
+ if(Verbose)
+ printf("BER %lld/%lld (%10.3g) FER %d/%d (%10.3g)\r",
+ tot_errs,(long long)framebits*(tr+1),tot_errs/((double)framebits*(tr+1)),
+ badframes,tr+1,(double)badframes/(tr+1));
+ fflush(stdout);
+ }
+ if(Verbose > 1)
+ printf("nframes = %d framesize = %d ebn0 = %.2f dB gain = %g\n",trials,framebits,ebn0,Gain);
+ else if(Verbose == 0)
+ printf("BER %lld/%lld (%.3g) FER %d/%d (%.3g)\n",
+ tot_errs,(long long)framebits*trials,tot_errs/((double)framebits*trials),
+ badframes,tr+1,(double)badframes/(tr+1));
+ else
+ printf("\n");
+ } else {
+ /* Do time trials */
+ memset(symbols,127,sizeof(symbols));
+ printf("Starting time trials\n");
+ getrusage(RUSAGE_SELF,&start);
+ for(tr=0;tr < trials;tr++){
+ /* Initialize Viterbi decoder */
+ init_viterbi39(vp,0);
+
+ /* Decode block */
+ update_viterbi39_blk(vp,symbols,framebits);
+
+ /* Do Viterbi chainback */
+ chainback_viterbi39(vp,data,framebits,0);
+ }
+ getrusage(RUSAGE_SELF,&finish);
+ extime = finish.ru_utime.tv_sec - start.ru_utime.tv_sec + 1e-6*(finish.ru_utime.tv_usec - start.ru_utime.tv_usec);
+ printf("Execution time for %d %d-bit frames: %.2f sec\n",trials,
+ framebits,extime);
+ printf("decoder speed: %g bits/s\n",trials*framebits/extime);
+ }
+ exit(0);
+}
+
+