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