1064 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1064 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 | |
|  *
 | |
|  *  Use of this source code is governed by a BSD-style license
 | |
|  *  that can be found in the LICENSE file in the root of the source
 | |
|  *  tree. An additional intellectual property rights grant can be found
 | |
|  *  in the file PATENTS.  All contributing project authors may
 | |
|  *  be found in the AUTHORS file in the root of the source tree.
 | |
|  */
 | |
| 
 | |
| // ReleaseTest-API.cpp : Defines the entry point for the console application.
 | |
| //
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <time.h>
 | |
| #include <ctype.h>
 | |
| #include <iostream>
 | |
| 
 | |
| /* include API */
 | |
| #include "isac.h"
 | |
| #include "utility.h"
 | |
| 
 | |
| /* Defines */
 | |
| #define SEED_FILE "randseed.txt"  /* Used when running decoder on garbage data  */
 | |
| #define MAX_FRAMESAMPLES     960  /* max number of samples per frame 
 | |
|                                       (= 60 ms frame & 16 kHz) or 
 | |
|                                       (= 30 ms frame & 32 kHz)                  */
 | |
| #define FRAMESAMPLES_10ms	 160   /* number of samples per 10ms frame          */
 | |
| #define SWBFRAMESAMPLES_10ms 320
 | |
| //#define FS		        	16000 /* sampling frequency (Hz) */
 | |
| 
 | |
| #ifdef WIN32
 | |
| #define CLOCKS_PER_SEC      1000  /* Runtime statistics */
 | |
| #endif
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| int main(int argc, char* argv[])
 | |
