📄 eiddemo.c
字号:
/* 28.Mar.2000 V3.2 ============================================================================ EIDDEMO.C ~~~~~~~~~ Description: ~~~~~~~~~~~~ DEMO program to show the use of the error insertion device (EID), implementing: - bit error insertion: random to highly correlated (controlled by parameter gamma). - random frame erasure - TO BE IMPLEMENTED: burst frame erasure using the Bellcore module. The EID software needs a special data format. Each bit of the soft data bitstream is located in one 16-word, where the following definitions are assumed: Bit '0' is represented as '0x007F' Bit '1' is represented as '0x0081' This was defined to be compatible in the future with the so called 'softbit' format, where the channel decoder outputs probabilities that the received bit is '0' or '1'. Frame boundaries are marked by a synchronism header, which is composed by a synchronism (SYNC) word defined as: SYNC-word = 0x6B21 followed by a 16-bit, 2-complement word representing the number of softbits per frame (LFRAME). Therefore, the total number of 16-bit words (shorts) per frame is n+2. All the interfaces with the STL functions use LFRAME+2 as frame length parameter. These definition is compatible with the bitstream format in Annex B of ITU-T Recommendation G.192. A binary file format is used, where the first word on the file must be the SYNC-word, the second is the frame length word (equals to LFRAME), and then followed by LFRAME softbits (LFRAME=number of bits in one frame); then the next SYNC and frame length words, followed by the next frame, ... and so on. The program detects automatically the number of bits per frame by simply counting the bits between the first two SYNC headers. This program has been modified from the pre-STL96 version in order to handle G.192-compatible bitstreams. The pre-STL96 sync headers consisted only of the sync word, what has been changed in the STL96 version of the STL. Software Tests: ~~~~~~~~~~~~~~~ This software was tested at PKI under: * VAX/VMS * Turboc++ on a Compaq Deskpro 386/33L * Highc on a Compaq Deskpro 386/33L With all three platforms/compilers identical results have been produced processing about 100000 bits. Notes: ~~~~~~ The error patterns in the EID are generated by a Gilbert-Elliot-Channel model. The random generator for producing equally distributed random numbers is implemented as of type "linear congruential sequence". a) produce next random number (32 bit unsigned) seed = (69069*seed + 1)(modulo 2^32) b) return double value between 0.0 ... 1.0: RAN = seed/2^32 If the function "open_eid" is called, the system time of the current CPU is taken as the starting value for for "seed". So, at every newstart a different error pattern sequence will be produced. If one likes to save the complete state of the channel (for example to reproduce results) he must store the contents of the EID-struct at the end of his procedure. In this DEMO-program it is shown, how the user may store or recall the channel state from/to file. Compilation: ~~~~~~~~~~~~ VAX/VMS: $ cc eiddemo $ link eiddemo $ eid :== $eid_disk:[scd_dir]eiddemo $ eid Turbo-C, Turbo-C++: > tcc eiddemo > eiddemo HighC (MetaWare, version R2.32): > hc386 eiddemo.c > run386 eiddemo Sun-C (BSD-Unix) # cc -o eiddemo eiddemo.c -lm # eiddemo Original author: ~~~~~~~~~~~~~~~~ Rudolf Hofmann PHILIPS KOMMUNIKATIONS INDUSTRIE AG Phone : +49 911 526-2603 Kommunikationssysteme FAX : +49 911 526-3385 Thurn-und-Taxis-Strasse 14 EMail : hf@pkinbg.uucp D-8500 Nuernberg 10 (Germany) History: ~~~~~~~~ 28.Feb.1992 1.0 Release of 1st version to UGST <hf@pkinbg.uucp> 22.Mar.1992 2.0 1st update due to changes in eid.c (v2.0) <hf@pkinbg.uucp> 30.Apr.1992 2.2 Change in program interface <tdsimao@cpqd.ansp.br> 06.Jun.1995 2.3 Change in self-documentation to reflect compatibility modification of the definition of the softbit values of bits '1' and '0'. <simao@ctd.comsat.com> 22.Feb.1996 2.4 Included ctype.h, fixed some small warnings, changed local prototypes to smart prototypes, changed read/write system calls to ANSI fread/fwrite calls <simao> 07.Mar.1996 3.0 Modified to comply with the bitstream data representation in Annex B of G.192. <simao@ctd.comsat.com> 06.Oct.1997 3.1 Removed some compilation warnings <simao> 13.Jan.1998 3.11 Clarified ambigous syntax in save_EID_to_file() <simao> 28.Mar.2000 3.2 Added warning if module compiled in portability test mode <simao.campos@labs.comsat.com> ============================================================================*//* ......... Includes ......... */#include <stdio.h> /* Standard I/O Definitions */#include <ctype.h> /* for toupper() */#include "ugstdemo.h" /* general UGST definitions */#include "eid.h" /* EID functions *//* .. Local function prototypes for saving/retrieving EID states in file .. */void display_usage ARGS((void));long save_EID_to_file ARGS((SCD_EID *EID, char *EIDfile, double ber, double gamma));SCD_EID *recall_eid_from_file ARGS((char *EIDfile, double *ber, double *gamma));long READ_L ARGS((FILE *fp, long n, long *longary));long READ_lf ARGS((FILE *fp, long n, double *doubleary));long READ_c ARGS((FILE *fp, long n, char *chr));/* Local definitions */#define SYNC_WORD (short)0x6B21#ifdef STL92#define OVERHEAD 1 /* Overhead is sync word */#else#define OVERHEAD 2 /* Overhead is sync word and length word*/#endif/* ------------------------------------------------------------------------ *//* Main Program *//* ------------------------------------------------------------------------ */int main(argc, argv) int argc; char *argv[];{ SCD_EID *BEReid; /* pointer to EID-structure */ SCD_EID *FEReid; /* pointer to EID-structure */ char BERfile[128]; /* file for saving bit error EID */ char FERfile[128]; /* file for saving bit error EID */ char ifile[128], ofile[128]; FILE *ifilptr, *ofilptr; static int EOF_detected = 0; double FER; /* frame erasure rate */ double BER; /* bit error rate */ double BER_gamma, FER_gamma; /* burst factors */ long lseg; /* length of one transmitted frame */ double ber1, fer1; /* returns values from BER_generator */ double ersfrms; /* total distorted frames */ double prcfrms; /* number of processed frames */ double dstbits; /* total distorted bits */ double prcbits; /* number of processed bits */ short *xbuff, *ybuff; /* pointer to bit-buffer */ short *EPbuff; /* pointer to bit-buffer */ short SYNCword, i; long smpno; /* samples read from file */ char quiet=0; clock_t t1, t2; double t;#if defined(VMS) char mrs[15]="mrs=512"; /* mrs definition for VMS */#endif#ifdef PORT_TEST extern int PORTABILITY_TEST_OPERATION; if (PORTABILITY_TEST_OPERATION) fprintf(stderr, "WARNING! %s: compiled for PORTABILITY tests!\n\a", argv[0]);#endif /* ......... INITIALIZATIONS ......... */ t = 0; t1 = 0; /* ......... DISPLAY INFOS ......... */ printf("\n ** Error Insertion Device Demo Program - 07-Mar-96 V3.0 **\n"); /* ......... GET PARAMETERS ......... */ /* Check options */ if (argc < 2) display_usage(); else { while (argc > 1 && argv[1][0] == '-') if (strcmp(argv[1],"-q")==0) { /* Define resolution */ quiet = 1; /* Move arg{c,v} over the option to the next argument */ argc --; argv ++; } else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-?") == 0) { /* Display help */ display_usage(); } else { fprintf(stderr, "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); display_usage(); } } /* Get first parameter, open file and test for sync word and length */ GET_PAR_S(1, "_File with input bitstream: ................ ", ifile); if ((ifilptr = fopen(ifile, RB)) == NULL) HARAKIRI(" Could not open input file", 1); /* Check if first word in bit-stream file is a SYNC word */ smpno = fread(&SYNCword, sizeof(SYNCword),1,ifilptr); if (SYNCword != SYNC_WORD) HARAKIRI(" First word on input file not the SYNC-word (0x6B21)", 1); /* Now find the number of bits per frame, lseg */ for (lseg = -OVERHEAD, i = 0; i != SYNC_WORD; lseg++) { if ((smpno = fread(&i, sizeof(short),1,ifilptr)) == 0) HARAKIRI(" No next SYNC-word found on input file", 1); } /* move file pointer back to begin */ fseek(ifilptr, 0L, 0); /* ... Continue with other parameters ... */ GET_PAR_S(2, "_File for disturbed bitstream: ............. ", ofile); if ((ofilptr = fopen(ofile, WB)) == NULL) HARAKIRI(" Could not create output file", 1); /* Ask for file with EID-States for INSERTING BIT ERRORS */ GET_PAR_S(3, "_File with EID-states for bit errors: ...... ", BERfile); /* ... and file with EID-States for FRAME ERASURE MODULE */ GET_PAR_S(4, "_File with EID-states for frame erasure: ... ", FERfile); /* ---------------------------------------------------------------------- * Try to open file with EID-States for INSERTING BIT ERRORS. If failed * (file does not exist), the user is asked to enter bit error rate and * burst factor. If the file exists, the BIT ERROR INSERTION module * continues with last states, stored on file (bit error rate and gamma are * defined by the states, stored on that file. * ---------------------------------------------------------------------- */ BEReid = recall_eid_from_file(&BERfile[0], &BER, &BER_gamma); if (BEReid == (SCD_EID *) 0) { fprintf(stderr, "%s%s%c", "!!! File with EID-states (bit error insertion)", " does not exist: created one!\n", 7); GET_PAR_D(5, "__bit error rate (0.0 ... 0.50): ....... ", BER); GET_PAR_D(6, "__burst factor (0.0 ... 0.99): ....... ", BER_gamma); /* Setup a new EID */ if ((BEReid = open_eid(BER, BER_gamma)) == (SCD_EID *) 0) HARAKIRI(" Could not create EID for bit errors!?", 1); i = 7; /* next parameter number */ } else { i = 5; /* next parameter number */ fprintf(stderr, "__bit error rate on BER-file: .............. %f\n", BER); fprintf(stderr, "__burst factor BER_gamma: .................. %f\n", BER_gamma); } /* ---------------------------------------------------------------------- * Find to open file with EID-States for FRAME ERASURE MODULE. If failed * (file does not exist), the user is asked to enter frame erasure rate and * burst factor. If the file exists, the FRAME ERASURE MODULE continues * with last states, stored on file (frame erasure rate and gamma are * defined by the states, stored on that file. * ---------------------------------------------------------------------- */ FEReid = recall_eid_from_file(&FERfile[0], &FER, &FER_gamma); if (FEReid == (SCD_EID *) 0) { fprintf(stderr, "%s%s%c", "!!! File with EID-states (frame ", "erasure) does not exist: created one!\n", 7); GET_PAR_D(i, "__Frame erasure rate (0.0 ... 0.50): ....... ", FER); if (FER != 0.0) { GET_PAR_D(i + 1, "__Burst factor (0.0 ... 0.99): ....... ", FER_gamma); /* Initialize EID (frame erasure) */ FEReid = open_eid(FER, FER_gamma); /* Open EID for frame erasure */ /* gamma=0 ==> random err.sequence */ if (FEReid == (SCD_EID *) 0) HARAKIRI(" Could not create EID for frame erasure module!?", 1); } else printf(" FRAME ERASURE MODULE switched off\n"); } else { fprintf(stderr, "__Frame erasure rate on FER-file: .......... %f\n", FER); fprintf(stderr, "__Burst factor FER_gamma: .................. %f\n", FER_gamma); }/* * ......... Allocate memory for I/O-buffer ......... */ printf("_Bit-frame length found on input file: ..... %ld\n", lseg); /* Buffer for data from input file: */ xbuff = (short *) malloc((OVERHEAD + lseg) * sizeof(short)); if (xbuff == (short *) 0) HARAKIRI(" Could not allocate memory for input bitstream buffer", 1); /* Buffer for output bitstream: */ ybuff = (short *) malloc((OVERHEAD + lseg) * sizeof(short)); if (ybuff == (short *) 0) HARAKIRI(" Could not allocate memory for output bitstream buffer", 1); /* Buffer for storing the error pattern: */ if ((EPbuff = (short *) malloc((lseg) * sizeof(short))) == (short *) 0) HARAKIRI(" Could not allocate memory for error pattern buffer", 1);/* * ......... Now process input file ......... */ /* initialize counters to compute bit error and frame erasure rates */ ersfrms = 0.0; /* number of erased frames */ prcfrms = 0.0; /* number of processed frames */ dstbits = 0.0; /* number of distorted bits */ prcbits = 0.0; /* number of processed bits */ /* Read input soft bitstream frames of lenght lseg+OVERHEAD from file */ /* while ((smpno=fread(xbuff, sizeof(short), (lseg+OVERHEAD)/sizeof(short), ifilptr)) == (lseg + OVERHEAD)/sizeof(short)) */ while ((smpno=fread(xbuff, sizeof(short), (lseg+OVERHEAD), ifilptr)) == (lseg + OVERHEAD)) { if (xbuff[0] == SYNCword && EOF_detected == 0) { /* Start measuring CPU-time for this round */ t1 = clock(); /* Generate error pattern ('hard'-bits) */ ber1 = BER_generator(BEReid, lseg, EPbuff); dstbits += ber1; /* count number of disturbed bits */ prcbits += (double) lseg; /* count number of processed bits */ /* Modify input bitstream according to the stored error pattern */ BER_insertion(lseg + OVERHEAD, xbuff, ybuff, EPbuff); /* Apply frame erasure module if requested */ if (FER != 0.0) { /* Subject bitstream to frame erasure ... */ fer1 = FER_module(FEReid, lseg + OVERHEAD, ybuff, xbuff); ersfrms += fer1; /* count number of erased frames */ prcfrms += (double) 1; /* count number of processed frames */ } else { /* Copy processed bitstream without subjecting to frame erasure ... */ for (i = 0; i < lseg + OVERHEAD; i++) xbuff[i] = ybuff[i]; } /* Get partial timimg */ t2 = clock(); t += (t2 - t1) / (double) CLOCKS_PER_SEC; /* and write disturbed bits to output file */ smpno = fwrite(xbuff, sizeof(short), (lseg + OVERHEAD), ofilptr); /* Print frame info */ if (!quiet) fprintf(stderr, "\r%.0f bits processed", prcbits); } else EOF_detected = 1; } if (EOF_detected == 1) printf(" --- end of file detected (no SYNCword match) ---\n"); printf("\n");/* * ......... Print time and message with measured bit error rate ......... */ /* Print frame info */ if (quiet)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -