/* Soft decision Viterbi Decoder Test Driver */ /* Copyright (c) 1999, Spectrum Applications, Derwood, MD, USA */ /* All rights reserved */ /* Version 2.0 Last Modified 1999.02.20 */ #include <alloc.h> #include <conio.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include "vdsim.h" extern void gen01dat(long data_len, int *out_array); extern void cnv_encd(int g[2][K], long data_len, int *in_array, int *out_array); extern void addnoise(float es_ovr_n0, long data_len, int *in_array, float *out_array); extern void sdvd(int g[2][K], float es_ovr_n0, long channel_length, float *channel_output_vector, int *decoder_output_matrix); void testsdvd(void) { long iter, t, msg_length, channel_length; /* loop variables, length of I/O files */ int *onezer; int *encoded; /* original, encoded, & decoded data arrays */ int *sdvdout; int start; float *splusn; /* noisy data array */ int i_rxdata, m; /* int rx data , m = K - 1*/ float es_ovr_n0, number_errors_encoded, number_errors_unencoded, e_threshold, ue_threshold, e_ber, ue_ber; /* various statistics */ #if K == 3 /* polynomials for K = 3 */ int g[2][K] = {{1, 1, 1}, /* 7 */ {1, 0, 1}}; /* 5 */ #endif #if K == 5 /* polynomials for K = 5 */ int g[2][K] = {{1, 1, 1, 0, 1}, /* 35 */ {1, 0, 0, 1, 1}}; /* 23 */ #endif #if K == 7 /* polynomials for K = 7 */ int g[2][K] = {{1, 1, 1, 1, 0, 0, 1}, /* 171 */ {1, 0, 1, 1, 0, 1, 1}}; /* 133 */ #endif #if K == 9 /* polynomials for K = 9 */ int g[2][K] = {{1, 1, 1, 1, 0, 1, 0, 1, 1}, /* 753 */ {1, 0, 1, 1, 1, 0, 0, 0, 1}}; /* 561 */ #endif clrscr(); printf("\nK = %d", K); #if K == 3 printf("\ng1 = %d%d%d", g[0][0], g[0][1], g[0][2] ); printf("\ng2 = %d%d%d\n", g[1][0], g[1][1], g[1][2] ); #endif #if K == 5 printf("\ng1 = %d%d %d%d%d", g[0][0], g[0][1], g[0][2], g[0][3], g[0][4] ); printf("\ng2 = %d%d %d%d%d\n", g[1][0], g[1][1], g[1][2], g[1][3], g[1][4] ); #endif #if K == 7 printf("\ng1 = %d %d%d%d %d%d%d", g[0][0], g[0][1], g[0][2], g[0][3], g[0][4], g[0][5], g[0][6] ); printf("\ng2 = %d %d%d%d %d%d%d\n", g[1][0], g[1][1], g[1][2], g[1][3], g[1][4], g[1][5], g[1][6] ); #endif #if K == 9 printf("\ng1 = %d%d%d %d%d%d %d%d%d", g[0][0], g[0][1], g[0][2], g[0][3], g[0][4], g[0][5], g[0][6], g[0][7], g[0][8] ); printf("\ng2 = %d%d%d %d%d%d %d%d%d\n", g[1][0], g[1][1], g[1][2], g[1][3], g[1][4], g[1][5], g[1][6], g[1][7], g[1][8] ); #endif m = K - 1; msg_length = MSG_LEN; channel_length = ( msg_length + m ) * 2; onezer = malloc( msg_length * sizeof( int ) ); if (onezer == NULL) { printf("\n testsdvd.c: error allocating onezer array, aborting!"); exit(1); } encoded = malloc( channel_length * sizeof(int) ); if (encoded == NULL) { printf("\n testsdvd.c: error allocating encoded array, aborting!"); exit(1); } splusn = malloc( channel_length * sizeof(float) ); if (splusn == NULL) { printf("\n testsdvd.c: error allocating splusn array, aborting!"); exit(1); } sdvdout = malloc( msg_length * sizeof( int ) ); if (sdvdout == NULL) { printf("\n testsdvd.c: error allocating sdvdout array, aborting!"); exit(1); } for (es_ovr_n0 = LOESN0; es_ovr_n0 <= HIESN0; es_ovr_n0 += ESN0STEP) { start = time(NULL); number_errors_encoded = 0.0; e_ber = 0.0; iter = 0; #ifdef DOENC if (es_ovr_n0 <= 9) e_threshold = 100; /* +/- 20% */ else e_threshold = 20; /* +/- 100 % */ while (number_errors_encoded < e_threshold) { iter += 1; /*printf("Generating one-zero data\n");*/ gen01dat(msg_length, onezer); /*printf("Convolutionally encoding the data\n");*/ cnv_encd(g, msg_length, onezer, encoded); /*printf("Adding noise to the encoded data\n");*/ addnoise(es_ovr_n0, channel_length, encoded, splusn); /*printf("Decoding the BSC data\n");*/ sdvd(g, es_ovr_n0, channel_length, splusn, sdvdout); for (t = 0; t < msg_length; t++) { if ( *(onezer + t) != *(sdvdout + t) ) { /*printf("\n error occurred at location %ld", t);*/ number_errors_encoded += 1; } /* end if */ } /* end t for-loop */ if (kbhit()) exit(0); /*printf("\nDone!");*/ } e_ber = number_errors_encoded / (msg_length * iter); printf("\nThe elapsed time was %d seconds for %d iterations", time(NULL) - start, iter); #endif number_errors_unencoded = 0.0; ue_ber = 0.0; iter = 0; #ifdef DONOENC if (es_ovr_n0 <= 12) ue_threshold = 100; else ue_threshold = 20; while (number_errors_unencoded < ue_threshold) { iter += 1; /*printf("Generating one-zero data\n");*/ gen01dat(msg_length, onezer); /*printf("Adding noise to the unencoded data\n");*/ addnoise(es_ovr_n0, msg_length, onezer, splusn); for (t = 0; t < msg_length; t++) { if ( *(splusn + t) < 0.0 ) i_rxdata = 1; else i_rxdata = 0; if ( *(onezer + t) != i_rxdata ) number_errors_unencoded += 1; } if (kbhit()) exit(0); /*printf("\nDone!");*/ } ue_ber = number_errors_unencoded / (msg_length * iter); #endif printf("\nAt %1.1fdB Es/No, ", es_ovr_n0); #ifdef DOENC printf("the e_ber was %1.1e ", e_ber); #ifdef DONOENC printf("and "); #endif #endif #ifdef DONOENC printf("the ue_ber was %1.1e", ue_ber); #endif } free(onezer); free(encoded); free(splusn); free(sdvdout); while ( !kbhit() ) { } exit(0); }