| {
 | |
| 
 | |
|     char inname[100], outname[100], bottleneck_file[100], vadfile[100];	
 | |
| 	FILE *inp, *outp, *f_bn=NULL, *vadp, *bandwidthp;
 | |
| 	int framecnt, endfile;
 | |
| 
 | |
| 	int i, errtype, VADusage = 0, packetLossPercent = 0;
 | |
| 	WebRtc_Word16 CodingMode;
 | |
| 	WebRtc_Word32 bottleneck;
 | |
| 	WebRtc_Word16 framesize = 30;           /* ms */
 | |
| 	int cur_framesmpls, err;
 | |
| 	int testCE=0;
 | |
| 
 | |
| 	/* Runtime statistics */
 | |
| 	double starttime, runtime, length_file;
 | |
| 
 | |
| 	WebRtc_Word16 stream_len = 0;
 | |
| 	WebRtc_Word16 declen, lostFrame = 0, declenTC;
 | |
| 	
 | |
| 	WebRtc_Word16 shortdata[SWBFRAMESAMPLES_10ms];
 | |
| 	WebRtc_Word16 vaddata[SWBFRAMESAMPLES_10ms*3];
 | |
| 	WebRtc_Word16 decoded[MAX_FRAMESAMPLES << 1];
 | |
| 	WebRtc_Word16 decodedTC[MAX_FRAMESAMPLES << 1];
 | |
| 	WebRtc_UWord16 streamdata[500];
 | |
| 	WebRtc_Word16	speechType[1];
 | |
|     WebRtc_Word16 prevFrameSize = 1;
 | |
|     WebRtc_Word16 rateBPS = 0;
 | |
|     WebRtc_Word16 fixedFL = 0; 
 | |
|     WebRtc_Word16 payloadSize = 0;
 | |
|     WebRtc_Word32 payloadRate = 0;
 | |
|     int setControlBWE = 0;
 | |
|     short FL, testNum;
 | |
| 	char version_number[20];
 | |
| 	int readLoss; 
 | |
|     FILE  *plFile;
 | |
|     WebRtc_Word32 sendBN;
 | |
| 
 | |
| #ifdef _DEBUG
 | |
| 	FILE *fy;
 | |
| 	double kbps;
 | |
| #endif /* _DEBUG */
 | |
| 	int totalbits =0;
 | |
| 	int totalsmpls =0;
 | |
| 
 | |
|     /* For fault test 10, garbage data */
 | |
|     //FILE *seedfile;
 | |
|     unsigned int random_seed = (unsigned int) time(NULL);//1196764538
 | |
| 
 | |
|     /* If use GNS file */
 | |
|     FILE *fp_gns = NULL;
 | |
| 	int gns = 0;
 | |
| 	int cur_delay = 0;
 | |
| 	char gns_file[100];
 | |
|     short maxStreamLen30 = 0;
 | |
|     short maxStreamLen60 = 0;
 | |
|     short sampFreqKHz = 32;
 | |
|     short samplesIn10Ms;
 | |
|     short useAssign = 0;
 | |
|     //FILE logFile;
 | |
|     bool doTransCoding = false;
 | |
|     WebRtc_Word32 rateTransCoding = 0;
 | |
|     WebRtc_UWord16 streamDataTransCoding[600];
 | |
|     WebRtc_Word16 streamLenTransCoding;
 | |
|     FILE* transCodingFile;
 | |
|     FILE* transcodingBitstream;
 | |
|     WebRtc_UWord32 numTransCodingBytes=0;
 | |
|     WebRtc_UWord32 numREDTransCodingBytes=0;
 | |
| 
 | |
| 	/* only one structure used for ISAC encoder */
 | |
| 	ISACStruct* ISAC_main_inst;
 | |
|     ISACStruct* decoderTransCoding;
 | |
| 
 | |
| 	BottleNeckModel       BN_data;
 | |
| 
 | |
| #ifdef _DEBUG
 | |
| 	fy = fopen("bit_rate.dat", "w");
 | |
| 	fclose(fy);
 | |
| 	fy = fopen("bytes_frames.dat", "w");
 | |
| 	fclose(fy);
 | |
| #endif /* _DEBUG */
 | |
| 
 | |
| 	/* Handling wrong input arguments in the command line */
 | |
| 	if((argc<3) || (argc>17))  {
 | |
| 		printf("\n\nWrong number of arguments or flag values.\n\n");
 | |
| 
 | |
|         printf("\n");
 | |
|         WebRtcIsac_version(version_number);
 | |
|         printf("iSAC-swb version %s \n\n", version_number);
 | |
| 
 | |
|         printf("Usage:\n\n");
 | |
|         printf("./kenny.exe [-I] bottleneck_value infile outfile \n\n");
 | |
|         printf("with:\n");
 | |
|         printf("[-FS num]       :   sampling frequency in kHz, valid values are 16 & 32,\n");
 | |
|         printf("                    with 16 as default.\n");
 | |
|         printf("[-I]            :   if -I option is specified, the coder will use\n");
 | |
|         printf("                    an instantaneous Bottleneck value. If not, it\n");
 | |
|         printf("                    will be an adaptive Bottleneck value.\n\n");
 | |
|         printf("[-assign]       :   Use Assign API.\n");          
 | |
|         printf("[-B num]        :   the value of the bottleneck provided either\n");
 | |
|         printf("                    as a fixed value in bits/sec (e.g. 25000) or\n");
 | |
|         printf("                    read from a file (e.g. bottleneck.txt)\n\n");
 | |
|         printf("[-INITRATE num] :   Set a new value for initial rate. Note! Only used in \n");
 | |
|         printf("                    adaptive mode.\n\n");
 | |
|         printf("[-FL num]       :   Set (initial) frame length in msec. Valid length are \n");
 | |
|         printf("                    30 and 60 msec.\n\n");
 | |
|         printf("[-FIXED_FL]     :   Frame length will be fixed to initial value.\n\n");
 | |
|         printf("[-MAX num]      :   Set the limit for the payload size of iSAC in bytes. \n");
 | |
|         printf("                    Minimum 100 maximum 400.\n\n");
 | |
|         printf("[-MAXRATE num]  :   Set the maxrate for iSAC in bits per second. \n");
 | |
|         printf("                    Minimum 32000, maximum 53400.\n\n");
 | |
|         printf("[-F num]        :   if -F option is specified, the test function\n");
 | |
|         printf("                    will run the iSAC API fault scenario specified by the\n");
 | |
|         printf("                    supplied number.\n");
 | |
|         printf("                    F 1 - Call encoder prior to init encoder call\n");
 | |
|         printf("                    F 2 - Call decoder prior to init decoder call\n");
 | |
|         printf("                    F 3 - Call decoder prior to encoder call\n");
 | |
|         printf("                    F 4 - Call decoder with a too short coded sequence\n");
 | |
|         printf("                    F 5 - Call decoder with a too long coded sequence\n");
 | |
|         printf("                    F 6 - Call decoder with random bit stream\n");
 | |
|         printf("                    F 7 - Call init encoder/decoder at random during a call\n");
 | |
|         printf("                    F 8 - Call encoder/decoder without having allocated memory \n");
 | |
|         printf("                          for encoder/decoder instance\n");
 | |
|         printf("                    F 9 - Call decodeB without calling decodeA\n");
 | |
|         printf("                    F 10 - Call decodeB with garbage data\n");
 | |
|         printf("[-PL num]       :   if -PL option is specified \n");
 | |
|         printf("[-T rate file]  :   test trans-coding with target bottleneck 'rate' bits/sec\n");
 | |
|         printf("                    the output file is written to 'file'\n");
 | |
|         printf("[-LOOP num]     :   number of times to repeat coding the input file for stress testing\n");
 | |
|         //printf("[-CE num]       :   Test of APIs used by Conference Engine.\n");
 | |
|         //printf("                    CE 1 - getNewBitstream, getBWE \n"); 
 | |
|         //printf("                    (CE 2 - RESERVED for transcoding)\n");
 | |
|         //printf("                    CE 3 - getSendBWE, setSendBWE.  \n\n");     
 | |
|         //printf("-L filename     :   write the logging info into file (appending)\n");
 | |
|         printf("infile          :   Normal speech input file\n\n");
 | |
|         printf("outfile         :   Speech output file\n\n");
 | |
|     	exit(0);
 | |
| 	} 
 | |
| 
 | |
|     /* Print version number */
 | |
|     printf("-------------------------------------------------\n");
 | |
|     WebRtcIsac_version(version_number);
 | |
|     printf("iSAC version %s \n\n", version_number);
 | |
| 
 | |
|     /* Loop over all command line arguments */
 | |
| 	CodingMode = 0;
 | |
| 	testNum = 0;
 | |
| 	testCE = 0;
 | |
|     useAssign = 0;
 | |
|     //logFile = NULL;
 | |
|     char transCodingFileName[500];
 | |
|     WebRtc_Word16 totFileLoop = 0;
 | |
|     WebRtc_Word16 numFileLoop = 0;
 | |
| 	for (i = 1; i < argc-2;i++) 
 | |
|     {
 | |
|         if(!strcmp("-LOOP", argv[i]))
 | |
|         {
 | |
|             i++;
 | |
|             totFileLoop = (WebRtc_Word16)atol(argv[i]);
 | |
|             if(totFileLoop <= 0)
 | |
|             {
 | |
|                 fprintf(stderr, "Invalid number of runs for the given input file, %d.", totFileLoop);
 | |
|                 exit(0);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if(!strcmp("-T", argv[i]))
 | |
|         {
 | |
|             doTransCoding = true;
 | |
|             i++;
 | |
|             rateTransCoding = atoi(argv[i]);
 | |
|             i++;
 | |
|             strcpy(transCodingFileName, argv[i]);
 | |
|         }
 | |
| 
 | |
|         /*Should we use assign API*/
 | |
|         if(!strcmp("-assign", argv[i]))
 | |
|         {
 | |
|             useAssign = 1;
 | |
|         }
 | |
| 
 | |
|         /* Set Sampling Rate */
 | |
|         if(!strcmp("-FS", argv[i]))
 | |
|         {
 | |
|             i++;
 | |
|             sampFreqKHz = atoi(argv[i]);
 | |
|         }
 | |
| 
 | |
|         /* Instantaneous mode */
 | |
| 		if(!strcmp ("-I", argv[i])) 
 | |
|         {
 | |
| 			printf("Instantaneous BottleNeck\n");
 | |
| 			CodingMode = 1;
 | |
| 		}		
 | |
|        
 | |
|         /* Set (initial) bottleneck value */
 | |
|         if(!strcmp ("-INITRATE", argv[i]))	{
 | |
| 			rateBPS = atoi(argv[i + 1]);
 | |
|             setControlBWE = 1;
 | |
|             if((rateBPS < 10000) || (rateBPS > 32000)) 
 | |
|             {
 | |
| 				printf("\n%d is not a initial rate. Valid values are in the range 10000 to 32000.\n", rateBPS);
 | |
| 				exit(0);
 | |
|             }
 | |
| 			printf("New initial rate: %d\n", rateBPS);
 | |
| 			i++;
 | |
| 		}
 | |
|         
 | |
|         /* Set (initial) framelength */
 | |
|         if(!strcmp ("-FL", argv[i]))	{
 | |
| 			framesize = atoi(argv[i + 1]);
 | |
|             if((framesize != 30) && (framesize != 60)) 
 | |
|             {
 | |
| 				printf("\n%d is not a valid frame length. Valid length are 30 and 60 msec.\n", framesize);
 | |
| 				exit(0);
 | |
|             }
 | |
|             setControlBWE = 1;
 | |
| 			printf("Frame Length: %d\n", framesize);
 | |
| 			i++;
 | |
| 		}
 | |
|         
 | |
|         /* Fixed frame length */
 | |
|         if(!strcmp ("-FIXED_FL", argv[i])) 
 | |
|         {
 | |
| 			fixedFL = 1;
 | |
|             setControlBWE = 1;
 | |
| 			printf("Fixed Frame Length\n");
 | |
| 		}
 | |
|         
 | |
|         /* Set maximum allowed payload size in bytes */
 | |
|         if(!strcmp ("-MAX", argv[i]))	{
 | |
| 			payloadSize = atoi(argv[i + 1]);
 | |
|             printf("Maximum Payload Size: %d\n", payloadSize);
 | |
| 			i++;
 | |
| 		}
 | |
| 
 | |
|         /* Set maximum rate in bytes */
 | |
|         if(!strcmp ("-MAXRATE", argv[i]))	{
 | |
| 			payloadRate = atoi(argv[i + 1]);
 | |
|             printf("Maximum Rate in kbps: %d\n", payloadRate);
 | |
| 			i++;
 | |
| 		}
 | |
| 
 | |
|         /* Test of fault scenarious */
 | |
|         if(!strcmp ("-F", argv[i])) 
 | |
|         {
 | |
| 			testNum = atoi(argv[i + 1]);
 | |
| 			printf("Fault test: %d\n", testNum);
 | |
| 			if(testNum < 1 || testNum > 10)	
 | |
|             {
 | |
| 				printf("\n%d is not a valid Fault Scenario number. Valid Fault Scenarios are numbered 1-10.\n", testNum);
 | |
| 				exit(0);
 | |
| 			}
 | |
| 			i++;
 | |
| 		}
 | |
| 		
 | |
|         /* Packet loss test */
 | |
| 		if(!strcmp ("-PL", argv[i])) 
 | |
|         {
 | |
| 			if( isdigit( *argv[i+1] ) )	
 | |
|             {
 | |
| 				packetLossPercent = atoi( argv[i+1] );
 | |
| 				if( (packetLossPercent < 0) | (packetLossPercent > 100) ) 
 | |
|                 {
 | |
| 					printf( "\nInvalid packet loss perentage \n" );
 | |
| 					exit( 0 );
 | |
| 				}
 | |
|                 if( packetLossPercent > 0 ) 
 | |
|                 {
 | |
| 					printf( "Simulating %d %% of independent packet loss\n", packetLossPercent );
 | |
|                 } 
 | |
|                 else 
 | |
|                 {
 | |
| 					printf( "\nNo Packet Loss Is Simulated \n" );
 | |
|                 }
 | |
| 				readLoss = 0;
 | |
|             } 
 | |
|             else 
 | |
|             {
 | |
| 				readLoss = 1;
 | |
| 				plFile = fopen( argv[i+1], "rb" );
 | |
| 				if( plFile == NULL ) 
 | |
|                 {
 | |
| 					printf( "\n couldn't open the frameloss file: %s\n", argv[i+1] );
 | |
| 					exit( 0 );
 | |
| 				}
 | |
| 				printf( "Simulating packet loss through the given channel file: %s\n", argv[i+1] );	
 | |
| 			}
 | |
| 			i++;
 | |
| 		}
 | |
| 
 | |
|         /* Random packetlosses */
 | |
| 		if(!strcmp ("-rnd", argv[i])) 
 | |
|         {
 | |
| 			srand((unsigned int)time(NULL) );	
 | |
| 			printf( "Random pattern in lossed packets \n" );
 | |
| 		}
 | |
| 
 | |
|         /* Use gns file */
 | |
| 		if(!strcmp ("-G", argv[i])) 
 | |
|         {
 | |
| 			sscanf(argv[i + 1], "%s", gns_file);
 | |
| 			fp_gns = fopen(gns_file, "rb");
 | |
| 			if(fp_gns  == NULL) 
 | |
|             {
 | |
| 				printf("Cannot read file %s.\n", gns_file);
 | |
| 				exit(0);
 | |
| 			}
 | |
| 			gns = 1;
 | |
| 			i++;
 | |
| 		}
 | |
| 
 | |
| 
 | |
|         // make it with '-B'
 | |
|         /* Get Bottleneck value */
 | |
|         if(!strcmp("-B", argv[i]))
 | |
|         {
 | |
|             i++;
 | |
|             bottleneck = atoi(argv[i]);
 | |
|             if(bottleneck == 0)
 | |
|             {
 | |
|                 sscanf(argv[i], "%s", bottleneck_file);
 | |
|                 f_bn = fopen(bottleneck_file, "rb");
 | |
|                 if(f_bn  == NULL)
 | |
|                 {
 | |
|                     printf("Error No value provided for BottleNeck and cannot read file %s.\n", bottleneck_file);
 | |
|                     exit(0);
 | |
|                 }
 | |
|                 else 
 | |
|                 {
 | |
|                     printf("reading bottleneck rates from file %s\n\n",bottleneck_file);
 | |
|                     if(fscanf(f_bn, "%d", &bottleneck) == EOF)
 | |
|                     {
 | |
|                         /* Set pointer to beginning of file */
 | |
|                         fseek(f_bn, 0L, SEEK_SET);
 | |
|                         fscanf(f_bn, "%d", &bottleneck);
 | |
|                     }		
 | |
| 
 | |
|                     /*	Bottleneck is a cosine function 
 | |
|                     *	Matlab code for writing the bottleneck file:
 | |
|                     *	BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
 | |
|                     *	fid = fopen('bottleneck.txt', 'wb');
 | |
|                     *	fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
 | |
|                     */
 | |
|                 }
 | |
|             }
 | |
|             else 
 | |
|             {
 | |
|                 printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
 | |
|             }
 | |
|         }
 | |
|         /* Run Conference Engine APIs */
 | |
|         //     Do not test it in the first release
 | |
|         //
 | |
|         //     if(!strcmp ("-CE", argv[i]))
 | |
|         //     {
 | |
|         //         testCE = atoi(argv[i + 1]);
 | |
|         //         if(testCE==1) 
 | |
|         //         {
 | |
|         //             i++;
 | |
|         //             scale = (float)atof( argv[i+1] );
 | |
|         //         } 
 | |
|         //         else if(testCE == 2) 
 | |
|         //         {
 | |
|         //             printf("\nCE-test 2 (transcoding) not implemented.\n");
 | |
|         //             exit(0);
 | |
|         //         } 
 | |
|         //         else if(testCE < 1 || testCE > 3) 
 | |
|         //         {
 | |
|         //             printf("\n%d is not a valid CE-test number. Valid CE tests are 1-3.\n", testCE);
 | |
|         //             exit(0);
 | |
|         //         }
 | |
|         //         printf("CE-test number: %d\n", testCE);
 | |
|         //         i++;
 | |
|         //     }
 | |
|     }
 | |
| 
 | |
| 	if(CodingMode == 0)
 | |
| 	{
 | |
| 		printf("\nAdaptive BottleNeck\n");
 | |
| 	}
 | |
| 
 | |
|     switch(sampFreqKHz)
 | |
|     {
 | |
|     case 16:
 | |
|         {
 | |
|             printf("iSAC Wideband.\n");
 | |
|             samplesIn10Ms = FRAMESAMPLES_10ms;
 | |
|             break;
 | |
|         }
 | |
|     case 32:
 | |
|         {
 | |
|             printf("iSAC Supper-Wideband.\n");
 | |
|             samplesIn10Ms = SWBFRAMESAMPLES_10ms;
 | |
|             break;
 | |
|         }
 | |
|     default:
 | |
|             printf("Unsupported sampling frequency %d kHz", sampFreqKHz);
 | |
|             exit(0);
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 	/* Get Input and Output files */
 | |
| 	sscanf(argv[argc-2], "%s", inname);
 | |
| 	sscanf(argv[argc-1], "%s", outname);
 | |
|     printf("\nInput file: %s\n", inname);
 | |
|     printf("Output file: %s\n\n", outname);
 | |
| 	if((inp = fopen(inname,"rb")) == NULL) 
 | |
|     {
 | |
| 		printf("  Error iSAC Cannot read file %s.\n", inname);
 | |
|         cout << flush;
 | |
| 		exit(1);
 | |
| 	}
 | |
| 
 | |
| 	if((outp = fopen(outname,"wb")) == NULL) 
 | |
|     {
 | |
| 		printf("  Error iSAC Cannot write file %s.\n", outname);
 | |
|         cout << flush;
 | |
|         getchar();
 | |
| 		exit(1);
 | |
| 	}
 | |
| 	if(VADusage) 
 | |
|     {
 | |
| 		if((vadp = fopen(vadfile,"rb")) == NULL) 
 | |
|         {
 | |
| 			printf("  Error iSAC Cannot read file %s.\n", vadfile);
 | |
|             cout << flush;
 | |
| 			exit(1);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
|     if((bandwidthp = fopen("bwe.pcm","wb")) == NULL) 
 | |
|     {
 | |
|             printf("  Error iSAC Cannot read file %s.\n", "bwe.pcm");
 | |
|             cout << flush;
 | |
|             exit(1);
 | |
|     }
 | |
| 
 | |
| 
 | |
| 	starttime = clock()/(double)CLOCKS_PER_SEC; /* Runtime statistics */
 | |
| 
 | |
|     /* Initialize the ISAC and BN structs */
 | |
|     if(testNum != 8)
 | |
|     {
 | |
|         if(!useAssign)
 | |
|         {
 | |
|             err =WebRtcIsac_Create(&ISAC_main_inst);
 | |
|             WebRtcIsac_SetEncSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); 
 | |
|             WebRtcIsac_SetDecSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             /* Test the Assign functions */
 | |
|             int sss;
 | |
|             void *ppp;
 | |
|             err = WebRtcIsac_AssignSize(&sss); 
 | |
|             ppp = malloc(sss);
 | |
|             err = WebRtcIsac_Assign(&ISAC_main_inst, ppp); 
 | |
|             WebRtcIsac_SetEncSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); 
 | |
|             WebRtcIsac_SetDecSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband);
 | |
|         }
 | |
|         /* Error check */
 | |
|         if(err < 0) 
 | |
|         {
 | |
|             printf("\n\n Error in create.\n\n");
 | |
|             cout << flush;
 | |
|             exit(EXIT_FAILURE);
 | |
|         }
 | |
|     }
 | |
| 	BN_data.arrival_time  = 0;
 | |
| 	BN_data.sample_count  = 0;
 | |
| 	BN_data.rtp_number    = 0;
 | |
| 
 | |
| 	/* Initialize encoder and decoder */
 | |
|     framecnt= 0;
 | |
|     endfile	= 0;
 | |
| 	
 | |
|     if(doTransCoding)
 | |
|     {
 | |
|         WebRtcIsac_Create(&decoderTransCoding); 
 | |
|         WebRtcIsac_SetEncSampRate(decoderTransCoding, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); 
 | |
|         WebRtcIsac_SetDecSampRate(decoderTransCoding, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband);
 | |
|         WebRtcIsac_DecoderInit(decoderTransCoding);
 | |
|         transCodingFile = fopen(transCodingFileName, "wb");
 | |
|         if(transCodingFile == NULL)
 | |
|         {
 | |
|             printf("Could not open %s to output trans-coding.\n", transCodingFileName);
 | |
|             exit(0);
 | |
|         }
 | |
|         strcat(transCodingFileName, ".bit");
 | |
|         transcodingBitstream = fopen(transCodingFileName, "wb");
 | |
|         if(transcodingBitstream == NULL)
 | |
|         {
 | |
|             printf("Could not open %s to write the bit-stream of transcoder.\n", transCodingFileName);
 | |
|             exit(0);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if(testNum != 1) 
 | |
|     {
 | |
| 		if(WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode) < 0)
 | |
|         {
 | |
|             printf("Error could not initialize the encoder \n");
 | |
|             cout << flush;
 | |
|             return 0;
 | |
|         }
 | |
| 	}
 | |
|     if(testNum != 2) 
 | |
|     {
 | |
|         if(WebRtcIsac_DecoderInit(ISAC_main_inst) < 0) 
 | |
|         {
 | |
|             printf("Error could not initialize the decoder \n");
 | |
|             cout << flush;
 | |
|             return 0;
 | |
|         }
 | |
| 	}		
 | |
| 	if(CodingMode == 1) 
 | |
|     {
 | |
|         err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
 | |
|         if(err < 0) 
 | |
|         {
 | |
|             /* exit if returned with error */
 | |
|             errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|             printf("\n\n Error in initialization (control): %d.\n\n", errtype);
 | |
|             cout << flush;
 | |
|             if(testNum == 0)
 | |
|             {
 | |
|                 exit(EXIT_FAILURE);
 | |
|             }
 | |
|         }
 | |
| 	}
 | |
| 
 | |
|     if((setControlBWE) && (CodingMode == 0)) 
 | |
|     {
 | |
|         err = WebRtcIsac_ControlBwe(ISAC_main_inst, rateBPS, framesize, fixedFL);    
 | |
|         if(err < 0) 
 | |
|         {
 | |
|             /* exit if returned with error */
 | |
|             errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|             
 | |
|             printf("\n\n Error in Control BWE: %d.\n\n", errtype);
 | |
|             cout << flush;
 | |
|             exit(EXIT_FAILURE);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if(payloadSize != 0) 
 | |
|     {
 | |
|         err = WebRtcIsac_SetMaxPayloadSize(ISAC_main_inst, payloadSize);
 | |
|         if(err < 0) 
 | |
|         {
 | |
|             /* exit if returned with error */
 | |
|             errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|             printf("\n\n Error in SetMaxPayloadSize: %d.\n\n", errtype);
 | |
|             cout << flush;
 | |
|             exit(EXIT_FAILURE);
 | |
|         }
 | |
|     }
 | |
|     if(payloadRate != 0) 
 | |
|     {
 | |
|         err = WebRtcIsac_SetMaxRate(ISAC_main_inst, payloadRate);
 | |
|         if(err < 0) 
 | |
|         {
 | |
|             /* exit if returned with error */
 | |
|             errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|             printf("\n\n Error in SetMaxRateInBytes: %d.\n\n", errtype);
 | |
|             cout << flush;
 | |
|             exit(EXIT_FAILURE);
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 	*speechType = 1;
 | |
| 
 | |
|     cout << "\n" << flush;
 | |
| 
 | |
|     length_file = 0;
 | |
|     WebRtc_Word16 bnIdxTC;
 | |
|     WebRtc_Word16 jitterInfoTC;
 | |
|     while (endfile == 0) 
 | |
|     {	
 | |
|         /* Call init functions at random, fault test number 7 */
 | |
| 		if(testNum == 7 && (rand()%2 == 0))	
 | |
|         {
 | |
|             err = WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
 | |
|             /* Error check */
 | |
|             if(err < 0) 
 | |
|             {
 | |
|                 errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|                 printf("\n\n Error in encoderinit: %d.\n\n", errtype);
 | |
|                 cout << flush;
 | |
|             }
 | |
| 
 | |
|             err = WebRtcIsac_DecoderInit(ISAC_main_inst);		
 | |
|             /* Error check */
 | |
|             if(err < 0) 
 | |
|             {
 | |
|                 errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|                 printf("\n\n Error in decoderinit: %d.\n\n", errtype);
 | |
|                 cout << flush;
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 		cur_framesmpls = 0;
 | |
| 		while (1) 
 | |
|         {
 | |
|             int kkk;
 | |
|             
 | |
|             /* Read 10 ms speech block */
 | |
|             endfile = readframe(shortdata, inp, samplesIn10Ms);
 | |
| 
 | |
|             if(endfile)
 | |
|             {
 | |
|                 numFileLoop++;
 | |
|                 if(numFileLoop < totFileLoop)
 | |
|                 {
 | |
|                     rewind(inp);
 | |
|                     framecnt = 0;
 | |
|                     fprintf(stderr, "\n");
 | |
|                     endfile = readframe(shortdata, inp, samplesIn10Ms);
 | |
|                 }
 | |
|             }
 | |
|                 
 | |
|             if(testNum == 7) 
 | |
|             {
 | |
| 		    	srand((unsigned int)time(NULL));
 | |
| 		    }
 | |
| 
 | |
|             /* iSAC encoding */
 | |
|             if(!(testNum == 3 && framecnt == 0)) 
 | |
|             {
 | |
|                 stream_len = WebRtcIsac_Encode(ISAC_main_inst, 
 | |
|                     shortdata,
 | |
|                     (WebRtc_Word16*)streamdata);
 | |
|                 if((payloadSize != 0) && (stream_len > payloadSize)) 
 | |
|                 {
 | |
|                     if(testNum == 0)
 | |
|                     {
 | |
|                         printf("\n\n");
 | |
|                     }
 | |
| 
 | |
|                     printf("\nError: Streamsize out of range %d\n", stream_len - payloadSize);
 | |
|                     cout << flush;
 | |
|                 }
 | |
|                      
 | |
|                 kkk = WebRtcIsac_GetUplinkBw(ISAC_main_inst, &sendBN);
 | |
|  
 | |
|                 if(stream_len>0) 
 | |
|                 {
 | |
|                     if(doTransCoding)
 | |
|                     {
 | |
|                         WebRtc_Word16 indexStream;
 | |
|                         WebRtc_UWord8 auxUW8;
 | |
| 
 | |
|                         /************************* Main Transcoding stream *******************************/
 | |
|                         WebRtcIsac_GetDownLinkBwIndex(ISAC_main_inst, &bnIdxTC, &jitterInfoTC);
 | |
|                         streamLenTransCoding = WebRtcIsac_GetNewBitStream(
 | |
|                             ISAC_main_inst, bnIdxTC, jitterInfoTC, rateTransCoding,
 | |
|                             (WebRtc_Word16*)streamDataTransCoding, false);
 | |
|                         if(streamLenTransCoding < 0)
 | |
|                         {
 | |
|                             fprintf(stderr, "Error in trans-coding\n");
 | |
|                             exit(0);
 | |
|                         }
 | |
|                         auxUW8 = (WebRtc_UWord8)(((streamLenTransCoding & 0xFF00) >> 8) &  0x00FF);
 | |
|                         fwrite(&auxUW8, sizeof(WebRtc_UWord8),
 | |
|                             1, transcodingBitstream);
 | |
| 
 | |
|                         auxUW8 = (WebRtc_UWord8)(streamLenTransCoding & 0x00FF);
 | |
|                         fwrite(&auxUW8, sizeof(WebRtc_UWord8),
 | |
|                             1, transcodingBitstream);
 | |
| 
 | |
|                         fwrite((WebRtc_UWord8*)streamDataTransCoding, sizeof(WebRtc_UWord8),
 | |
|                             streamLenTransCoding, transcodingBitstream);
 | |
| 
 | |
|                         WebRtcIsac_ReadBwIndex((WebRtc_Word16*)streamDataTransCoding, &indexStream);
 | |
|                         if(indexStream != bnIdxTC)
 | |
|                         {
 | |
|                             fprintf(stderr, "Error in inserting Bandwidth index into transcoding stream.\n");
 | |
|                             exit(0);
 | |
|                         }
 | |
|                         numTransCodingBytes += streamLenTransCoding;
 | |
|                     }
 | |
|                 }
 | |
|             } 
 | |
|             else 
 | |
|             {
 | |
|                 kkk = 0;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
| 			if(stream_len < 0) 
 | |
|             {
 | |
| 				/* exit if returned with error */
 | |
| 				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|                 printf("\n\nError in encoder: %d.\n\n", errtype);
 | |
|                 cout << flush;
 | |
| 			}
 | |
| 			cur_framesmpls += samplesIn10Ms;
 | |
| 			/* exit encoder loop if the encoder returned a bitstream */
 | |
| 			if(stream_len != 0) break;
 | |
| 		}
 | |
| 
 | |
|         /* read next bottleneck rate */
 | |
|         if(f_bn != NULL) 
 | |
|         {
 | |
|             if(fscanf(f_bn, "%d", &bottleneck) == EOF) 
 | |
|             {
 | |
|                 /* Set pointer to beginning of file */
 | |
|                 fseek(f_bn, 0L, SEEK_SET);
 | |
|                 fscanf(f_bn, "%d", &bottleneck);
 | |
|             }
 | |
|             if(CodingMode == 1)
 | |
|             {
 | |
|                 WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         length_file += cur_framesmpls;
 | |
|         if(cur_framesmpls == (3 * samplesIn10Ms))
 | |
|         {
 | |
|             maxStreamLen30 = (stream_len > maxStreamLen30)? stream_len:maxStreamLen30;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             maxStreamLen60 = (stream_len > maxStreamLen60)? stream_len:maxStreamLen60;
 | |
|         }
 | |
| 
 | |
|         if(!lostFrame) 
 | |
|         {
 | |
|             lostFrame = ((rand()%100) < packetLossPercent);
 | |
|         } 
 | |
|         else 
 | |
|         {
 | |
|             lostFrame = 0;
 | |
|         }
 | |
|         
 | |
|         // RED.
 | |
|         if(lostFrame) 
 | |
|         {
 | |
|             stream_len = WebRtcIsac_GetRedPayload(ISAC_main_inst, 
 | |
|                 (WebRtc_Word16*)streamdata);
 | |
| 
 | |
|             if(doTransCoding)
 | |
|             {
 | |
|                 streamLenTransCoding = WebRtcIsac_GetNewBitStream(
 | |
|                     ISAC_main_inst, bnIdxTC, jitterInfoTC, rateTransCoding,
 | |
|                     (WebRtc_Word16*)streamDataTransCoding, true);
 | |
|                 if(streamLenTransCoding < 0)
 | |
|                 {
 | |
|                     fprintf(stderr, "Error in RED trans-coding\n");
 | |
|                     exit(0);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /* make coded sequence to short be inreasing */
 | |
| 		/* the length the decoder expects */
 | |
| 		if(testNum == 4) 
 | |
|         {
 | |
| 			stream_len += 10;
 | |
| 		}
 | |
| 
 | |
| 		/* make coded sequence to long be decreasing */
 | |
| 		/* the length the decoder expects */
 | |
| 		if(testNum == 5) 
 | |
|         {
 | |
| 			stream_len -= 10;
 | |
| 		}
 | |
| 
 | |
|         if(testNum == 6) 
 | |
|         {
 | |
| 			srand((unsigned int)time(NULL));
 | |
|             for(i = 0; i < stream_len; i++) 
 | |
|             {
 | |
| 				streamdata[i] = rand();
 | |
|             }
 | |
| 		}
 | |
| 
 | |
|         if(VADusage){
 | |
|             readframe(vaddata, vadp, samplesIn10Ms*3);
 | |
|         }
 | |
| 
 | |
| 		/* simulate packet handling through NetEq and the modem */
 | |
| 		if(!(testNum == 3 && framecnt == 0)) 
 | |
|         {
 | |
|             get_arrival_time(cur_framesmpls, stream_len, bottleneck, &BN_data,
 | |
|                 sampFreqKHz*1000, sampFreqKHz*1000);
 | |
|         }
 | |
| 
 | |
| 		if(VADusage && (framecnt>10 && vaddata[0]==0))
 | |
|         {
 | |
| 			BN_data.rtp_number--;
 | |
| 		} 
 | |
|         else 
 | |
|         {
 | |
|             /* Error test number 10, garbage data */
 | |
|             if(testNum == 10) 
 | |
|             {
 | |
|                 /* Test to run decoder with garbage data */
 | |
|                 for(i = 0; i < stream_len; i++) 
 | |
|                 {
 | |
|                     streamdata[i] = (short) (streamdata[i]) + (short) rand();
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if(testNum != 9) 
 | |
|             {
 | |
|                 err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata, 
 | |
|                     stream_len, BN_data.rtp_number, BN_data.sample_count, 
 | |
|                     BN_data.arrival_time);
 | |
| 
 | |
|                 if(err < 0) 
 | |
|                 {
 | |
|                     /* exit if returned with error */
 | |
|                     errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|                     if(testNum == 0)
 | |
|                     {
 | |
|                         printf("\n\n");
 | |
|                     }
 | |
| 
 | |
|                     printf("Error: in decoder: %d.", errtype);
 | |
|                     cout << flush;
 | |
|                     if(testNum == 0)
 | |
|                     {
 | |
|                         printf("\n\n");
 | |
|                     }
 | |
| 
 | |
|                 }
 | |
|             }
 | |
|  
 | |
|             /* Call getFramelen, only used here for function test */
 | |
|             err = WebRtcIsac_ReadFrameLen(ISAC_main_inst, 
 | |
|                 (WebRtc_Word16*)streamdata, &FL);
 | |
|             if(err < 0) 
 | |
|             {
 | |
|                 /* exit if returned with error */
 | |
|                 errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|                 if(testNum == 0)
 | |
|                 {
 | |
|                     printf("\n\n");
 | |
|                 }
 | |
|                 printf("    Error: in getFrameLen %d.", errtype);
 | |
|                 cout << flush;
 | |
|                 if(testNum == 0)
 | |
|                 {
 | |
|                     printf("\n\n");
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // iSAC decoding
 | |
|             
 | |
|             if(lostFrame)
 | |
|             {
 | |
|                 declen = WebRtcIsac_DecodeRcu(ISAC_main_inst, streamdata,
 | |
|                     stream_len, decoded, speechType);
 | |
| 
 | |
|                 if(doTransCoding)
 | |
|                 {
 | |
|                     declenTC = WebRtcIsac_DecodeRcu(decoderTransCoding, 
 | |
|                         streamDataTransCoding, streamLenTransCoding, 
 | |
|                         decodedTC, speechType);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata,
 | |
|                     stream_len, decoded, speechType);
 | |
| 
 | |
|                 if(doTransCoding)
 | |
|                 {
 | |
|                     declenTC = WebRtcIsac_Decode(decoderTransCoding, 
 | |
|                         streamDataTransCoding, streamLenTransCoding,
 | |
|                         decodedTC, speechType);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if(declen < 0) 
 | |
|             {
 | |
|                 /* exit if returned with error */
 | |
|                 errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
 | |
|                 if(testNum == 0)
 | |
|                 {
 | |
|                     printf("\n\n");
 | |
|                 }
 | |
|                 printf("    Error: in decoder %d.", errtype);
 | |
|                 cout << flush;
 | |
|                 if(testNum == 0)
 | |
|                 {
 | |
|                     printf("\n\n");
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if(declenTC < 0)
 | |
|             {
 | |
|                 if(testNum == 0)
 | |
|                 {
 | |
|                     printf("\n\n");
 | |
|                 }
 | |
|                 printf("    Error: in decoding the transcoded stream");
 | |
|                 cout << fflush;
 | |
|                 if(testNum == 0)
 | |
|                 {
 | |
|                     printf("\n\n");
 | |
|                 }
 | |
| 
 | |
|             }
 | |
|         }
 | |
|         /* Write decoded speech frame to file */
 | |
|         if((declen > 0) && (numFileLoop == 0))
 | |
|         {
 | |
|             fwrite(decoded, sizeof(WebRtc_Word16), declen, outp);
 | |
|         }
 | |
| 
 | |
|         if((declenTC > 0) && (numFileLoop == 0))
 | |
|         {
 | |
|             fwrite(decodedTC, sizeof(WebRtc_Word16), declen, transCodingFile);
 | |
|         }
 | |
| 
 | |
| 		
 | |
| 		fprintf(stderr, "\rframe = %5d  ", framecnt);
 | |
|         fflush(stderr);
 | |
| 		framecnt++;
 | |
|     
 | |
|         /* Error test number 10, garbage data */
 | |
|         //if(testNum == 10) 
 | |
|         //{
 | |
|         //    /* Test to run decoder with garbage data */
 | |
|         //    if( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) 
 | |
|         //    {
 | |
|         //        fprintf(stderr, "Error: Could not open file %s\n", SEED_FILE);
 | |
|         //    }
 | |
|         //    else 
 | |
|         //    {
 | |
|         //        fprintf(seedfile, "ok\n\n");
 | |
|         //        fclose(seedfile);
 | |
|         //    }
 | |
|         //}
 | |
|         /* Error test number 10, garbage data */
 | |
|         //if(testNum == 10) 
 | |
|         //{
 | |
|         //    /* Test to run decoder with garbage data */
 | |
|         //    for ( i = 0; i < stream_len; i++) 
 | |
|         //    {
 | |
|         //        streamdata[i] = (short) (streamdata[i] + (short) rand());
 | |
|         //    }
 | |
|         //}
 | |
| 
 | |
| 		
 | |
| 		totalsmpls += declen;
 | |
| 		totalbits += 8 * stream_len;
 | |
| #ifdef _DEBUG
 | |
|         kbps = ((double) sampFreqKHz * 1000.) / ((double) cur_framesmpls) * 8.0 * stream_len / 1000.0;// kbits/s
 | |
| 		fy = fopen("bit_rate.dat", "a");
 | |
| 		fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
 | |
| 		fclose(fy);
 | |
| 		
 | |
| #endif /* _DEBUG */
 | |
| 
 | |
| 	}
 | |
| 	printf("\n");
 | |
| 	printf("total bits               = %d bits\n", totalbits);
 | |
| 	printf("measured average bitrate = %0.3f kbits/s\n", 
 | |
|         (double)totalbits *(sampFreqKHz) / totalsmpls);
 | |
|     if(doTransCoding)
 | |
|     {
 | |
|         printf("Transcoding average bit-rate = %0.3f kbps\n",
 | |
|             (double)numTransCodingBytes * 8.0 *(sampFreqKHz) / totalsmpls);
 | |
|         fclose(transCodingFile);
 | |
|     }
 | |
| 	printf("\n");
 | |
| 	
 | |
| 	/* Runtime statistics */
 | |
| 	runtime = (double)(clock()/(double)CLOCKS_PER_SEC-starttime);
 | |
| 	length_file = length_file /(sampFreqKHz * 1000.);
 | |
| 	 
 | |
|     printf("\n\nLength of speech file: %.1f s\n", length_file);
 | |
| 	printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime, (100*runtime/length_file));
 | |
| 
 | |
|     if(maxStreamLen30 != 0)
 | |
|     {
 | |
|         printf("Maximum payload size 30ms Frames %d bytes (%0.3f kbps)\n", 
 | |
|             maxStreamLen30,
 | |
|             maxStreamLen30 * 8 / 30.);
 | |
|     }
 | |
|     if(maxStreamLen60 != 0)
 | |
|     {
 | |
|         printf("Maximum payload size 60ms Frames %d bytes (%0.3f kbps)\n", 
 | |
|             maxStreamLen60,
 | |
|             maxStreamLen60 * 8 / 60.);
 | |
|     }
 | |
|     //fprintf(stderr, "\n");
 | |
| 
 | |
| 	fprintf(stderr, "   %.1f s", length_file);
 | |
|     fprintf(stderr, "   %0.1f kbps", (double)totalbits *(sampFreqKHz) / totalsmpls);
 | |
|     if(maxStreamLen30 != 0)
 | |
|     {
 | |
|         fprintf(stderr, "   plmax-30ms %d bytes (%0.0f kbps)", 
 | |
|             maxStreamLen30,
 | |
|             maxStreamLen30 * 8 / 30.);
 | |
|     }
 | |
|     if(maxStreamLen60 != 0)
 | |
|     {
 | |
|         fprintf(stderr, "   plmax-60ms %d bytes (%0.0f kbps)", 
 | |
|             maxStreamLen60,
 | |
|             maxStreamLen60 * 8 / 60.);
 | |
|     }
 | |
|     if(doTransCoding)
 | |
|     {
 | |
|         fprintf(stderr, "  transcoding rate %.0f kbps",
 | |
|             (double)numTransCodingBytes * 8.0 *(sampFreqKHz) / totalsmpls);
 | |
|     }
 | |
| 
 | |
|     fclose(inp);
 | |
| 	fclose(outp);
 | |
| 	WebRtcIsac_Free(ISAC_main_inst);
 | |
| 
 | |
| 
 | |
| 	exit(0);
 | |
| }	
 | 
