/* ***************************************************************************** * * COPYRIGHT (C) 2000 ERICSSON RADIO SYSTEMS AB * * The copyright to the program(s) herein is the property of * Ericsson Radio Systems AB, Sweden. * * The program(s) may be used and/or copied only for the ETSI/3GPP * AMR-WB qualification/selection/characterization tests. * ***************************************************************************** * * File : wcdma_eid.c * Purpose : error insertion device for Application E * ***************************************************************************** */ /* ***************************************************************************** * VERSION ID ***************************************************************************** */ const char wcdma_eid_id[] = "$Id: wcdma_eid.c,v 1.2 2000/03/16 12:19:55 erasbru PA3 $"; /* ***************************************************************************** * INCLUDE FILES ***************************************************************************** */ #include #include #include /* ***************************************************************************** * FUNCTIONS ***************************************************************************** */ /* * Sets value to x if option '-optname=x' is present * Returns 0 on success * Returns -1 when failed sscanf * Returns 1 when option not defined */ int intOptArg(char *optname, int *value, int argc, char **argv) { int i; int n; char *s; if ((s = (char *) malloc(strlen(optname) + 2 + 1)) == 0) { fprintf(stderr, "intOptArg: Cannot malloc buffer, aborting!\n"); exit(1); } /* Build "-optname=" string */ s[0] = '-'; strcpy(s + 1, optname); strcat(s, "="); for(i = 1; i < argc; i++) { if (strncmp(s, argv[i], strlen(optname) + 2) == 0) { if (sscanf(argv[i] + strlen(optname) + 2, "%d", &n) != 1) { return -1; } else { *value = n; return 0; } } } return 1; } /* * Returns the n:th argument not begining with '-' * Returns NULL if failed */ char* fileNameArg(int fileNo, int argc, char **argv) { int n = 0; int i; for(i = 1; i < argc; i++) { if (argv[i][0] != '-') { n++; if (n == fileNo) { return argv[i]; } } } return NULL; } /* ***************************************************************************** * MAIN FUNCTION ***************************************************************************** */ int main (int argc, char *argv[]) { /*-----------------------------------------------------------------------* * declarations of variables * *-----------------------------------------------------------------------*/ int noAbits; /* number of speech coder bits per frame */ int maxnoBbits; /* maximum number of bits in the least sigificant class */ int choffs; /* offset (in frames) for channel profiles */ char *fileName_FER; /* file name for FER profile */ char *fileName_RBER; /* file name for RBER profile */ char *fileName_in; /* file name for input bitstream */ char *fileName_out; /* file name for output bitstream */ FILE *fp_FER; /* file pointer to FER profile */ FILE *fp_RBER; /* file pointer to RBER profile */ FILE *fp_in; /* file pointer to input bitstream */ FILE *fp_out; /* file pointer to output bitstream */ short *sync; /* pointer to synchronisation header */ short *frame; /* pointer to bitstream data for one frame */ int newframe; /* enable to read new frame from input bitstream */ int offscount; /* counter to set offset for channel profiles */ int bfi; /* BFI flag */ int bitcount; /* counter of bits in one frame */ char biterr; /* indicator of residual bit error for a single bit */ long framecount; /* current frame number */ if ((argc == 7) || (argc == 8)) { /*-----------------------------------------------------------------------* * get command line parameters * *-----------------------------------------------------------------------*/ if (intOptArg("classA", &noAbits, argc, argv)) { fprintf(stderr, "missing option classA\n"); return -1; } if (intOptArg("maxclassB", &maxnoBbits, argc, argv)) { fprintf(stderr, "missing option maxclassB\n"); return -1; } if (intOptArg("offset", &choffs, argc, argv)) { choffs = 0; } fileName_FER = fileNameArg(1, argc, argv); fileName_RBER = fileNameArg(2, argc, argv); fileName_in = fileNameArg(3, argc, argv); fileName_out = fileNameArg(4, argc, argv); /*-----------------------------------------------------------------------* * open input and output files * *-----------------------------------------------------------------------*/ if ((fp_FER = fopen(fileName_FER, "r")) == NULL) { fprintf(stderr, "error opening FER profile %s\n", fileName_FER); return -1; } if ((fp_RBER = fopen(fileName_RBER, "r")) == NULL) { fprintf(stderr, "error opening RBER profile %s\n", fileName_RBER); return -1; } if ((fp_in = fopen(fileName_in, "r")) == NULL) { fprintf(stderr, "error opening input bitstream %s\n", fileName_in); return -1; } if ((fp_out = fopen(fileName_out, "w")) == NULL) { fprintf(stderr, "error opening output bitstream %s\n", fileName_out); return -1; } sync = malloc(2*sizeof(short)); newframe = 1; framecount = 0; /*-----------------------------------------------------------------------* * set offset for channel profiles * *-----------------------------------------------------------------------*/ if (choffs != 0) { for (offscount = 0; offscount < choffs; offscount++) { if (EOF == fscanf(fp_FER, "%d", &bfi)) { fprintf(stderr, "read after end of file in channel profiles\n"); exit(-1); } } fseek(fp_RBER, choffs*(maxnoBbits*sizeof(char)), SEEK_SET); } /*-----------------------------------------------------------------------* * error insertion according to automatically rewinded channel profiles * *-----------------------------------------------------------------------*/ while (newframe) { fread(sync, sizeof(short), 2, fp_in); if (!feof(fp_in)) { frame = malloc(sync[1]*sizeof(short)); fread(frame, sizeof(short), sync[1], fp_in); framecount++; if (EOF == fscanf(fp_FER,"%d",&bfi)) { rewind(fp_FER); fscanf(fp_FER,"%d",&bfi); rewind(fp_RBER); } if (bfi) { sync[0] = 0x6B20; for (bitcount = 0; bitcount < noAbits; bitcount++) { frame[bitcount] = 0x0000; } } for (bitcount = noAbits; bitcount < sync[1]; bitcount++) { fread(&biterr, sizeof(biterr), 1, fp_RBER); if (biterr) { frame[bitcount] = (-frame[bitcount])&0x00FF; } } fwrite(sync, sizeof(short), 2, fp_out); fwrite(frame, sizeof(short), sync[1], fp_out); fseek(fp_RBER, (framecount+choffs)*(maxnoBbits*sizeof(char)), SEEK_SET); free(frame); } else { fclose(fp_FER); fclose(fp_RBER); fclose(fp_in); fclose(fp_out); newframe = 0; } } free(sync); } else { /*-----------------------------------------------------------------------* * usage printout * *-----------------------------------------------------------------------*/ printf("*****************************************************************************\n"); printf("* *\n"); printf("* COPYRIGHT (C) 2000 ERICSSON RADIO SYSTEMS AB *\n"); printf("* *\n"); printf("* The copyright to the program(s) herein is the property of *\n"); printf("* Ericsson Radio Systems AB, Sweden. *\n"); printf("* *\n"); printf("* The program(s) may be used and/or copied only for the ETSI/3GPP *\n"); printf("* AMR-WB qualification/selection/characterization tests. *\n"); printf("* *\n"); printf("*****************************************************************************\n\n"); printf("usage:\n\nwcdma_eid -classA= -maxclassB= [-offset=] FERfilename RBERfilename inputbitstream outputbitstream\n\n"); printf(" noAbits: number of class A bits\n"); printf(" maxnoBbits: maximum number of class B bits (in channel file!)\n"); printf(" choffs: offset in frames into channel file (default 0)\n"); printf(" FERfilename: text file for the FER profile\n"); printf(" RBERfilename: binary file for the residual BER profile\n"); printf(" inputbitstream: binary file of encoded bits ordered with decreased error sensitivity (G.192 format)\n"); printf(" outputbitstream: corresponding binary file containing residual biterrors for decoding (G.192 format)\n\n"); } return 0; }