/* 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);
}