Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2012 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 #include <stdio.h>
     12 #include <stdlib.h>
     13 #include <string.h>
     14 #include <time.h>
     15 #include <ctype.h>
     16 
     17 #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
     18 #include "webrtc/test/testsupport/perf_test.h"
     19 
     20 // TODO(kma): Clean up the code and change benchmarking the whole codec to
     21 // separate encoder and decoder.
     22 
     23 /* Defines */
     24 #define SEED_FILE "randseed.txt"  /* Used when running decoder on garbage data */
     25 #define MAX_FRAMESAMPLES    960   /* max number of samples per frame (= 60 ms frame) */
     26 #define FRAMESAMPLES_10ms 160   /* number of samples per 10ms frame */
     27 #define FS           16000 /* sampling frequency (Hz) */
     28 
     29 /* Function for reading audio data from PCM file */
     30 int readframe(int16_t *data, FILE *inp, int length) {
     31 
     32   short k, rlen, status = 0;
     33 
     34   rlen = fread(data, sizeof(int16_t), length, inp);
     35   if (rlen < length) {
     36     for (k = rlen; k < length; k++)
     37       data[k] = 0;
     38     status = 1;
     39   }
     40 
     41   return status;
     42 }
     43 
     44 /* Struct for bottleneck model */
     45 typedef struct {
     46   uint32_t send_time;            /* samples */
     47   uint32_t arrival_time;         /* samples */
     48   uint32_t sample_count;         /* samples */
     49   uint16_t rtp_number;
     50 } BottleNeckModel;
     51 
     52 void get_arrival_time(int current_framesamples,   /* samples */
     53                       int packet_size,            /* bytes */
     54                       int bottleneck,             /* excluding headers; bits/s */
     55                       BottleNeckModel *BN_data)
     56 {
     57   const int HeaderSize = 35;
     58   int HeaderRate;
     59 
     60   HeaderRate = HeaderSize * 8 * FS / current_framesamples;     /* bits/s */
     61 
     62   /* everything in samples */
     63   BN_data->sample_count = BN_data->sample_count + current_framesamples;
     64 
     65   BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate);
     66   BN_data->send_time += current_framesamples;
     67 
     68   if (BN_data->arrival_time < BN_data->sample_count)
     69     BN_data->arrival_time = BN_data->sample_count;
     70 
     71   BN_data->rtp_number++;
     72 }
     73 
     74 void get_arrival_time2(int current_framesamples,
     75                        int current_delay,
     76                        BottleNeckModel *BN_data)
     77 {
     78   if (current_delay == -1)
     79     //dropped packet
     80   {
     81     BN_data->arrival_time += current_framesamples;
     82   }
     83   else if (current_delay != -2)
     84   {
     85     //
     86     BN_data->arrival_time += (current_framesamples + ((FS/1000) * current_delay));
     87   }
     88   //else
     89   //current packet has same timestamp as previous packet
     90 
     91   BN_data->rtp_number++;
     92 }
     93 
     94 int main(int argc, char* argv[])
     95 {
     96 
     97   char inname[100], outname[100],  outbitsname[100], bottleneck_file[100];
     98   FILE *inp, *outp, *f_bn, *outbits;
     99   int endfile;
    100 
    101   int i, errtype, h = 0, k, packetLossPercent = 0;
    102   int16_t CodingMode;
    103   int16_t bottleneck;
    104   int16_t framesize = 30;           /* ms */
    105   int cur_framesmpls, err = 0, lostPackets = 0;
    106 
    107   /* Runtime statistics */
    108   double starttime, runtime, length_file;
    109 
    110   int16_t stream_len = 0;
    111   int16_t framecnt, declen = 0;
    112   int16_t shortdata[FRAMESAMPLES_10ms];
    113   int16_t decoded[MAX_FRAMESAMPLES];
    114   uint16_t streamdata[500];
    115   int16_t speechType[1];
    116   int16_t prevFrameSize = 1;
    117   int16_t rateBPS = 0;
    118   int16_t fixedFL = 0;
    119   int16_t payloadSize = 0;
    120   int32_t payloadRate = 0;
    121   int setControlBWE = 0;
    122   int readLoss;
    123   FILE  *plFile = NULL;
    124 
    125   char version_number[20];
    126   char tmpBit[5] = ".bit";
    127 
    128   int totalbits =0;
    129   int totalsmpls =0;
    130   int16_t testNum, testCE;
    131 
    132   FILE *fp_gns = NULL;
    133   int gns = 0;
    134   int cur_delay = 0;
    135   char gns_file[100];
    136 
    137   int nbTest = 0;
    138   int16_t lostFrame;
    139   float scale = (float)0.7;
    140   /* only one structure used for ISAC encoder */
    141   ISACFIX_MainStruct *ISAC_main_inst = NULL;
    142 
    143   /* For fault test 10, garbage data */
    144   FILE *seedfile;
    145   unsigned int random_seed = (unsigned int) time(NULL);//1196764538
    146 
    147   BottleNeckModel       BN_data;
    148   f_bn  = NULL;
    149 
    150   readLoss = 0;
    151   packetLossPercent = 0;
    152 
    153   /* Handling wrong input arguments in the command line */
    154   if ((argc<3) || (argc>21))  {
    155     printf("\n\nWrong number of arguments or flag values.\n\n");
    156 
    157     printf("\n");
    158     WebRtcIsacfix_version(version_number);
    159     printf("iSAC version %s \n\n", version_number);
    160 
    161     printf("Usage:\n\n");
    162     printf("./kenny.exe [-F num][-I] bottleneck_value infile outfile \n\n");
    163     printf("with:\n");
    164     printf("[-I]             :if -I option is specified, the coder will use\n");
    165     printf("                  an instantaneous Bottleneck value. If not, it\n");
    166     printf("                  will be an adaptive Bottleneck value.\n\n");
    167     printf("bottleneck_value :the value of the bottleneck provided either\n");
    168     printf("                  as a fixed value (e.g. 25000) or\n");
    169     printf("                  read from a file (e.g. bottleneck.txt)\n\n");
    170     printf("[-INITRATE num]  :Set a new value for initial rate. Note! Only used"
    171            " in adaptive mode.\n\n");
    172     printf("[-FL num]        :Set (initial) frame length in msec. Valid length"
    173            " are 30 and 60 msec.\n\n");
    174     printf("[-FIXED_FL]      :Frame length to be fixed to initial value.\n\n");
    175     printf("[-MAX num]       :Set the limit for the payload size of iSAC"
    176            " in bytes. \n");
    177     printf("                  Minimum 100, maximum 400.\n\n");
    178     printf("[-MAXRATE num]   :Set the maxrate for iSAC in bits per second. \n");
    179     printf("                  Minimum 32000, maximum 53400.\n\n");
    180     printf("[-F num]         :if -F option is specified, the test function\n");
    181     printf("                  will run the iSAC API fault scenario specified"
    182            " by the\n");
    183     printf("                  supplied number.\n");
    184     printf("                  F 1 - Call encoder prior to init encoder call\n");
    185     printf("                  F 2 - Call decoder prior to init decoder call\n");
    186     printf("                  F 3 - Call decoder prior to encoder call\n");
    187     printf("                  F 4 - Call decoder with a too short coded"
    188            " sequence\n");
    189     printf("                  F 5 - Call decoder with a too long coded"
    190            " sequence\n");
    191     printf("                  F 6 - Call decoder with random bit stream\n");
    192     printf("                  F 7 - Call init encoder/decoder at random"
    193            " during a call\n");
    194     printf("                  F 8 - Call encoder/decoder without having"
    195            " allocated memory for \n");
    196     printf("                        encoder/decoder instance\n");
    197     printf("                  F 9 - Call decodeB without calling decodeA\n");
    198     printf("                  F 10 - Call decodeB with garbage data\n");
    199     printf("[-PL num]       : if -PL option is specified 0<num<100 will "
    200            "specify the\n");
    201     printf("                  percentage of packet loss\n\n");
    202     printf("[-G file]       : if -G option is specified the file given is"
    203            " a .gns file\n");
    204     printf("                  that represents a network profile\n\n");
    205     printf("[-NB num]       : if -NB option, use the narrowband interfaces\n");
    206     printf("                  num=1 => encode with narrowband encoder"
    207            " (infile is narrowband)\n");
    208     printf("                  num=2 => decode with narrowband decoder"
    209            " (outfile is narrowband)\n\n");
    210     printf("[-CE num]       : Test of APIs used by Conference Engine.\n");
    211     printf("                  CE 1 - createInternal, freeInternal,"
    212            " getNewBitstream \n");
    213     printf("                  CE 2 - transcode, getBWE \n");
    214     printf("                  CE 3 - getSendBWE, setSendBWE.  \n\n");
    215     printf("[-RTP_INIT num] : if -RTP_INIT option is specified num will be"
    216            " the initial\n");
    217     printf("                  value of the rtp sequence number.\n\n");
    218     printf("infile          : Normal speech input file\n\n");
    219     printf("outfile         : Speech output file\n\n");
    220     printf("Example usage   : \n\n");
    221     printf("./kenny.exe -I bottleneck.txt speechIn.pcm speechOut.pcm\n\n");
    222     exit(0);
    223 
    224   }
    225 
    226   /* Print version number */
    227   WebRtcIsacfix_version(version_number);
    228   printf("iSAC version %s \n\n", version_number);
    229 
    230   /* Loop over all command line arguments */
    231   CodingMode = 0;
    232   testNum = 0;
    233   testCE = 0;
    234   for (i = 1; i < argc-2;i++) {
    235     /* Instantaneous mode */
    236     if (!strcmp ("-I", argv[i])) {
    237       printf("\nInstantaneous BottleNeck\n");
    238       CodingMode = 1;
    239       i++;
    240     }
    241 
    242     /* Set (initial) bottleneck value */
    243     if (!strcmp ("-INITRATE", argv[i])) {
    244       rateBPS = atoi(argv[i + 1]);
    245       setControlBWE = 1;
    246       if ((rateBPS < 10000) || (rateBPS > 32000)) {
    247         printf("\n%d is not a initial rate. "
    248                "Valid values are in the range 10000 to 32000.\n", rateBPS);
    249         exit(0);
    250       }
    251       printf("\nNew initial rate: %d\n", rateBPS);
    252       i++;
    253     }
    254 
    255     /* Set (initial) framelength */
    256     if (!strcmp ("-FL", argv[i])) {
    257       framesize = atoi(argv[i + 1]);
    258       if ((framesize != 30) && (framesize != 60)) {
    259         printf("\n%d is not a valid frame length. "
    260                "Valid length are 30 and 60 msec.\n", framesize);
    261         exit(0);
    262       }
    263       printf("\nFrame Length: %d\n", framesize);
    264       i++;
    265     }
    266 
    267     /* Fixed frame length */
    268     if (!strcmp ("-FIXED_FL", argv[i])) {
    269       fixedFL = 1;
    270       setControlBWE = 1;
    271     }
    272 
    273     /* Set maximum allowed payload size in bytes */
    274     if (!strcmp ("-MAX", argv[i])) {
    275       payloadSize = atoi(argv[i + 1]);
    276       printf("Maximum Payload Size: %d\n", payloadSize);
    277       i++;
    278     }
    279 
    280     /* Set maximum rate in bytes */
    281     if (!strcmp ("-MAXRATE", argv[i])) {
    282       payloadRate = atoi(argv[i + 1]);
    283       printf("Maximum Rate in kbps: %d\n", payloadRate);
    284       i++;
    285     }
    286 
    287     /* Test of fault scenarious */
    288     if (!strcmp ("-F", argv[i])) {
    289       testNum = atoi(argv[i + 1]);
    290       printf("\nFault test: %d\n", testNum);
    291       if (testNum < 1 || testNum > 10) {
    292         printf("\n%d is not a valid Fault Scenario number."
    293                " Valid Fault Scenarios are numbered 1-10.\n", testNum);
    294         exit(0);
    295       }
    296       i++;
    297     }
    298 
    299     /* Packet loss test */
    300     if (!strcmp ("-PL", argv[i])) {
    301       if( isdigit( *argv[i+1] ) ) {
    302         packetLossPercent = atoi( argv[i+1] );
    303         if( (packetLossPercent < 0) | (packetLossPercent > 100) ) {
    304           printf( "\nInvalid packet loss perentage \n" );
    305           exit( 0 );
    306         }
    307         if( packetLossPercent > 0 ) {
    308           printf( "\nSimulating %d %% of independent packet loss\n",
    309                   packetLossPercent );
    310         } else {
    311           printf( "\nNo Packet Loss Is Simulated \n" );
    312         }
    313         readLoss = 0;
    314       } else {
    315         readLoss = 1;
    316         plFile = fopen( argv[i+1], "rb" );
    317         if( plFile == NULL ) {
    318           printf( "\n couldn't open the frameloss file: %s\n", argv[i+1] );
    319           exit( 0 );
    320         }
    321         printf( "\nSimulating packet loss through the given "
    322                 "channel file: %s\n", argv[i+1] );
    323       }
    324       i++;
    325     }
    326 
    327     /* Random packetlosses */
    328     if (!strcmp ("-rnd", argv[i])) {
    329       srand(time(NULL) );
    330       printf( "\n Random pattern in lossed packets \n" );
    331     }
    332 
    333     /* Use gns file */
    334     if (!strcmp ("-G", argv[i])) {
    335       sscanf(argv[i + 1], "%s", gns_file);
    336       fp_gns = fopen(gns_file, "rb");
    337       if (fp_gns  == NULL) {
    338         printf("Cannot read file %s.\n", gns_file);
    339         exit(0);
    340       }
    341       gns = 1;
    342       i++;
    343     }
    344 
    345     /* Run Narrowband interfaces (either encoder or decoder) */
    346     if (!strcmp ("-NB", argv[i])) {
    347       nbTest = atoi(argv[i + 1]);
    348       i++;
    349     }
    350 
    351     /* Run Conference Engine APIs */
    352     if (!strcmp ("-CE", argv[i])) {
    353       testCE = atoi(argv[i + 1]);
    354       if (testCE==1 || testCE==2) {
    355         i++;
    356         scale = (float)atof( argv[i+1] );
    357       } else if (testCE < 1 || testCE > 3) {
    358         printf("\n%d is not a valid CE-test number, valid Fault "
    359                "Scenarios are numbered 1-3\n", testCE);
    360         exit(0);
    361       }
    362       i++;
    363     }
    364 
    365     /* Set initial RTP number */
    366     if (!strcmp ("-RTP_INIT", argv[i])) {
    367       i++;
    368     }
    369   }
    370 
    371   /* Get Bottleneck value                                                   */
    372   /* Gns files and bottleneck should not and can not be used simultaneously */
    373   bottleneck = atoi(argv[CodingMode+1]);
    374   if (bottleneck == 0 && gns == 0) {
    375     sscanf(argv[CodingMode+1], "%s", bottleneck_file);
    376     f_bn = fopen(bottleneck_file, "rb");
    377     if (f_bn  == NULL) {
    378       printf("No value provided for BottleNeck and cannot read file %s\n",
    379              bottleneck_file);
    380       exit(0);
    381     } else {
    382       int aux_var;
    383       printf("reading bottleneck rates from file %s\n\n",bottleneck_file);
    384       if (fscanf(f_bn, "%d", &aux_var) == EOF) {
    385         /* Set pointer to beginning of file */
    386         fseek(f_bn, 0L, SEEK_SET);
    387         if (fscanf(f_bn, "%d", &aux_var) == EOF) {
    388           exit(0);
    389         }
    390       }
    391       bottleneck = (int16_t)aux_var;
    392       /* Bottleneck is a cosine function
    393        * Matlab code for writing the bottleneck file:
    394        * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
    395        * fid = fopen('bottleneck.txt', 'wb');
    396        * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
    397        */
    398     }
    399   } else {
    400     f_bn = NULL;
    401     printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
    402   }
    403 
    404   if (CodingMode == 0) {
    405     printf("\nAdaptive BottleNeck\n");
    406   }
    407 
    408   /* Get Input and Output files */
    409   sscanf(argv[argc-2], "%s", inname);
    410   sscanf(argv[argc-1], "%s", outname);
    411 
    412   /* Add '.bit' to output bitstream file */
    413   while ((int)outname[h] != 0) {
    414     outbitsname[h] = outname[h];
    415     h++;
    416   }
    417   for (k=0; k<5; k++) {
    418     outbitsname[h] = tmpBit[k];
    419     h++;
    420   }
    421   if ((inp = fopen(inname,"rb")) == NULL) {
    422     printf("  iSAC: Cannot read file %s\n", inname);
    423     exit(1);
    424   }
    425   if ((outp = fopen(outname,"wb")) == NULL) {
    426     printf("  iSAC: Cannot write file %s\n", outname);
    427     exit(1);
    428   }
    429 
    430   if ((outbits = fopen(outbitsname,"wb")) == NULL) {
    431     printf("  iSAC: Cannot write file %s\n", outbitsname);
    432     exit(1);
    433   }
    434   printf("\nInput:%s\nOutput:%s\n\n", inname, outname);
    435 
    436   /* Error test number 10, garbage data */
    437   if (testNum == 10) {
    438     /* Test to run decoder with garbage data */
    439     srand(random_seed);
    440 
    441     if ( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) {
    442       printf("Error: Could not open file %s\n", SEED_FILE);
    443     }
    444     else {
    445       fprintf(seedfile, "%u\n", random_seed);
    446       fclose(seedfile);
    447     }
    448   }
    449 
    450   /* Runtime statistics */
    451   starttime = clock()/(double)CLOCKS_PER_SEC;
    452 
    453   /* Initialize the ISAC and BN structs */
    454   if (testNum != 8)
    455   {
    456     if(1){
    457       err =WebRtcIsacfix_Create(&ISAC_main_inst);
    458     }else{
    459       /* Test the Assign functions */
    460       int sss;
    461       void *ppp;
    462       err =WebRtcIsacfix_AssignSize(&sss);
    463       ppp=malloc(sss);
    464       err =WebRtcIsacfix_Assign(&ISAC_main_inst,ppp);
    465     }
    466     /* Error check */
    467     if (err < 0) {
    468       printf("\n\n Error in create.\n\n");
    469     }
    470     if (testCE == 1) {
    471       err = WebRtcIsacfix_CreateInternal(ISAC_main_inst);
    472       /* Error check */
    473       if (err < 0) {
    474         printf("\n\n Error in createInternal.\n\n");
    475       }
    476     }
    477   }
    478 
    479   /* Init of bandwidth data */
    480   BN_data.send_time     = 0;
    481   BN_data.arrival_time  = 0;
    482   BN_data.sample_count  = 0;
    483   BN_data.rtp_number    = 0;
    484 
    485   /* Initialize encoder and decoder */
    486   framecnt= 0;
    487   endfile = 0;
    488   if (testNum != 1) {
    489     WebRtcIsacfix_EncoderInit(ISAC_main_inst, CodingMode);
    490   }
    491   if (testNum != 2) {
    492     WebRtcIsacfix_DecoderInit(ISAC_main_inst);
    493   }
    494 
    495   if (CodingMode == 1) {
    496     err = WebRtcIsacfix_Control(ISAC_main_inst, bottleneck, framesize);
    497     if (err < 0) {
    498       /* exit if returned with error */
    499       errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    500       printf("\n\n Error in control: %d.\n\n", errtype);
    501     }
    502   } else if(setControlBWE == 1) {
    503     err = WebRtcIsacfix_ControlBwe(ISAC_main_inst, rateBPS, framesize, fixedFL);
    504   }
    505 
    506   if (payloadSize != 0) {
    507     err = WebRtcIsacfix_SetMaxPayloadSize(ISAC_main_inst, payloadSize);
    508     if (err < 0) {
    509       /* exit if returned with error */
    510       errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    511       printf("\n\n Error in SetMaxPayloadSize: %d.\n\n", errtype);
    512       exit(EXIT_FAILURE);
    513     }
    514   }
    515   if (payloadRate != 0) {
    516     err = WebRtcIsacfix_SetMaxRate(ISAC_main_inst, payloadRate);
    517     if (err < 0) {
    518       /* exit if returned with error */
    519       errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    520       printf("\n\n Error in SetMaxRateInBytes: %d.\n\n", errtype);
    521       exit(EXIT_FAILURE);
    522     }
    523   }
    524 
    525   *speechType = 1;
    526 
    527 
    528   while (endfile == 0) {
    529 
    530     if(testNum == 7 && (rand()%2 == 0)) {
    531       err = WebRtcIsacfix_EncoderInit(ISAC_main_inst, CodingMode);
    532       /* Error check */
    533       if (err < 0) {
    534         errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    535         printf("\n\n Error in encoderinit: %d.\n\n", errtype);
    536       }
    537 
    538       err = WebRtcIsacfix_DecoderInit(ISAC_main_inst);
    539       /* Error check */
    540       if (err < 0) {
    541         errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    542         printf("\n\n Error in decoderinit: %d.\n\n", errtype);
    543       }
    544     }
    545 
    546 
    547     cur_framesmpls = 0;
    548     while (1) {
    549       /* Read 10 ms speech block */
    550       if (nbTest != 1) {
    551         endfile = readframe(shortdata, inp, FRAMESAMPLES_10ms);
    552       } else {
    553         endfile = readframe(shortdata, inp, (FRAMESAMPLES_10ms/2));
    554       }
    555 
    556       if (testNum == 7) {
    557         srand(time(NULL));
    558       }
    559 
    560       /* iSAC encoding */
    561       if (!(testNum == 3 && framecnt == 0)) {
    562         if (nbTest != 1) {
    563           short bwe;
    564 
    565           /* Encode */
    566           stream_len = WebRtcIsacfix_Encode(ISAC_main_inst,
    567                                             shortdata,
    568                                             (uint8_t*)streamdata);
    569 
    570           /* If packet is ready, and CE testing, call the different API
    571              functions from the internal API. */
    572           if (stream_len>0) {
    573             if (testCE == 1) {
    574               err = WebRtcIsacfix_ReadBwIndex((int16_t*)streamdata, &bwe);
    575               stream_len = WebRtcIsacfix_GetNewBitStream(
    576                   ISAC_main_inst,
    577                   bwe,
    578                   scale,
    579                   (int16_t*)streamdata);
    580             } else if (testCE == 2) {
    581               /* transcode function not supported */
    582             } else if (testCE == 3) {
    583               /* Only for Function testing. The functions should normally
    584                  not be used in this way                                      */
    585 
    586               err = WebRtcIsacfix_GetDownLinkBwIndex(ISAC_main_inst, &bwe);
    587               /* Error Check */
    588               if (err < 0) {
    589                 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    590                 printf("\nError in getSendBWE: %d.\n", errtype);
    591               }
    592 
    593               err = WebRtcIsacfix_UpdateUplinkBw(ISAC_main_inst, bwe);
    594               /* Error Check */
    595               if (err < 0) {
    596                 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    597                 printf("\nError in setBWE: %d.\n", errtype);
    598               }
    599 
    600             }
    601           }
    602         } else {
    603 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    604           stream_len = WebRtcIsacfix_EncodeNb(ISAC_main_inst,
    605                                               shortdata,
    606                                               streamdata);
    607 #else
    608           stream_len = -1;
    609 #endif
    610         }
    611       }
    612       else
    613       {
    614         break;
    615       }
    616 
    617       if (stream_len < 0 || err < 0) {
    618         /* exit if returned with error */
    619         errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    620         printf("\nError in encoder: %d.\n", errtype);
    621       } else {
    622         if (fwrite(streamdata, sizeof(char),
    623                    stream_len, outbits) != (size_t)stream_len) {
    624           return -1;
    625         }
    626       }
    627 
    628       cur_framesmpls += FRAMESAMPLES_10ms;
    629 
    630       /* read next bottleneck rate */
    631       if (f_bn != NULL) {
    632         int aux_var;
    633         if (fscanf(f_bn, "%d", &aux_var) == EOF) {
    634           /* Set pointer to beginning of file */
    635           fseek(f_bn, 0L, SEEK_SET);
    636           if (fscanf(f_bn, "%d", &aux_var) == EOF) {
    637             exit(0);
    638           }
    639         }
    640         bottleneck = (int16_t)aux_var;
    641         if (CodingMode == 1) {
    642           WebRtcIsacfix_Control(ISAC_main_inst, bottleneck, framesize);
    643         }
    644       }
    645 
    646       /* exit encoder loop if the encoder returned a bitstream */
    647       if (stream_len != 0) break;
    648     }
    649 
    650     /* make coded sequence to short be inreasing */
    651     /* the length the decoder expects */
    652     if (testNum == 4) {
    653       stream_len += 10;
    654     }
    655 
    656     /* make coded sequence to long be decreasing */
    657     /* the length the decoder expects */
    658     if (testNum == 5) {
    659       stream_len -= 10;
    660     }
    661 
    662     if (testNum == 6) {
    663       srand(time(NULL));
    664       for (i = 0; i < stream_len; i++ ) {
    665         streamdata[i] = rand();
    666       }
    667     }
    668 
    669     /* set pointer to beginning of file */
    670     if (fp_gns != NULL) {
    671       if (fscanf(fp_gns, "%d", &cur_delay) == EOF) {
    672         fseek(fp_gns, 0L, SEEK_SET);
    673         if (fscanf(fp_gns, "%d", &cur_delay) == EOF) {
    674           exit(0);
    675         }
    676       }
    677     }
    678 
    679     /* simulate packet handling through NetEq and the modem */
    680     if (!(testNum == 3 && framecnt == 0)) {
    681       if (gns == 0) {
    682         get_arrival_time(cur_framesmpls, stream_len, bottleneck,
    683                          &BN_data);
    684       } else {
    685         get_arrival_time2(cur_framesmpls, cur_delay, &BN_data);
    686       }
    687     }
    688 
    689     /* packet not dropped */
    690     if (cur_delay != -1) {
    691 
    692       /* Error test number 10, garbage data */
    693       if (testNum == 10) {
    694         for ( i = 0; i < stream_len; i++) {
    695           streamdata[i] = (short) (streamdata[i] + (short) rand());
    696         }
    697       }
    698 
    699       if (testNum != 9) {
    700         err = WebRtcIsacfix_UpdateBwEstimate(ISAC_main_inst,
    701                                              streamdata,
    702                                              stream_len,
    703                                              BN_data.rtp_number,
    704                                              BN_data.send_time,
    705                                              BN_data.arrival_time);
    706 
    707         if (err < 0) {
    708           /* exit if returned with error */
    709           errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    710           printf("\nError in decoder: %d.\n", errtype);
    711         }
    712       }
    713 
    714       if( readLoss == 1 ) {
    715         if( fread( &lostFrame, sizeof(int16_t), 1, plFile ) != 1 ) {
    716           rewind( plFile );
    717         }
    718         lostFrame = !lostFrame;
    719       } else {
    720         lostFrame = (rand()%100 < packetLossPercent);
    721       }
    722 
    723 
    724 
    725       /* iSAC decoding */
    726       if( lostFrame && framecnt >  0) {
    727         if (nbTest !=2) {
    728           declen = WebRtcIsacfix_DecodePlc(ISAC_main_inst,
    729                                            decoded, prevFrameSize );
    730         } else {
    731 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    732           declen = WebRtcIsacfix_DecodePlcNb(ISAC_main_inst, decoded,
    733                                              prevFrameSize );
    734 #else
    735           declen = -1;
    736 #endif
    737         }
    738         lostPackets++;
    739       } else {
    740         if (nbTest !=2 ) {
    741           short FL;
    742           /* Call getFramelen, only used here for function test */
    743           err = WebRtcIsacfix_ReadFrameLen((int16_t*)streamdata, &FL);
    744           declen = WebRtcIsacfix_Decode( ISAC_main_inst, streamdata, stream_len,
    745                                          decoded, speechType );
    746           /* Error check */
    747           if (err<0 || declen<0 || FL!=declen) {
    748             errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    749             printf("\nError in decode_B/or getFrameLen: %d.\n", errtype);
    750           }
    751           prevFrameSize = declen/480;
    752 
    753         } else {
    754 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
    755           declen = WebRtcIsacfix_DecodeNb( ISAC_main_inst, streamdata,
    756                                            stream_len, decoded, speechType );
    757 #else
    758           declen = -1;
    759 #endif
    760           prevFrameSize = declen/240;
    761         }
    762       }
    763 
    764       if (declen <= 0) {
    765         /* exit if returned with error */
    766         errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
    767         printf("\nError in decoder: %d.\n", errtype);
    768       }
    769 
    770       /* Write decoded speech frame to file */
    771       if (fwrite(decoded, sizeof(int16_t),
    772                  declen, outp) != (size_t)declen) {
    773         return -1;
    774       }
    775       //   fprintf( ratefile, "%f \n", stream_len / ( ((double)declen)/
    776       // ((double)FS) ) * 8 );
    777     } else {
    778       lostPackets++;
    779     }
    780     framecnt++;
    781 
    782     totalsmpls += declen;
    783     totalbits += 8 * stream_len;
    784 
    785     /* Error test number 10, garbage data */
    786     if (testNum == 10) {
    787       if ( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) {
    788         printf( "Error: Could not open file %s\n", SEED_FILE);
    789       }
    790       else {
    791         fprintf(seedfile, "ok\n\n");
    792         fclose(seedfile);
    793       }
    794     }
    795   }
    796   printf("\nLost Frames %d ~ %4.1f%%\n", lostPackets,
    797          (double)lostPackets/(double)framecnt*100.0 );
    798   printf("\n\ntotal bits                          = %d bits", totalbits);
    799   printf("\nmeasured average bitrate              = %0.3f kbits/s",
    800          (double)totalbits *(FS/1000) / totalsmpls);
    801   printf("\n");
    802 
    803   /* Runtime statistics */
    804 
    805 
    806   runtime = (double)(((double)clock()/(double)CLOCKS_PER_SEC)-starttime);
    807   length_file = ((double)framecnt*(double)declen/FS);
    808   printf("\n\nLength of speech file: %.1f s\n", length_file);
    809   printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n",
    810          runtime, (100*runtime/length_file));
    811   printf("\n\n_______________________________________________\n");
    812 
    813   // Record the results with Perf test tools.
    814   webrtc::test::PrintResult("isac", "", "time_per_10ms_frame",
    815                             (runtime * 10000) / length_file, "us", false);
    816 
    817   fclose(inp);
    818   fclose(outp);
    819   fclose(outbits);
    820 
    821   if ( testCE == 1) {
    822     WebRtcIsacfix_FreeInternal(ISAC_main_inst);
    823   }
    824   WebRtcIsacfix_Free(ISAC_main_inst);
    825   return 0;
    826 }
    827