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