Home | History | Annotate | Download | only in ReleaseTest-API
      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 // ReleaseTest-API.cpp : Defines the entry point for the console application.
     12 //
     13 
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <string.h>
     17 #include <time.h>
     18 #include <ctype.h>
     19 #include <iostream>
     20 
     21 /* include API */
     22 #include "isac.h"
     23 #include "utility.h"
     24 #include "webrtc/base/format_macros.h"
     25 
     26 /* Defines */
     27 #define SEED_FILE "randseed.txt" /* Used when running decoder on garbage data */
     28 #define MAX_FRAMESAMPLES 960     /* max number of samples per frame
     29                                     (= 60 ms frame & 16 kHz) or
     30                                     (= 30 ms frame & 32 kHz) */
     31 #define FRAMESAMPLES_10ms 160 /* number of samples per 10ms frame */
     32 #define SWBFRAMESAMPLES_10ms 320
     33 //#define FS 16000 /* sampling frequency (Hz) */
     34 
     35 #ifdef WIN32
     36 #define CLOCKS_PER_SEC 1000 /* Runtime statistics */
     37 #endif
     38 
     39 using namespace std;
     40 
     41 int main(int argc, char* argv[]) {
     42   char inname[100], outname[100], bottleneck_file[100], vadfile[100];
     43   FILE* inp, *outp, * f_bn = NULL, * vadp = NULL, *bandwidthp;
     44   int framecnt, endfile;
     45 
     46   size_t i;
     47   int errtype, VADusage = 0, packetLossPercent = 0;
     48   int16_t CodingMode;
     49   int32_t bottleneck = 0;
     50   int framesize = 30; /* ms */
     51   int cur_framesmpls, err;
     52 
     53   /* Runtime statistics */
     54   double starttime, runtime, length_file;
     55 
     56   size_t stream_len = 0;
     57   int declen = 0, declenTC = 0;
     58   bool lostFrame = false;
     59 
     60   int16_t shortdata[SWBFRAMESAMPLES_10ms];
     61   int16_t vaddata[SWBFRAMESAMPLES_10ms * 3];
     62   int16_t decoded[MAX_FRAMESAMPLES << 1];
     63   int16_t decodedTC[MAX_FRAMESAMPLES << 1];
     64   uint16_t streamdata[500];
     65   int16_t speechType[1];
     66   int16_t rateBPS = 0;
     67   int16_t fixedFL = 0;
     68   int16_t payloadSize = 0;
     69   int32_t payloadRate = 0;
     70   int setControlBWE = 0;
     71   short FL, testNum;
     72   char version_number[20];
     73   FILE* plFile;
     74   int32_t sendBN;
     75 
     76 #if !defined(NDEBUG)
     77   FILE* fy;
     78   double kbps;
     79 #endif
     80   size_t totalbits = 0;
     81   int totalsmpls = 0;
     82 
     83   /* If use GNS file */
     84   FILE* fp_gns = NULL;
     85   char gns_file[100];
     86   size_t maxStreamLen30 = 0;
     87   size_t maxStreamLen60 = 0;
     88   short sampFreqKHz = 32;
     89   short samplesIn10Ms;
     90   short useAssign = 0;
     91   // FILE logFile;
     92   bool doTransCoding = false;
     93   int32_t rateTransCoding = 0;
     94   uint8_t streamDataTransCoding[1200];
     95   size_t streamLenTransCoding = 0;
     96   FILE* transCodingFile = NULL;
     97   FILE* transcodingBitstream = NULL;
     98   size_t numTransCodingBytes = 0;
     99 
    100   /* only one structure used for ISAC encoder */
    101   ISACStruct* ISAC_main_inst = NULL;
    102   ISACStruct* decoderTransCoding = NULL;
    103 
    104   BottleNeckModel BN_data;
    105 
    106 #if !defined(NDEBUG)
    107   fy = fopen("bit_rate.dat", "w");
    108   fclose(fy);
    109   fy = fopen("bytes_frames.dat", "w");
    110   fclose(fy);
    111 #endif
    112 
    113   /* Handling wrong input arguments in the command line */
    114   if ((argc < 3) || (argc > 17)) {
    115     printf("\n\nWrong number of arguments or flag values.\n\n");
    116 
    117     printf("\n");
    118     WebRtcIsac_version(version_number);
    119     printf("iSAC-swb version %s \n\n", version_number);
    120 
    121     printf("Usage:\n\n");
    122     printf("./kenny.exe [-I] bottleneck_value infile outfile \n\n");
    123     printf("with:\n");
    124     printf("[-FS num]       : sampling frequency in kHz, valid values are\n");
    125     printf("                  16 & 32, with 16 as default.\n");
    126     printf("[-I]            : if -I option is specified, the coder will use\n");
    127     printf("                  an instantaneous Bottleneck value. If not, it\n");
    128     printf("                  will be an adaptive Bottleneck value.\n");
    129     printf("[-assign]       : Use Assign API.\n");
    130     printf("[-B num]        : the value of the bottleneck provided either\n");
    131     printf("                  as a fixed value in bits/sec (e.g. 25000) or\n");
    132     printf("                  read from a file (e.g. bottleneck.txt)\n");
    133     printf("[-INITRATE num] : Set a new value for initial rate. Note! Only\n");
    134     printf("                  used in adaptive mode.\n");
    135     printf("[-FL num]       : Set (initial) frame length in msec. Valid\n");
    136     printf("                  lengths are 30 and 60 msec.\n");
    137     printf("[-FIXED_FL]     : Frame length will be fixed to initial value.\n");
    138     printf("[-MAX num]      : Set the limit for the payload size of iSAC\n");
    139     printf("                  in bytes. Minimum 100 maximum 400.\n");
    140     printf("[-MAXRATE num]  : Set the maxrate for iSAC in bits per second.\n");
    141     printf("                  Minimum 32000, maximum 53400.\n");
    142     printf("[-F num]        : if -F option is specified, the test function\n");
    143     printf("                  will run the iSAC API fault scenario\n");
    144     printf("                  specified by the supplied number.\n");
    145     printf("                  F 1 - Call encoder prior to init encoder call\n");
    146     printf("                  F 2 - Call decoder prior to init decoder call\n");
    147     printf("                  F 3 - Call decoder prior to encoder call\n");
    148     printf("                  F 4 - Call decoder with a too short coded\n");
    149     printf("                        sequence\n");
    150     printf("                  F 5 - Call decoder with a too long coded\n");
    151     printf("                        sequence\n");
    152     printf("                  F 6 - Call decoder with random bit stream\n");
    153     printf("                  F 7 - Call init encoder/decoder at random\n");
    154     printf("                        during a call\n");
    155     printf("                  F 8 - Call encoder/decoder without having\n");
    156     printf("                        allocated memory for encoder/decoder\n");
    157     printf("                        instance\n");
    158     printf("                  F 9 - Call decodeB without calling decodeA\n");
    159     printf("                  F 10 - Call decodeB with garbage data\n");
    160     printf("[-PL num]       : if -PL option is specified \n");
    161     printf("[-T rate file]  : test trans-coding with target bottleneck\n");
    162     printf("                  'rate' bits/sec\n");
    163     printf("                  the output file is written to 'file'\n");
    164     printf("[-LOOP num]     : number of times to repeat coding the input\n");
    165     printf("                  file for stress testing\n");
    166     // printf("[-CE num]       : Test of APIs used by Conference Engine.\n");
    167     // printf("                  CE 1 - getNewBitstream, getBWE \n");
    168     // printf("                  (CE 2 - RESERVED for transcoding)\n");
    169     // printf("                  CE 3 - getSendBWE, setSendBWE.  \n");
    170     // printf("-L filename     : write the logging info into file
    171     // (appending)\n");
    172     printf("infile          :   Normal speech input file\n");
    173     printf("outfile         :   Speech output file\n");
    174     exit(0);
    175   }
    176 
    177   /* Print version number */
    178   printf("-------------------------------------------------\n");
    179   WebRtcIsac_version(version_number);
    180   printf("iSAC version %s \n\n", version_number);
    181 
    182   /* Loop over all command line arguments */
    183   CodingMode = 0;
    184   testNum = 0;
    185   useAssign = 0;
    186   // logFile = NULL;
    187   char transCodingFileName[500];
    188   int16_t totFileLoop = 0;
    189   int16_t numFileLoop = 0;
    190   for (i = 1; i + 2 < static_cast<size_t>(argc); i++) {
    191     if (!strcmp("-LOOP", argv[i])) {
    192       i++;
    193       totFileLoop = (int16_t)atol(argv[i]);
    194       if (totFileLoop <= 0) {
    195         fprintf(stderr, "Invalid number of runs for the given input file, %d.",
    196                 totFileLoop);
    197         exit(0);
    198       }
    199     }
    200 
    201     if (!strcmp("-T", argv[i])) {
    202       doTransCoding = true;
    203       i++;
    204       rateTransCoding = atoi(argv[i]);
    205       i++;
    206       strcpy(transCodingFileName, argv[i]);
    207     }
    208 
    209     /*Should we use assign API*/
    210     if (!strcmp("-assign", argv[i])) {
    211       useAssign = 1;
    212     }
    213 
    214     /* Set Sampling Rate */
    215     if (!strcmp("-FS", argv[i])) {
    216       i++;
    217       sampFreqKHz = atoi(argv[i]);
    218     }
    219 
    220     /* Instantaneous mode */
    221     if (!strcmp("-I", argv[i])) {
    222       printf("Instantaneous BottleNeck\n");
    223       CodingMode = 1;
    224     }
    225 
    226     /* Set (initial) bottleneck value */
    227     if (!strcmp("-INITRATE", argv[i])) {
    228       rateBPS = atoi(argv[i + 1]);
    229       setControlBWE = 1;
    230       if ((rateBPS < 10000) || (rateBPS > 32000)) {
    231         printf("\n%d is not a initial rate. Valid values are in the range "
    232                "10000 to 32000.\n", rateBPS);
    233         exit(0);
    234       }
    235       printf("New initial rate: %d\n", rateBPS);
    236       i++;
    237     }
    238 
    239     /* Set (initial) framelength */
    240     if (!strcmp("-FL", argv[i])) {
    241       framesize = atoi(argv[i + 1]);
    242       if ((framesize != 30) && (framesize != 60)) {
    243         printf("\n%d is not a valid frame length. Valid length are 30 and 60 "
    244                "msec.\n", framesize);
    245         exit(0);
    246       }
    247       setControlBWE = 1;
    248       printf("Frame Length: %d\n", framesize);
    249       i++;
    250     }
    251 
    252     /* Fixed frame length */
    253     if (!strcmp("-FIXED_FL", argv[i])) {
    254       fixedFL = 1;
    255       setControlBWE = 1;
    256       printf("Fixed Frame Length\n");
    257     }
    258 
    259     /* Set maximum allowed payload size in bytes */
    260     if (!strcmp("-MAX", argv[i])) {
    261       payloadSize = atoi(argv[i + 1]);
    262       printf("Maximum Payload Size: %d\n", payloadSize);
    263       i++;
    264     }
    265 
    266     /* Set maximum rate in bytes */
    267     if (!strcmp("-MAXRATE", argv[i])) {
    268       payloadRate = atoi(argv[i + 1]);
    269       printf("Maximum Rate in kbps: %d\n", payloadRate);
    270       i++;
    271     }
    272 
    273     /* Test of fault scenarious */
    274     if (!strcmp("-F", argv[i])) {
    275       testNum = atoi(argv[i + 1]);
    276       printf("Fault test: %d\n", testNum);
    277       if (testNum < 1 || testNum > 10) {
    278         printf("\n%d is not a valid Fault Scenario number. Valid Fault "
    279                "Scenarios are numbered 1-10.\n", testNum);
    280         exit(0);
    281       }
    282       i++;
    283     }
    284 
    285     /* Packet loss test */
    286     if (!strcmp("-PL", argv[i])) {
    287       if (isdigit(*argv[i + 1])) {
    288         packetLossPercent = atoi(argv[i + 1]);
    289         if ((packetLossPercent < 0) | (packetLossPercent > 100)) {
    290           printf("\nInvalid packet loss perentage \n");
    291           exit(0);
    292         }
    293         if (packetLossPercent > 0) {
    294           printf("Simulating %d %% of independent packet loss\n",
    295                  packetLossPercent);
    296         } else {
    297           printf("\nNo Packet Loss Is Simulated \n");
    298         }
    299       } else {
    300         plFile = fopen(argv[i + 1], "rb");
    301         if (plFile == NULL) {
    302           printf("\n couldn't open the frameloss file: %s\n", argv[i + 1]);
    303           exit(0);
    304         }
    305         printf("Simulating packet loss through the given channel file: %s\n",
    306                argv[i + 1]);
    307       }
    308       i++;
    309     }
    310 
    311     /* Random packetlosses */
    312     if (!strcmp("-rnd", argv[i])) {
    313       srand((unsigned int)time(NULL));
    314       printf("Random pattern in lossed packets \n");
    315     }
    316 
    317     /* Use gns file */
    318     if (!strcmp("-G", argv[i])) {
    319       sscanf(argv[i + 1], "%s", gns_file);
    320       fp_gns = fopen(gns_file, "rb");
    321       if (fp_gns == NULL) {
    322         printf("Cannot read file %s.\n", gns_file);
    323         exit(0);
    324       }
    325       i++;
    326     }
    327 
    328     // make it with '-B'
    329     /* Get Bottleneck value */
    330     if (!strcmp("-B", argv[i])) {
    331       i++;
    332       bottleneck = atoi(argv[i]);
    333       if (bottleneck == 0) {
    334         sscanf(argv[i], "%s", bottleneck_file);
    335         f_bn = fopen(bottleneck_file, "rb");
    336         if (f_bn == NULL) {
    337           printf("Error No value provided for BottleNeck and cannot read file "
    338                  "%s.\n", bottleneck_file);
    339           exit(0);
    340         } else {
    341           printf("reading bottleneck rates from file %s\n\n", bottleneck_file);
    342           if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
    343             /* Set pointer to beginning of file */
    344             fseek(f_bn, 0L, SEEK_SET);
    345             if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
    346               exit(0);
    347             }
    348           }
    349 
    350           /* Bottleneck is a cosine function
    351            * Matlab code for writing the bottleneck file:
    352            * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
    353            * fid = fopen('bottleneck.txt', 'wb');
    354            * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
    355            */
    356         }
    357       } else {
    358         printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
    359       }
    360     }
    361     /* Run Conference Engine APIs */
    362     //     Do not test it in the first release
    363     //
    364     //     if(!strcmp ("-CE", argv[i]))
    365     //     {
    366     //         testCE = atoi(argv[i + 1]);
    367     //         if(testCE==1)
    368     //         {
    369     //             i++;
    370     //             scale = (float)atof( argv[i+1] );
    371     //         }
    372     //         else if(testCE == 2)
    373     //         {
    374     //             printf("\nCE-test 2 (transcoding) not implemented.\n");
    375     //             exit(0);
    376     //         }
    377     //         else if(testCE < 1 || testCE > 3)
    378     //         {
    379     //             printf("\n%d is not a valid CE-test number. Valid CE tests
    380     //             are 1-3.\n", testCE);
    381     //             exit(0);
    382     //         }
    383     //         printf("CE-test number: %d\n", testCE);
    384     //         i++;
    385     //     }
    386   }
    387 
    388   if (CodingMode == 0) {
    389     printf("\nAdaptive BottleNeck\n");
    390   }
    391 
    392   switch (sampFreqKHz) {
    393     case 16: {
    394       printf("iSAC Wideband.\n");
    395       samplesIn10Ms = FRAMESAMPLES_10ms;
    396       break;
    397     }
    398     case 32: {
    399       printf("iSAC Supper-Wideband.\n");
    400       samplesIn10Ms = SWBFRAMESAMPLES_10ms;
    401       break;
    402     }
    403     default:
    404       printf("Unsupported sampling frequency %d kHz", sampFreqKHz);
    405       exit(0);
    406   }
    407 
    408   /* Get Input and Output files */
    409   sscanf(argv[argc - 2], "%s", inname);
    410   sscanf(argv[argc - 1], "%s", outname);
    411   printf("\nInput file: %s\n", inname);
    412   printf("Output file: %s\n\n", outname);
    413   if ((inp = fopen(inname, "rb")) == NULL) {
    414     printf("  Error iSAC Cannot read file %s.\n", inname);
    415     cout << flush;
    416     exit(1);
    417   }
    418 
    419   if ((outp = fopen(outname, "wb")) == NULL) {
    420     printf("  Error iSAC Cannot write file %s.\n", outname);
    421     cout << flush;
    422     getc(stdin);
    423     exit(1);
    424   }
    425   if (VADusage) {
    426     if ((vadp = fopen(vadfile, "rb")) == NULL) {
    427       printf("  Error iSAC Cannot read file %s.\n", vadfile);
    428       cout << flush;
    429       exit(1);
    430     }
    431   }
    432 
    433   if ((bandwidthp = fopen("bwe.pcm", "wb")) == NULL) {
    434     printf("  Error iSAC Cannot read file %s.\n", "bwe.pcm");
    435     cout << flush;
    436     exit(1);
    437   }
    438 
    439   starttime = clock() / (double)CLOCKS_PER_SEC; /* Runtime statistics */
    440 
    441   /* Initialize the ISAC and BN structs */
    442   if (testNum != 8) {
    443     if (!useAssign) {
    444       err = WebRtcIsac_Create(&ISAC_main_inst);
    445       WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000);
    446       WebRtcIsac_SetDecSampRate(ISAC_main_inst,
    447                                 sampFreqKHz >= 32 ? 32000 : 16000);
    448     } else {
    449       /* Test the Assign functions */
    450       int sss;
    451       void* ppp;
    452       err = WebRtcIsac_AssignSize(&sss);
    453       ppp = malloc(sss);
    454       err = WebRtcIsac_Assign(&ISAC_main_inst, ppp);
    455       WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000);
    456       WebRtcIsac_SetDecSampRate(ISAC_main_inst,
    457                                 sampFreqKHz >= 32 ? 32000 : 16000);
    458     }
    459     /* Error check */
    460     if (err < 0) {
    461       printf("\n\n Error in create.\n\n");
    462       cout << flush;
    463       exit(EXIT_FAILURE);
    464     }
    465   }
    466   BN_data.arrival_time = 0;
    467   BN_data.sample_count = 0;
    468   BN_data.rtp_number = 0;
    469 
    470   /* Initialize encoder and decoder */
    471   framecnt = 0;
    472   endfile = 0;
    473 
    474   if (doTransCoding) {
    475     WebRtcIsac_Create(&decoderTransCoding);
    476     WebRtcIsac_SetEncSampRate(decoderTransCoding, sampFreqKHz * 1000);
    477     WebRtcIsac_SetDecSampRate(decoderTransCoding,
    478                               sampFreqKHz >= 32 ? 32000 : 16000);
    479     WebRtcIsac_DecoderInit(decoderTransCoding);
    480     transCodingFile = fopen(transCodingFileName, "wb");
    481     if (transCodingFile == NULL) {
    482       printf("Could not open %s to output trans-coding.\n",
    483              transCodingFileName);
    484       exit(0);
    485     }
    486     strcat(transCodingFileName, ".bit");
    487     transcodingBitstream = fopen(transCodingFileName, "wb");
    488     if (transcodingBitstream == NULL) {
    489       printf("Could not open %s to write the bit-stream of transcoder.\n",
    490              transCodingFileName);
    491       exit(0);
    492     }
    493   }
    494 
    495   if (testNum != 1) {
    496     if (WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode) < 0) {
    497       printf("Error could not initialize the encoder \n");
    498       cout << flush;
    499       return 0;
    500     }
    501   }
    502   if (testNum != 2)
    503     WebRtcIsac_DecoderInit(ISAC_main_inst);
    504   if (CodingMode == 1) {
    505     err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
    506     if (err < 0) {
    507       /* exit if returned with error */
    508       errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    509       printf("\n\n Error in initialization (control): %d.\n\n", errtype);
    510       cout << flush;
    511       if (testNum == 0) {
    512         exit(EXIT_FAILURE);
    513       }
    514     }
    515   }
    516 
    517   if ((setControlBWE) && (CodingMode == 0)) {
    518     err = WebRtcIsac_ControlBwe(ISAC_main_inst, rateBPS, framesize, fixedFL);
    519     if (err < 0) {
    520       /* exit if returned with error */
    521       errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    522 
    523       printf("\n\n Error in Control BWE: %d.\n\n", errtype);
    524       cout << flush;
    525       exit(EXIT_FAILURE);
    526     }
    527   }
    528 
    529   if (payloadSize != 0) {
    530     err = WebRtcIsac_SetMaxPayloadSize(ISAC_main_inst, payloadSize);
    531     if (err < 0) {
    532       /* exit if returned with error */
    533       errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    534       printf("\n\n Error in SetMaxPayloadSize: %d.\n\n", errtype);
    535       cout << flush;
    536       exit(EXIT_FAILURE);
    537     }
    538   }
    539   if (payloadRate != 0) {
    540     err = WebRtcIsac_SetMaxRate(ISAC_main_inst, payloadRate);
    541     if (err < 0) {
    542       /* exit if returned with error */
    543       errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    544       printf("\n\n Error in SetMaxRateInBytes: %d.\n\n", errtype);
    545       cout << flush;
    546       exit(EXIT_FAILURE);
    547     }
    548   }
    549 
    550   *speechType = 1;
    551 
    552   cout << "\n" << flush;
    553 
    554   length_file = 0;
    555   int16_t bnIdxTC = 0;
    556   int16_t jitterInfoTC = 0;
    557   while (endfile == 0) {
    558     /* Call init functions at random, fault test number 7 */
    559     if (testNum == 7 && (rand() % 2 == 0)) {
    560       err = WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
    561       /* Error check */
    562       if (err < 0) {
    563         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    564         printf("\n\n Error in encoderinit: %d.\n\n", errtype);
    565         cout << flush;
    566       }
    567 
    568       WebRtcIsac_DecoderInit(ISAC_main_inst);
    569     }
    570 
    571     cur_framesmpls = 0;
    572     while (1) {
    573       int stream_len_int = 0;
    574 
    575       /* Read 10 ms speech block */
    576       endfile = readframe(shortdata, inp, samplesIn10Ms);
    577 
    578       if (endfile) {
    579         numFileLoop++;
    580         if (numFileLoop < totFileLoop) {
    581           rewind(inp);
    582           framecnt = 0;
    583           fprintf(stderr, "\n");
    584           endfile = readframe(shortdata, inp, samplesIn10Ms);
    585         }
    586       }
    587 
    588       if (testNum == 7) {
    589         srand((unsigned int)time(NULL));
    590       }
    591 
    592       /* iSAC encoding */
    593       if (!(testNum == 3 && framecnt == 0)) {
    594         stream_len_int =
    595             WebRtcIsac_Encode(ISAC_main_inst, shortdata, (uint8_t*)streamdata);
    596         if ((payloadSize != 0) && (stream_len_int > payloadSize)) {
    597           if (testNum == 0) {
    598             printf("\n\n");
    599           }
    600 
    601           printf("\nError: Streamsize out of range %d\n",
    602                  stream_len_int - payloadSize);
    603           cout << flush;
    604         }
    605 
    606         WebRtcIsac_GetUplinkBw(ISAC_main_inst, &sendBN);
    607 
    608         if (stream_len_int > 0) {
    609           if (doTransCoding) {
    610             int16_t indexStream;
    611             uint8_t auxUW8;
    612 
    613             /******************** Main Transcoding stream ********************/
    614             WebRtcIsac_GetDownLinkBwIndex(ISAC_main_inst, &bnIdxTC,
    615                                           &jitterInfoTC);
    616             int streamLenTransCoding_int = WebRtcIsac_GetNewBitStream(
    617                 ISAC_main_inst, bnIdxTC, jitterInfoTC, rateTransCoding,
    618                 streamDataTransCoding, false);
    619             if (streamLenTransCoding_int < 0) {
    620               fprintf(stderr, "Error in trans-coding\n");
    621               exit(0);
    622             }
    623             streamLenTransCoding =
    624                 static_cast<size_t>(streamLenTransCoding_int);
    625             auxUW8 = (uint8_t)(((streamLenTransCoding & 0xFF00) >> 8) & 0x00FF);
    626             if (fwrite(&auxUW8, sizeof(uint8_t), 1, transcodingBitstream) !=
    627                 1) {
    628               return -1;
    629             }
    630 
    631             auxUW8 = (uint8_t)(streamLenTransCoding & 0x00FF);
    632             if (fwrite(&auxUW8, sizeof(uint8_t), 1, transcodingBitstream) !=
    633                 1) {
    634               return -1;
    635             }
    636 
    637             if (fwrite(streamDataTransCoding, sizeof(uint8_t),
    638                        streamLenTransCoding, transcodingBitstream) !=
    639                 streamLenTransCoding) {
    640               return -1;
    641             }
    642 
    643             WebRtcIsac_ReadBwIndex(streamDataTransCoding, &indexStream);
    644             if (indexStream != bnIdxTC) {
    645               fprintf(stderr,
    646                       "Error in inserting Bandwidth index into transcoding "
    647                       "stream.\n");
    648               exit(0);
    649             }
    650             numTransCodingBytes += streamLenTransCoding;
    651           }
    652         }
    653       } else {
    654         break;
    655       }
    656 
    657       if (stream_len_int < 0) {
    658         /* exit if returned with error */
    659         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    660         fprintf(stderr, "Error in encoder: %d.\n", errtype);
    661         cout << flush;
    662         exit(0);
    663       }
    664       stream_len = static_cast<size_t>(stream_len_int);
    665 
    666       cur_framesmpls += samplesIn10Ms;
    667       /* exit encoder loop if the encoder returned a bitstream */
    668       if (stream_len != 0)
    669         break;
    670     }
    671 
    672     /* read next bottleneck rate */
    673     if (f_bn != NULL) {
    674       if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
    675         /* Set pointer to beginning of file */
    676         fseek(f_bn, 0L, SEEK_SET);
    677         if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
    678           exit(0);
    679         }
    680       }
    681       if (CodingMode == 1) {
    682         WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
    683       }
    684     }
    685 
    686     length_file += cur_framesmpls;
    687     if (cur_framesmpls == (3 * samplesIn10Ms)) {
    688       maxStreamLen30 =
    689           (stream_len > maxStreamLen30) ? stream_len : maxStreamLen30;
    690     } else {
    691       maxStreamLen60 =
    692           (stream_len > maxStreamLen60) ? stream_len : maxStreamLen60;
    693     }
    694 
    695     if (!lostFrame) {
    696       lostFrame = ((rand() % 100) < packetLossPercent);
    697     } else {
    698       lostFrame = false;
    699     }
    700 
    701     // RED.
    702     if (lostFrame) {
    703       int stream_len_int = WebRtcIsac_GetRedPayload(
    704           ISAC_main_inst, reinterpret_cast<uint8_t*>(streamdata));
    705       if (stream_len_int < 0) {
    706         fprintf(stderr, "Error getting RED payload\n");
    707         exit(0);
    708       }
    709       stream_len = static_cast<size_t>(stream_len_int);
    710 
    711       if (doTransCoding) {
    712         int streamLenTransCoding_int = WebRtcIsac_GetNewBitStream(
    713             ISAC_main_inst, bnIdxTC, jitterInfoTC, rateTransCoding,
    714             streamDataTransCoding, true);
    715         if (streamLenTransCoding_int < 0) {
    716           fprintf(stderr, "Error in RED trans-coding\n");
    717           exit(0);
    718         }
    719         streamLenTransCoding =
    720             static_cast<size_t>(streamLenTransCoding_int);
    721       }
    722     }
    723 
    724     /* make coded sequence to short be inreasing */
    725     /* the length the decoder expects */
    726     if (testNum == 4) {
    727       stream_len += 10;
    728     }
    729 
    730     /* make coded sequence to long be decreasing */
    731     /* the length the decoder expects */
    732     if (testNum == 5) {
    733       stream_len -= 10;
    734     }
    735 
    736     if (testNum == 6) {
    737       srand((unsigned int)time(NULL));
    738       for (i = 0; i < stream_len; i++) {
    739         streamdata[i] = rand();
    740       }
    741     }
    742 
    743     if (VADusage) {
    744       readframe(vaddata, vadp, samplesIn10Ms * 3);
    745     }
    746 
    747     /* simulate packet handling through NetEq and the modem */
    748     if (!(testNum == 3 && framecnt == 0)) {
    749       get_arrival_time(cur_framesmpls, stream_len, bottleneck, &BN_data,
    750                        sampFreqKHz * 1000, sampFreqKHz * 1000);
    751     }
    752 
    753     if (VADusage && (framecnt > 10 && vaddata[0] == 0)) {
    754       BN_data.rtp_number--;
    755     } else {
    756       /* Error test number 10, garbage data */
    757       if (testNum == 10) {
    758         /* Test to run decoder with garbage data */
    759         for (i = 0; i < stream_len; i++) {
    760           streamdata[i] = (short)(streamdata[i]) + (short)rand();
    761         }
    762       }
    763 
    764       if (testNum != 9) {
    765         err = WebRtcIsac_UpdateBwEstimate(
    766             ISAC_main_inst, reinterpret_cast<const uint8_t*>(streamdata),
    767             stream_len, BN_data.rtp_number, BN_data.sample_count,
    768             BN_data.arrival_time);
    769 
    770         if (err < 0) {
    771           /* exit if returned with error */
    772           errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    773           if (testNum == 0) {
    774             printf("\n\n");
    775           }
    776 
    777           printf("Error: in decoder: %d.", errtype);
    778           cout << flush;
    779           if (testNum == 0) {
    780             printf("\n\n");
    781           }
    782         }
    783       }
    784 
    785       /* Call getFramelen, only used here for function test */
    786       err = WebRtcIsac_ReadFrameLen(
    787           ISAC_main_inst, reinterpret_cast<const uint8_t*>(streamdata), &FL);
    788       if (err < 0) {
    789         /* exit if returned with error */
    790         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    791         if (testNum == 0) {
    792           printf("\n\n");
    793         }
    794         printf("    Error: in getFrameLen %d.", errtype);
    795         cout << flush;
    796         if (testNum == 0) {
    797           printf("\n\n");
    798         }
    799       }
    800 
    801       // iSAC decoding
    802 
    803       if (lostFrame) {
    804         declen = WebRtcIsac_DecodeRcu(
    805             ISAC_main_inst, reinterpret_cast<const uint8_t*>(streamdata),
    806             stream_len, decoded, speechType);
    807 
    808         if (doTransCoding) {
    809           declenTC =
    810               WebRtcIsac_DecodeRcu(decoderTransCoding, streamDataTransCoding,
    811                                    streamLenTransCoding, decodedTC, speechType);
    812         }
    813       } else {
    814         declen = WebRtcIsac_Decode(ISAC_main_inst,
    815                                    reinterpret_cast<const uint8_t*>(streamdata),
    816                                    stream_len, decoded, speechType);
    817         if (doTransCoding) {
    818           declenTC =
    819               WebRtcIsac_Decode(decoderTransCoding, streamDataTransCoding,
    820                                 streamLenTransCoding, decodedTC, speechType);
    821         }
    822       }
    823 
    824       if (declen < 0) {
    825         /* exit if returned with error */
    826         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    827         if (testNum == 0) {
    828           printf("\n\n");
    829         }
    830         printf("    Error: in decoder %d.", errtype);
    831         cout << flush;
    832         if (testNum == 0) {
    833           printf("\n\n");
    834         }
    835       }
    836 
    837       if (declenTC < 0) {
    838         if (testNum == 0) {
    839           printf("\n\n");
    840         }
    841         printf("    Error: in decoding the transcoded stream");
    842         cout << flush;
    843         if (testNum == 0) {
    844           printf("\n\n");
    845         }
    846       }
    847     }
    848     /* Write decoded speech frame to file */
    849     if ((declen > 0) && (numFileLoop == 0)) {
    850       if (fwrite(decoded, sizeof(int16_t), declen, outp) !=
    851           static_cast<size_t>(declen)) {
    852         return -1;
    853       }
    854     }
    855 
    856     if ((declenTC > 0) && (numFileLoop == 0)) {
    857       if (fwrite(decodedTC, sizeof(int16_t), declen, transCodingFile) !=
    858           static_cast<size_t>(declen)) {
    859         return -1;
    860       }
    861     }
    862 
    863     fprintf(stderr, "\rframe = %5d  ", framecnt);
    864     fflush(stderr);
    865     framecnt++;
    866 
    867     /* Error test number 10, garbage data */
    868     // if (testNum == 10)
    869     // {
    870     //   /* Test to run decoder with garbage data */
    871     //   if ((seedfile = fopen(SEED_FILE, "a+t")) == NULL) {
    872     //     fprintf(stderr, "Error: Could not open file %s\n", SEED_FILE);
    873     //   } else {
    874     //     fprintf(seedfile, "ok\n\n");
    875     //     fclose(seedfile);
    876     //   }
    877     // }
    878     /* Error test number 10, garbage data */
    879     // if (testNum == 10) {
    880     //   /* Test to run decoder with garbage data */
    881     //   for (i = 0; i < stream_len; i++) {
    882     //     streamdata[i] = (short) (streamdata[i] + (short) rand());
    883     //   }
    884     // }
    885 
    886     totalsmpls += declen;
    887     totalbits += 8 * stream_len;
    888 #if !defined(NDEBUG)
    889     kbps = ((double)sampFreqKHz * 1000.) / ((double)cur_framesmpls) * 8.0 *
    890            stream_len / 1000.0;  // kbits/s
    891     fy = fopen("bit_rate.dat", "a");
    892     fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
    893     fclose(fy);
    894 
    895 #endif
    896   }
    897   printf("\n");
    898   printf("total bits               = %" PRIuS " bits\n", totalbits);
    899   printf("measured average bitrate = %0.3f kbits/s\n",
    900          (double)totalbits * (sampFreqKHz) / totalsmpls);
    901   if (doTransCoding) {
    902     printf("Transcoding average bit-rate = %0.3f kbps\n",
    903            (double)numTransCodingBytes * 8.0 * (sampFreqKHz) / totalsmpls);
    904     fclose(transCodingFile);
    905   }
    906   printf("\n");
    907 
    908   /* Runtime statistics */
    909   runtime = (double)(clock() / (double)CLOCKS_PER_SEC - starttime);
    910   length_file = length_file / (sampFreqKHz * 1000.);
    911 
    912   printf("\n\nLength of speech file: %.1f s\n", length_file);
    913   printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime,
    914          (100 * runtime / length_file));
    915 
    916   if (maxStreamLen30 != 0) {
    917     printf("Maximum payload size 30ms Frames %" PRIuS " bytes (%0.3f kbps)\n",
    918            maxStreamLen30, maxStreamLen30 * 8 / 30.);
    919   }
    920   if (maxStreamLen60 != 0) {
    921     printf("Maximum payload size 60ms Frames %" PRIuS " bytes (%0.3f kbps)\n",
    922            maxStreamLen60, maxStreamLen60 * 8 / 60.);
    923   }
    924   // fprintf(stderr, "\n");
    925 
    926   fprintf(stderr, "   %.1f s", length_file);
    927   fprintf(stderr, "   %0.1f kbps",
    928           (double)totalbits * (sampFreqKHz) / totalsmpls);
    929   if (maxStreamLen30 != 0) {
    930     fprintf(stderr, "   plmax-30ms %" PRIuS " bytes (%0.0f kbps)",
    931             maxStreamLen30, maxStreamLen30 * 8 / 30.);
    932   }
    933   if (maxStreamLen60 != 0) {
    934     fprintf(stderr, "   plmax-60ms %" PRIuS " bytes (%0.0f kbps)",
    935             maxStreamLen60, maxStreamLen60 * 8 / 60.);
    936   }
    937   if (doTransCoding) {
    938     fprintf(stderr, "  transcoding rate %.0f kbps",
    939             (double)numTransCodingBytes * 8.0 * (sampFreqKHz) / totalsmpls);
    940   }
    941 
    942   fclose(inp);
    943   fclose(outp);
    944   WebRtcIsac_Free(ISAC_main_inst);
    945 
    946   exit(0);
    947 }
    948