/* * 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. */ /****************************************************************** Stand Alone test application for ISACFIX and ISAC LC ******************************************************************/ #include #include #include #include "typedefs.h" #include "isacfix.h" ISACFIX_MainStruct *ISACfix_inst; #define FS 16000 typedef struct { WebRtc_UWord32 arrival_time; /* samples */ WebRtc_UWord32 sample_count; /* samples */ WebRtc_UWord16 rtp_number; } BottleNeckModel; void get_arrival_time(int current_framesamples, /* samples */ int packet_size, /* bytes */ int bottleneck, /* excluding headers; bits/s */ BottleNeckModel *BN_data) { const int HeaderSize = 35; int HeaderRate; HeaderRate = HeaderSize * 8 * FS / current_framesamples; /* bits/s */ /* everything in samples */ BN_data->sample_count = BN_data->sample_count + current_framesamples; BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate); if (BN_data->arrival_time < BN_data->sample_count) BN_data->arrival_time = BN_data->sample_count; BN_data->rtp_number++; } /* #ifdef __cplusplus extern "C" { #endif */ int main(int argc, char* argv[]){ /* Parameters */ FILE *pInFile, *pOutFile, *pChcFile; WebRtc_Word8 inFile[40]; WebRtc_Word8 outFile[40]; WebRtc_Word8 chcFile[40]; WebRtc_Word8 codec[10]; WebRtc_Word16 bitrt, spType, size; WebRtc_UWord16 frameLen; WebRtc_Word16 sigOut[1000], sigIn[1000]; WebRtc_UWord16 bitStream[500]; /* double to 32 kbps for 60 ms */ WebRtc_Word16 chc, ok; int noOfCalls, cdlen; WebRtc_Word16 noOfLostFrames; int err, errtype; BottleNeckModel BN_data; int totalbits =0; int totalsmpls =0; /*End Parameters*/ if ((argc==6)||(argc==7) ){ strcpy(codec,argv[5]); if(argc==7){ if (!_stricmp("isac",codec)){ bitrt = atoi(argv[6]); if ( (bitrt<10000)&&(bitrt>32000)){ printf("Error: Supported bit rate in the range 10000-32000 bps!\n"); exit(-1); } }else{ printf("Error: Codec not recognized. Check spelling!\n"); exit(-1); } } else { printf("Error: Codec not recognized. Check spelling!\n"); exit(-1); } } else { printf("Error: Wrong number of input parameter!\n\n"); exit(-1); } frameLen = atoi(argv[4]); strcpy(chcFile,argv[3]); strcpy(outFile,argv[2]); strcpy(inFile,argv[1]); /* Open file streams */ if( (pInFile = fopen(inFile,"rb")) == NULL ) { printf( "Error: Did not find input file!\n" ); exit(-1); } strcat(outFile,"_"); strcat(outFile, argv[4]); strcat(outFile,"_"); strcat(outFile, codec); if (argc==7){ strcat(outFile,"_"); strcat(outFile, argv[6]); } if (_stricmp("none", chcFile)){ strcat(outFile,"_"); strcat(outFile, "plc"); } strcat(outFile, ".otp"); if (_stricmp("none", chcFile)){ if( (pChcFile = fopen(chcFile,"rb")) == NULL ) { printf( "Error: Did not find channel file!\n" ); exit(-1); } } /******************************************************************/ if (!_stricmp("isac", codec)){ /* ISAC */ if ((frameLen!=480)&&(frameLen!=960)) { printf("Error: ISAC only supports 480 and 960 samples per frame (not %d)\n", frameLen); exit(-1); } if( (pOutFile = fopen(outFile,"wb")) == NULL ) { printf( "Could not open output file!\n" ); exit(-1); } ok=WebRtcIsacfix_Create(&ISACfix_inst); if (ok!=0) { printf("Couldn't allocate memory for iSAC fix instance\n"); exit(-1); } BN_data.arrival_time = 0; BN_data.sample_count = 0; BN_data.rtp_number = 0; WebRtcIsacfix_EncoderInit(ISACfix_inst,1); WebRtcIsacfix_DecoderInit(ISACfix_inst); err = WebRtcIsacfix_Control(ISACfix_inst, bitrt, (frameLen>>4)); if (err < 0) { /* exit if returned with error */ errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); printf("\n\n Error in initialization: %d.\n\n", errtype); exit(EXIT_FAILURE); } /* loop over frame */ while (fread(sigIn,sizeof(WebRtc_Word16),frameLen,pInFile) == frameLen) { noOfCalls=0; cdlen=0; while (cdlen<=0) { cdlen=WebRtcIsacfix_Encode(ISACfix_inst,&sigIn[noOfCalls*160],(WebRtc_Word16*)bitStream); if(cdlen==-1){ errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); printf("\n\nError in encoder: %d.\n\n", errtype); exit(-1); } noOfCalls++; } if(_stricmp("none", chcFile)){ if (fread(&chc,sizeof(WebRtc_Word16),1,pChcFile)!=1) /* packet may be lost */ break; } else { chc = 1; /* packets never lost */ } /* simulate packet handling through NetEq and the modem */ get_arrival_time(frameLen, cdlen, bitrt, &BN_data); if (chc){ /* decode */ err = WebRtcIsacfix_UpdateBwEstimate1(ISACfix_inst, bitStream, cdlen, BN_data.rtp_number, BN_data.arrival_time); if (err < 0) { /* exit if returned with error */ errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); printf("\n\nError in decoder: %d.\n\n", errtype); exit(EXIT_FAILURE); } size = WebRtcIsacfix_Decode(ISACfix_inst, bitStream, cdlen, sigOut, &spType); if(size<=0){ /* exit if returned with error */ errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); printf("\n\nError in decoder: %d.\n\n", errtype); exit(-1); } } else { /* PLC */ if (frameLen == 480){ noOfLostFrames = 1; } else{ noOfLostFrames = 2; } size = WebRtcIsacfix_DecodePlc(ISACfix_inst, sigOut, noOfLostFrames ); if(size<=0){ errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); printf("\n\nError in decoder: %d.\n\n", errtype); exit(-1); } } /* Write decoded speech to file */ fwrite(sigOut,sizeof(short),size,pOutFile); totalbits += 8 * cdlen; totalsmpls += size; } /******************************************************************/ } // printf("\n\ntotal bits = %d bits", totalbits); printf("\nmeasured average bitrate = %0.3f kbits/s", (double)totalbits * 16 / totalsmpls); printf("\n"); fclose(pInFile); fclose(pOutFile); if (_stricmp("none", chcFile)){ fclose(pChcFile); } if (!_stricmp("isac", codec)){ WebRtcIsacfix_Free(ISACfix_inst); } return 0; }