| /* |
| * 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 <string.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #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; |
| |
| } |