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