/*==================================================================================== EVS Codec 3GPP TS26.442 Jun 30, 2015. Version CR 26.442-0010 ====================================================================================*/ #include #include #include #include "options.h" /* Compilation switches */ #include "stl.h" #include "cnst_fx.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "disclaimer.h" /*for disclaimer*/ #include "basop_util.h" #include "mime.h" #include /* WMC_TOOL_SKIP_FILE */ /*---------------------------------------------------------------------* * Local functions *---------------------------------------------------------------------*/ static void usage_dec(void); static char *to_upper( char *str ); static char * bit_rate_to_string(char *string, Word32 bit_rate) { char *src, *dst; assert(bit_rate >= 100); src = string + sprintf(string, "%i", bit_rate); /* Insert a '.' before last two digits and remove last digit */ /* What we want is to print %.2f of bit_rate/1000.0 */ dst = src--; *--dst = *--src; *--dst = *--src; *--dst = '.'; return string; } /*---------------------------------------------------------------------* * io_ini_dec() * * Processing of command line parameters *---------------------------------------------------------------------*/ void io_ini_dec_fx( const int argc, /* i : command line arguments number */ char *argv[], /* i : command line arguments */ FILE **f_stream, /* o : input bitstream file */ FILE **f_synth, /* o : output synthesis file */ Word16 *quietMode, /* o : limited printouts */ Word16 *noDelayCmp, /* o : turn off delay compensation */ Decoder_State_fx *st_fx, /* o : Decoder static variables structure */ #ifdef SUPPORT_JBM_TRACEFILE char **jbmTraceFileName, /* o : VOIP tracefilename */ #endif char **jbmFECoffsetFileName /* : Output file for Optimum FEC offset */ ) { short i; char stmp[50]; Word16 evs_magic, amrwb_magic; char bit_rate_string[14]; print_disclaimer(stderr); /*-----------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ i = 1; *f_synth = NULL; *f_stream = NULL; st_fx->Opt_AMR_WB_fx = 0; st_fx->Opt_VOIP_fx = 0; set_zero_Word8((Word8 *)stmp, sizeof(stmp)); st_fx->bitstreamformat = G192; st_fx->amrwb_rfc4867_flag = -1; IF ( argc <= 1 ) { usage_dec(); } /*-----------------------------------------------------------------* * Optional input arguments *-----------------------------------------------------------------*/ WHILE ( i < argc-3 ) { /*-----------------------------------------------------------------* * VOIP mode *-----------------------------------------------------------------*/ IF ( strcmp( to_upper(argv[i]), "-VOIP") == 0) { st_fx->Opt_VOIP_fx = 1; move16(); i += 1; } #ifdef SUPPORT_JBM_TRACEFILE /*-----------------------------------------------------------------* * VOIP Tracefile *-----------------------------------------------------------------*/ ELSE IF ( strcmp( to_upper(argv[i]), "-TRACEFILE" ) == 0 ) { *jbmTraceFileName = argv[i+1]; i = i + 2; } #endif /*-----------------------------------------------------------------* * FEC offset file *-----------------------------------------------------------------*/ ELSE IF ( strcmp( to_upper(argv[i]), "-FEC_CFG_FILE" ) == 0 ) { st_fx->writeFECoffset = 1; *jbmFECoffsetFileName = argv[i+1]; i = i + 2; } /*-----------------------------------------------------------------* * Quiet mode *-----------------------------------------------------------------*/ ELSE IF ( strcmp( to_upper(argv[i]), "-Q" ) == 0 ) { *quietMode = 1; move16(); i++; } /*-----------------------------------------------------------------* * deactivate delay compensation *-----------------------------------------------------------------*/ ELSE IF ( strcmp( to_upper(argv[i]), "-NO_DELAY_CMP" ) == 0 ) { *noDelayCmp = 1; i++; } /*-----------------------------------------------------------------* * MIME input file format *-----------------------------------------------------------------*/ ELSE IF( strcmp( to_upper(argv[i]), "-MIME" ) == 0 ) { st_fx->bitstreamformat = MIME; st_fx->amrwb_rfc4867_flag = 0; i++; } /*-----------------------------------------------------------------* * Option not recognized *-----------------------------------------------------------------*/ ELSE { fprintf(stderr, "Error: Unknown option %s\n\n", argv[i]); usage_dec(); } } /* end of while */ /*-----------------------------------------------------------------* * Mandatory input arguments *-----------------------------------------------------------------*/ /*-----------------------------------------------------------------* * Output sampling frequency *-----------------------------------------------------------------*/ if( i < argc - 2 ) { st_fx->output_Fs_fx = (int)atoi( argv[i] ) * 1000; if( st_fx->output_Fs_fx != 8000 && st_fx->output_Fs_fx != 16000 && st_fx->output_Fs_fx != 32000 && st_fx->output_Fs_fx != 48000 ) { fprintf(stderr, "Error: %d kHz is not a supported sampling rate\n\n", atoi( argv[i] ) ); usage_dec(); } i++; } else { fprintf (stderr, "Error: Sampling rate is not specified\n\n"); usage_dec(); } /*-----------------------------------------------------------------* * Input bitstream file *-----------------------------------------------------------------*/ if( i < argc - 1 ) { if ( (*f_stream = fopen(argv[i], "rb")) == NULL) { fprintf(stderr,"Error: input bitstream file %s cannot be opened\n\n", argv[i]); usage_dec(); } /* If MIME/storage format selected, scan for the magic number at the beginning of the bitstream file */ if( st_fx->bitstreamformat == MIME ) { char buf[13]; evs_magic = 1 ; amrwb_magic = 1; fgets(buf,13,*f_stream); /* verify AMRWB magic number */ if ( strncmp(buf, AMRWB_MAGIC_NUMBER, strlen(AMRWB_MAGIC_NUMBER))) { amrwb_magic = 0; } if ( strncmp(buf, EVS_MAGIC_NUMBER, strlen(EVS_MAGIC_NUMBER))) /* strncmp safer than strcmp */ { evs_magic = 0; } if( evs_magic != 0 ) { if ((fread(&buf,sizeof(char), 4, *f_stream) != 4 ) || !((buf[3] == 1) && (buf[2] == 0) && (buf[1] == 0) && (buf[0] == 0)) ) { fprintf(stderr, "Error: input bitstream file %s specifies unsupported number of evs audio channels\n\n",argv[i]); usage_dec(); } } if( evs_magic == 0 && amrwb_magic == 0 ) { /* no valid MIME magic number */ fprintf(stderr, "Error: input bitstream file %s specifies unsupported MIME magic number (%13s) \n\n",argv[i],buf ); usage_dec(); } if( evs_magic ) { fprintf( stderr, "Found MIME Magic number %s\n", EVS_MAGIC_NUMBER ); st_fx->amrwb_rfc4867_flag = 0; } else { fprintf( stderr, "Found MIME Magic number %s\n",AMRWB_MAGIC_NUMBER ); st_fx->amrwb_rfc4867_flag = 1; } } else if( st_fx->Opt_VOIP_fx == 0 ) { /* G.192 format .... preread the G.192 sync header */ UWord16 utmp; if ( fread( &utmp, sizeof(unsigned short), 1, *f_stream ) != 1 ) { /* error during pre-reading */ if( ferror( *f_stream ) ) { fprintf(stderr, "Error: input G.192 bitstream file %s , can not be read \n\n",argv[i] ); } else { fprintf(stderr, "Error: input G.192 bitstream file %s , has zero size, can not be read \n\n",argv[i] ); } usage_dec(); } if( (sub(utmp, SYNC_GOOD_FRAME) != 0) && (sub(utmp, SYNC_BAD_FRAME) != 0) ) { /* check for a valid first G.192 synch word in Sync Header */ fprintf(stderr, "Error: input bitstream file %s does not have a valid G.192 synch word value \n\n",argv[i]); usage_dec(); } /* now rewind the G.192 bitstream file */ fseek( *f_stream , 0L, SEEK_SET ); } /* JBM format */ fprintf( stderr, "Input bitstream file: %s\n", argv[i]); i++; } else { fprintf (stderr, "Error: no input bitstream file specified\n\n"); usage_dec(); } /*-----------------------------------------------------------------* * Output synthesis file *-----------------------------------------------------------------*/ if( i < argc ) { if ( (*f_synth = fopen(argv[i], "wb")) == NULL ) { fprintf( stderr, "Error: ouput synthesis file %s cannot be opened\n\n", argv[i] ); usage_dec(); } fprintf( stdout, "Output synthesis file: %s\n", argv[i] ); i++; } else { fprintf( stderr, "Error: no output synthesis file specified\n\n" ); usage_dec(); } fprintf( stdout, "\n" ); if( !st_fx->Opt_VOIP_fx ) { /*-----------------------------------------------------------------* * Read information from bitstream *-----------------------------------------------------------------*/ if( st_fx->bitstreamformat == G192 ) { read_indices_fx( st_fx, *f_stream, 1 ); /* rew_flag == 1 , reads future frames */ } else { read_indices_mime( st_fx, *f_stream, 1 ); /* rew_flag == 1 , checks only very first frame */ if( st_fx->amrwb_rfc4867_flag != 0 ) { fseek(*f_stream,strlen(AMRWB_MAGIC_NUMBER),SEEK_SET); /* restart after 9 bytes */ } else { fseek(*f_stream,strlen(EVS_MAGIC_NUMBER)+4, SEEK_SET); /* restart after 16 bytes */ } } /*-----------------------------------------------------------------* * Print info on screen *-----------------------------------------------------------------*/ /*-----------------------------------------------------------------* * Print output sampling frequency *-----------------------------------------------------------------*/ fprintf( stdout, "Output sampling rate: %d Hz\n", st_fx->output_Fs_fx ); /*-----------------------------------------------------------------* * Print bitrate *-----------------------------------------------------------------*/ fprintf( stdout, "Bitrate: %s kbps\n", bit_rate_to_string(bit_rate_string, st_fx->total_brate_fx) ); } return; } /*---------------------------------------------------------------------* * to_upper() * * Capitalize all letters of a string. * (normally to_upper() function would be used but it does not work in Unix) *---------------------------------------------------------------------*/ static char *to_upper( char *str ) { short i; char *p = str; i = 0; while (str[i] != 0) { if (str[i] >= 'a' && str[i] <= 'z') str[i] -= 0x20; i++; } return p; } static void usage_dec( void ) { fprintf(stdout,"Usage : EVS_dec.exe [Options] Fs bitstream_file output_file\n\n"); fprintf(stdout,"Mandatory parameters:\n"); fprintf(stdout,"---------------------\n"); fprintf(stdout,"Fs : Output sampling rate in kHz (8, 16, 32 or 48)\n"); fprintf(stdout,"bitstream_file : Input bitstream filename or RTP packet filename (in VOIP mode)\n"); fprintf(stdout,"output_file : Output speech filename \n\n"); fprintf(stdout,"Options:\n"); fprintf(stdout,"--------\n"); fprintf(stdout, "-VOIP : VOIP mode,\n"); #ifdef SUPPORT_JBM_TRACEFILE fprintf(stdout, "-Tracefile TF : Generate trace file named TF,\n"); #endif fprintf(stdout, "-no_delay_cmp : Turn off delay compensation\n"); fprintf(stdout, "-fec_cfg_file : Output of the channel aware configuration. The outptut is \n"); fprintf(stdout, " written into a .txt file. Each line contains the FER indicator \n"); fprintf(stdout, " (HI|LO) and optimum FEC offset. \n"); fprintf(stdout, "-mime : Mime input bitstream file format\n"); fprintf(stdout, " The decoder reads both TS26.445 Annex.2.6 and RFC4867 Mime Storage Format,\n"); fprintf(stdout, " the magic word in the mime input file is used to determine the format.\n"); fprintf(stdout, " default input bitstream file format is G.192\n"); fprintf(stdout, "-q : Quiet mode, no frame counter\n"); fprintf(stdout, " default is OFF\n"); fprintf(stdout, "\n"); exit(-1); }