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 */
30int 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 */
45typedef 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
52void 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
75void 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
95int 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