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