ReleaseTest-API.cc revision 396a5e00012ea505a58447e9378a64227e74346b
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,
691                            bnIdxTC,
692                            jitterInfoTC,
693                            rateTransCoding,
694                            reinterpret_cast<uint8_t*>(streamDataTransCoding),
695                            false);
696                        if(streamLenTransCoding < 0)
697                        {
698                            fprintf(stderr, "Error in trans-coding\n");
699                            exit(0);
700                        }
701                        auxUW8 = (uint8_t)(((streamLenTransCoding & 0xFF00) >> 8) &  0x00FF);
702                        if (fwrite(&auxUW8, sizeof(uint8_t), 1,
703                                   transcodingBitstream) != 1) {
704                          return -1;
705                        }
706
707                        auxUW8 = (uint8_t)(streamLenTransCoding & 0x00FF);
708                        if (fwrite(&auxUW8, sizeof(uint8_t),
709                                   1, transcodingBitstream) != 1) {
710                          return -1;
711                        }
712
713                        if (fwrite((uint8_t*)streamDataTransCoding,
714                                   sizeof(uint8_t),
715                                   streamLenTransCoding,
716                                   transcodingBitstream) !=
717                            static_cast<size_t>(streamLenTransCoding)) {
718                          return -1;
719                        }
720
721                        WebRtcIsac_ReadBwIndex(reinterpret_cast<const uint8_t*>(
722                                                   streamDataTransCoding),
723                                               &indexStream);
724                        if (indexStream != bnIdxTC) {
725                            fprintf(stderr, "Error in inserting Bandwidth index into transcoding stream.\n");
726                            exit(0);
727                        }
728                        numTransCodingBytes += streamLenTransCoding;
729                    }
730                }
731            }
732            else
733            {
734                break;
735            }
736
737			if(stream_len < 0)
738            {
739				/* exit if returned with error */
740				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
741                printf("\n\nError in encoder: %d.\n\n", errtype);
742                cout << flush;
743			}
744			cur_framesmpls += samplesIn10Ms;
745			/* exit encoder loop if the encoder returned a bitstream */
746			if(stream_len != 0) break;
747		}
748
749        /* read next bottleneck rate */
750        if(f_bn != NULL)
751        {
752            if(fscanf(f_bn, "%d", &bottleneck) == EOF)
753            {
754                /* Set pointer to beginning of file */
755                fseek(f_bn, 0L, SEEK_SET);
756                if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
757                    exit(0);
758                }
759            }
760            if(CodingMode == 1)
761            {
762                WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
763            }
764        }
765
766        length_file += cur_framesmpls;
767        if(cur_framesmpls == (3 * samplesIn10Ms))
768        {
769            maxStreamLen30 = (stream_len > maxStreamLen30)? stream_len:maxStreamLen30;
770        }
771        else
772        {
773            maxStreamLen60 = (stream_len > maxStreamLen60)? stream_len:maxStreamLen60;
774        }
775
776        if(!lostFrame)
777        {
778            lostFrame = ((rand()%100) < packetLossPercent);
779        }
780        else
781        {
782            lostFrame = 0;
783        }
784
785        // RED.
786        if(lostFrame)
787        {
788            stream_len = WebRtcIsac_GetRedPayload(
789                ISAC_main_inst, reinterpret_cast<uint8_t*>(streamdata));
790
791            if(doTransCoding)
792            {
793                streamLenTransCoding = WebRtcIsac_GetNewBitStream(
794                    ISAC_main_inst,
795                    bnIdxTC,
796                    jitterInfoTC,
797                    rateTransCoding,
798                    reinterpret_cast<uint8_t*>(streamDataTransCoding),
799                    true);
800                if(streamLenTransCoding < 0)
801                {
802                    fprintf(stderr, "Error in RED trans-coding\n");
803                    exit(0);
804                }
805            }
806        }
807
808        /* make coded sequence to short be inreasing */
809		/* the length the decoder expects */
810		if(testNum == 4)
811        {
812			stream_len += 10;
813		}
814
815		/* make coded sequence to long be decreasing */
816		/* the length the decoder expects */
817		if(testNum == 5)
818        {
819			stream_len -= 10;
820		}
821
822        if(testNum == 6)
823        {
824			srand((unsigned int)time(NULL));
825            for(i = 0; i < stream_len; i++)
826            {
827				streamdata[i] = rand();
828            }
829		}
830
831        if(VADusage){
832            readframe(vaddata, vadp, samplesIn10Ms*3);
833        }
834
835		/* simulate packet handling through NetEq and the modem */
836		if(!(testNum == 3 && framecnt == 0))
837        {
838            get_arrival_time(cur_framesmpls, stream_len, bottleneck, &BN_data,
839                sampFreqKHz*1000, sampFreqKHz*1000);
840        }
841
842		if(VADusage && (framecnt>10 && vaddata[0]==0))
843        {
844			BN_data.rtp_number--;
845		}
846        else
847        {
848            /* Error test number 10, garbage data */
849            if(testNum == 10)
850            {
851                /* Test to run decoder with garbage data */
852                for(i = 0; i < stream_len; i++)
853                {
854                    streamdata[i] = (short) (streamdata[i]) + (short) rand();
855                }
856            }
857
858            if(testNum != 9)
859            {
860              err = WebRtcIsac_UpdateBwEstimate(
861                  ISAC_main_inst,
862                  reinterpret_cast<const uint8_t*>(streamdata),
863                  stream_len,
864                  BN_data.rtp_number,
865                  BN_data.sample_count,
866                  BN_data.arrival_time);
867
868                if(err < 0)
869                {
870                    /* exit if returned with error */
871                    errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
872                    if(testNum == 0)
873                    {
874                        printf("\n\n");
875                    }
876
877                    printf("Error: in decoder: %d.", errtype);
878                    cout << flush;
879                    if(testNum == 0)
880                    {
881                        printf("\n\n");
882                    }
883
884                }
885            }
886
887            /* Call getFramelen, only used here for function test */
888            err = WebRtcIsac_ReadFrameLen(
889                ISAC_main_inst,
890                reinterpret_cast<const uint8_t*>(streamdata),
891                &FL);
892            if(err < 0)
893            {
894                /* exit if returned with error */
895                errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
896                if(testNum == 0)
897                {
898                    printf("\n\n");
899                }
900                printf("    Error: in getFrameLen %d.", errtype);
901                cout << flush;
902                if(testNum == 0)
903                {
904                    printf("\n\n");
905                }
906            }
907
908            // iSAC decoding
909
910            if(lostFrame)
911            {
912                declen = WebRtcIsac_DecodeRcu(
913                    ISAC_main_inst,
914                    reinterpret_cast<const uint8_t*>(streamdata),
915                    stream_len,
916                    decoded,
917                    speechType);
918
919                if(doTransCoding)
920                {
921                    declenTC = WebRtcIsac_DecodeRcu(
922                        decoderTransCoding,
923                        reinterpret_cast<const uint8_t*>(streamDataTransCoding),
924                        streamLenTransCoding,
925                        decodedTC,
926                        speechType);
927                }
928            }
929            else
930            {
931                declen = WebRtcIsac_Decode(
932                    ISAC_main_inst,
933                    reinterpret_cast<const uint8_t*>(streamdata),
934                    stream_len,
935                    decoded,
936                    speechType);
937                if(doTransCoding)
938                {
939                    declenTC = WebRtcIsac_Decode(
940                        decoderTransCoding,
941                        reinterpret_cast<const uint8_t*>(streamDataTransCoding),
942                        streamLenTransCoding,
943                        decodedTC,
944                        speechType);
945                }
946            }
947
948            if(declen < 0)
949            {
950                /* exit if returned with error */
951                errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
952                if(testNum == 0)
953                {
954                    printf("\n\n");
955                }
956                printf("    Error: in decoder %d.", errtype);
957                cout << flush;
958                if(testNum == 0)
959                {
960                    printf("\n\n");
961                }
962            }
963
964            if(declenTC < 0)
965            {
966                if(testNum == 0)
967                {
968                    printf("\n\n");
969                }
970                printf("    Error: in decoding the transcoded stream");
971                cout << flush;
972                if(testNum == 0)
973                {
974                    printf("\n\n");
975                }
976
977            }
978        }
979        /* Write decoded speech frame to file */
980        if((declen > 0) && (numFileLoop == 0))
981        {
982          if (fwrite(decoded, sizeof(int16_t), declen,
983                     outp) != static_cast<size_t>(declen)) {
984            return -1;
985          }
986        }
987
988        if((declenTC > 0) && (numFileLoop == 0))
989        {
990          if (fwrite(decodedTC, sizeof(int16_t), declen,
991                     transCodingFile) != static_cast<size_t>(declen)) {
992            return -1;
993          }
994        }
995
996
997		fprintf(stderr, "\rframe = %5d  ", framecnt);
998        fflush(stderr);
999		framecnt++;
1000
1001        /* Error test number 10, garbage data */
1002        //if(testNum == 10)
1003        //{
1004        //    /* Test to run decoder with garbage data */
1005        //    if( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL )
1006        //    {
1007        //        fprintf(stderr, "Error: Could not open file %s\n", SEED_FILE);
1008        //    }
1009        //    else
1010        //    {
1011        //        fprintf(seedfile, "ok\n\n");
1012        //        fclose(seedfile);
1013        //    }
1014        //}
1015        /* Error test number 10, garbage data */
1016        //if(testNum == 10)
1017        //{
1018        //    /* Test to run decoder with garbage data */
1019        //    for ( i = 0; i < stream_len; i++)
1020        //    {
1021        //        streamdata[i] = (short) (streamdata[i] + (short) rand());
1022        //    }
1023        //}
1024
1025
1026		totalsmpls += declen;
1027		totalbits += 8 * stream_len;
1028#ifdef _DEBUG
1029        kbps = ((double) sampFreqKHz * 1000.) / ((double) cur_framesmpls) * 8.0 * stream_len / 1000.0;// kbits/s
1030		fy = fopen("bit_rate.dat", "a");
1031		fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
1032		fclose(fy);
1033
1034#endif /* _DEBUG */
1035
1036	}
1037	printf("\n");
1038	printf("total bits               = %d bits\n", totalbits);
1039	printf("measured average bitrate = %0.3f kbits/s\n",
1040        (double)totalbits *(sampFreqKHz) / totalsmpls);
1041    if(doTransCoding)
1042    {
1043        printf("Transcoding average bit-rate = %0.3f kbps\n",
1044            (double)numTransCodingBytes * 8.0 *(sampFreqKHz) / totalsmpls);
1045        fclose(transCodingFile);
1046    }
1047	printf("\n");
1048
1049	/* Runtime statistics */
1050	runtime = (double)(clock()/(double)CLOCKS_PER_SEC-starttime);
1051	length_file = length_file /(sampFreqKHz * 1000.);
1052
1053    printf("\n\nLength of speech file: %.1f s\n", length_file);
1054	printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime, (100*runtime/length_file));
1055
1056    if(maxStreamLen30 != 0)
1057    {
1058        printf("Maximum payload size 30ms Frames %d bytes (%0.3f kbps)\n",
1059            maxStreamLen30,
1060            maxStreamLen30 * 8 / 30.);
1061    }
1062    if(maxStreamLen60 != 0)
1063    {
1064        printf("Maximum payload size 60ms Frames %d bytes (%0.3f kbps)\n",
1065            maxStreamLen60,
1066            maxStreamLen60 * 8 / 60.);
1067    }
1068    //fprintf(stderr, "\n");
1069
1070	fprintf(stderr, "   %.1f s", length_file);
1071    fprintf(stderr, "   %0.1f kbps", (double)totalbits *(sampFreqKHz) / totalsmpls);
1072    if(maxStreamLen30 != 0)
1073    {
1074        fprintf(stderr, "   plmax-30ms %d bytes (%0.0f kbps)",
1075            maxStreamLen30,
1076            maxStreamLen30 * 8 / 30.);
1077    }
1078    if(maxStreamLen60 != 0)
1079    {
1080        fprintf(stderr, "   plmax-60ms %d bytes (%0.0f kbps)",
1081            maxStreamLen60,
1082            maxStreamLen60 * 8 / 60.);
1083    }
1084    if(doTransCoding)
1085    {
1086        fprintf(stderr, "  transcoding rate %.0f kbps",
1087            (double)numTransCodingBytes * 8.0 *(sampFreqKHz) / totalsmpls);
1088    }
1089
1090    fclose(inp);
1091	fclose(outp);
1092	WebRtcIsac_Free(ISAC_main_inst);
1093
1094
1095	exit(0);
1096}
1097