• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
readframe(int16_t * data,FILE * inp,int length)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 
get_arrival_time(int current_framesamples,size_t packet_size,int bottleneck,BottleNeckModel * BN_data)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 
get_arrival_time2(int current_framesamples,int current_delay,BottleNeckModel * BN_data)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 
main(int argc,char * argv[])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