1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 /****************************************************************** 12 Stand Alone test application for ISACFIX and ISAC LC 13 14 ******************************************************************/ 15 16 #include <string.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include "typedefs.h" 20 21 #include "isacfix.h" 22 ISACFIX_MainStruct *ISACfix_inst; 23 24 #define FS 16000 25 26 27 typedef struct { 28 WebRtc_UWord32 arrival_time; /* samples */ 29 WebRtc_UWord32 sample_count; /* samples */ 30 WebRtc_UWord16 rtp_number; 31 } BottleNeckModel; 32 33 void get_arrival_time(int current_framesamples, /* samples */ 34 int packet_size, /* bytes */ 35 int bottleneck, /* excluding headers; bits/s */ 36 BottleNeckModel *BN_data) 37 { 38 const int HeaderSize = 35; 39 int HeaderRate; 40 41 HeaderRate = HeaderSize * 8 * FS / current_framesamples; /* bits/s */ 42 43 /* everything in samples */ 44 BN_data->sample_count = BN_data->sample_count + current_framesamples; 45 46 BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate); 47 48 if (BN_data->arrival_time < BN_data->sample_count) 49 BN_data->arrival_time = BN_data->sample_count; 50 51 BN_data->rtp_number++; 52 } 53 54 /* 55 #ifdef __cplusplus 56 extern "C" { 57 #endif 58 */ 59 int main(int argc, char* argv[]){ 60 61 /* Parameters */ 62 FILE *pInFile, *pOutFile, *pChcFile; 63 WebRtc_Word8 inFile[40]; 64 WebRtc_Word8 outFile[40]; 65 WebRtc_Word8 chcFile[40]; 66 WebRtc_Word8 codec[10]; 67 WebRtc_Word16 bitrt, spType, size; 68 WebRtc_UWord16 frameLen; 69 WebRtc_Word16 sigOut[1000], sigIn[1000]; 70 WebRtc_UWord16 bitStream[500]; /* double to 32 kbps for 60 ms */ 71 72 WebRtc_Word16 chc, ok; 73 int noOfCalls, cdlen; 74 WebRtc_Word16 noOfLostFrames; 75 int err, errtype; 76 77 BottleNeckModel BN_data; 78 79 int totalbits =0; 80 int totalsmpls =0; 81 82 /*End Parameters*/ 83 84 85 if ((argc==6)||(argc==7) ){ 86 87 strcpy(codec,argv[5]); 88 89 if(argc==7){ 90 if (!_stricmp("isac",codec)){ 91 bitrt = atoi(argv[6]); 92 if ( (bitrt<10000)&&(bitrt>32000)){ 93 printf("Error: Supported bit rate in the range 10000-32000 bps!\n"); 94 exit(-1); 95 } 96 97 }else{ 98 printf("Error: Codec not recognized. Check spelling!\n"); 99 exit(-1); 100 } 101 102 } else { 103 printf("Error: Codec not recognized. Check spelling!\n"); 104 exit(-1); 105 } 106 } else { 107 printf("Error: Wrong number of input parameter!\n\n"); 108 exit(-1); 109 } 110 111 frameLen = atoi(argv[4]); 112 strcpy(chcFile,argv[3]); 113 strcpy(outFile,argv[2]); 114 strcpy(inFile,argv[1]); 115 116 /* Open file streams */ 117 if( (pInFile = fopen(inFile,"rb")) == NULL ) { 118 printf( "Error: Did not find input file!\n" ); 119 exit(-1); 120 } 121 strcat(outFile,"_"); 122 strcat(outFile, argv[4]); 123 strcat(outFile,"_"); 124 strcat(outFile, codec); 125 126 if (argc==7){ 127 strcat(outFile,"_"); 128 strcat(outFile, argv[6]); 129 } 130 if (_stricmp("none", chcFile)){ 131 strcat(outFile,"_"); 132 strcat(outFile, "plc"); 133 } 134 135 strcat(outFile, ".otp"); 136 137 if (_stricmp("none", chcFile)){ 138 if( (pChcFile = fopen(chcFile,"rb")) == NULL ) { 139 printf( "Error: Did not find channel file!\n" ); 140 exit(-1); 141 } 142 } 143 /******************************************************************/ 144 if (!_stricmp("isac", codec)){ /* ISAC */ 145 if ((frameLen!=480)&&(frameLen!=960)) { 146 printf("Error: ISAC only supports 480 and 960 samples per frame (not %d)\n", frameLen); 147 exit(-1); 148 } 149 if( (pOutFile = fopen(outFile,"wb")) == NULL ) { 150 printf( "Could not open output file!\n" ); 151 exit(-1); 152 } 153 ok=WebRtcIsacfix_Create(&ISACfix_inst); 154 if (ok!=0) { 155 printf("Couldn't allocate memory for iSAC fix instance\n"); 156 exit(-1); 157 } 158 159 BN_data.arrival_time = 0; 160 BN_data.sample_count = 0; 161 BN_data.rtp_number = 0; 162 163 WebRtcIsacfix_EncoderInit(ISACfix_inst,1); 164 WebRtcIsacfix_DecoderInit(ISACfix_inst); 165 err = WebRtcIsacfix_Control(ISACfix_inst, bitrt, (frameLen>>4)); 166 if (err < 0) { 167 /* exit if returned with error */ 168 errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); 169 printf("\n\n Error in initialization: %d.\n\n", errtype); 170 exit(EXIT_FAILURE); 171 } 172 /* loop over frame */ 173 while (fread(sigIn,sizeof(WebRtc_Word16),frameLen,pInFile) == frameLen) { 174 175 noOfCalls=0; 176 cdlen=0; 177 while (cdlen<=0) { 178 cdlen=WebRtcIsacfix_Encode(ISACfix_inst,&sigIn[noOfCalls*160],(WebRtc_Word16*)bitStream); 179 if(cdlen==-1){ 180 errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); 181 printf("\n\nError in encoder: %d.\n\n", errtype); 182 exit(-1); 183 } 184 noOfCalls++; 185 } 186 187 188 if(_stricmp("none", chcFile)){ 189 if (fread(&chc,sizeof(WebRtc_Word16),1,pChcFile)!=1) /* packet may be lost */ 190 break; 191 } else { 192 chc = 1; /* packets never lost */ 193 } 194 195 /* simulate packet handling through NetEq and the modem */ 196 get_arrival_time(frameLen, cdlen, bitrt, &BN_data); 197 198 if (chc){ /* decode */ 199 200 err = WebRtcIsacfix_UpdateBwEstimate1(ISACfix_inst, 201 bitStream, 202 cdlen, 203 BN_data.rtp_number, 204 BN_data.arrival_time); 205 206 if (err < 0) { 207 /* exit if returned with error */ 208 errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); 209 printf("\n\nError in decoder: %d.\n\n", errtype); 210 exit(EXIT_FAILURE); 211 } 212 size = WebRtcIsacfix_Decode(ISACfix_inst, bitStream, cdlen, sigOut, &spType); 213 if(size<=0){ 214 /* exit if returned with error */ 215 errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); 216 printf("\n\nError in decoder: %d.\n\n", errtype); 217 exit(-1); 218 } 219 } else { /* PLC */ 220 if (frameLen == 480){ 221 noOfLostFrames = 1; 222 } else{ 223 noOfLostFrames = 2; 224 } 225 size = WebRtcIsacfix_DecodePlc(ISACfix_inst, sigOut, noOfLostFrames ); 226 if(size<=0){ 227 errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst); 228 printf("\n\nError in decoder: %d.\n\n", errtype); 229 exit(-1); 230 } 231 } 232 233 /* Write decoded speech to file */ 234 fwrite(sigOut,sizeof(short),size,pOutFile); 235 236 totalbits += 8 * cdlen; 237 totalsmpls += size; 238 239 } 240 /******************************************************************/ 241 } 242 243 // printf("\n\ntotal bits = %d bits", totalbits); 244 printf("\nmeasured average bitrate = %0.3f kbits/s", (double)totalbits * 16 / totalsmpls); 245 printf("\n"); 246 247 248 fclose(pInFile); 249 fclose(pOutFile); 250 if (_stricmp("none", chcFile)){ 251 fclose(pChcFile); 252 } 253 254 if (!_stricmp("isac", codec)){ 255 WebRtcIsacfix_Free(ISACfix_inst); 256 } 257 258 return 0; 259 260 } 261